diff --git a/.changeset/attribution-2881.md b/.changeset/attribution-2881.md deleted file mode 100644 index 7683ed4f61..0000000000 --- a/.changeset/attribution-2881.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"emdash": patch -"@emdash-cms/plugin-audit-log": patch ---- - -Fixes content attribution for authenticated REST, visual editing, and MCP saves. - -- Revisions record the acting user without changing the entry owner. MCP updates preserve the existing owner, and actorless internal writes leave revision attribution unset instead of inferring it from ownership. -- `content:beforeSave` and `content:afterSave` receive an actor snapshot with the authenticated user's `id` and `role`. The snapshot is isolated between hooks so one plugin cannot change the attribution seen by another. -- The audit-log plugin stores the actor ID as `userId` on content create and update entries. diff --git a/.changeset/bright-lions-connect.md b/.changeset/bright-lions-connect.md deleted file mode 100644 index e40099d340..0000000000 --- a/.changeset/bright-lions-connect.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@emdash-cms/plugin-cli": minor -"@emdash-cms/registry-client": minor ---- - -Adds repository-level automated plugin releases. `emdash-plugin release setup` writes one shared `.github/workflows/emdash-release.yml` at the Git repository root, including when setup runs from a nested package. The workflow resolves `@` tags to a unique plugin manifest, rejects version mismatches before attestation, and requests its first repository connection through GitHub OpenID Connect without an Actions secret. - -Prepare later packages with `emdash-plugin profile setup --dir `. Their first release reuses approved repository workflow scopes when the signed package profile names the same repository. Tag and manual-run scopes accumulate after publisher confirmation instead of replacing each other. Existing package approvals remain package-scoped until the publisher explicitly confirms a repository connection; existing generated workflows and the legacy optional connection-invitation input remain supported. diff --git a/.changeset/bright-plugins-name.md b/.changeset/bright-plugins-name.md deleted file mode 100644 index 83817ec8fd..0000000000 --- a/.changeset/bright-plugins-name.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@emdash-cms/admin": minor ---- - -Adds public names for registry plugins in the `@publisher.example/plugin-slug` format. Registry results and installed-plugin cards display the verified public name and link to a handle-based detail URL, while exact public-name searches open the matching package. - -When a publisher handle conclusively fails identity verification, the admin displays **INVALID HANDLE** and prevents installation. Temporary lookup failures fall back to the stable publisher identifier without marking the handle invalid. diff --git a/.changeset/bright-snapshots-travel.md b/.changeset/bright-snapshots-travel.md deleted file mode 100644 index 84bdc5bf71..0000000000 --- a/.changeset/bright-snapshots-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes snapshot exports and content backups on PostgreSQL so preview snapshots, manual backups, and scheduled backups include the same content and portable schema metadata as SQLite. diff --git a/.changeset/calm-bindings-report.md b/.changeset/calm-bindings-report.md deleted file mode 100644 index 38fd4f0622..0000000000 --- a/.changeset/calm-bindings-report.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"emdash": patch -"@emdash-cms/cloudflare": patch ---- - -Fixes Cloudflare binding failures during runtime startup returning `NOT_CONFIGURED` from EmDash API routes. Missing D1, R2, KV, Durable Object, and Hyperdrive bindings now return `BINDING_NOT_FOUND` with the binding-specific setup message. Invalid KV and Hyperdrive binding configuration returns `CONFIGURATION_ERROR`. diff --git a/.changeset/calm-bundles-stay.md b/.changeset/calm-bundles-stay.md deleted file mode 100644 index 23df68520a..0000000000 --- a/.changeset/calm-bundles-stay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes overlapping marketplace or registry plugin updates and downgrades deleting the active plugin bundle. Updates retain previous version bundles so delayed work cannot remove a version that becomes active again. diff --git a/.changeset/calm-foxes-scaffold.md b/.changeset/calm-foxes-scaffold.md deleted file mode 100644 index f9853c1325..0000000000 --- a/.changeset/calm-foxes-scaffold.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@emdash-cms/plugin-cli": minor ---- - -Updates `emdash-plugin init` to produce a validated, package-manager-aware plugin project. Interactive setup shows the resolved publisher, author, security contact, repository, target, and package manager before writing. Non-interactive setup requires explicit ownership flags unless `--use-detected` opts into the active publisher session and local Git metadata. - -Generated projects pin the plugin CLI version, use bounded EmDash dependencies, include validation and publishing scripts, and add `AGENTS.md` with a local `creating-plugins` skill. `.agents/skills` and `.claude/skills` link to the same canonical skill directory, while `.claude/CLAUDE.md` links to `AGENTS.md`. pnpm projects include the reviewed `esbuild` install policy and use an explicit `SandboxedPlugin` annotation so declaration output remains portable. The scaffolder validates the complete manifest and parent paths before writing and stages new projects atomically. diff --git a/.changeset/calm-keys-guide.md b/.changeset/calm-keys-guide.md deleted file mode 100644 index 796457c540..0000000000 --- a/.changeset/calm-keys-guide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/admin": patch ---- - -Improves passkey account creation with device-aware guidance before the browser prompt. EmDash explains what a passkey is and where it is saved, detects when a built-in authenticator is unavailable, and guides users through Windows Hello, another device, or a security key. Compatible browsers receive a preference for the selected path, while the browser continues to control the secure passkey prompt. diff --git a/.changeset/calm-registry-first-releases.md b/.changeset/calm-registry-first-releases.md deleted file mode 100644 index e3c80997f0..0000000000 --- a/.changeset/calm-registry-first-releases.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@emdash-cms/registry-lexicons": minor -"@emdash-cms/registry-client": minor -"@emdash-cms/admin": patch -"emdash": patch ---- - -Adds a fail-closed first-release exemption to the plugin registry's optional minimum release age policy. A package's first release can install immediately only when the aggregator reports exactly one retained release and confirms that it continuously observed the package's release history. - -Existing packages, backfilled packages, and packages with missing or incomplete history remain subject to the configured holdback. Deleted releases still count, and explicit publisher or package exemptions continue to work. diff --git a/.changeset/calm-themes-follow.md b/.changeset/calm-themes-follow.md deleted file mode 100644 index 0293c32e81..0000000000 --- a/.changeset/calm-themes-follow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/admin": patch ---- - -Fixes the admin appearance toggle so every click changes the visible color scheme. The admin follows the system preference whenever the selected appearance matches it. diff --git a/.changeset/collection-sidebar-groups.md b/.changeset/collection-sidebar-groups.md deleted file mode 100644 index 467c81ecee..0000000000 --- a/.changeset/collection-sidebar-groups.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"emdash": minor -"@emdash-cms/admin": minor ---- - -Adds a `group` setting to collections. Collections that share a group render as one collapsible folder in the admin sidebar, positioned where the first of them appears; a taxonomy joins the folder when every collection it is assigned to is shown in that folder. A folder you have not touched opens while one of its members is active; once you open or close it yourself, the sidebar remembers that choice in the browser. Set the group in the content type editor under Navigation, in seed files, or through the schema API and the MCP collection tools; leaving it empty keeps today's flat list. diff --git a/.changeset/complete-pt-br-admin-translation.md b/.changeset/complete-pt-br-admin-translation.md deleted file mode 100644 index d1120adfc4..0000000000 --- a/.changeset/complete-pt-br-admin-translation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/admin": patch ---- - -Completes the Brazilian Portuguese (`pt-BR`) admin translation. Brazilian Portuguese admins now see localized text throughout the admin instead of falling back to English for 1,170 of 2,292 strings. diff --git a/.changeset/emdashhead-seo-panel.md b/.changeset/emdashhead-seo-panel.md deleted file mode 100644 index 07307178c6..0000000000 --- a/.changeset/emdashhead-seo-panel.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"emdash": minor ---- - -`` now applies the entry's SEO panel values (title, description, image, canonical, noindex) automatically on server-rendered content pages. Previously the panel was silently ignored unless the page wired `getSeoMeta()` by hand. - -#### Affected pages - -Pages that include `` and fetch their entry through `getEmDashEntry()` receive the overlay. This includes warm object-cache hits, because `getEmDashEntry()` primes the same request-scoped cache from the cached snapshot when the loader never runs. Multi-entry collection results (e.g. `getEmDashCollection()`) are not currently covered. - -#### What editors can override - -Editor-set panel values replace the template-provided base fields for `description`, `og:title`, `og:description`, `og:image`, the canonical URL, and robots. They also feed the JSON-LD structured data, so head tags and structured data stay in sync. - -#### What plugins see - -Plugin `page:metadata` and `page:fragments` hooks — in the head and in the body components — receive the overlaid page context, but plugin contributions still win via first-wins dedup. - -#### What does not change - -- The `` element remains the template's responsibility. -- Prerendered pages and pages that bypass `<EmDashHead>` keep using `getSeoMeta()`. -- No additional database query is made; the panel data rides along on the entry query the page already runs. - -#### Canonical and image URL resolution - -`getSeoMeta()` now resolves an explicit SEO panel canonical through the same resolver as `<EmDashHead>`: root-relative values (`/custom-path`) are absolutized against the site URL when one is configured (previously they were returned unchanged), and protocol-relative values (`//host/path`) pass through untouched. The same panel value now produces the same canonical URL on both paths. - -Protocol-relative SEO image references (`//cdn.example.com/x.png`) are no longer prefixed with the site URL, which previously produced a broken doubled-path URL. This corrects `og:image` output everywhere the panel image is resolved: the `<EmDashHead>` overlay, `getSeoMeta()`, and image URLs in the sitemap. diff --git a/.changeset/entry-edit-lock.md b/.changeset/entry-edit-lock.md deleted file mode 100644 index 5a58c05708..0000000000 --- a/.changeset/entry-edit-lock.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"emdash": minor -"@emdash-cms/admin": minor ---- - -Adds an edit lock per content entry, so two people no longer discover a collision only after both have done the work. - -Opening an entry in the admin takes a lock on it. A second editor is told who has it and chooses between opening the entry read-only, where nothing they type can be lost to a refused save, and taking it over. After a take-over, the previous holder is told within two minutes that the entry moved on, their next save is refused, and a banner names who holds it now. - -The lock lasts seven minutes. The admin renews it every two minutes while the entry is open, so a pause in typing does not lose it, and every save on the entry extends it too. Leaving the editor or closing the tab releases it, as does moving the entry to the trash; a tab that loses power or network lets it lapse. - -#### Who is newly refused - -Scripts, API tokens and the CLI that update, delete, publish, unpublish, schedule or discard an entry while an editor has it open in the admin now receive `409 ENTRY_LOCKED` where the write used to succeed. This applies to every collection once the migration has run. The response's `error.message` names the holder and `error.details` carries their `userId`, `userName`, `acquiredAt` and `expiresAt`. Pass `"overrideLock": true` in the request body to write anyway, or `?overrideLock=true` on `DELETE`, which has no body. The CLI takes `--override-lock` on `content update`, `content delete`, `content publish`, `content unpublish` and `content schedule`. The MCP content tools do not honour the lock yet. - -Locks are per entry and per locale, so two translations of the same entry can be edited at once. - -Take or read a lock directly through `GET`, `POST` and `DELETE` on `/_emdash/api/content/{collection}/{id}/lock`. - -#### Turning it off - -Locking is on for every collection. Switch it off under **Content Types** → your collection → **Edit locking**, with `editLocking: false` in a seed file, or through `schema_update_collection`: - -```json -{ "slug": "posts", "editLocking": false } -``` - -#### Upgrading - -Includes database migration `075_entry_edit_locks`. Projects on the default `auto` runtime migration mode need no action. Projects that migrate as a deployment step: run `emdash migrate` before deploying this version. diff --git a/.changeset/fresh-tools-test.md b/.changeset/fresh-tools-test.md deleted file mode 100644 index ad72b6467c..0000000000 --- a/.changeset/fresh-tools-test.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@emdash-cms/plugin-test": minor -"@emdash-cms/plugin-cli": minor ---- - -Adds a workerd-backed Vitest host for sandboxed plugin tests and includes it in projects created by `emdash-plugin init`. `emdashPluginTest()` builds the plugin and configures D1, Worker Loader, and the production `PluginBridge`; `createPluginTestHost()` invokes hooks and routes through the production sandbox boundary and provides helpers for content fixtures, plugin storage, and KV assertions. diff --git a/.changeset/friendly-dogs-plan.md b/.changeset/friendly-dogs-plan.md deleted file mode 100644 index e86c6ee290..0000000000 --- a/.changeset/friendly-dogs-plan.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@emdash-cms/plugin-cli": minor ---- - -Adds Changesets-aware automated plugin releases. `emdash-plugin release setup` detects a root `.changeset/config.json` and offers to follow Changesets releases, `<slug>@<version>` tags, or manual runs. Use `--trigger auto|changesets|tags|manual` in non-interactive setup. - -The Changesets variant accepts the official Changesets Action published-package JSON through a reusable workflow. It supports mixed monorepos where npm package names differ from EmDash plugin IDs, ignores ordinary npm packages, verifies every reported plugin version, and publishes matching plugins as a matrix. Private EmDash-only packages produce a setup warning unless Changesets versions and tags them. diff --git a/.changeset/gallery-cell-sizes.md b/.changeset/gallery-cell-sizes.md deleted file mode 100644 index 16abd63204..0000000000 --- a/.changeset/gallery-cell-sizes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes the Portable Text `Gallery` component telling browsers each image fills the viewport. Its `sizes` attribute now describes one grid cell, using the gallery's column count and its two-column layout at 640px and below, so browsers stop downloading oversized images for multi-column galleries. Pass the new `sizes` prop to `Gallery` when it renders in a container narrower than the viewport. diff --git a/.changeset/german-translations-tables-passkeys.md b/.changeset/german-translations-tables-passkeys.md deleted file mode 100644 index 03fc6707bc..0000000000 --- a/.changeset/german-translations-tables-passkeys.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/admin": patch ---- - -Completes the German admin translations so German-speaking editors see localized text instead of English in the table editor, passkey setup, edit locking, image field uploads, and the plugin registry. diff --git a/.changeset/hidden-collections-dashboard-quick-action.md b/.changeset/hidden-collections-dashboard-quick-action.md deleted file mode 100644 index 55480de9e6..0000000000 --- a/.changeset/hidden-collections-dashboard-quick-action.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/admin": patch ---- - -Fixes the dashboard showing a "+ New …" quick action for collections marked `hidden`, matching the sidebar link the flag already removes. diff --git a/.changeset/inline-editor-unchanged-saves.md b/.changeset/inline-editor-unchanged-saves.md deleted file mode 100644 index 545536bfd6..0000000000 --- a/.changeset/inline-editor-unchanged-saves.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes visual editing saving a new draft when nothing changed. With edit mode on, the inline Portable Text editor saved the body every time focus left it and every time the page was left, even if no one had typed, because each save check compared freshly generated block keys against the stored ones. Entries picked up drafts that differed only in `_key` and showed "Pending changes" in the admin. The editor now compares its document with the one last saved, so an unedited body is never saved and a real edit is saved once. diff --git a/.changeset/moderation-manipulation-findings.md b/.changeset/moderation-manipulation-findings.md deleted file mode 100644 index 9afea465cb..0000000000 --- a/.changeset/moderation-manipulation-findings.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@emdash-cms/registry-moderation": minor -"@emdash-cms/registry-lexicons": minor ---- - -Adds `moderation-manipulation` findings so labelers can distinguish direct attempts to bypass automated moderation from quoted or descriptive discussion of prompt injection. diff --git a/.changeset/non-translatable-sync-on-publish.md b/.changeset/non-translatable-sync-on-publish.md deleted file mode 100644 index 460aa47f2e..0000000000 --- a/.changeset/non-translatable-sync-on-publish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes non-translatable fields never reaching an entry's other translations on collections with revisions, which is the default. Publishing an entry now copies the non-translatable values it changed to the rest of its translation group, and a save that started from a translation's earlier version gets a conflict instead of overwriting the copied values. Values that already differ between translations stay as they are until a change to that field is published in one of them. diff --git a/.changeset/olive-crabs-repeat.md b/.changeset/olive-crabs-repeat.md deleted file mode 100644 index 3a79f94596..0000000000 --- a/.changeset/olive-crabs-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes visual editing on list pages. Entries from `getEmDashCollection` now carry a working `edit` proxy in edit mode, so spreading `{...entry.edit.title}` renders the annotation and the toolbar makes the element editable. Previously every collection entry received a no-op proxy in every mode, so only pages built from `getEmDashEntry` were click-to-edit — fields shown exclusively in a list, and collections with no detail page, could not be edited on the page at all. diff --git a/.changeset/permalink-date-tokens.md b/.changeset/permalink-date-tokens.md deleted file mode 100644 index 2b3f4c4961..0000000000 --- a/.changeset/permalink-date-tokens.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"emdash": minor -"@emdash-cms/admin": minor ---- - -Adds WordPress-style date tokens to collection URL patterns. `url_pattern` now supports `{year}`, `{month}`, `{day}`, `{hour}`, `{minute}`, `{second}` (resolved from the entry's publish date, zero-padded) alongside `{slug}` and `{id}` — so you can reproduce permalinks like `/{year}/{month}/{day}/{slug}.html`. The tokens resolve everywhere the pattern is used: sitemap canonical URLs, hreflang alternates, navigation menu links, slug-change auto-redirects, and the admin's preview and "View published" links. Tokens stay literal when an entry has no publish date, so canonical URLs remain stable across edits. diff --git a/.changeset/plugin-http-external-targets.md b/.changeset/plugin-http-external-targets.md deleted file mode 100644 index 160f05448e..0000000000 --- a/.changeset/plugin-http-external-targets.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"emdash": patch -"@emdash-cms/sandbox-workerd": patch ---- - -Fixes plugin HTTP requests with `allowedHosts` so initial URLs and redirects also pass SSRF validation. Requests are rejected when URL or DNS validation identifies an unsupported scheme or a non-public address. - -Existing callers of the shared outbound URL validator also reject these non-public ranges. - -The default validator resolves public hostnames through `cloudflare-dns.com` before dispatch. Self-hosted deployments must permit access to that endpoint when using the default resolver. diff --git a/.changeset/plugin-storage-range-filter-guard.md b/.changeset/plugin-storage-range-filter-guard.md deleted file mode 100644 index 9958f2634a..0000000000 --- a/.changeset/plugin-storage-range-filter-guard.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"emdash": patch ---- - -Fixes a plugin storage range filter whose every bound is `undefined` matching every row instead of failing. Building a bound from an optional value — `where: { stock: { gte: minStock } }` where `minStock` is `undefined` — type-checks, but contributed no SQL, so `query()` and `count()` returned the whole collection and `updateIf()` applied its write with no guard at all. A guarded decrement could then drive a counter past the bound the caller asked for. - -Such a filter now throws `StorageQueryError` naming the field. Pass a defined bound, or omit the field when you mean to match unconditionally: - -```typescript -const where = minStock === undefined ? {} : { stock: { gte: minStock } }; -await ctx.storage.products.query({ where }); -``` diff --git a/.changeset/plugin-storage-updateif.md b/.changeset/plugin-storage-updateif.md deleted file mode 100644 index 081e22ff81..0000000000 --- a/.changeset/plugin-storage-updateif.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"emdash": minor -"@emdash-cms/cloudflare": patch -"@emdash-cms/sandbox-workerd": patch ---- - -Adds `ctx.storage.<collection>.updateIf(id, { where, set?, delta? })` for atomic conditional updates to existing plugin documents. Use `where` to check stored fields, `set` to replace field values, and `delta` to increment or decrement integer counters. The method returns `{ applied: true, data }` with the updated document, or `{ applied: false }` when the document is absent or the condition fails. It never inserts a document. - -Malformed update arguments reject without writing. Deltas require safe integer operands and results; missing or `null` counters start at `0`. Invalid stored counters, overflow, and non-object documents return `{ applied: false }` without changing any fields. - -Available to native plugins and sandboxed plugins on Cloudflare and Workerd, with SQLite, D1, and PostgreSQL support. PostgreSQL serialization failures and deadlocks expose `code: "STORAGE_SERIALIZATION_FAILURE"` and `retryable: true`, including across sandbox transports. Retry standalone calls with bounded backoff, or restart the entire explicit transaction. diff --git a/.changeset/polished-portable-text-tables.md b/.changeset/polished-portable-text-tables.md deleted file mode 100644 index d2822f2417..0000000000 --- a/.changeset/polished-portable-text-tables.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@emdash-cms/admin": minor -"emdash": minor ---- - -Adds responsive, lossless Portable Text tables with an accessible size picker, complete row and column controls, merge and split, persistent column widths, HTML and spreadsheet clipboard support, keyboard navigation, and right-to-left resizing. Wide tables keep their horizontal position while resizing, hide native scrollbar chrome, and show edge shadows for hidden columns. - -Use the compact, scrollable Table menu for structural actions, or press Backspace or Delete to remove selected full rows or columns. Undo restores the removed content and structure. - -The editor toolbar no longer includes Spotlight Mode, leaving more room for table controls at the standard editor width. - -The public renderer now preserves table headers, spans, alignment, and preferred widths. Existing legacy string-cell tables continue to render. `portableTextToProsemirror()` now returns real `table`, `tableRow`, `tableHeader`, and `tableCell` nodes, so custom ProseMirror schemas that consume its output must register the existing TipTap table extensions. - -Pass a localized `tablePlaceholder` string to `PortableText` to set the inline editor's initial table label. Omitted values retain the English label. diff --git a/.changeset/purge-entry-term-assignments.md b/.changeset/purge-entry-term-assignments.md deleted file mode 100644 index fe9a900981..0000000000 --- a/.changeset/purge-entry-term-assignments.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes permanently deleting an entry leaving its taxonomy term assignments in the database. The assignments are removed with the last translation of the entry and kept while another translation exists, including one in the trash. diff --git a/.changeset/quiet-sandboxes-listen.md b/.changeset/quiet-sandboxes-listen.md deleted file mode 100644 index 38d22b8fd9..0000000000 --- a/.changeset/quiet-sandboxes-listen.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@emdash-cms/cloudflare": patch -"create-emdash": patch -"emdash": patch ---- - -New Cloudflare projects leave the paid-plan Worker Loader binding disabled so they can deploy on the Workers free plan. Enable sandboxed plugins in the scaffold prompt or with `--sandboxed-plugins`. - -The Cloudflare `sandbox()` helper now selects the runner from the `LOADER` binding in `wrangler.jsonc`, including the named environment selected with `CLOUDFLARE_ENV`. Without it, config-based sandboxed plugins do not load and marketplace or registry installs return `SANDBOX_NOT_AVAILABLE`, while browsing remains available. diff --git a/.changeset/quiet-taxis.md b/.changeset/quiet-taxis.md deleted file mode 100644 index a6618cc432..0000000000 --- a/.changeset/quiet-taxis.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@emdash-cms/admin": patch -"emdash": patch ---- - -Fixes marketplace plugin updates so administrators review newly requested capabilities, public routes, and MCP tools before granting them. Update confirmation remains pinned to the version that was reviewed, so a newer release requires a separate review. diff --git a/.changeset/sandbox-unavailable-reason.md b/.changeset/sandbox-unavailable-reason.md deleted file mode 100644 index 7df47fba3e..0000000000 --- a/.changeset/sandbox-unavailable-reason.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"emdash": minor -"@emdash-cms/cloudflare": patch -"@emdash-cms/sandbox-workerd": patch ---- - -Adds the cause to the `SANDBOX_NOT_AVAILABLE` error and to the "Plugin sandbox is configured but not available on this platform" startup warning when a configured sandbox runner cannot run plugins. On Cloudflare Workers the message names the missing `worker_loaders` binding or `PluginBridge` export; on Node.js it says that the `workerd` binary did not run. - -Sandbox runners report the cause through a new optional `unavailableReason()` method on `SandboxRunner`. Runners without it keep the previous messages. diff --git a/.changeset/tame-registry-config-errors.md b/.changeset/tame-registry-config-errors.md deleted file mode 100644 index cc5843ed58..0000000000 --- a/.changeset/tame-registry-config-errors.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"emdash": patch -"@emdash-cms/admin": patch ---- - -Fixes invalid plugin registry settings causing the admin manifest to fail with a generic server error. EmDash reports malformed `experimental.registry` fields while Astro loads the site configuration. If invalid registry settings reach the runtime, the admin remains available and shows which field to correct in `astro.config.mjs`. diff --git a/.changeset/term-counts-missing-tables.md b/.changeset/term-counts-missing-tables.md deleted file mode 100644 index f0248fb1a7..0000000000 --- a/.changeset/term-counts-missing-tables.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Taxonomy term counting no longer sends queries against declared collections that were never created, eliminating the phantom `no such table: ec_posts` database error logs that sites without a `posts` collection produced on every uncached taxonomy render. On multi-isolate deployments, term counts now pick up a collection created or deleted on another isolate within about a minute instead of immediately; the write-handling isolate reflects it at once. diff --git a/.changeset/unpublish-token-fix.md b/.changeset/unpublish-token-fix.md deleted file mode 100644 index 4a59970bd2..0000000000 --- a/.changeset/unpublish-token-fix.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@emdash-cms/admin": patch -"emdash": patch ---- - -Fix stale revision tokens after unpublish, discard, and revision restore. - -The admin editor now reads the new `_rev` returned by unpublish, discard-draft, and revision-restore responses and advances its optimistic-concurrency token before the next save. Unpublish also flushes pending editor changes before sending the request, matching the ordering already used for publish, schedule, and publication-date changes, and it now catches the promise rejection when the action is blocked by invalid fields or a click while another publishing action is already in progress. This prevents subsequent autosaves or publish actions from being refused as a 409 conflict, stops unpublished posts from overwriting unsaved edits, and avoids unhandled promise rejections from the unpublish button. diff --git a/.changeset/wide-d1-entry-loading.md b/.changeset/wide-d1-entry-loading.md deleted file mode 100644 index fb8ef9d22e..0000000000 --- a/.changeset/wide-d1-entry-loading.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"emdash": patch ---- - -Fixes entries in wide collections failing to load on Cloudflare D1 with a "too many columns in result set" error. diff --git a/.changeset/workerd-give-up-diagnostics.md b/.changeset/workerd-give-up-diagnostics.md deleted file mode 100644 index c61feb1f77..0000000000 --- a/.changeset/workerd-give-up-diagnostics.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@emdash-cms/sandbox-workerd": patch ---- - -Fixes the workerd plugin sandbox logging `Plugins will run unsandboxed` after it stops restarting a repeatedly crashing `workerd`, when in fact every sandboxed hook and route fails from that point. The log line now names that consequence, and the reason on `SandboxUnavailableError` distinguishes a spent crash budget from a runner that never started. diff --git a/packages/admin/CHANGELOG.md b/packages/admin/CHANGELOG.md index 7a3e2a563f..670a4b59fb 100644 --- a/packages/admin/CHANGELOG.md +++ b/packages/admin/CHANGELOG.md @@ -1,5 +1,81 @@ # @emdash-cms/admin +## 0.38.0 + +### Minor Changes + +- [#3080](https://github.com/emdash-cms/emdash/pull/3080) [`7bbd8ea`](https://github.com/emdash-cms/emdash/commit/7bbd8eaa062a97026bf3efa19c9ee8b25ff5d84a) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds public names for registry plugins in the `@publisher.example/plugin-slug` format. Registry results and installed-plugin cards display the verified public name and link to a handle-based detail URL, while exact public-name searches open the matching package. + + When a publisher handle conclusively fails identity verification, the admin displays **INVALID HANDLE** and prevents installation. Temporary lookup failures fall back to the stable publisher identifier without marking the handle invalid. + +- [#3062](https://github.com/emdash-cms/emdash/pull/3062) [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c) Thanks [@swissky](https://github.com/swissky)! - Adds a `group` setting to collections. Collections that share a group render as one collapsible folder in the admin sidebar, positioned where the first of them appears; a taxonomy joins the folder when every collection it is assigned to is shown in that folder. A folder you have not touched opens while one of its members is active; once you open or close it yourself, the sidebar remembers that choice in the browser. Set the group in the content type editor under Navigation, in seed files, or through the schema API and the MCP collection tools; leaving it empty keeps today's flat list. + +- [#2919](https://github.com/emdash-cms/emdash/pull/2919) [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3) Thanks [@danielmlr](https://github.com/danielmlr)! - Adds an edit lock per content entry, so two people no longer discover a collision only after both have done the work. + + Opening an entry in the admin takes a lock on it. A second editor is told who has it and chooses between opening the entry read-only, where nothing they type can be lost to a refused save, and taking it over. After a take-over, the previous holder is told within two minutes that the entry moved on, their next save is refused, and a banner names who holds it now. + + The lock lasts seven minutes. The admin renews it every two minutes while the entry is open, so a pause in typing does not lose it, and every save on the entry extends it too. Leaving the editor or closing the tab releases it, as does moving the entry to the trash; a tab that loses power or network lets it lapse. + + #### Who is newly refused + + Scripts, API tokens and the CLI that update, delete, publish, unpublish, schedule or discard an entry while an editor has it open in the admin now receive `409 ENTRY_LOCKED` where the write used to succeed. This applies to every collection once the migration has run. The response's `error.message` names the holder and `error.details` carries their `userId`, `userName`, `acquiredAt` and `expiresAt`. Pass `"overrideLock": true` in the request body to write anyway, or `?overrideLock=true` on `DELETE`, which has no body. The CLI takes `--override-lock` on `content update`, `content delete`, `content publish`, `content unpublish` and `content schedule`. The MCP content tools do not honour the lock yet. + + Locks are per entry and per locale, so two translations of the same entry can be edited at once. + + Take or read a lock directly through `GET`, `POST` and `DELETE` on `/_emdash/api/content/{collection}/{id}/lock`. + + #### Turning it off + + Locking is on for every collection. Switch it off under **Content Types** → your collection → **Edit locking**, with `editLocking: false` in a seed file, or through `schema_update_collection`: + + ```json + { "slug": "posts", "editLocking": false } + ``` + + #### Upgrading + + Includes database migration `075_entry_edit_locks`. Projects on the default `auto` runtime migration mode need no action. Projects that migrate as a deployment step: run `emdash migrate` before deploying this version. + +- [#1526](https://github.com/emdash-cms/emdash/pull/1526) [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127) Thanks [@swissky](https://github.com/swissky)! - Adds WordPress-style date tokens to collection URL patterns. `url_pattern` now supports `{year}`, `{month}`, `{day}`, `{hour}`, `{minute}`, `{second}` (resolved from the entry's publish date, zero-padded) alongside `{slug}` and `{id}` — so you can reproduce permalinks like `/{year}/{month}/{day}/{slug}.html`. The tokens resolve everywhere the pattern is used: sitemap canonical URLs, hreflang alternates, navigation menu links, slug-change auto-redirects, and the admin's preview and "View published" links. Tokens stay literal when an entry has no publish date, so canonical URLs remain stable across edits. + +- [#2934](https://github.com/emdash-cms/emdash/pull/2934) [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728) Thanks [@khoinguyenpham04](https://github.com/khoinguyenpham04)! - Adds responsive, lossless Portable Text tables with an accessible size picker, complete row and column controls, merge and split, persistent column widths, HTML and spreadsheet clipboard support, keyboard navigation, and right-to-left resizing. Wide tables keep their horizontal position while resizing, hide native scrollbar chrome, and show edge shadows for hidden columns. + + Use the compact, scrollable Table menu for structural actions, or press Backspace or Delete to remove selected full rows or columns. Undo restores the removed content and structure. + + The editor toolbar no longer includes Spotlight Mode, leaving more room for table controls at the standard editor width. + + The public renderer now preserves table headers, spans, alignment, and preferred widths. Existing legacy string-cell tables continue to render. `portableTextToProsemirror()` now returns real `table`, `tableRow`, `tableHeader`, and `tableCell` nodes, so custom ProseMirror schemas that consume its output must register the existing TipTap table extensions. + + Pass a localized `tablePlaceholder` string to `PortableText` to set the inline editor's initial table label. Omitted values retain the English label. + +### Patch Changes + +- [#2979](https://github.com/emdash-cms/emdash/pull/2979) [`5f51e55`](https://github.com/emdash-cms/emdash/commit/5f51e550827e0e42c8118e0c1279faa69cb1deb1) Thanks [@ascorbic](https://github.com/ascorbic)! - Improves passkey account creation with device-aware guidance before the browser prompt. EmDash explains what a passkey is and where it is saved, detects when a built-in authenticator is unavailable, and guides users through Windows Hello, another device, or a security key. Compatible browsers receive a preference for the selected path, while the browser continues to control the secure passkey prompt. + +- [#3078](https://github.com/emdash-cms/emdash/pull/3078) [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a fail-closed first-release exemption to the plugin registry's optional minimum release age policy. A package's first release can install immediately only when the aggregator reports exactly one retained release and confirms that it continuously observed the package's release history. + + Existing packages, backfilled packages, and packages with missing or incomplete history remain subject to the configured holdback. Deleted releases still count, and explicit publisher or package exemptions continue to work. + +- [#3072](https://github.com/emdash-cms/emdash/pull/3072) [`a350627`](https://github.com/emdash-cms/emdash/commit/a3506272966ca6e5795a5675d40f8c16532ad2d5) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes the admin appearance toggle so every click changes the visible color scheme. The admin follows the system preference whenever the selected appearance matches it. + +- [#2971](https://github.com/emdash-cms/emdash/pull/2971) [`9d5d8ed`](https://github.com/emdash-cms/emdash/commit/9d5d8ed9df84c59a823b978f5c32ade7cc053d09) Thanks [@marks-zyz](https://github.com/marks-zyz)! - Completes the Brazilian Portuguese (`pt-BR`) admin translation. Brazilian Portuguese admins now see localized text throughout the admin instead of falling back to English for 1,170 of 2,292 strings. + +- [#3100](https://github.com/emdash-cms/emdash/pull/3100) [`d2ad846`](https://github.com/emdash-cms/emdash/commit/d2ad846b371bc1f9a8fea20eb544a0aa999a8af2) Thanks [@danielmlr](https://github.com/danielmlr)! - Completes the German admin translations so German-speaking editors see localized text instead of English in the table editor, passkey setup, edit locking, image field uploads, and the plugin registry. + +- [#3060](https://github.com/emdash-cms/emdash/pull/3060) [`d30207d`](https://github.com/emdash-cms/emdash/commit/d30207d391bfb10f8a0566992e02df246dfa8c02) Thanks [@swissky](https://github.com/swissky)! - Fixes the dashboard showing a "+ New …" quick action for collections marked `hidden`, matching the sidebar link the flag already removes. + +- [#3076](https://github.com/emdash-cms/emdash/pull/3076) [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes marketplace plugin updates so administrators review newly requested capabilities, public routes, and MCP tools before granting them. Update confirmation remains pinned to the version that was reviewed, so a newer release requires a separate review. + +- [#3077](https://github.com/emdash-cms/emdash/pull/3077) [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes invalid plugin registry settings causing the admin manifest to fail with a generic server error. EmDash reports malformed `experimental.registry` fields while Astro loads the site configuration. If invalid registry settings reach the runtime, the admin remains available and shows which field to correct in `astro.config.mjs`. + +- [#3092](https://github.com/emdash-cms/emdash/pull/3092) [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9) Thanks [@emdashbot](https://github.com/apps/emdashbot)! - Fix stale revision tokens after unpublish, discard, and revision restore. + + The admin editor now reads the new `_rev` returned by unpublish, discard-draft, and revision-restore responses and advances its optimistic-concurrency token before the next save. Unpublish also flushes pending editor changes before sending the request, matching the ordering already used for publish, schedule, and publication-date changes, and it now catches the promise rejection when the action is blocked by invalid fields or a click while another publishing action is already in progress. This prevents subsequent autosaves or publish actions from being refused as a 409 conflict, stops unpublished posts from overwriting unsaved edits, and avoids unhandled promise rejections from the unpublish button. +- Updated dependencies [[`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec)]: + - @emdash-cms/registry-client@0.6.0 + - @emdash-cms/registry-lexicons@0.5.0 + - @emdash-cms/blocks@0.38.0 + ## 0.37.0 ### Minor Changes diff --git a/packages/admin/package.json b/packages/admin/package.json index fde211fc45..c3fab0f9af 100644 --- a/packages/admin/package.json +++ b/packages/admin/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/admin", - "version": "0.37.0", + "version": "0.38.0", "description": "Admin UI for EmDash CMS", "type": "module", "main": "dist/index.js", diff --git a/packages/auth-atproto/CHANGELOG.md b/packages/auth-atproto/CHANGELOG.md index dac96b9429..b1ac94e9b4 100644 --- a/packages/auth-atproto/CHANGELOG.md +++ b/packages/auth-atproto/CHANGELOG.md @@ -1,5 +1,12 @@ # @emdash-cms/auth-atproto +## 0.2.38 + +### Patch Changes + +- Updated dependencies []: + - @emdash-cms/auth@0.38.0 + ## 0.2.37 ### Patch Changes diff --git a/packages/auth-atproto/package.json b/packages/auth-atproto/package.json index 5aa7a2c7e8..143bc94bc1 100644 --- a/packages/auth-atproto/package.json +++ b/packages/auth-atproto/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/auth-atproto", - "version": "0.2.37", + "version": "0.2.38", "description": "AT Protocol / Atmosphere authentication provider for EmDash CMS", "type": "module", "main": "src/auth.ts", diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index c55de8f43f..5273d8a62a 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -1,5 +1,9 @@ # @emdash-cms/auth +## 0.38.0 + +No changes in this release. + ## 0.37.0 ### Minor Changes diff --git a/packages/auth/package.json b/packages/auth/package.json index 76521f474e..6917e59bc8 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/auth", - "version": "0.37.0", + "version": "0.38.0", "description": "Passkey-first authentication for EmDash", "type": "module", "main": "dist/index.mjs", diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 155dc157da..7cf9cf6ed1 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -1,5 +1,9 @@ # @emdash-cms/blocks +## 0.38.0 + +No changes in this release. + ## 0.37.0 ## 0.36.0 diff --git a/packages/blocks/package.json b/packages/blocks/package.json index f62569bbbf..d19ae8036f 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/blocks", - "version": "0.37.0", + "version": "0.38.0", "description": "Declarative plugin UI blocks for EmDash CMS", "type": "module", "main": "dist/index.js", diff --git a/packages/cloudflare/CHANGELOG.md b/packages/cloudflare/CHANGELOG.md index f9fff21825..b4a4b749a2 100644 --- a/packages/cloudflare/CHANGELOG.md +++ b/packages/cloudflare/CHANGELOG.md @@ -1,5 +1,27 @@ # @emdash-cms/cloudflare +## 0.38.0 + +### Patch Changes + +- [#3065](https://github.com/emdash-cms/emdash/pull/3065) [`2b2f69e`](https://github.com/emdash-cms/emdash/commit/2b2f69e89f25afd9abe08d13fd73b3ad0d39ebc1) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes Cloudflare binding failures during runtime startup returning `NOT_CONFIGURED` from EmDash API routes. Missing D1, R2, KV, Durable Object, and Hyperdrive bindings now return `BINDING_NOT_FOUND` with the binding-specific setup message. Invalid KV and Hyperdrive binding configuration returns `CONFIGURATION_ERROR`. + +- [#2169](https://github.com/emdash-cms/emdash/pull/2169) [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7) Thanks [@vedanshujain](https://github.com/vedanshujain)! - Adds `ctx.storage.<collection>.updateIf(id, { where, set?, delta? })` for atomic conditional updates to existing plugin documents. Use `where` to check stored fields, `set` to replace field values, and `delta` to increment or decrement integer counters. The method returns `{ applied: true, data }` with the updated document, or `{ applied: false }` when the document is absent or the condition fails. It never inserts a document. + + Malformed update arguments reject without writing. Deltas require safe integer operands and results; missing or `null` counters start at `0`. Invalid stored counters, overflow, and non-object documents return `{ applied: false }` without changing any fields. + + Available to native plugins and sandboxed plugins on Cloudflare and Workerd, with SQLite, D1, and PostgreSQL support. PostgreSQL serialization failures and deadlocks expose `code: "STORAGE_SERIALIZATION_FAILURE"` and `retryable: true`, including across sandbox transports. Retry standalone calls with bounded backoff, or restart the entire explicit transaction. + +- [#2351](https://github.com/emdash-cms/emdash/pull/2351) [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2) Thanks [@MattieTK](https://github.com/MattieTK)! - New Cloudflare projects leave the paid-plan Worker Loader binding disabled so they can deploy on the Workers free plan. Enable sandboxed plugins in the scaffold prompt or with `--sandboxed-plugins`. + + The Cloudflare `sandbox()` helper now selects the runner from the `LOADER` binding in `wrangler.jsonc`, including the named environment selected with `CLOUDFLARE_ENV`. Without it, config-based sandboxed plugins do not load and marketplace or registry installs return `SANDBOX_NOT_AVAILABLE`, while browsing remains available. + +- [#3041](https://github.com/emdash-cms/emdash/pull/3041) [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436) Thanks [@danielmlr](https://github.com/danielmlr)! - Adds the cause to the `SANDBOX_NOT_AVAILABLE` error and to the "Plugin sandbox is configured but not available on this platform" startup warning when a configured sandbox runner cannot run plugins. On Cloudflare Workers the message names the missing `worker_loaders` binding or `PluginBridge` export; on Node.js it says that the `workerd` binary did not run. + + Sandbox runners report the cause through a new optional `unavailableReason()` method on `SandboxRunner`. Runners without it keep the previous messages. +- Updated dependencies [[`36a021c`](https://github.com/emdash-cms/emdash/commit/36a021c1185073e77da891d54a406ea9ce810826), [`573230f`](https://github.com/emdash-cms/emdash/commit/573230f539e03ea99e6c22f2cd7f704a4abd25d5), [`2b2f69e`](https://github.com/emdash-cms/emdash/commit/2b2f69e89f25afd9abe08d13fd73b3ad0d39ebc1), [`33cb7f0`](https://github.com/emdash-cms/emdash/commit/33cb7f08de03fb7febccc72c9eb29fcf88b9c248), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c), [`b73a133`](https://github.com/emdash-cms/emdash/commit/b73a1332324fdef1a60cccad56161c75932f7966), [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3), [`fea6beb`](https://github.com/emdash-cms/emdash/commit/fea6bebfe2d0f26eb7aca45af1a4704e4e7a97bd), [`3bd30da`](https://github.com/emdash-cms/emdash/commit/3bd30da4178f63bafa7aa7147a5cec1d405fa6dd), [`e13fa01`](https://github.com/emdash-cms/emdash/commit/e13fa01118406bba3fc069bb475cb6f13f3bb9ad), [`f9ac286`](https://github.com/emdash-cms/emdash/commit/f9ac286f5a8582809f997aff2999e8a2881c0d74), [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127), [`4c89130`](https://github.com/emdash-cms/emdash/commit/4c8913057cdab82c7af66a126722525ee74ba4cb), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728), [`ef22a2d`](https://github.com/emdash-cms/emdash/commit/ef22a2dc9ffa39844cb7c5caf24eab96e319b07c), [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2), [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2), [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436), [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116), [`d409722`](https://github.com/emdash-cms/emdash/commit/d409722ebcb682c767934381a497ccda2b1a068d), [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728)]: + - emdash@0.38.0 + ## 0.37.0 ### Patch Changes diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index 498694a86d..4ae036b9b8 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/cloudflare", - "version": "0.37.0", + "version": "0.38.0", "description": "Cloudflare adapters for EmDash - D1, R2, Access, and Worker Loader sandbox", "type": "module", "main": "dist/index.mjs", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e898629148..b92f5cf78a 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,151 @@ # emdash +## 0.38.0 + +### Minor Changes + +- [#3062](https://github.com/emdash-cms/emdash/pull/3062) [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c) Thanks [@swissky](https://github.com/swissky)! - Adds a `group` setting to collections. Collections that share a group render as one collapsible folder in the admin sidebar, positioned where the first of them appears; a taxonomy joins the folder when every collection it is assigned to is shown in that folder. A folder you have not touched opens while one of its members is active; once you open or close it yourself, the sidebar remembers that choice in the browser. Set the group in the content type editor under Navigation, in seed files, or through the schema API and the MCP collection tools; leaving it empty keeps today's flat list. + +- [#1963](https://github.com/emdash-cms/emdash/pull/1963) [`b73a133`](https://github.com/emdash-cms/emdash/commit/b73a1332324fdef1a60cccad56161c75932f7966) Thanks [@swissky](https://github.com/swissky)! - `<EmDashHead>` now applies the entry's SEO panel values (title, description, image, canonical, noindex) automatically on server-rendered content pages. Previously the panel was silently ignored unless the page wired `getSeoMeta()` by hand. + + #### Affected pages + + Pages that include `<EmDashHead>` and fetch their entry through `getEmDashEntry()` receive the overlay. This includes warm object-cache hits, because `getEmDashEntry()` primes the same request-scoped cache from the cached snapshot when the loader never runs. Multi-entry collection results (e.g. `getEmDashCollection()`) are not currently covered. + + #### What editors can override + + Editor-set panel values replace the template-provided base fields for `description`, `og:title`, `og:description`, `og:image`, the canonical URL, and robots. They also feed the JSON-LD structured data, so head tags and structured data stay in sync. + + #### What plugins see + + Plugin `page:metadata` and `page:fragments` hooks — in the head and in the body components — receive the overlaid page context, but plugin contributions still win via first-wins dedup. + + #### What does not change + + - The `<title>` element remains the template's responsibility. + - Prerendered pages and pages that bypass `<EmDashHead>` keep using `getSeoMeta()`. + - No additional database query is made; the panel data rides along on the entry query the page already runs. + + #### Canonical and image URL resolution + + `getSeoMeta()` now resolves an explicit SEO panel canonical through the same resolver as `<EmDashHead>`: root-relative values (`/custom-path`) are absolutized against the site URL when one is configured (previously they were returned unchanged), and protocol-relative values (`//host/path`) pass through untouched. The same panel value now produces the same canonical URL on both paths. + + Protocol-relative SEO image references (`//cdn.example.com/x.png`) are no longer prefixed with the site URL, which previously produced a broken doubled-path URL. This corrects `og:image` output everywhere the panel image is resolved: the `<EmDashHead>` overlay, `getSeoMeta()`, and image URLs in the sitemap. + +- [#2919](https://github.com/emdash-cms/emdash/pull/2919) [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3) Thanks [@danielmlr](https://github.com/danielmlr)! - Adds an edit lock per content entry, so two people no longer discover a collision only after both have done the work. + + Opening an entry in the admin takes a lock on it. A second editor is told who has it and chooses between opening the entry read-only, where nothing they type can be lost to a refused save, and taking it over. After a take-over, the previous holder is told within two minutes that the entry moved on, their next save is refused, and a banner names who holds it now. + + The lock lasts seven minutes. The admin renews it every two minutes while the entry is open, so a pause in typing does not lose it, and every save on the entry extends it too. Leaving the editor or closing the tab releases it, as does moving the entry to the trash; a tab that loses power or network lets it lapse. + + #### Who is newly refused + + Scripts, API tokens and the CLI that update, delete, publish, unpublish, schedule or discard an entry while an editor has it open in the admin now receive `409 ENTRY_LOCKED` where the write used to succeed. This applies to every collection once the migration has run. The response's `error.message` names the holder and `error.details` carries their `userId`, `userName`, `acquiredAt` and `expiresAt`. Pass `"overrideLock": true` in the request body to write anyway, or `?overrideLock=true` on `DELETE`, which has no body. The CLI takes `--override-lock` on `content update`, `content delete`, `content publish`, `content unpublish` and `content schedule`. The MCP content tools do not honour the lock yet. + + Locks are per entry and per locale, so two translations of the same entry can be edited at once. + + Take or read a lock directly through `GET`, `POST` and `DELETE` on `/_emdash/api/content/{collection}/{id}/lock`. + + #### Turning it off + + Locking is on for every collection. Switch it off under **Content Types** → your collection → **Edit locking**, with `editLocking: false` in a seed file, or through `schema_update_collection`: + + ```json + { "slug": "posts", "editLocking": false } + ``` + + #### Upgrading + + Includes database migration `075_entry_edit_locks`. Projects on the default `auto` runtime migration mode need no action. Projects that migrate as a deployment step: run `emdash migrate` before deploying this version. + +- [#1526](https://github.com/emdash-cms/emdash/pull/1526) [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127) Thanks [@swissky](https://github.com/swissky)! - Adds WordPress-style date tokens to collection URL patterns. `url_pattern` now supports `{year}`, `{month}`, `{day}`, `{hour}`, `{minute}`, `{second}` (resolved from the entry's publish date, zero-padded) alongside `{slug}` and `{id}` — so you can reproduce permalinks like `/{year}/{month}/{day}/{slug}.html`. The tokens resolve everywhere the pattern is used: sitemap canonical URLs, hreflang alternates, navigation menu links, slug-change auto-redirects, and the admin's preview and "View published" links. Tokens stay literal when an entry has no publish date, so canonical URLs remain stable across edits. + +- [#2169](https://github.com/emdash-cms/emdash/pull/2169) [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7) Thanks [@vedanshujain](https://github.com/vedanshujain)! - Adds `ctx.storage.<collection>.updateIf(id, { where, set?, delta? })` for atomic conditional updates to existing plugin documents. Use `where` to check stored fields, `set` to replace field values, and `delta` to increment or decrement integer counters. The method returns `{ applied: true, data }` with the updated document, or `{ applied: false }` when the document is absent or the condition fails. It never inserts a document. + + Malformed update arguments reject without writing. Deltas require safe integer operands and results; missing or `null` counters start at `0`. Invalid stored counters, overflow, and non-object documents return `{ applied: false }` without changing any fields. + + Available to native plugins and sandboxed plugins on Cloudflare and Workerd, with SQLite, D1, and PostgreSQL support. PostgreSQL serialization failures and deadlocks expose `code: "STORAGE_SERIALIZATION_FAILURE"` and `retryable: true`, including across sandbox transports. Retry standalone calls with bounded backoff, or restart the entire explicit transaction. + +- [#2934](https://github.com/emdash-cms/emdash/pull/2934) [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728) Thanks [@khoinguyenpham04](https://github.com/khoinguyenpham04)! - Adds responsive, lossless Portable Text tables with an accessible size picker, complete row and column controls, merge and split, persistent column widths, HTML and spreadsheet clipboard support, keyboard navigation, and right-to-left resizing. Wide tables keep their horizontal position while resizing, hide native scrollbar chrome, and show edge shadows for hidden columns. + + Use the compact, scrollable Table menu for structural actions, or press Backspace or Delete to remove selected full rows or columns. Undo restores the removed content and structure. + + The editor toolbar no longer includes Spotlight Mode, leaving more room for table controls at the standard editor width. + + The public renderer now preserves table headers, spans, alignment, and preferred widths. Existing legacy string-cell tables continue to render. `portableTextToProsemirror()` now returns real `table`, `tableRow`, `tableHeader`, and `tableCell` nodes, so custom ProseMirror schemas that consume its output must register the existing TipTap table extensions. + + Pass a localized `tablePlaceholder` string to `PortableText` to set the inline editor's initial table label. Omitted values retain the English label. + +- [#3041](https://github.com/emdash-cms/emdash/pull/3041) [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436) Thanks [@danielmlr](https://github.com/danielmlr)! - Adds the cause to the `SANDBOX_NOT_AVAILABLE` error and to the "Plugin sandbox is configured but not available on this platform" startup warning when a configured sandbox runner cannot run plugins. On Cloudflare Workers the message names the missing `worker_loaders` binding or `PluginBridge` export; on Node.js it says that the `workerd` binary did not run. + + Sandbox runners report the cause through a new optional `unavailableReason()` method on `SandboxRunner`. Runners without it keep the previous messages. + +### Patch Changes + +- [#3057](https://github.com/emdash-cms/emdash/pull/3057) [`36a021c`](https://github.com/emdash-cms/emdash/commit/36a021c1185073e77da891d54a406ea9ce810826) Thanks [@emdashbot](https://github.com/apps/emdashbot)! - Fixes content attribution for authenticated REST, visual editing, and MCP saves. + + - Revisions record the acting user without changing the entry owner. MCP updates preserve the existing owner, and actorless internal writes leave revision attribution unset instead of inferring it from ownership. + - `content:beforeSave` and `content:afterSave` receive an actor snapshot with the authenticated user's `id` and `role`. The snapshot is isolated between hooks so one plugin cannot change the attribution seen by another. + - The audit-log plugin stores the actor ID as `userId` on content create and update entries. + +- [#3026](https://github.com/emdash-cms/emdash/pull/3026) [`573230f`](https://github.com/emdash-cms/emdash/commit/573230f539e03ea99e6c22f2cd7f704a4abd25d5) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes snapshot exports and content backups on PostgreSQL so preview snapshots, manual backups, and scheduled backups include the same content and portable schema metadata as SQLite. + +- [#3065](https://github.com/emdash-cms/emdash/pull/3065) [`2b2f69e`](https://github.com/emdash-cms/emdash/commit/2b2f69e89f25afd9abe08d13fd73b3ad0d39ebc1) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes Cloudflare binding failures during runtime startup returning `NOT_CONFIGURED` from EmDash API routes. Missing D1, R2, KV, Durable Object, and Hyperdrive bindings now return `BINDING_NOT_FOUND` with the binding-specific setup message. Invalid KV and Hyperdrive binding configuration returns `CONFIGURATION_ERROR`. + +- [#3075](https://github.com/emdash-cms/emdash/pull/3075) [`33cb7f0`](https://github.com/emdash-cms/emdash/commit/33cb7f08de03fb7febccc72c9eb29fcf88b9c248) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes overlapping marketplace or registry plugin updates and downgrades deleting the active plugin bundle. Updates retain previous version bundles so delayed work cannot remove a version that becomes active again. + +- [#3078](https://github.com/emdash-cms/emdash/pull/3078) [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a fail-closed first-release exemption to the plugin registry's optional minimum release age policy. A package's first release can install immediately only when the aggregator reports exactly one retained release and confirms that it continuously observed the package's release history. + + Existing packages, backfilled packages, and packages with missing or incomplete history remain subject to the configured holdback. Deleted releases still count, and explicit publisher or package exemptions continue to work. + +- [#3103](https://github.com/emdash-cms/emdash/pull/3103) [`fea6beb`](https://github.com/emdash-cms/emdash/commit/fea6bebfe2d0f26eb7aca45af1a4704e4e7a97bd) Thanks [@dchaudhari7177](https://github.com/dchaudhari7177)! - Fixes the Portable Text `Gallery` component telling browsers each image fills the viewport. Its `sizes` attribute now describes one grid cell, using the gallery's column count and its two-column layout at 640px and below, so browsers stop downloading oversized images for multi-column galleries. Pass the new `sizes` prop to `Gallery` when it renders in a container narrower than the viewport. + +- [#3074](https://github.com/emdash-cms/emdash/pull/3074) [`3bd30da`](https://github.com/emdash-cms/emdash/commit/3bd30da4178f63bafa7aa7147a5cec1d405fa6dd) Thanks [@eisenbruch](https://github.com/eisenbruch)! - Fixes visual editing saving a new draft when nothing changed. With edit mode on, the inline Portable Text editor saved the body every time focus left it and every time the page was left, even if no one had typed, because each save check compared freshly generated block keys against the stored ones. Entries picked up drafts that differed only in `_key` and showed "Pending changes" in the admin. The editor now compares its document with the one last saved, so an unedited body is never saved and a real edit is saved once. + +- [#3090](https://github.com/emdash-cms/emdash/pull/3090) [`e13fa01`](https://github.com/emdash-cms/emdash/commit/e13fa01118406bba3fc069bb475cb6f13f3bb9ad) Thanks [@danielmlr](https://github.com/danielmlr)! - Fixes non-translatable fields never reaching an entry's other translations on collections with revisions, which is the default. Publishing an entry now copies the non-translatable values it changed to the rest of its translation group, and a save that started from a translation's earlier version gets a conflict instead of overwriting the copied values. Values that already differ between translations stay as they are until a change to that field is published in one of them. + +- [#2970](https://github.com/emdash-cms/emdash/pull/2970) [`f9ac286`](https://github.com/emdash-cms/emdash/commit/f9ac286f5a8582809f997aff2999e8a2881c0d74) Thanks [@jakevis](https://github.com/jakevis)! - Fixes visual editing on list pages. Entries from `getEmDashCollection` now carry a working `edit` proxy in edit mode, so spreading `{...entry.edit.title}` renders the annotation and the toolbar makes the element editable. Previously every collection entry received a no-op proxy in every mode, so only pages built from `getEmDashEntry` were click-to-edit — fields shown exclusively in a list, and collections with no detail page, could not be edited on the page at all. + +- [#3050](https://github.com/emdash-cms/emdash/pull/3050) [`4c89130`](https://github.com/emdash-cms/emdash/commit/4c8913057cdab82c7af66a126722525ee74ba4cb) Thanks [@logelog](https://github.com/logelog)! - Fixes plugin HTTP requests with `allowedHosts` so initial URLs and redirects also pass SSRF validation. Requests are rejected when URL or DNS validation identifies an unsupported scheme or a non-public address. + + Existing callers of the shared outbound URL validator also reject these non-public ranges. + + The default validator resolves public hostnames through `cloudflare-dns.com` before dispatch. Self-hosted deployments must permit access to that endpoint when using the default resolver. + +- [#2169](https://github.com/emdash-cms/emdash/pull/2169) [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7) Thanks [@vedanshujain](https://github.com/vedanshujain)! - Fixes a plugin storage range filter whose every bound is `undefined` matching every row instead of failing. Building a bound from an optional value — `where: { stock: { gte: minStock } }` where `minStock` is `undefined` — type-checks, but contributed no SQL, so `query()` and `count()` returned the whole collection and `updateIf()` applied its write with no guard at all. A guarded decrement could then drive a counter past the bound the caller asked for. + + Such a filter now throws `StorageQueryError` naming the field. Pass a defined bound, or omit the field when you mean to match unconditionally: + + ```typescript + const where = minStock === undefined ? {} : { stock: { gte: minStock } }; + await ctx.storage.products.query({ where }); + ``` + +- [#3091](https://github.com/emdash-cms/emdash/pull/3091) [`ef22a2d`](https://github.com/emdash-cms/emdash/commit/ef22a2dc9ffa39844cb7c5caf24eab96e319b07c) Thanks [@danielmlr](https://github.com/danielmlr)! - Fixes permanently deleting an entry leaving its taxonomy term assignments in the database. The assignments are removed with the last translation of the entry and kept while another translation exists, including one in the trash. + +- [#2351](https://github.com/emdash-cms/emdash/pull/2351) [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2) Thanks [@MattieTK](https://github.com/MattieTK)! - New Cloudflare projects leave the paid-plan Worker Loader binding disabled so they can deploy on the Workers free plan. Enable sandboxed plugins in the scaffold prompt or with `--sandboxed-plugins`. + + The Cloudflare `sandbox()` helper now selects the runner from the `LOADER` binding in `wrangler.jsonc`, including the named environment selected with `CLOUDFLARE_ENV`. Without it, config-based sandboxed plugins do not load and marketplace or registry installs return `SANDBOX_NOT_AVAILABLE`, while browsing remains available. + +- [#3076](https://github.com/emdash-cms/emdash/pull/3076) [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes marketplace plugin updates so administrators review newly requested capabilities, public routes, and MCP tools before granting them. Update confirmation remains pinned to the version that was reviewed, so a newer release requires a separate review. + +- [#3077](https://github.com/emdash-cms/emdash/pull/3077) [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes invalid plugin registry settings causing the admin manifest to fail with a generic server error. EmDash reports malformed `experimental.registry` fields while Astro loads the site configuration. If invalid registry settings reach the runtime, the admin remains available and shows which field to correct in `astro.config.mjs`. + +- [#2043](https://github.com/emdash-cms/emdash/pull/2043) [`d409722`](https://github.com/emdash-cms/emdash/commit/d409722ebcb682c767934381a497ccda2b1a068d) Thanks [@swissky](https://github.com/swissky)! - Taxonomy term counting no longer sends queries against declared collections that were never created, eliminating the phantom `no such table: ec_posts` database error logs that sites without a `posts` collection produced on every uncached taxonomy render. On multi-isolate deployments, term counts now pick up a collection created or deleted on another isolate within about a minute instead of immediately; the write-handling isolate reflects it at once. + +- [#3092](https://github.com/emdash-cms/emdash/pull/3092) [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9) Thanks [@emdashbot](https://github.com/apps/emdashbot)! - Fix stale revision tokens after unpublish, discard, and revision restore. + + The admin editor now reads the new `_rev` returned by unpublish, discard-draft, and revision-restore responses and advances its optimistic-concurrency token before the next save. Unpublish also flushes pending editor changes before sending the request, matching the ordering already used for publish, schedule, and publication-date changes, and it now catches the promise rejection when the action is blocked by invalid fields or a click while another publishing action is already in progress. This prevents subsequent autosaves or publish actions from being refused as a 409 conflict, stops unpublished posts from overwriting unsaved edits, and avoids unhandled promise rejections from the unpublish button. + +- [#2934](https://github.com/emdash-cms/emdash/pull/2934) [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728) Thanks [@khoinguyenpham04](https://github.com/khoinguyenpham04)! - Fixes entries in wide collections failing to load on Cloudflare D1 with a "too many columns in result set" error. +- Updated dependencies [[`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de), [`7bbd8ea`](https://github.com/emdash-cms/emdash/commit/7bbd8eaa062a97026bf3efa19c9ee8b25ff5d84a), [`5f51e55`](https://github.com/emdash-cms/emdash/commit/5f51e550827e0e42c8118e0c1279faa69cb1deb1), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`a350627`](https://github.com/emdash-cms/emdash/commit/a3506272966ca6e5795a5675d40f8c16532ad2d5), [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c), [`9d5d8ed`](https://github.com/emdash-cms/emdash/commit/9d5d8ed9df84c59a823b978f5c32ade7cc053d09), [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3), [`d2ad846`](https://github.com/emdash-cms/emdash/commit/d2ad846b371bc1f9a8fea20eb544a0aa999a8af2), [`d30207d`](https://github.com/emdash-cms/emdash/commit/d30207d391bfb10f8a0566992e02df246dfa8c02), [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec), [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728), [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2), [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116), [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9)]: + - @emdash-cms/registry-client@0.6.0 + - @emdash-cms/admin@0.38.0 + - @emdash-cms/registry-lexicons@0.5.0 + - @emdash-cms/registry-verification@0.3.1 + - @emdash-cms/auth@0.38.0 + - @emdash-cms/gutenberg-to-portable-text@0.38.0 + ## 0.37.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index fa959f1722..8895b61c22 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "emdash", - "version": "0.37.0", + "version": "0.38.0", "description": "Astro-native CMS with WordPress migration support", "type": "module", "main": "dist/index.mjs", diff --git a/packages/create-emdash/CHANGELOG.md b/packages/create-emdash/CHANGELOG.md index 9f3feac6c3..7a1266d603 100644 --- a/packages/create-emdash/CHANGELOG.md +++ b/packages/create-emdash/CHANGELOG.md @@ -1,5 +1,13 @@ # create-emdash +## 0.38.0 + +### Patch Changes + +- [#2351](https://github.com/emdash-cms/emdash/pull/2351) [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2) Thanks [@MattieTK](https://github.com/MattieTK)! - New Cloudflare projects leave the paid-plan Worker Loader binding disabled so they can deploy on the Workers free plan. Enable sandboxed plugins in the scaffold prompt or with `--sandboxed-plugins`. + + The Cloudflare `sandbox()` helper now selects the runner from the `LOADER` binding in `wrangler.jsonc`, including the named environment selected with `CLOUDFLARE_ENV`. Without it, config-based sandboxed plugins do not load and marketplace or registry installs return `SANDBOX_NOT_AVAILABLE`, while browsing remains available. + ## 0.37.0 ### Patch Changes diff --git a/packages/create-emdash/package.json b/packages/create-emdash/package.json index 2e87aa99cc..94dadfa6b7 100644 --- a/packages/create-emdash/package.json +++ b/packages/create-emdash/package.json @@ -1,6 +1,6 @@ { "name": "create-emdash", - "version": "0.37.0", + "version": "0.38.0", "description": "Create a new EmDash CMS project", "type": "module", "bin": "./dist/index.mjs", diff --git a/packages/gutenberg-to-portable-text/CHANGELOG.md b/packages/gutenberg-to-portable-text/CHANGELOG.md index c2f13f6a50..de6fa662cf 100644 --- a/packages/gutenberg-to-portable-text/CHANGELOG.md +++ b/packages/gutenberg-to-portable-text/CHANGELOG.md @@ -1,5 +1,9 @@ # @emdash-cms/gutenberg-to-portable-text +## 0.38.0 + +No changes in this release. + ## 0.37.0 ## 0.36.0 diff --git a/packages/gutenberg-to-portable-text/package.json b/packages/gutenberg-to-portable-text/package.json index 536f4d48cd..f230abba76 100644 --- a/packages/gutenberg-to-portable-text/package.json +++ b/packages/gutenberg-to-portable-text/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/gutenberg-to-portable-text", - "version": "0.37.0", + "version": "0.38.0", "description": "Convert WordPress Gutenberg blocks to Portable Text", "type": "module", "main": "dist/index.mjs", diff --git a/packages/plugin-cli/CHANGELOG.md b/packages/plugin-cli/CHANGELOG.md index 16cdfda3c5..7825a5f166 100644 --- a/packages/plugin-cli/CHANGELOG.md +++ b/packages/plugin-cli/CHANGELOG.md @@ -1,5 +1,29 @@ # @emdash-cms/registry-cli +## 0.11.0 + +### Minor Changes + +- [#3081](https://github.com/emdash-cms/emdash/pull/3081) [`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds repository-level automated plugin releases. `emdash-plugin release setup` writes one shared `.github/workflows/emdash-release.yml` at the Git repository root, including when setup runs from a nested package. The workflow resolves `<slug>@<version>` tags to a unique plugin manifest, rejects version mismatches before attestation, and requests its first repository connection through GitHub OpenID Connect without an Actions secret. + + Prepare later packages with `emdash-plugin profile setup --dir <package-directory>`. Their first release reuses approved repository workflow scopes when the signed package profile names the same repository. Tag and manual-run scopes accumulate after publisher confirmation instead of replacing each other. Existing package approvals remain package-scoped until the publisher explicitly confirms a repository connection; existing generated workflows and the legacy optional connection-invitation input remain supported. + +- [#3081](https://github.com/emdash-cms/emdash/pull/3081) [`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de) Thanks [@ascorbic](https://github.com/ascorbic)! - Updates `emdash-plugin init` to produce a validated, package-manager-aware plugin project. Interactive setup shows the resolved publisher, author, security contact, repository, target, and package manager before writing. Non-interactive setup requires explicit ownership flags unless `--use-detected` opts into the active publisher session and local Git metadata. + + Generated projects pin the plugin CLI version, use bounded EmDash dependencies, include validation and publishing scripts, and add `AGENTS.md` with a local `creating-plugins` skill. `.agents/skills` and `.claude/skills` link to the same canonical skill directory, while `.claude/CLAUDE.md` links to `AGENTS.md`. pnpm projects include the reviewed `esbuild` install policy and use an explicit `SandboxedPlugin` annotation so declaration output remains portable. The scaffolder validates the complete manifest and parent paths before writing and stages new projects atomically. + +- [#3084](https://github.com/emdash-cms/emdash/pull/3084) [`b581ff8`](https://github.com/emdash-cms/emdash/commit/b581ff80af9d9ad73b11374b194da59ccf71d43d) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a workerd-backed Vitest host for sandboxed plugin tests and includes it in projects created by `emdash-plugin init`. `emdashPluginTest()` builds the plugin and configures D1, Worker Loader, and the production `PluginBridge`; `createPluginTestHost()` invokes hooks and routes through the production sandbox boundary and provides helpers for content fixtures, plugin storage, and KV assertions. + +- [#3093](https://github.com/emdash-cms/emdash/pull/3093) [`ea2ccd5`](https://github.com/emdash-cms/emdash/commit/ea2ccd548f7aba9883bc1c9d0cf3c6f642c10a62) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds Changesets-aware automated plugin releases. `emdash-plugin release setup` detects a root `.changeset/config.json` and offers to follow Changesets releases, `<slug>@<version>` tags, or manual runs. Use `--trigger auto|changesets|tags|manual` in non-interactive setup. + + The Changesets variant accepts the official Changesets Action published-package JSON through a reusable workflow. It supports mixed monorepos where npm package names differ from EmDash plugin IDs, ignores ordinary npm packages, verifies every reported plugin version, and publishes matching plugins as a matrix. Private EmDash-only packages produce a setup warning unless Changesets versions and tags them. + +### Patch Changes + +- Updated dependencies [[`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec)]: + - @emdash-cms/registry-client@0.6.0 + - @emdash-cms/registry-lexicons@0.5.0 + ## 0.10.0 ### Minor Changes diff --git a/packages/plugin-cli/package.json b/packages/plugin-cli/package.json index 51e0bdd722..b6fc353063 100644 --- a/packages/plugin-cli/package.json +++ b/packages/plugin-cli/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/plugin-cli", - "version": "0.10.0", + "version": "0.11.0", "description": "CLI for authoring, building, and publishing EmDash plugins. Covers init / build / dev / bundle / publish plus registry search and identity. Atproto OAuth, FAIR-shaped records, sandboxed-plugin-only.", "type": "module", "main": "dist/api.mjs", diff --git a/packages/plugin-test/CHANGELOG.md b/packages/plugin-test/CHANGELOG.md new file mode 100644 index 0000000000..3c88d3563a --- /dev/null +++ b/packages/plugin-test/CHANGELOG.md @@ -0,0 +1,14 @@ +# @emdash-cms/plugin-test + +## 0.1.0 + +### Minor Changes + +- [#3084](https://github.com/emdash-cms/emdash/pull/3084) [`b581ff8`](https://github.com/emdash-cms/emdash/commit/b581ff80af9d9ad73b11374b194da59ccf71d43d) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a workerd-backed Vitest host for sandboxed plugin tests and includes it in projects created by `emdash-plugin init`. `emdashPluginTest()` builds the plugin and configures D1, Worker Loader, and the production `PluginBridge`; `createPluginTestHost()` invokes hooks and routes through the production sandbox boundary and provides helpers for content fixtures, plugin storage, and KV assertions. + +### Patch Changes + +- Updated dependencies [[`36a021c`](https://github.com/emdash-cms/emdash/commit/36a021c1185073e77da891d54a406ea9ce810826), [`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de), [`573230f`](https://github.com/emdash-cms/emdash/commit/573230f539e03ea99e6c22f2cd7f704a4abd25d5), [`2b2f69e`](https://github.com/emdash-cms/emdash/commit/2b2f69e89f25afd9abe08d13fd73b3ad0d39ebc1), [`33cb7f0`](https://github.com/emdash-cms/emdash/commit/33cb7f08de03fb7febccc72c9eb29fcf88b9c248), [`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c), [`b73a133`](https://github.com/emdash-cms/emdash/commit/b73a1332324fdef1a60cccad56161c75932f7966), [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3), [`b581ff8`](https://github.com/emdash-cms/emdash/commit/b581ff80af9d9ad73b11374b194da59ccf71d43d), [`ea2ccd5`](https://github.com/emdash-cms/emdash/commit/ea2ccd548f7aba9883bc1c9d0cf3c6f642c10a62), [`fea6beb`](https://github.com/emdash-cms/emdash/commit/fea6bebfe2d0f26eb7aca45af1a4704e4e7a97bd), [`3bd30da`](https://github.com/emdash-cms/emdash/commit/3bd30da4178f63bafa7aa7147a5cec1d405fa6dd), [`e13fa01`](https://github.com/emdash-cms/emdash/commit/e13fa01118406bba3fc069bb475cb6f13f3bb9ad), [`f9ac286`](https://github.com/emdash-cms/emdash/commit/f9ac286f5a8582809f997aff2999e8a2881c0d74), [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127), [`4c89130`](https://github.com/emdash-cms/emdash/commit/4c8913057cdab82c7af66a126722525ee74ba4cb), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728), [`ef22a2d`](https://github.com/emdash-cms/emdash/commit/ef22a2dc9ffa39844cb7c5caf24eab96e319b07c), [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2), [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2), [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436), [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116), [`d409722`](https://github.com/emdash-cms/emdash/commit/d409722ebcb682c767934381a497ccda2b1a068d), [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728)]: + - emdash@0.38.0 + - @emdash-cms/plugin-cli@0.11.0 + - @emdash-cms/cloudflare@0.38.0 diff --git a/packages/plugin-test/package.json b/packages/plugin-test/package.json index 7b93c130f2..d8e03db00d 100644 --- a/packages/plugin-test/package.json +++ b/packages/plugin-test/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/plugin-test", - "version": "0.0.0", + "version": "0.1.0", "description": "Workerd-backed Vitest host for sandboxed EmDash plugins", "type": "module", "main": "dist/index.mjs", diff --git a/packages/plugins/audit-log/CHANGELOG.md b/packages/plugins/audit-log/CHANGELOG.md index aef5e6afdd..6acad90fd1 100644 --- a/packages/plugins/audit-log/CHANGELOG.md +++ b/packages/plugins/audit-log/CHANGELOG.md @@ -1,5 +1,15 @@ # @emdash-cms/plugin-audit-log +## 0.2.2 + +### Patch Changes + +- [#3057](https://github.com/emdash-cms/emdash/pull/3057) [`36a021c`](https://github.com/emdash-cms/emdash/commit/36a021c1185073e77da891d54a406ea9ce810826) Thanks [@emdashbot](https://github.com/apps/emdashbot)! - Fixes content attribution for authenticated REST, visual editing, and MCP saves. + + - Revisions record the acting user without changing the entry owner. MCP updates preserve the existing owner, and actorless internal writes leave revision attribution unset instead of inferring it from ownership. + - `content:beforeSave` and `content:afterSave` receive an actor snapshot with the authenticated user's `id` and `role`. The snapshot is isolated between hooks so one plugin cannot change the attribution seen by another. + - The audit-log plugin stores the actor ID as `userId` on content create and update entries. + ## 0.2.1 ### Patch Changes diff --git a/packages/plugins/audit-log/package.json b/packages/plugins/audit-log/package.json index cedce921fd..853f88d433 100644 --- a/packages/plugins/audit-log/package.json +++ b/packages/plugins/audit-log/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/plugin-audit-log", - "version": "0.2.1", + "version": "0.2.2", "description": "Audit logging plugin for EmDash CMS - tracks content changes", "type": "module", "main": "dist/index.mjs", diff --git a/packages/plugins/embeds/CHANGELOG.md b/packages/plugins/embeds/CHANGELOG.md index c6f459fa02..696548ac77 100644 --- a/packages/plugins/embeds/CHANGELOG.md +++ b/packages/plugins/embeds/CHANGELOG.md @@ -1,5 +1,12 @@ # @emdash-cms/plugin-embeds +## 0.1.46 + +### Patch Changes + +- Updated dependencies []: + - @emdash-cms/blocks@0.38.0 + ## 0.1.45 ### Patch Changes diff --git a/packages/plugins/embeds/package.json b/packages/plugins/embeds/package.json index 51cf55a53e..237165e42f 100644 --- a/packages/plugins/embeds/package.json +++ b/packages/plugins/embeds/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/plugin-embeds", - "version": "0.1.45", + "version": "0.1.46", "description": "Embed blocks for EmDash CMS - YouTube, Vimeo, Twitter, Bluesky, Mastodon, and more", "type": "module", "main": "src/index.ts", diff --git a/packages/registry-client/CHANGELOG.md b/packages/registry-client/CHANGELOG.md index 79e260156a..6d18b1dcaa 100644 --- a/packages/registry-client/CHANGELOG.md +++ b/packages/registry-client/CHANGELOG.md @@ -1,5 +1,23 @@ # @emdash-cms/registry-client +## 0.6.0 + +### Minor Changes + +- [#3081](https://github.com/emdash-cms/emdash/pull/3081) [`da171b3`](https://github.com/emdash-cms/emdash/commit/da171b3d8d918066e91aa6068e72adbbcd3678de) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds repository-level automated plugin releases. `emdash-plugin release setup` writes one shared `.github/workflows/emdash-release.yml` at the Git repository root, including when setup runs from a nested package. The workflow resolves `<slug>@<version>` tags to a unique plugin manifest, rejects version mismatches before attestation, and requests its first repository connection through GitHub OpenID Connect without an Actions secret. + + Prepare later packages with `emdash-plugin profile setup --dir <package-directory>`. Their first release reuses approved repository workflow scopes when the signed package profile names the same repository. Tag and manual-run scopes accumulate after publisher confirmation instead of replacing each other. Existing package approvals remain package-scoped until the publisher explicitly confirms a repository connection; existing generated workflows and the legacy optional connection-invitation input remain supported. + +- [#3078](https://github.com/emdash-cms/emdash/pull/3078) [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a fail-closed first-release exemption to the plugin registry's optional minimum release age policy. A package's first release can install immediately only when the aggregator reports exactly one retained release and confirms that it continuously observed the package's release history. + + Existing packages, backfilled packages, and packages with missing or incomplete history remain subject to the configured holdback. Deleted releases still count, and explicit publisher or package exemptions continue to work. + +### Patch Changes + +- Updated dependencies [[`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec)]: + - @emdash-cms/registry-lexicons@0.5.0 + - @emdash-cms/registry-moderation@0.2.0 + ## 0.5.0 ### Minor Changes diff --git a/packages/registry-client/package.json b/packages/registry-client/package.json index c88feea76f..1d79550836 100644 --- a/packages/registry-client/package.json +++ b/packages/registry-client/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/registry-client", - "version": "0.5.0", + "version": "0.6.0", "description": "Atproto-aware client for the EmDash plugin registry: credential storage, publisher repo operations, and discovery against an aggregator.", "type": "module", "main": "dist/index.js", diff --git a/packages/registry-lexicons/CHANGELOG.md b/packages/registry-lexicons/CHANGELOG.md index ce0d9825bd..63eb7c9db7 100644 --- a/packages/registry-lexicons/CHANGELOG.md +++ b/packages/registry-lexicons/CHANGELOG.md @@ -1,5 +1,15 @@ # @emdash-cms/registry-lexicons +## 0.5.0 + +### Minor Changes + +- [#3078](https://github.com/emdash-cms/emdash/pull/3078) [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds a fail-closed first-release exemption to the plugin registry's optional minimum release age policy. A package's first release can install immediately only when the aggregator reports exactly one retained release and confirms that it continuously observed the package's release history. + + Existing packages, backfilled packages, and packages with missing or incomplete history remain subject to the configured holdback. Deleted releases still count, and explicit publisher or package exemptions continue to work. + +- [#2742](https://github.com/emdash-cms/emdash/pull/2742) [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds `moderation-manipulation` findings so labelers can distinguish direct attempts to bypass automated moderation from quoted or descriptive discussion of prompt injection. + ## 0.4.0 ### Minor Changes diff --git a/packages/registry-lexicons/package.json b/packages/registry-lexicons/package.json index a5ca3a1175..dbb83e4ff5 100644 --- a/packages/registry-lexicons/package.json +++ b/packages/registry-lexicons/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/registry-lexicons", - "version": "0.4.0", + "version": "0.5.0", "description": "Generated TypeScript types for EmDash plugin registry lexicons (com.emdashcms.experimental.*). EXPERIMENTAL: NSIDs and shapes will change.", "type": "module", "main": "dist/index.js", diff --git a/packages/registry-moderation/CHANGELOG.md b/packages/registry-moderation/CHANGELOG.md index c67d1ea7b4..e1488c6276 100644 --- a/packages/registry-moderation/CHANGELOG.md +++ b/packages/registry-moderation/CHANGELOG.md @@ -1,5 +1,11 @@ # @emdash-cms/registry-moderation +## 0.2.0 + +### Minor Changes + +- [#2742](https://github.com/emdash-cms/emdash/pull/2742) [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec) Thanks [@ascorbic](https://github.com/ascorbic)! - Adds `moderation-manipulation` findings so labelers can distinguish direct attempts to bypass automated moderation from quoted or descriptive discussion of prompt injection. + ## 0.1.0 ### Minor Changes diff --git a/packages/registry-moderation/package.json b/packages/registry-moderation/package.json index b3d8da177e..d1f15d7812 100644 --- a/packages/registry-moderation/package.json +++ b/packages/registry-moderation/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/registry-moderation", - "version": "0.1.0", + "version": "0.2.0", "description": "Shared listing-label reduction, visibility policy, and metadata moderation contracts for the EmDash plugin registry.", "type": "module", "main": "dist/index.js", diff --git a/packages/registry-verification/CHANGELOG.md b/packages/registry-verification/CHANGELOG.md index 5baceb232e..d0a7a7472f 100644 --- a/packages/registry-verification/CHANGELOG.md +++ b/packages/registry-verification/CHANGELOG.md @@ -1,5 +1,12 @@ # @emdash-cms/registry-verification +## 0.3.1 + +### Patch Changes + +- Updated dependencies [[`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`4cc150e`](https://github.com/emdash-cms/emdash/commit/4cc150e931313644a96b796627e5ec74b46c0aec)]: + - @emdash-cms/registry-lexicons@0.5.0 + ## 0.3.0 ### Minor Changes diff --git a/packages/registry-verification/package.json b/packages/registry-verification/package.json index 624cbf5cae..c1c4505fbe 100644 --- a/packages/registry-verification/package.json +++ b/packages/registry-verification/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/registry-verification", - "version": "0.3.0", + "version": "0.3.1", "description": "Runtime-neutral verification primitives for the EmDash plugin registry.", "type": "module", "main": "dist/index.js", diff --git a/packages/workerd/CHANGELOG.md b/packages/workerd/CHANGELOG.md index 8350594f3b..9ce0a393e1 100644 --- a/packages/workerd/CHANGELOG.md +++ b/packages/workerd/CHANGELOG.md @@ -1,5 +1,29 @@ # @emdash-cms/sandbox-workerd +## 0.5.4 + +### Patch Changes + +- [#3050](https://github.com/emdash-cms/emdash/pull/3050) [`4c89130`](https://github.com/emdash-cms/emdash/commit/4c8913057cdab82c7af66a126722525ee74ba4cb) Thanks [@logelog](https://github.com/logelog)! - Fixes plugin HTTP requests with `allowedHosts` so initial URLs and redirects also pass SSRF validation. Requests are rejected when URL or DNS validation identifies an unsupported scheme or a non-public address. + + Existing callers of the shared outbound URL validator also reject these non-public ranges. + + The default validator resolves public hostnames through `cloudflare-dns.com` before dispatch. Self-hosted deployments must permit access to that endpoint when using the default resolver. + +- [#2169](https://github.com/emdash-cms/emdash/pull/2169) [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7) Thanks [@vedanshujain](https://github.com/vedanshujain)! - Adds `ctx.storage.<collection>.updateIf(id, { where, set?, delta? })` for atomic conditional updates to existing plugin documents. Use `where` to check stored fields, `set` to replace field values, and `delta` to increment or decrement integer counters. The method returns `{ applied: true, data }` with the updated document, or `{ applied: false }` when the document is absent or the condition fails. It never inserts a document. + + Malformed update arguments reject without writing. Deltas require safe integer operands and results; missing or `null` counters start at `0`. Invalid stored counters, overflow, and non-object documents return `{ applied: false }` without changing any fields. + + Available to native plugins and sandboxed plugins on Cloudflare and Workerd, with SQLite, D1, and PostgreSQL support. PostgreSQL serialization failures and deadlocks expose `code: "STORAGE_SERIALIZATION_FAILURE"` and `retryable: true`, including across sandbox transports. Retry standalone calls with bounded backoff, or restart the entire explicit transaction. + +- [#3041](https://github.com/emdash-cms/emdash/pull/3041) [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436) Thanks [@danielmlr](https://github.com/danielmlr)! - Adds the cause to the `SANDBOX_NOT_AVAILABLE` error and to the "Plugin sandbox is configured but not available on this platform" startup warning when a configured sandbox runner cannot run plugins. On Cloudflare Workers the message names the missing `worker_loaders` binding or `PluginBridge` export; on Node.js it says that the `workerd` binary did not run. + + Sandbox runners report the cause through a new optional `unavailableReason()` method on `SandboxRunner`. Runners without it keep the previous messages. + +- [#2967](https://github.com/emdash-cms/emdash/pull/2967) [`c531f30`](https://github.com/emdash-cms/emdash/commit/c531f300dce8edf948fb565d07576ce21ef75aa9) Thanks [@danielmlr](https://github.com/danielmlr)! - Fixes the workerd plugin sandbox logging `Plugins will run unsandboxed` after it stops restarting a repeatedly crashing `workerd`, when in fact every sandboxed hook and route fails from that point. The log line now names that consequence, and the reason on `SandboxUnavailableError` distinguishes a spent crash budget from a runner that never started. +- Updated dependencies [[`36a021c`](https://github.com/emdash-cms/emdash/commit/36a021c1185073e77da891d54a406ea9ce810826), [`573230f`](https://github.com/emdash-cms/emdash/commit/573230f539e03ea99e6c22f2cd7f704a4abd25d5), [`2b2f69e`](https://github.com/emdash-cms/emdash/commit/2b2f69e89f25afd9abe08d13fd73b3ad0d39ebc1), [`33cb7f0`](https://github.com/emdash-cms/emdash/commit/33cb7f08de03fb7febccc72c9eb29fcf88b9c248), [`befce6d`](https://github.com/emdash-cms/emdash/commit/befce6dcbbedcf2766d6540214a65f3bbb9e745a), [`3f516f4`](https://github.com/emdash-cms/emdash/commit/3f516f4732da476baaf619e930b9ead2826d063c), [`b73a133`](https://github.com/emdash-cms/emdash/commit/b73a1332324fdef1a60cccad56161c75932f7966), [`b1ccecd`](https://github.com/emdash-cms/emdash/commit/b1ccecd5b036522db28365310c1644ad56a5fab3), [`fea6beb`](https://github.com/emdash-cms/emdash/commit/fea6bebfe2d0f26eb7aca45af1a4704e4e7a97bd), [`3bd30da`](https://github.com/emdash-cms/emdash/commit/3bd30da4178f63bafa7aa7147a5cec1d405fa6dd), [`e13fa01`](https://github.com/emdash-cms/emdash/commit/e13fa01118406bba3fc069bb475cb6f13f3bb9ad), [`f9ac286`](https://github.com/emdash-cms/emdash/commit/f9ac286f5a8582809f997aff2999e8a2881c0d74), [`0bcb1d9`](https://github.com/emdash-cms/emdash/commit/0bcb1d9ba13d645009f6624fc08fe2cd3543a127), [`4c89130`](https://github.com/emdash-cms/emdash/commit/4c8913057cdab82c7af66a126722525ee74ba4cb), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`107c3cc`](https://github.com/emdash-cms/emdash/commit/107c3ccdffece10938ccd995b9b2675f3c54a5d7), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728), [`ef22a2d`](https://github.com/emdash-cms/emdash/commit/ef22a2dc9ffa39844cb7c5caf24eab96e319b07c), [`f0af9a1`](https://github.com/emdash-cms/emdash/commit/f0af9a10b34ea50a14d04ef3fe84c323b6d17ce2), [`dd5ef1a`](https://github.com/emdash-cms/emdash/commit/dd5ef1a23031055e230377480874974dd00d64a2), [`0ae2f26`](https://github.com/emdash-cms/emdash/commit/0ae2f2652281a90813616c146d75029397435436), [`27e432e`](https://github.com/emdash-cms/emdash/commit/27e432e197b592cfe150c9d536cd0696e042a116), [`d409722`](https://github.com/emdash-cms/emdash/commit/d409722ebcb682c767934381a497ccda2b1a068d), [`1a71c9e`](https://github.com/emdash-cms/emdash/commit/1a71c9e0d88f5e9934fe54329becfa08513d75b9), [`91a4aef`](https://github.com/emdash-cms/emdash/commit/91a4aef76bd2a6c588a22faa44897c7459d81728)]: + - emdash@0.38.0 + ## 0.5.3 ### Patch Changes diff --git a/packages/workerd/package.json b/packages/workerd/package.json index ac6063bcaa..fa0967b6f1 100644 --- a/packages/workerd/package.json +++ b/packages/workerd/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/sandbox-workerd", - "version": "0.5.3", + "version": "0.5.4", "description": "workerd-based plugin sandbox for EmDash on Node.js", "type": "module", "main": "dist/index.mjs", diff --git a/packages/x402/CHANGELOG.md b/packages/x402/CHANGELOG.md index 9b4029144f..5a77f91c70 100644 --- a/packages/x402/CHANGELOG.md +++ b/packages/x402/CHANGELOG.md @@ -1,5 +1,9 @@ # @emdash-cms/x402 +## 0.38.0 + +No changes in this release. + ## 0.37.0 ## 0.36.0 diff --git a/packages/x402/package.json b/packages/x402/package.json index 4e2007c16f..cad2f784d3 100644 --- a/packages/x402/package.json +++ b/packages/x402/package.json @@ -1,6 +1,6 @@ { "name": "@emdash-cms/x402", - "version": "0.37.0", + "version": "0.38.0", "description": "x402 payment protocol integration for Astro sites", "license": "MIT", "repository": {