EmDash 插件 CLI 实战指南:从 init 脚手架到委派发布的插件全生命周期
2026/9/23 17:02:40 网站建设 项目流程
  • CMS
  • 后端
  • 前端
  • 插件系统

【免费下载链接】emdash

EmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress

项目地址:https://gitcode.com/gh_mirrors/emdas/emdash
点击查看免费下载

@emdash-cms/plugin-cli(二进制名emdash-plugin)是 EmDash 生态中面向插件作者的官方命令行工具,覆盖插件从脚手架初始化、开发构建、本地验证到 atproto PDS 发布,以及基于 GitHub Actions 的委派发布全流程。本文以 packages/plugin-cli/README.md 为主体,结合 plugin-cli 源码 与测试用例,完整讲解每个命令的用法、emdash-plugin.jsonc清单的字段语义、发布安全模型与委派发布的授权机制。读完本文,你将能够独立完成一个沙箱化 EmDash 插件的创作、构建、发布与自动化发布链路配置。

一、认识 emdash-plugin:一个面向 atproto 的插件工具链

EmDash 的插件体系与传统 CMS 的"上传 zip"模式不同:插件发布在发布者自己的 atproto PDS(Personal Data Server)上,通过实验性聚合器(aggregator)做索引与检索。emdash-plugin是这套体系的发布者侧工具,它需要完成三类职责:

  • 身份与凭据:基于 atproto OAuth 的登录(login)、会话管理(logout/whoami/switch);
  • 构建与打包:把src/plugin.ts构建成运行时可加载的产物(build/dev/bundle);
  • 发布与协作:把构建产物上传到 PDS 并写入发布记录(publish),以及配置基于 GitHub Actions 的委派发布(profile/release)。

需要特别强调的是,当前 CLI 处于EXPERIMENTAL阶段:initbuilddevbundleloginwhoamiswitchpublish已经可以针对任意 atproto PDS 工作,而检索类命令(searchinfo)依赖聚合器——实验性聚合器默认指向registry.emdashcms.com(该默认值定义在 src/config.ts 的DEFAULT_AGGREGATOR_URL常量中,是代码里唯一需要更新的地方)。由于 RFC 0001 仍在推进,NSID(命名空间标识符)和记录结构可能变化,生产环境务必固定到精确版本(如@emdash-cms/plugin-cli@0.11.0)。

所有子命令都在 src/index.ts 中通过cittydefineCommand注册。注意该入口在runMain正常完成后会主动process.exit(0)——这是有意为之:login/logout的 OAuth 环回 HTTP 路径会留下存活句柄导致 CLI 挂起,强制退出能让你立刻回到 shell(源码注释 说明了这一点)。

二、安装与脚手架初始化

2.1 三种安装方式

方式一:零安装初始化(推荐)。用pnpm dlx直接脚手架一个插件,不污染全局环境:

pnpm dlx @emdash-cms/plugin-cli init my-plugin

交互式初始化会依次收集发布者(publisher)、作者与安全联系信息等元数据,自动探测当前使用的包管理器,并在写盘前展示项目摘要供确认。脚手架产物包含:

  • 一个基于 workerd 的 Vitest 测试宿主;
  • AGENTS.md
  • 规范的skills/creating-plugins技能,通过.agents/skills.claude/skills符号链接共享(仓库内的技能源文件见 skills/creating-plugins/SKILL.md);
  • Claude 指令链接;
  • 覆盖全部校验与发布命令的 package scripts;
  • 若选用 pnpm,还会写入 pnpm 的 build-script 策略(onlyBuiltDependencies之类)。

方式二:在已有插件中安装。脚手架生成的插件已把@emdash-cms/plugin-cli作为固定版本的 devDependency。若要在既有插件中使用 CLI:

pnpm add -D @emdash-cms/plugin-cli

然后统一用pnpm exec emdash-plugin运行项目命令。这样做的好处是:每次执行都使用插件锁定(pin)的版本,而不是为每条命令临时下载一个可能不同的版本

方式三:全局安装

npm install -g @emdash-cms/plugin-cli emdash-plugin init my-plugin

2.2 非交互式初始化

CI 或脚本场景需要跳过交互,此时必须显式提供所有权元数据:

pnpm dlx @emdash-cms/plugin-cli init my-plugin --yes \ --publisher did:plc:abc123def456 \ --author-name "Jane Doe" \ --security-email security@example.com

两个补充开关:

  • --package-manager npm|pnpm|yarn|bun:覆盖调用方探测结果;
  • --use-detected:仅当你希望命令使用当前激活的发布者会话、本地 Git 身份或仓库元数据时使用。

交互式环境的探测与元数据收集逻辑位于 src/init 目录,其中 environment.ts 负责包管理器探测、scaffold.ts 与 templates.ts 负责模板渲染与文件写盘,对应的行为验证见 tests/init-command.test.ts 与 tests/init-environment.test.ts。

三、命令全景

emdash-plugin的完整子命令如下(与 README 命令表 及 src/index.ts 注册表 一致):

emdash-plugin init [name] Scaffold a new sandboxed plugin emdash-plugin build Build dist/ artifacts (plugin.mjs, manifest.json, index.mjs) emdash-plugin dev Watch sources and rebuild on change emdash-plugin bundle Pack dist/ + assets into a registry tarball emdash-plugin publish Build, upload, and publish a release emdash-plugin profile setup Create or prepare the signed package profile emdash-plugin release setup Create the permanent GitHub release workflow emdash-plugin release plan Plan repository releases for GitHub Actions emdash-plugin release prepare <slug[@ver]> Prepare one repository package for GitHub Actions emdash-plugin release delegate Print a publisher delegation browser handoff emdash-plugin release revoke Print an authority revocation browser handoff emdash-plugin release workload Print a workload policy browser handoff emdash-plugin release enrol Print a passkey enrolment browser handoff emdash-plugin release approve <intent-id> Print a passkey approval browser handoff emdash-plugin release reject <intent-id> Print a passkey rejection browser handoff emdash-plugin release dry-run <release.json> Validate delegated release admission with GitHub OIDC emdash-plugin release submit <release.json> Submit a delegated release with GitHub OIDC emdash-plugin release status <intent-id> Read a delegated release intent emdash-plugin release cancel <intent-id> Cancel an unpublished delegated release intent emdash-plugin validate [path] Validate emdash-plugin.jsonc against the v1 schema emdash-plugin login <handle-or-did> Interactive atproto OAuth login emdash-plugin logout [--did <did>] Revoke the active session emdash-plugin whoami Show stored sessions emdash-plugin switch <did> Switch the active publisher session emdash-plugin search <query> Free-text search emdash-plugin info <handle-or-did> <slug> Show package details or listing-check status

通用约定:

  • 所有非交互输出命令支持--json以输出机器可读结果;
  • 检索类命令(searchinfo)支持--registry-url <url>,或通过环境变量EMDASH_REGISTRY_URL指定聚合器;
  • info还支持--labeler-url <origin>或环境变量EMDASH_LABELER_URL,用于那些使用其他 labeler 的注册表。

URL 的解析优先级是显式 flag > 环境变量 > 默认值,实现见 src/config.ts 的resolveAggregatorUrl/resolveLabelerUrl。聚合器与 labeler 默认值均为实验性托管地址,在 phase 1 切换时会退役替换,依赖特定聚合器的话务必通过 flag 固定

人读输出中,注册表包统一标识为@<publisher-handle>/<slug>格式;构建诊断需要显示 npm 包名时,会额外标注为npm package。格式化逻辑集中在 src/package-identifier.ts(formatPackageIdentifierformatPackageReleaseIdentifier)。

四、插件创作:两个文件与三个构建产物

4.1 package.json 脚本

一个典型插件的package.json只需两个脚本:

{ "scripts": { "build": "emdash-plugin build", "dev": "emdash-plugin dev" } }

4.2 作者只需写两个文件

  • emdash-plugin.jsonc——身份 + 信任契约:slug、publisher 构成身份;capabilities、allowedHosts、storage 构成信任契约;再加上 license、author、security 等 profile 字段(详见第六节)。
  • src/plugin.ts——运行时行为:实现 hooks 与 routes,赋值给一个emdash/pluginSandboxedPlugin类型的常量并作为默认导出。

4.3emdash-plugin build的三个产物

dist/plugin.mjs (+ dist/plugin.d.mts) 运行时字节码,集成方(进程内或沙箱 isolate)加载它 dist/manifest.json 线格式清单,含从 src/plugin.ts 探测出的 hooks + routes dist/index.mjs (+ dist/index.d.mts) 描述符模块,默认导出一个裸 PluginDescriptor,消费者直接 import

构建的探测(probing)与清单生成实现在 src/manifest 与 src/build 目录;bundle命令则负责把dist/与资源打包成注册表 tarball(见 src/bundle,其逻辑验证见 tests/bundle.test.ts 与 tests/bundle-utils.test.ts)。

4.4 生成测试环境:跨越沙箱边界

脚手架生成的vitest.config.ts@emdash-cms/plugin-test构建插件,并通过@cloudflare/vitest-plugin提供 D1、Worker Loader 与生产环境的PluginBridge。生成的测试通过沙箱边界调用 hooks 与 routes,而不是手工构造一个残缺的PluginContext——这样测试环境与生产运行环境的隔离语义保持一致。

五、发布:构建、上传与审核

5.1 两步发布

emdash-plugin login <handle-or-did> emdash-plugin publish

login走交互式 atproto OAuth(loopback 流程),会话状态默认存放在~/.emdash/oauth(src/config.ts 的DEFAULT_OAUTH_DIR,与@emdash-cms/registry-client的凭据存储同目录,方便统一清理)。publish会先构建插件,再把发布产物上传到你的 PDS 并写入发布记录。

5.2 外部托管 bundle

如果 tarball 托管在别处,用--url指定:

emdash-plugin publish --url https://example.com/foo-1.0.0.tar.gz

CLI 会下载该 URL 以校验字节并计算校验和(multihash 计算见 src/multihash.ts);release.artifacts中声明的 listing 图片仍会上传到你的 PDS。

5.3 首次发布的 profile 引导

首次发布必须提供--license--security-email(或--security-url)来引导包 profile;更推荐的方式是把它们直接写进emdash-plugin.jsonc(见第六节)。

5.4 发布后的状态跟踪

发布成功后,CLI 会打印未来的公开插件页 URL 和一条info --version <version> --watch命令。状态命令直接读取 labeler 的有效检查结果,而聚合器会把未批准的包元数据挡在公开结果之外——插件页在 listing 被批准之前保持不可用。这是"发布 ≠ 立即可见"的两阶段模型:PDS 上已有记录,但公开可见性取决于审核(labeler/聚合器)。

六、emdash-plugin.jsonc 清单详解

emdash-plugin.jsonc放在插件的package.json旁边,CLI 会自动从当前目录读取。通过内置的 JSON Schema 可获得 IDE 补全(schema 生成脚本见 scripts/gen-schema.ts,产物在 schemas/emdash-plugin.schema.json)。

{ "$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json", "slug": "gallery", "publisher": "did:plc:abc123def456", "license": "MIT", "author": { "name": "Jane Doe", "url": "https://example.com" }, "security": { "email": "security@example.com" }, // Optional "name": "Gallery", "description": "Image gallery block for EmDash.", "keywords": ["gallery", "images"], "repo": "https://github.com/example/plugin-gallery", // Trust contract "capabilities": ["content:read"], "allowedHosts": [], "storage": {}, }

6.1 JSONC 与便捷形态

清单是 JSONC:允许注释与尾随逗号。多作者或多安全联系人时改用数组形态authors: [...]securityContacts: [...](单作者形态author/security与数组形态不能混用,schema 会拒绝)。version可选——省略时 CLI 从相邻的package.json读取version

6.2 字段级约束(源码级佐证)

清单的 Zod schema 在 src/manifest/schema.ts 中逐字段定义,每个字段都带.meta({ description }),因此约束描述会直接流进生成的 JSON Schema 成为编辑器悬停提示。关键约束:

字段约束说明
slug小写字母开头,随后为小写字母/数字/-/_,≤64 字符(PLUGIN_SLUG_RE与发布记录的 rkey 同语法,slug + publisher 构成包主键
versionsemver 2.0 子集,禁止+build-metadata(atproto 记录键字母表没有+每次发布都要提升
license非空 SPDX 表达式,≤256 字符;SPDX 语法由聚合器做最终校验首次发布必填,后续发布以既有 profile 为准
authorname必填,url/email至少建议其一匿名但有名字的作者形态合法但会被警告
securityurlemail至少有一个(Lexicon 无法表达"required one-of",schema 在此强制)空联系人在此即失败,避免进入聚合器才被拒
publisher结构校验:DID 语法或 handle 语法实际解析在发布时经@atcute/identity-resolver完成
capabilities非空字符串数组,≤32 项,逐项做成员校验变更信任契约必须升版本,因为已安装用户同意的是旧契约
allowedHosts每项 ≤256 字符,禁止 scheme/路径/空白;*.前缀表示子域通配,≤64 项交叉规则:声明了network:request(且未声明network:request:unrestricted)时allowedHosts必须非空
storage集合名[a-z][a-z0-9_]*,值含indexes/uniqueIndexes集合名会直接作为 SQL 表后缀,语法必须安全
requires键为env:<name>或包 DID,值为 semver range(>=4.16^4.0.0与安装门禁共用@emdash-cms/registry-client/env的求值器
adminpages/widgets/settingsSchema/fieldWidgets/editorPanels/editorActions危险编辑动作(style: "danger"必须confirm
sections五个 FAIR 认可键:description/installation/faq/changelog/security每节 ≤20000 字节 / ≤2000 字素(grapheme),值可为内联 CommonMark 或{ "file": "..." }引用
release.artifactsicon/banner单文件,screenshots数组 ≤8 项图片在发布时被读取、哈希、测量像素并上传 PDS

关于capabilities的另一个细节:当前能力词表在 schema.ts 的CURRENT_CAPABILITIES中维护(如content:readcontent:writemedia:writeemail:sendnetwork:request等),已弃用的能力名会被硬拒绝并提示替代名(isDeprecatedCapability+CAPABILITY_RENAMES)——弃用窗口只服务于已发布插件,不服务新创作。

6.3 清单加载与错误定位

emdash-plugin validate在不发布的前提下校验清单。加载器在 src/manifest/load.ts 中实现,失败路径有四个可编程错误码:

  • MANIFEST_NOT_FOUND—— 文件不存在;
  • MANIFEST_TOO_LARGE—— 超过 1 MiB 上限(MANIFEST_MAX_BYTES,采用预分配缓冲区 + 哨兵字节的无 TOCTOU有界读取);
  • MANIFEST_PARSE_ERROR—— JSONC 语法错误,含行:列定位;重复键(duplicate key)也会在此报告——这是安全设计,防止git diff评审者被文件后部的恶意publisher键遮蔽顶部的诚实值;
  • MANIFEST_VALIDATION_ERROR—— 通过解析但违反 Zod schema,含字段路径(如authors[0].email)与源码定位。

错误信息刻意对齐tsc/eslint风格的指针,方便 CI 与编辑器工作流。CLI 标志(--license--author-name等)优先于清单值(CI 场景有用);--no-manifest可完全跳过清单。

七、Publisher 钉扎:DID 是身份,handle 只是别名

7.1 首次发布写回

第一次成功发布后,CLI 会把当前会话的 DID 写回清单作为publisher

{ "license": "MIT", "publisher": "did:plc:abc123def456", ... }

写回不是覆盖式编辑:它用jsonc-parsermodify+applyEditslicense之后插入(保持规范顺序),并嗅探原文件的缩进风格(publisher.tsdetectIndent),通过 tmpfile + rename 原子写盘,写前还会重新哈希文件做 TOCTOU 收窄——文件在发布期间被并发改动就放弃写回而不是覆盖用户编辑。若会话有 handle,还会在插入的 DID 行尾追加// <handle>注释便于人读git diff(CLI 永不读回该注释)。

7.2 钉扎校验与 MANIFEST_PUBLISHER_MISMATCH

此后每次发布,CLI 都会校验激活会话是否与钉扎的publisher一致(逻辑见 src/manifest/publisher.ts 的checkPublisher,错误码触发点见 src/commands/publish.ts):

  • DID 钉扎:与会话 DID 逐字比较,不一致即拒绝;
  • handle 钉扎:发布时经@atcute/identity-resolver解析为 DID 再比较;解析失败会得到独立的MANIFEST_PUBLISHER_UNRESOLVED错误码,以便区分"handle 写错"与"账号不对"。

不匹配时发布以MANIFEST_PUBLISHER_MISMATCH拒绝,防止你把插件误发到别的账号。解决方式二选一:

  • 切换会话:emdash-plugin switch <did>
  • 若在把插件转移给新发布者,则更新清单中的publisher

DIDs 是身份,不是 handle。内部始终比较会话 DID 与钉扎 DID;handle 钉扎只是更友好的别名。handle 是可变的:如果发布者域名易主、解析器指向了不同的 DID,发布会拒绝。DID 持久,是长寿命插件的推荐钉扎方式。

八、委派发布:把发布交给 GitHub Actions

委派发布解决的核心问题是:让 CI 无需长期持有你的 PDS 会话凭据,就能代表发布者安全地发布插件。发布者把受限授权(仅创建发布记录与上传文件)委派给 release-service,GitHub Actions 工作流通过 OpenID Connect(OIDC)向服务证明自己的身份。

8.1 初始化:release setup

插件目录(而非 monorepo 根)执行;从其他位置运行时加--dir <plugin-directory>

pnpm exec emdash-plugin login <handle-or-did> pnpm exec emdash-plugin release setup

该命令从emdash-plugin.jsonc读取插件元数据与发布者:

  • 若包 profile 不存在,提供创建;
  • 若 profile 早于委派发布功能,提供在保留既有包元数据的前提下追加签名仓库与发布策略;
  • 默认策略要求发布者的 Atmosphere 账户在插件权限增加时批准发布;可选择 every-release 选项以要求每次发布都批准。

repo可直接写进emdash-plugin.jsonc,或在提示时确认规范 GitHub 仓库 URL;若清单省略repo,setup 会探测 Gitoriginremote 作为提示默认值。独立的emdash-plugin profile setup只准备包 profile,然后展示手动发布或配置 GitHub Actions 的命令。

两个 setup 命令共同支持:

--repository <url> --confirmation escalation-only|always --yes

release setup额外支持--service-url--action-ref--trigger auto|changesets|tags|manual--force。默认托管服务地址为https://releases.emdashcms.com

8.2 生成的工作流文件

release setup会在Git 仓库根创建.github/workflows/emdash-release.yml(嵌套的插件包复用同一工作流)。审阅并提交该文件;命令不会推送,也不会替换已存在的其他工作流——确需替换时显式传--force。非交互环境必须传--yes接受默认批准策略;无法提示且无--yes时,命令宁可失败也不创建或改动 profile

8.3 三种触发变体

默认--trigger auto会在 Git 仓库根探测有效的.changeset/config.json

  • 交互式:询问 EmDash 应跟随 Changesets 发布、包标签还是手动运行;
  • 非交互:检测到 Changesets 就选它,否则选包标签。

Changesets 变体是可复用工作流。调用方 job 需把 Changesets Action 的published-packages输出传给它(Changesets Action v1 命名该步骤输出为publishedPackages,v2 为published-packages),它把 npm 包名映射到emdash-plugin.jsonc的 slug、忽略普通包、核验报告版本,并将匹配的插件作为矩阵发布。对仅 EmDash 的私有包,需在.changeset/config.json中同时设置privatePackages.versionprivatePackages.tagtrue(任一缺失 setup 都会警告)。

包标签变体<slug>@<version>标签解析为唯一的插件清单。手动运行接受插件 ID 并使用其清单版本。每种变体都会构建选中包、创建带签名的 GitHub 构建来源证明(Sigstore attestation)并发布。私有/内部 GitHub 仓库不受支持——其证明使用私有 Sigstore 信任根,release verifier 不信任它。

8.4 首次运行的仓库批准

用拥有插件的 Atmosphere 账户登录 release-service 仪表盘并授权 EmDash 创建插件发布。然后按 setup 选择的来源触发发布(让 Changesets 发布包、推送gallery@1.2.3之类的包标签、或手动运行工作流)。服务先核验签名的galleryprofile 确实指名了该 GitHub 仓库,随后该 ref scope 的首次运行会等待,并在 GitHub job summary 中追加仓库批准链接。打开链接,核对仓库、工作流文件、分支或标签与环境,确认连接后同一运行继续。

对于从标签发起的发布,仪表盘可授权所有包版本标签或仅当前标签;手动运行在其分支首次使用时请求批准。确认另一 scope 是扩展连接而非替换既有 scope。仓库与工作流路径保持精确匹配;当另一包签名的 profile 指名同一仓库时,可复用已批准的 scope。旧包级工作流创建的策略不会给另一包复用。

8.5 服务端执行链

工作流把 bundle 与原始 Sigstore 证明上传到私有、瞬时的服务端存储,每个请求都使用全新的 GitHub Actions OIDC token。服务核验确切字节,把插件 bundle 上传到发布者的 PDS,并发布一条含 PDS blob 引用的发布记录。发布的来源证明 URL 指向不可变的已核验证明。

服务在接受上传前会检查:包 profile 存在、包含委派发布设置、指名同一 GitHub 仓库。缺失或不兼容时以PACKAGE_PROFILE_REQUIRED失败——本地运行emdash-plugin profile setup后重启工作流即可。release-service 不能创建或编辑包 profile,因为其保留的授权仅限创建发布记录与上传文件。

8.6 底层自动化命令

dry-runsubmitstatuscancel供自定义工作流使用,它们以当前 GitHub Actions OIDC 身份认证,接受手工编写的 URL-source 发布记录:

emdash-plugin release submit release.json \ --service-url https://release.example.com \ --publisher-did did:web:publisher.example.com
  • EMDASH_RELEASE_SERVICE_URLEMDASH_PUBLISHER_DID可省略两个目标 flag;
  • 默认幂等键使用 GitHub run ID,重跑会复用既有 intent;--idempotency-key用于跨 job 重放;
  • 手工编写记录中的每个包或 listing 图片产物必须使用校验和绑定的 HTTPSurl不得blob(发布后的记录只含 PDS blob 引用,不含产物来源 URL);
  • --no-wait让命令在服务接受 intent 后立即返回。

statuscancel需要相同的发布者与 GitHub workload 身份:

emdash-plugin release status 01JABCDEFGHJKMNPQRSTVWXYZ0 emdash-plugin release cancel 01JABCDEFGHJKMNPQRSTVWXYZ0

这些命令在 GitHub Actions 之外会失败(无 OIDC 请求端点);标准工作流请使用release setup

8.7 浏览器交接命令

Atmosphere 授权与 passkey 仍是浏览器操作。以下命令打印经校验的浏览器链接,而不是把 OAuth 会话或 passkey 断言复制进终端:

emdash-plugin release delegate --service-url https://release.example.com emdash-plugin release workload --service-url https://release.example.com emdash-plugin release enrol --service-url https://release.example.com emdash-plugin release approve 01JABCDEFGHJKMNPQRSTVWXYZ0 \ --service-url https://release.example.com \ --publisher-did did:web:publisher.example.com

release revoke打开发布者权限撤销,release reject打开拒绝仪式。服务的应用会话 cookie 与 passkey 仪式都保持在服务自己的源(origin)上。委派发布的完整发布者旅程(release-service 授权、首次仓库批准、passkeys、故障排查)可进一步参考仓库内 skills/creating-plugins 技能及其 references;相关实现位于 src/release-setup.ts、src/release-prepare.ts 与 src/release-service/operations.ts,行为验证见 tests/release-setup.test.ts 与 tests/release-service-operations.test.ts。

九、编程 API:不经子进程调用

@emdash-cms/plugin-cli也导出面向工具链(编辑器、自定义构建脚本、其他 CLI)的编程接口(入口见 src/api.ts):

import { buildPlugin, bundlePlugin } from "@emdash-cms/plugin-cli"; await buildPlugin({ dir: "./my-plugin" }); const result = await bundlePlugin({ dir: "./my-plugin" });

该包还导出发布相关 API(publishReleasesetupPackageProfile)、slug/版本校验工具(isPluginSlugisPluginVersionderiveSlugFromIdPLUGIN_SLUG_REPLUGIN_VERSION_RE)、清单类型(PluginManifestPluginCapabilityPluginStorageConfig等)与sha256Multihash。其中 slug/版本工具与清单类型是从@emdash-cms/plugin-types复导出——新的工具链代码应直接从@emdash-cms/plugin-types导入。检索与凭据存储则从@emdash-cms/registry-client导入plugin-cli是发布者侧表面(bundle、publish),聚合器检索与 OAuth 凭据存储属于 registry-client 的职责。

十、本地开发与贡献

从干净检出开始,先安装再构建,然后做 scoped 类型检查:

pnpm install pnpm build pnpm --filter @emdash-cms/plugin-cli typecheck

构建会产出内部工作区类型声明供 scoped typecheck 使用,与 CI 的 build-then-typecheck 顺序一致(对应 package.json 的 scripts)。包内测试用pnpm --filter @emdash-cms/plugin-cli test(vitest)运行,覆盖清单 schema 漂移(tests/schema-drift.test.ts)、publisher 钉扎(tests/manifest-publisher.test.ts)、发布流程(tests/publish.test.ts)等关键路径,其中 tests/fixtures 提供了minimal-pluginbad-plugin两个对照样本。

结语:从脚手架到持续发布的完整闭环

回到开篇的流程图式理解:emdash-plugin把插件生命周期组织成三条清晰的路径——本地创作init→ 手写emdash-plugin.jsonc+src/plugin.tsbuild/dev/bundle)、手动发布loginpublish,DID 钉扎保证账号正确、labeler/聚合器把关公开可见性)、委派发布release setup生成工作流,GitHub OIDC + 仓库批准 + Atmosphere 授权共同构成最小权限链)。无论走哪条路径,emdash-plugin.jsonc都是单一事实来源:身份、信任契约与 profile 都在一个可 IDE 补全的 JSONC 文件中,schema 的严格模式与行:列错误定位让配置错误在本地而非线上暴露。对于任何准备把插件交付给 EmDash 用户的开发者,这套工具链值得按本文顺序完整走一遍。

  • CMS
  • 后端
  • 前端
  • 插件系统

【免费下载链接】emdash

EmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress

项目地址:https://gitcode.com/gh_mirrors/emdas/emdash
点击查看免费下载

相关推荐

上一篇:如何使用ReflectionDocBlock:PHP文档注释解析的终极指南
下一篇:Leaflet-search未来展望:地图搜索技术的发展趋势与路线图

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询