19 KiB
@emdash-cms/registry-cli
0.7.0
Minor Changes
- #1719
7c5de08Thanks @swissky! - Adds ataxonomies:readplugin capability with read-only taxonomy access: plugins that declare it getctx.taxonomiesto list taxonomy definitions (getAll()), fetch the terms of a taxonomy (getTerms()), and read the terms assigned to a content entry (getEntryTerms()) — in-process and in both sandbox runners.
Patch Changes
- Updated dependencies [
7c5de08]:- @emdash-cms/plugin-types@0.2.0
- @emdash-cms/registry-lexicons@0.2.0
- @emdash-cms/registry-client@0.3.3
0.6.0
Minor Changes
- #1461
b01aa9bThanks @ascorbic! - Fixes registry installs failing with "Plugin manifest has changed since you consented" for plugins that declare hook-registration capabilities (email transport, email events, page fragments) or read user records. Plugin bundles now declare their access as a structureddeclaredAccesscontract that the registry record, the install-consent dialog, and the sandbox all read consistently, so every capability a plugin declares is shown for consent and enforced — no capability is silently dropped. Re-publish affected plugins to adopt the new bundle format; existing installs are unaffected.
Patch Changes
-
#1447
141aa11Thanks @ascorbic! - Fixes@atcutepeer dependency warnings on install (#1435)Installing EmDash pulled in mismatched
@atcutepackage versions, sopnpm install/npm installreported unmet peer warnings for@atcute/identityand@atcute/lexicons. The bundled@atcutedependencies are now aligned on v2 and installs are clean. If your project also depends on@atcutepackages directly, note they have moved to v2 (@atcute/client5,@atcute/lexicons2,@atcute/atproto4,@atcute/oauth-node-client2). -
Updated dependencies [
141aa11,b01aa9b]:- @emdash-cms/registry-client@0.3.2
- @emdash-cms/registry-lexicons@0.1.1
- @emdash-cms/plugin-types@0.1.0
0.5.1
Patch Changes
- Updated dependencies [
69bdc97]:- @emdash-cms/registry-client@0.3.1
0.5.0
Minor Changes
-
#1238
60c0b2eThanks @ascorbic! - Registry plugins can now declare environment requirements. A plugin's manifest may set a release-levelrequiresblock (e.g.{ "env:emdash": ">=1.0.0", "env:astro": ">=4.16" }), which is published into the release record. When browsing a registry plugin, the admin compares those constraints against the running EmDash and Astro versions: if the host doesn't satisfy them, it shows a compatibility warning and disables the Install button. The server enforces the same check on install and update, refusing an incompatible release withENV_INCOMPATIBLEso the gate can't be bypassed. -
#1239
1a4918fThanks @ascorbic! - Plugins published to the experimental registry can now ship icon, screenshot, and banner images. Declare them inemdash-plugin.jsoncunderrelease.artifactsas file refs;emdash-plugin publish --artifact-base-url <url>measures each image's dimensions, uploads it, and records it in the release. The admin plugin detail page renders the icon, banner, and a screenshot gallery, fetched through a server-side image proxy. The proxy resolves each artifact's URL server-side from the validated release record (the client sends only the artifact's coordinates, never a URL), then applies SSRF defences and an image content-type allowlist before serving the bytes. Supported image types are PNG, JPEG, WebP, GIF, and AVIF; SVG is rejected at both publish and proxy because it is active content. -
#1253
d2f2679Thanks @ascorbic! - Plugins published to the experimental registry can now ship long-form profile sections. Declare them inemdash-plugin.jsoncunder a top-levelsectionsblock with any ofdescription,installation,faq,changelog, andsecurity. Each value is either inline CommonMark Markdown or a{ file: "./path.md" }ref read relative to the manifest at load time. Every section is capped at 20000 bytes and 2000 graphemes, enforced locally (inline strings during schema validation, file refs once their content is read) soemdash-plugin validate/publishfails with a clear message instead of a 400 from the PDS. File refs are resolved within the manifest directory; paths that escape it (via..or an absolute path) are rejected. Sections are profile-level: written to the package profile record on first publish and editable afterward withemdash-registry update-package, like the other profile fields.
Patch Changes
-
#1247
245f8dcThanks @mvanhorn! - Fixes plugin builds on Windows by importing the probe artifact through a file URL. -
Updated dependencies [
60c0b2e]:- @emdash-cms/registry-client@0.3.0
0.4.0
Minor Changes
-
#1126
cf3c706Thanks @ascorbic! - Addsemdash-plugin update-package, a CLI command for editing an already-published plugin's registry record (license, authors, security contacts, name, description, keywords) without cutting a new release. Without--yesit prints a diff and exits without writing; with--yesit writes the updated record to the publisher's PDS using atproto'sswapRecordprecondition (concurrent writes surface asSTALE_RECORDinstead of silently overwriting each other) and bumpslastUpdated. Optional fields use a "manifest absent = no change" policy: removing a key from the manifest doesn't wipe the published value, matchingpublishsemantics. Renaming a plugin via the manifest now surfaces a "looks like a rename" message listing the publisher's existing packages instead of a generic not-found, so publishers don't accidentally orphan releases under the old slug.The publishing client (
@emdash-cms/registry-client) gains aswapRecordparameter onputRecordandunsafePutRecordfor callers needing optimistic-concurrency writes.
Patch Changes
- #1145
463c7a2Thanks @ascorbic! - Refactors the build pipeline's runtime validation of the probed plugin's default export to use a Zod schema. Error messages keep the same format (hook "X" must be a function or { handler, ... },hook "X" has invalid FIELD VALUE (...)). Exotic-object entries (Date, RegExp, Promise, class instances) now produce the wrong-shape error instead of falling through to a misleading "missing handler" error. BigInt / cyclic-object / function / symbol field values are rendered safely in error messages instead of crashing with a TypeError. - Updated dependencies [
cf3c706]:- @emdash-cms/registry-client@0.2.0
0.3.0
Minor Changes
-
#1112
3756168Thanks @ascorbic! - Publishes the full profile block fromemdash-plugin.jsonc. First publish now writesname,description,keywords, multiple authors, and multiple security contacts to the package profile record, plus the sourcerepoURL to the release record — previously onlylicenseand a single author/security contact were sent.Deprecates the
--license,--author-*, and--security-*flags in favour of declaring these inemdash-plugin.jsonc. The flags still work and override the manifest when both are present; a deprecation warning is printed when they are used.
Patch Changes
- Updated dependencies [
3756168]:- @emdash-cms/registry-client@0.1.0
0.2.0
Minor Changes
-
#1040
e6f7311Thanks @ascorbic! - Addsemdash-plugin.jsoncmanifest support. Plugin authors can now declare profile fields (license, author, security contact, name, description, keywords, repo) once in a hand-edited JSONC file instead of passing them as flags on every publish. The CLI loads./emdash-plugin.jsoncautomatically; explicit flags still win for CI use.New
emdash-plugin validatecommand checks a manifest against the schema offline withtsc-style file:line:column diagnostics.The manifest's optional
publisherfield pins the publishing identity. On first successful publish, the CLI writes the active session's DID back to the manifest. Subsequent publishes verify the active session matches the pinned publisher and refuse on mismatch to prevent accidental cross-account publishes.JSON Schema for IDE completion ships in the package at
schemas/emdash-plugin.schema.json; reference it via"$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json". -
#1057
c0ce915Thanks @ascorbic! - Renames@emdash-cms/registry-clito@emdash-cms/plugin-cliand the binary fromemdash-registrytoemdash-plugin. The package's job has outgrown the original name —init,build,dev,bundle,publish,search,info,login,logout,whoami, andswitchcover plugin authoring + identity + discovery, not just registry interaction. Adopt the new name on first install; the old package is no longer published.This release also adds
emdash-plugin buildandemdash-plugin devand consolidates the build pipeline sobundleis a thin packaging step on top ofbuild.emdash-plugin buildreadsemdash-plugin.jsoncandsrc/plugin.ts, then emits:dist/plugin.mjs(+dist/plugin.d.mts) — runtime bytes (hooks + routes). The same artifact is consumed both in-process (when the plugin is inplugins: []) and by the sandbox loader (when insandboxed: []).dist/manifest.json— wire-shapePluginManifestincluding hooks + routes harvested from probingsrc/plugin.ts.bundlepacks this verbatim into the registry tarball; on the npm path it's metadata that consumers can read without parsing JSONC.dist/index.mjs(+dist/index.d.mts) — descriptor module that default-exports a barePluginDescriptorobject. Emitted only when a siblingpackage.jsonexists (registry-only plugins skip this, since nothing would import it).
emdash-plugin devwatchessrc/**,emdash-plugin.jsonc, andpackage.json, debouncing rebuilds at 150ms. On a failed rebuild it leaves the last gooddist/in place so a downstream site importing the plugin keeps working until the next successful build. Stop with Ctrl-C.A typical plugin
package.json:{ "scripts": { "build": "emdash-plugin build", "dev": "emdash-plugin dev" } }versioninemdash-plugin.jsoncis now optional. The build reconciles the manifest'sversionwithpackage.json#version:- Both set and matching → fine.
- Both set and different → hard error.
- One set → that value wins.
- Neither set → hard error.
The recommended pattern for npm-distributed plugins is to omit
versionfrom the manifest and letpackage.jsonbe the source of truth. Registry-only plugins (nopackage.json) must setversionin the manifest.emdash-plugin bundlehas been reduced to a packaging step: it now callsbuildto producedist/, validates the bundle contents (no Node-builtin imports, no oversized files, capability sanity), collects optional assets (README, icon, screenshots), and tarballs. Inside the tarball,plugin.mjsis renamed tobackend.jsto match the registry's wire-side filename.validateOnlystill skips tarball creation but now produces thedist/artifacts (since "validate" implies "build first").
Patch Changes
-
#1091
6725e91Thanks @ascorbic! - Renames the multi-word flags onbuild,dev, andbundlefrom camelCase to kebab-case for consistency withpublishand standard Unix CLI convention.--outDir->--out-dir--validateOnly->--validate-only
The short alias
-ofor--out-diris unchanged. -
#1092
6788829Thanks @ascorbic! - Renames the--aggregatorflag onsearchandinfoto--registry-urlfor consistency with theEMDASH_REGISTRY_URLenv var and the rest of the user-facing surface. Internally the override still selects the aggregator service to query — the rename only affects what users type.Old:
emdash-plugin search "image" --aggregator https://registry.example.comNew:
emdash-plugin search "image" --registry-url https://registry.example.com
0.1.0
Minor Changes
- #978
27e6d58Thanks @ascorbic! - Enforces the sandboxed plugin bundle size caps from RFC 0001 §"Bundle size limits" in both thebundleandpublishCLI flows: total decompressed ≤ 256 KB, per-file decompressed ≤ 128 KB, and at most 20 files per bundle. The previous bundle command capped only the total at 5 MB; the publish command now also re-validates the decompressed tarball before signing the release record so a publisher hits the same cap locally that aggregators enforce at ingest. Bundles between 256 KB and the old 5 MB ceiling will now be rejected — usually a sign the plugin is bundling host-provided dependencies or assets that belong in a CDN rather than the plugin payload.
Patch Changes
-
#929
5464b55Thanks @ascorbic! - Fixes the CLI hanging indefinitely after a successfulloginorlogout.run()was returning correctly, but something in the OAuth path left a ref'd handle alive that prevented Node's event loop from draining. Workaround: force-exit at the top level oncerunMainresolves. The underlying handle leak is unidentified. -
#929
5464b55Thanks @ascorbic! - Switches the login flow to request granular OAuth scopes derived from the@emdash-cms/registry-lexiconslexicon set instead of the broadtransition:generic:repo:for every record-shaped lexicon (package profile, package release, publisher profile, publisher verification) andrpc:<nsid>?aud=*for every aggregator query (getLatestRelease,getPackage,listReleases,resolvePackage,searchPackages). Display name resolution no longer goes throughcom.atproto.server.getSession; the handle is read from the DID document viaLocalActorResolverso the CLI doesn't need anrpc:com.atproto.*scope and isn't affected by PDS-side DPoP/Bearer compatibility quirks. If the PDS rejects the granular scopes withinvalid_scope, login automatically retries once withtransition:genericand prints a notice. Existing sessions continue working with their original scope until they're revoked or re-issued. -
#929
5464b55Thanks @ascorbic! - Improvesloginerror reporting for OAuth response failures. Previously, transient PDS errors surfaced as a bareunknown_errorwith a stack trace; the CLI now prints the HTTP status, endpoint, OAuth error code/description, a body snippet when the response wasn't OAuth-shaped JSON, and a hint to retry on 5xx responses. -
#923
943df46Thanks @ascorbic! - Adds@emdash-cms/registry-cli: standalone CLI for the experimental plugin registry. Subcommands forlogin,logout,whoami,switch,search,info,bundle, andpublish. Atproto OAuth via loopback callback server. Thepublishflow fetches the tarball from the URL, verifies a sha256 multihash, extracts and validatesmanifest.json, locally validates each lexicon record, and atomically writes profile + release records (with the EmDash declaredAccess trust extension) via a single atprotoapplyWrites. Distributes vianpx @emdash-cms/registry-clito keep atproto deps out of the core CMS install. -
Updated dependencies [
943df46,943df46,5464b55,943df46]:- @emdash-cms/plugin-types@0.0.1
- @emdash-cms/registry-client@0.0.1
- @emdash-cms/registry-lexicons@0.1.0