周毓杰

Skill 与 Plugin 发布

Workspace 提供统一的 Hub 发布器。它只读取本地归档,通过 Backend 创建 presigned upload 并把归档直接上传到 RustFS,随后调用 Skill Hub 或 Plugin Hub 完成严格校验、 签名和不可变版本发布。CLI 不读取对象存储凭据。

Plugin 的 runtime 选择、manifest、贡献 Skill、用户手册、本地开发和测试方式见 Plugin 开发手册

准备归档

发布器接收 .tgz,且归档必须只有一个顶层目录:

  • Skill:顶层目录内必须有 SKILL.md
  • Plugin:顶层目录内必须有 PLUGIN.md、根 plugin.json 和标准 skills/<name>/SKILL.md;使用 Open Nua 扩展时,专有文件必须位于 com.opennua.desktop/

例如:

COPYFILE_DISABLE=1 tar -czf /tmp/vibe-trading-research.tgz \
  --exclude='.env' \
  --exclude='.git' \
  --exclude='.venv' \
  --exclude='__pycache__' \
  --exclude='node_modules' \
  -C plugins/packages vibe-trading-research

在 macOS 上必须保留 COPYFILE_DISABLE=1,避免 tar 写入隐藏的 ._* AppleDouble 元数据文件;这类文件会使归档出现额外顶层成员,因而被安全校验拒绝。

Backend 是包结构、manifest、digest 和版本合法性的最终校验方。

首次发布

本地默认通过 Gateway 使用 Desktop 的 apps/desktop/.session。也可以用 OPEN_NEO_SESSION_TOKEN 显式提供当前登录会话。部署 Gateway 不会复用这份本地 Desktop session;先用终端登录,为目标 Hub 建立 origin 隔离的发布会话:

npm run publish:login -- \
  --gateway-url https://openneo-prod.test \
  --username <name>

命令会在终端中无回显地询问密码,绝不把密码放进命令行或环境变量。成功后仅在 ~/.open-neo/hub-sessions/ 保存一个权限为 0600、绑定到该 Hub origin 的 Gateway session。若本地尚未信任 prod-sim 的 Caddy 根证书,可在登录和发布时都设置:

NODE_EXTRA_CA_CERTS=~/.open-neo/prod-sim/caddy/data/caddy/pki/authorities/local/root.crt \
  npm run publish:login -- --gateway-url https://openneo-prod.test --username <name>

发布时显式指定同一个 Hub API base URL:

npm run publish:plugin -- \
  --base-url https://openneo-prod.test/api/proxy/open-neo/skills/api \
  --archive /tmp/vibe-trading-research.tgz \
  --slug vibe-trading-research \
  --version 1.0.0 \
  --visibility authenticated \
  --tags finance,research

也可运行 npm run publish:login -- --help 查看完整参数。

npm run publish:plugin -- \
  --archive /tmp/vibe-trading-research.tgz \
  --slug vibe-trading-research \
  --version 1.0.0 \
  --visibility authenticated \
  --tags finance,research

Skill 使用同一套参数,并可额外传 --category

npm run publish:skill -- \
  --archive /tmp/meeting-summary.tgz \
  --slug meeting-summary \
  --version 1.0.0 \
  --visibility team \
  --team-id <team-uuid> \
  --category 效率提升

public 可见性仍受 Backend 发布策略约束;CLI 不绕过服务端授权。

发布新版本

资产版本不可覆盖。使用 Hub 中已有的 Skill/Plugin ID 发布新版本:

npm run publish:plugin -- \
  --archive /tmp/vibe-trading-research-1.1.0.tgz \
  --asset-id <plugin-uuid> \
  --version 1.1.0

--asset-id 模式只接受归档和版本,不修改 slug、owner、visibility、标签、分类或 icon。

直连 Backend(仅开发环境)

Backend 开发接口使用明确的 account header:

npm run publish:plugin -- \
  --base-url http://127.0.0.1:8000/api \
  --account yujie.zhou \
  --archive /tmp/plugin.tgz \
  --slug demo-plugin \
  --version 1.0.0

部署环境应使用 Gateway session,不应将 Backend 的开发期 account header 暴露为 公网认证机制。完整参数可运行 npm run publish:plugin -- --help 查看。

重新加载本地 Plugin

Desktop 本地开发实例运行并开放 CDP 时,可以直接从命令行重新加载已安装的本地 Plugin,不需要进入资产库操作。命令复用 Desktop 与 UI 相同的 reload 能力,并保留 插件当前的启用/停用状态。本地开发 Plugin 默认在 Desktop 托管目录创建指向源码 目录的符号链接(Windows 使用 junction),不会在每次 reload 时复制整个依赖目录; Hub 安装的已发布 Plugin 仍使用经过签名校验的独立副本:

npm run plugin -- reload-local deep-tutor-mastery

也可以传最初加载的源码目录,CLI 会读取根 plugin.json 得到 Plugin ID:

npm run plugin -- reload-local \
  plugins/packages/deep-tutor-mastery

默认连接 http://127.0.0.1:9225;可使用 --cdp-url 覆盖,使用 --json 输出机器 可读结果。Desktop 未运行、未开放 CDP、目标不是本地目录加载的 Plugin,或源码校验 失败时,命令会以非零状态退出并保留原安装副本。