Skip to content

docs(plugins): plugin CLI, manifest & authoring-shape docs#1059

Merged
ascorbic merged 6 commits into
mainfrom
docs/plugin-cli-1057-migration
May 18, 2026
Merged

docs(plugins): plugin CLI, manifest & authoring-shape docs#1059
ascorbic merged 6 commits into
mainfrom
docs/plugin-cli-1057-migration

Conversation

@ascorbic
Copy link
Copy Markdown
Collaborator

What does this PR do?

Documents the plugin CLI / manifest / authoring-shape changes from #1040 (merged) and #1057 (open).

  • New: migration guide for site operators (plugins/upgrading-sites) — @emdash-cms/registry-cli@emdash-cms/plugin-cli rename, and the named-export → default-export change for plugin-audit-log, plugin-webhook-notifier, plugin-atproto.
  • New: migration guide for plugin authors (plugins/creating-plugins/migrating-to-the-cli) — definePlugin()satisfies SandboxedPlugin, two-file → src/plugin.ts + emdash-plugin.jsonc, tsdownemdash-plugin build/dev, type renames for sandbox-runner authors.
  • New: reference pagesemdash-plugin.jsonc manifest (fields, trust contract, publisher pinning) and the emdash-plugin CLI (init/build/dev/validate/bundle/publish), plus a "Your Atmosphere account" section.
  • Rewritten to the new shape: your-first-plugin, publishing (now the Atmosphere/atproto model), storage, api-routes, settings, capabilities, block-kit, hooks, choosing-a-format. Native-plugin docs left untouched (unaffected by feat(plugin-cli): sandboxed plugin authoring CLI #1057).
  • Sidebar wired up in docs/astro.config.mjs.

Both migration guides follow Astro's breaking-changes format (per-change entries with a "What should I do?" section and minimal Expressive Code diffs). Atmosphere account terminology is used throughout, cross-linked to the existing Atmosphere login guide and atmosphereaccount.com.

Note

This documents the open PR #1057. It should merge with or after #1057, since it describes that PR's behavior. #1040 is already merged.

Closes #

Type of change

  • Documentation

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes — N/A, docs-only (content)
  • pnpm lint passes — N/A, docs-only (content)
  • pnpm test passes (or targeted tests for my change) — N/A, docs-only
  • pnpm format has been run — N/A, oxfmt does not format .mdx; frontmatter/JSX/fence/link/anchor checks done manually
  • I have added/updated tests for my changes (if applicable) — N/A
  • User-visible strings in the admin UI are wrapped for translation (if applicable) — N/A, no admin UI changes
  • I have added a changeset (if this PR changes a published package) — N/A, docs-only (CONTRIBUTING says skip changesets for docs-only)
  • New features link to an approved Discussion: documents feat(plugin-cli): sandboxed plugin authoring CLI #1057Marketplace Discussion #296

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.7

Screenshots / test output

Full astro build is blocked locally by a pre-existing Cloudflare env issue (AI_SEARCH binding instance missing) unrelated to content. Validated instead: frontmatter, JSX tag balance, code-fence parity, internal links, and heading anchors across all touched pages.

… changes (#1040, #1057)

Adds migration guides for site operators and plugin authors, new
reference pages for emdash-plugin.jsonc and the emdash-plugin CLI, and
rewrites the sandboxed-plugin guides to the new default-export shape.
Migration guides follow Astro's breaking-changes format; Atmosphere
account terminology used throughout.
Copilot AI review requested due to automatic review settings May 16, 2026 10:44
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 16, 2026

⚠️ No Changeset found

Latest commit: de4f38e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

Scope check

This PR changes 1,278 lines across 14 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-perf-coordinator de4f38e May 18 2026, 03:55 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-i18n de4f38e May 18 2026, 03:56 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
docs de4f38e May 18 2026, 03:56 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground de4f38e May 18 2026, 03:57 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache de4f38e May 18 2026, 03:57 PM

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 16, 2026

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1059

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1059

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1059

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1059

emdash

npm i https://pkg.pr.new/emdash@1059

create-emdash

npm i https://pkg.pr.new/create-emdash@1059

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1059

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1059

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1059

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1059

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1059

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1059

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1059

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1059

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1059

commit: de4f38e

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Documents the new sandboxed plugin authoring shape and toolchain introduced by the plugin CLI/manifest work (referencing #1040 and the in-flight #1057), and rewrites the plugin docs set to match the new model for site operators and plugin authors.

Changes:

  • Adds new migration guides for site operators and plugin authors covering the CLI rename and the new default-export + manifest-based authoring shape.
  • Adds new reference pages for emdash-plugin.jsonc and the emdash-plugin CLI, and updates existing “creating plugins” docs to use them.
  • Wires the new docs pages into the Starlight sidebar.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/src/content/docs/plugins/upgrading-sites.mdx New site-operator migration guide for CLI rename + default export plugins.
docs/src/content/docs/plugins/creating-plugins/your-first-plugin.mdx Rewrites tutorial to the new manifest + src/plugin.ts authoring shape and new CLI flow.
docs/src/content/docs/plugins/creating-plugins/storage.mdx Updates storage docs to declare storage in the manifest and use the new runtime export shape.
docs/src/content/docs/plugins/creating-plugins/settings.mdx Updates settings docs to new sandboxed authoring/runtime shape + manifest-declared admin pages.
docs/src/content/docs/plugins/creating-plugins/publishing.mdx Rewrites publishing docs for Atmosphere identity model + hosted tarball publishing.
docs/src/content/docs/plugins/creating-plugins/migrating-to-the-cli.mdx New plugin-author migration guide from definePlugin() to satisfies SandboxedPlugin + manifest/CLI build.
docs/src/content/docs/plugins/creating-plugins/manifest.mdx New manifest reference page (identity/profile/trust contract/publisher pinning).
docs/src/content/docs/plugins/creating-plugins/hooks.mdx Updates hook signature guidance to rely on satisfies SandboxedPlugin inference.
docs/src/content/docs/plugins/creating-plugins/cli.mdx New CLI reference page for emdash-plugin commands and outputs.
docs/src/content/docs/plugins/creating-plugins/choosing-a-format.mdx Updates sandboxed-vs-native comparison to the new authoring shape terminology.
docs/src/content/docs/plugins/creating-plugins/capabilities.mdx Moves capability declarations to the manifest and updates validation guidance.
docs/src/content/docs/plugins/creating-plugins/block-kit.mdx Updates Block Kit examples to the new sandboxed plugin export shape.
docs/src/content/docs/plugins/creating-plugins/api-routes.mdx Updates route examples/signature notes for the new sandboxed plugin typing model.
docs/astro.config.mjs Adds new docs pages to the plugins sidebar navigation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


</Steps>

`--validate-only` skips tarball creation but still produces the `dist/` artifacts — "validate" implies "build first".
Comment on lines +66 to +75
## Profile

These feed the registry listing. `license` and a security contact are required; the rest are optional.

| Field | Required | Notes |
| -------------------------- | -------- | ------------------------------------------------------------------ |
| `license` | Yes | SPDX expression (`"MIT"`, `"Apache-2.0"`, `"MIT OR Apache-2.0"`). Used on first publish; the existing profile wins on later publishes. |
| `author` / `authors` | Yes | One of the two. `author: { name, url?, email? }` for a single author; `authors: [...]` (≤ 32) for several. Setting both is an error. |
| `security` / `securityContacts` | Yes | One of the two. Each contact needs at least one of `email` or `url`. `securityContacts: [...]` (≤ 8) for several. Setting both is an error. |
| `name` | No | Display name. Defaults to the slug. |
## Prerequisites

## Bundle format
- A valid [`emdash-plugin.jsonc`](/plugins/creating-plugins/manifest/) with `slug`, `publisher`, `license`, and a security contact. Run `emdash-plugin validate` to confirm.

Replace the `definePlugin()` wrapper with a bare object and a `satisfies` annotation:

```ts del={1} ins={2} "} satisfies SandboxedPlugin;"
Comment on lines 58 to +68
"scripts": {
"build": "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean"
"build": "emdash-plugin build",
"dev": "emdash-plugin dev"
},
"peerDependencies": {
"emdash": "*"
"emdash": ">=0.12.0"
},
"devDependencies": {
"emdash": "*",
"tsdown": "^0.6.0",
"typescript": "^5.5.0"
"@emdash-cms/plugin-cli": ">=0.1.0",
"emdash": ">=0.12.0",
"typescript": "^5.9.0"
"emdash": "*",
"tsdown": "^0.6.0",
"typescript": "^5.5.0"
"@emdash-cms/plugin-cli": ">=0.1.0",
Self-review of #1059 against the standards formalized since it was written.
Removed definition-by-negation and bundle-internal framing from the guide
pages (migration guides left as-is — comparison/changelog is their purpose):

- 'You do not write a descriptor or a build script' -> dropped (the positive
  sentence already says what build does)
- 'the build produces both, so you never hand-write either' -> 'generates both'
- 'type-only, so the emdash runtime does not enter the plugin bundle' /
  'the bundler erases them — no emdash runtime enters' -> 'provides only
  types, so a sandboxed plugin has no runtime dependency on emdash'
- 'you never write it by hand' -> 'EmDash derives ... automatically'
- 'init never requires extra flags to succeed' -> 'A slug is the only
  required input'
- 'wire-side filename' -> '(the filename the registry expects)'
- 'The registry never stores your plugin's code' lead -> dropped; the
  positive 'you host the tarball; registry stores a link' carries it

Tropes scan clean; em-dashes appositive; bold bullets definitional.
ascorbic added a commit that referenced this pull request May 16, 2026
* docs: add documentation style guide and bring all docs up to standard

Adds a Documentation Style Guide (contributing/docs-style-guide) distilling
Astro-grade conventions: readability, neutral voice (no we/us/let's), code-sample
intros, Expressive Code diffs, the upgrade-guide breaking-changes format, headings,
and EmDash specifics (sandboxed vs native, Atmosphere accounts, experimental
surfaces, no messages.po in PRs).

Audits and updates every other docs page against it. Excludes the pages in
PR #1059 (plugin CLI/manifest/authoring docs). Also fixes real defects found
during the audit: broken Astro frontmatter in three coming-from/wordpress code
samples, two dead internal links (plugin-porting -> porting-plugins), an
inconsistent field-type count, and competitor name-drops.

* docs: separate 'how to use' from 'how it's built'

Adds contributing/architecture (internals) and rewrites concepts/architecture,
concepts/content-model, and concepts/admin-panel around what a reader decides
and does. Relocates table layouts, the request path, code generation, admin
internals, and the ImportSource extensibility API into the contributor doc
rather than deleting them. Trims protocol/format internals from
reference/mcp-server, migration/content-import, and guides/preview.

Also corrects contributing/translating: AI-generated translations are accepted
when a fluent speaker reviews every string and previews them in the running
admin panel; only unsupervised machine output is rejected.

* docs: cut recency bias, straw-man framing, and definition-by-negation

Removes 'database-first/schema as data' framing from user-facing pages
(it described an internal decision, not a user capability) and reframes
around what the reader does. The mechanism stays only in the contributor
architecture doc. Removes definition-by-negation ('no migration to write',
'no rebuild', 'without code') in favour of positive statements of what
happens. Keeps honest, specific comparison only on the evaluation and
'coming from' orientation pages.

Adds 'What to emphasise', 'Evergreen, not changelog', and a
definition-by-negation rule to the style guide, and reorders its own
'EmDash specifics' so it models the principle rather than ranking by
recency. Corrects the translating policy (supervised AI translations
are accepted).

* docs: remove AI tropes (negation, em-dash drama, builder-salience leaks)

Sweep against the AI-tropes reference across all in-scope pages. Mostly
definition-by-negation and straw-man self-definition still hiding in
intros and benefit cards ('no PHP', 'no API round-trips', 'without
rebuilds', 'no bundler, no manifest — just a regular npm package'),
restated as what the reader does or gets. Also: dramatic-pause em-dashes
split into sentences, prose pipeline arrows and a breadcrumb arrow
de-unicoded, a Kysely reference dropped from the introduction diagram,
and roadmap/changelog voice removed from the encryption-key and
auth-secret deployment notes. Definitional bold lists, appositive
em-dashes, UI breadcrumbs, code/diagram arrows, native plugin API code,
and honest comparison on evaluation/coming-from pages were preserved.

* docs: fix factual errors found auditing claims against source

Verified each against packages/* source:
- getSections returns { items, nextCursor }, not Section[] (sections guide, api ref)
- removed fictional getSectionCategories / getSections({category}) from API ref
- getEmDashEntry options param, getSiteSetting("title"), isPreviewRequest/getPreviewToken take URL, search() returns { items } (api ref)
- content create flag is --draft (+ --locale/--translation-of), not --status (cli ref)
- r2/d1 import from @emdash-cms/cloudflare not emdash/astro|emdash/db; emdashLoader() takes no args; fonts list missing farsi (config ref)
- hook page:metadata link.rel allowlist + jsonld graph union (hooks ref)
- field type count 16 not 14; added url/repeater rows; corrected reserved field slugs (field-types ref, collections)
- REST: admin plugin paths, PUT not PATCH for collection/field/user updates, search response envelope, error codes (rest-api ref)
- MCP: 45 tools not 43, role requirements, error-envelope shape (mcp ref)
- media-library/architecture r2/local import paths; menus getMenus includes locale; widgets post.data.slug; admin-panel roles (no 'Developer' role)

* docs: remove hallucinated APIs flagged in correctness audit

Confirmed against source as non-existent (not planned, not drift-to-real):
- auth config object { selfSignup, session, cloudflareAccess }: emdash({auth})
  takes an adapter (access() from @emdash-cms/cloudflare). Rewrote the
  configuration + authentication auth sections to the real AuthDescriptor /
  access() surface with accurate AccessConfig options; removed the invented
  selfSignup/session config; pointed self-signup at the real provider allowlists.
- reference/api.mdx: removed Database functions / Repositories / Schema
  registry sections (createDatabase is not a public export and there is no
  public Kysely handle) and the searchCollection example (wrong signature,
  needs a non-public db arg). Kept the verified-public search().
- guides/internationalization: removed the fictional 'emdash import wordpress
  --locale --translation-of-locale' (no import CLI command/flags); point to
  the real admin import flow + content create --locale --translation-of.
- configuration.mdx: dropped package.json emdash.description / emdash.preview
  (not read by any code; label/seed/url are).

* docs: address Copilot review on #1060

- installing.mdx: fix marketplace + config snippets — default import
  'emdash from emdash/astro', add missing defineConfig import,
  sandboxRunner is a module specifier string not a boolean
  (verified: EmDashConfig.sandboxRunner?: string)
- field-kit.mdx: integration imports from emdash/astro, not emdash
- contributing/docs-style-guide.mdx: 'memorise' -> 'memorize' (US spelling)
- themes/seed-files.mdx: correct the slug-validation summary (slug rules
  differ by type) instead of the misleading 'lowercase, underscores'

Field-type count (field-types/collections, '14' -> '16') was already
fixed in the earlier source-correctness pass; verified still correct.

* docs: stop presenting EmDash as SQLite-only — PostgreSQL is a first-class adapter

postgres() is exported from emdash/db alongside sqlite/libsql (verified
in source); only deployment/database + reference/configuration mentioned
it. Corrected the SQLite-only framing in the pages that enumerate
supported databases:

- introduction: 'SQLite-compatible databases (D1, libSQL, local
  SQLite)' / cloud-portable bullets / aside / diagram
- why-emdash: Cloud-Portable card + Cloudflare-deployment intro
- concepts/architecture: diagram + 'what you configure' bullet
- contributing/architecture: Kysely supported-dialect list
- coming-from/astro: two comparison-table cells
- deployment/nodejs: note libSQL/PostgreSQL also work, link to Database Options

Diagram lines re-padded to preserve box alignment. Opinionated SQLite
examples (getting-started, the nodejs walkthrough body) left as-is —
they demonstrate one choice, they don't claim it's the only one.
@ascorbic ascorbic changed the title docs(plugins): plugin CLI, manifest & authoring-shape docs (#1040, #1057) docs(plugins): plugin CLI, manifest & authoring-shape docs May 18, 2026
- Manifest profile prose lists author and security contact as required,
  matching the table and the actual ManifestSchema (.refine() rules in
  packages/plugin-cli/src/manifest/schema.ts require one of author/
  authors and one of security/securityContacts).
- Publishing prerequisites match the same required-fields story.
- Bundle flag documentation uses kebab-case (--out-dir, --validate-only)
  to match the post-rename CLI (#1091).
- your-first-plugin scaffolding example bumps emdash to >=0.13.0 (the
  first release exposing the emdash/plugin entrypoint) and pins
  @emdash-cms/plugin-cli to 0.2.0 (exact pin per the publishing page's
  experimental-registry guidance).
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

@@ -7,21 +7,20 @@ import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";

Plugins can expose API routes for their admin UI and external integrations. Routes are mounted under `/_emdash/api/plugins/<plugin-id>/<route-name>` and run inside the sandbox runtime with the same `PluginContext` that hooks receive.
Comment on lines 358 to 359
interface SandboxedRouteContext<TInput = unknown> {
input: TInput;
Hooks let plugins run code in response to events. All hooks receive an event object and the plugin context, and they're declared at plugin definition time — there's no dynamic registration at runtime.

This page covers sandboxed (standard-format) plugins. Hooks work identically in native plugins; the only difference is that native plugins can also register `page:fragments`, which sandboxed plugins can't.
This page covers sandboxed plugins. Hooks work identically in native plugins; native plugins can additionally register `page:fragments`.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — but keeping the current framing here. The user-facing distinction in EmDash docs is native vs sandboxed (where the plugin is installed: plugins: [] vs sandboxed: [] in live.config.ts), not trusted vs sandboxed. We are deliberately moving away from the "trusted" terminology in user-facing docs because it is misleading — "trusted" describes a runtime mode, not something a plugin author chooses, and conflating it with the install location confuses readers more than it clarifies.

A sandboxed-format plugin that gets installed under plugins: [] is, from the docs perspective, a native plugin — so saying page:fragments is "native only" is accurate at the level docs operate at.

Comment on lines 47 to 50
1. **Custom React admin pages or widgets.** Sandboxed plugins describe their admin UI with Block Kit — a JSON schema that the admin renders on the plugin's behalf. If you need full React (custom hooks, third-party components, complex state), you need native.
2. **Astro components for rendering Portable Text blocks on the public site.** A plugin can declare a custom block type with `format: "standard"`, but the Astro components that render it on the public site have to be loaded at build time from npm. Only native plugins can provide a `componentsEntry`.
2. **Astro components for rendering Portable Text blocks on the public site.** A sandboxed plugin can declare a custom block type, but the Astro components that render it on the public site have to be loaded at build time from npm. Only native plugins can provide a `componentsEntry`.
3. **Injecting raw HTML, scripts, or stylesheets into public pages.** The `page:fragments` hook ships first-party code to visitors' browsers — outside any sandbox boundary. It's restricted to native plugins. Sandboxed plugins can still contribute to public pages through the `page:metadata` hook, which covers a lot of real use cases:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — but keeping the current framing here. The user-facing distinction in EmDash docs is native vs sandboxed (where the plugin is installed: plugins: [] vs sandboxed: [] in live.config.ts), not trusted vs sandboxed. We are deliberately moving away from the "trusted" terminology in user-facing docs because it is misleading — "trusted" describes a runtime mode, not something a plugin author chooses, and conflating it with the install location confuses readers more than it clarifies.

A sandboxed-format plugin that gets installed under plugins: [] is, from the docs perspective, a native plugin — so saying page:fragments is "native only" is accurate at the level docs operate at.

| `network:request:unrestricted` | Outbound HTTP to any host. Used instead of `network:request`. |
| `hooks.email-transport:register` | Register an email transport hook. |
| `hooks.email-events:register` | Register email lifecycle hooks. |
| `hooks.page-fragments:register` | Register a `page:fragments` hook (native only). |
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — but keeping the current framing here. The user-facing distinction in EmDash docs is native vs sandboxed (where the plugin is installed: plugins: [] vs sandboxed: [] in live.config.ts), not trusted vs sandboxed. We are deliberately moving away from the "trusted" terminology in user-facing docs because it is misleading — "trusted" describes a runtime mode, not something a plugin author chooses, and conflating it with the install location confuses readers more than it clarifies.

A sandboxed-format plugin that gets installed under plugins: [] is, from the docs perspective, a native plugin — so saying page:fragments is "native only" is accurate at the level docs operate at.

emdash-plugin info <handle-or-did> <slug> Show package details
```

All commands accept `--json`. Discovery commands (`search`, `info`) accept `--aggregator <url>` (or `EMDASH_REGISTRY_URL`).
- api-routes: clarify that the route URL segment is the plugin's slug
  (the same value as ctx.plugin.id at runtime) — previously phrased as
  <plugin-id> without explaining what that is.
- api-routes: SandboxedRouteContext is non-generic in emdash/plugin
  (input is unknown; authors narrow with a route-level Zod schema). The
  earlier reference snippet showed a TInput generic that doesn't exist
  in the exported type.
- cli: --json is supported by the non-interactive output commands
  (whoami, validate, search, info, login, publish), not all commands —
  logout, switch, init, build, dev, bundle do not define a json arg.
The CLI flag for overriding the discovery endpoint is being renamed
from --aggregator to --registry-url in #1092, matching the
EMDASH_REGISTRY_URL env var and the user-facing concept of a registry.
Update the docs to use the new flag name and drop the user-facing
mention of 'aggregator' in publishing.mdx in favour of 'registry'.
@ascorbic ascorbic merged commit 9553084 into main May 18, 2026
36 of 37 checks passed
@ascorbic ascorbic deleted the docs/plugin-cli-1057-migration branch May 18, 2026 18:46
ski added a commit to ski/emdash that referenced this pull request May 20, 2026
Catches deployment/suhail-ski up with emdash-cms/emdash main. Conflict in
pnpm-lock.yaml resolved by taking upstream's lock and re-running
pnpm install to pick up the @suhailski/57th-parallel template deps.

Notable upstream changes folded in:
  - Plugin authoring CLI + manifest format (emdash-cms#1057, emdash-cms#1059)
  - Registry packages — lexicons, client, CLI (emdash-cms#923)
  - Migration 036 taxonomy preservation (emdash-cms#1086)
  - WXR import w/ WPML/Polylang translations (emdash-cms#1087)
  - TypeScript 6 upgrade, tsgo beta (emdash-cms#1074)
  - FTS5 corruption fix on publish (emdash-cms#768)
  - Plugin bundle size caps (emdash-cms#978)
  - And ~280 smaller fixes / chores

CLI rebuilt against the new core. Verified by listing posts on
suhail.ski — both tutorial posts come back as expected.

57th-parallel template untouched by upstream. Our 5 local commits
preserved across the merge.

Used --config.manage-package-manager-versions=false to bypass pnpm's
self-switch to 11.1.3, which packages weirdly on Windows. The current
shell's pnpm 10.12.4 worked fine against the merged manifests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants