Skip to content

RFC-0002:Plugin / Bundle Artifact 的 apply 合同 ​

状态:Implemented 关联:Epic #5;#2、#3、#6;R5
消费者证据:私有 Preset 组合入口 jue-preset-ai-assets(ai-assets presets/personal)
官方依据(2026-08 核验):

背景 ​

RFC-0001 已规定 Plugin、Bundle 与配置都是 Artifact 形态。Claude / Codex Adapter 的 write() 已支持 artifactKind: "plugin";本 RFC 将 Artifact 选择、Adapter-owned layout detection 与 Core 执行路径统一接线。targets.*.artifact、enabled 与 scope 属于转换环境,不进入 Canonical DSL。

JUE-302 的实测对象是 workspace 项目树(AGENTS.md / skills/ / hooks/)。 OpenClaw 官方文档(2026-08 核验)还定义了独立可安装表面 Compatible bundle:

OpenClaw 表面是什么与 Jue 的关系
Workspace项目内 skills/hooks/AGENTSAdapter 已实现
Compatible bundle安装 Claude / Codex / Cursor 布局,映射为 OpenClaw 能力应用 Claude/Codex 已有 plugin 产物,零新布局
Native pluginopenclaw.plugin.json + 进程内 TS 运行时超出 Canonical 能力包;本 RFC 非目标

Hermes 的「plugin」是另一套产品语义:

Hermes 表面是什么与 Jue 的关系
Workspaceskills/<cat>/<name>/、config.yaml mcp、MEMORY.mdAdapter 已实现;能力包主路径
General pluginplugin.yaml + __init__.py(Python tools/hooks/commands)运行时扩展;不是 Canonical skill 包的默认载体
Plugin-bundled skills同上目录内 skills/<name>/SKILL.md + ctx.register_skill可选薄封装;需生成少量 Python
~/.hermes/plugins / installs.json安装注册表不是可分发 Artifact 本身

若不按官方表面选型,会误造「第四种 OpenClaw 目录」或「假 Hermes plugin.json」,成本高且无法 plugins install 验收。

目标 ​

  1. CLI / targets 可选 Artifact 形态(默认不变)。
  2. 私有 / npm pack Preset 不经公网 publish 即可产出可安装产物。
  3. 最小代价:能复用 Claude/Codex plugin writer 的绝不重写;不为 OpenClaw 发明新目录树;不为 Hermes 生成完整 Python 工具插件(除非用户显式要 runtime 扩展)。
  4. Smoke 可对所选形态做原生确认(或诚实 unsupported)。

非目标 ​

  • OpenClaw native plugin(openclaw.plugin.json + definePluginEntry / 进程内工具)。
  • Hermes 完整 Python 工具 / platform / memory / model-provider 插件生成。
  • Marketplace / ClawHub / pip 发布流水线。
  • 修改 Canonical DSL;强制四端 degraded 清零;在 ai-assets 写 Adapter。

官方映射(决定实现形状) ​

OpenClaw compatible bundle(已支持安装) ​

bash
openclaw plugins install ./my-bundle
openclaw plugins list          # Format: bundle;Bundle format: claude|codex|cursor
openclaw plugins inspect <id>

检测标记(官方):

Bundle formatMarkerOpenClaw 映射(supported)
Codex.codex-plugin/plugin.jsonskills;hooks(仅 HOOK.md+`handler.ts
Claude.claude-plugin/plugin.json 或无 manifest 默认布局skills;commands/→当 skill 根;MCP;settings/LSP;agents / hooks.json 仅 detect
Cursor.cursor-plugin/plugin.jsonskills;commands→skills;其余多 detect-only

安全边界:bundle 不加载任意 in-process 模块;比 native plugin 更窄——这正适合 Jue 从 Canonical 导出的内容包。

Hermes plugin(Python 优先) ​

text
~/.hermes/plugins/<name>/
├── plugin.yaml
├── __init__.py          # register(ctx)
└── skills/<name>/SKILL.md   # 可选;ctx.register_skill
  • 项目本地:./.hermes/plugins/(默认关,需 HERMES_ENABLE_PROJECT_PLUGINS=true)。
  • 能力包(skills/agents/commands 文本)的默认 Hermes 交付仍是 workspace,不是 Python plugin。
  • 若需「可 hermes plugins install 的 skill 包」,只做 thin skill-plugin(yaml + 自动生成的 register_skill 循环 + flat skills/),不生成业务 tools。

候选方案 ​

A. 四端各自发明聚合目录 ​

成本高;OpenClaw 官方已提供 Claude/Codex 入口,重复造轮子。否决。

B. 仅 CLI 接线 Claude/Codex;OpenClaw/Hermes 永不做聚合 ​

成本最低短期;但浪费 OpenClaw 已有 plugins install bundle 能力,R5 四端聚合不闭合。作 Phase 0,不作终点。

C. 配置优先 + CLI 覆盖;OpenClaw 委托已有 plugin writer;Hermes 分层(推荐) ​

见决策。

决策(Accepted) ​

采用 方案 C,并冻结 kind 名与实现策略:

AdapterKind实现策略(最小代价)
claude-codeproject, plugin已有 write/confirm;只接 CLI/config
codexproject, plugin同上
openclawworkspace, compatible-bundlecompatible-bundle 复用 Claude 或 Codex 的 write(..., { artifactKind: "plugin" }) 产出目录,再以 openclaw plugins install / inspect 确认 Format: bundle
hermesworkspace, skill-pluginskill-plugin 生成 plugin.yaml + 最小 __init__.py(仅 register_skill)+ flat skills/<name>/;mcp 继续走 workspace/config.yaml

OpenClaw compatible-bundle 细节 ​

  1. 默认 bundle 基底:claude(ai-assets 以 skills/commands 为主;Claude commands/→OpenClaw skill 根)。
  2. 当 Canonical 含 hooks 且需要 OpenClaw 可执行 hooks 时,改用 codex 基底(官方:仅 Codex 式 HOOK.md+handler 可执行;Claude hooks/hooks.json 为 detect-only)。
  3. 选择来源:tools.openclaw.bundleFormat: "claude" | "codex" | "cursor" | "auto"(auto = 有 runnable hooks → codex,否则 claude;永不自动选 Cursor)。
  4. Adapter 代码路径:OpenClaw write 在 compatible-bundle 分支 委托
    ai-jue-adapter-claude / ai-jue-adapter-codex 的 write(或抽共享 helper),禁止复制粘贴第二套目录逻辑。
  5. Confirm:隔离目录上优先执行 openclaw plugins install <dir> → openclaw plugins inspect <id>,断言 Format: bundle 与 Bundle format: claude|codex;CLI 不可用时保留结构证据并返回 unconfirmed。native openclaw.plugin.json 不作为 Canonical bundle 的确认证据。
  6. Workspace 与 bundle 分离:workspace 继续写 AGENTS/skills/hooks 到项目树;bundle 不替代 workspace,除非用户显式选 kind。

Hermes skill-plugin 细节 ​

  1. 仅打包 canonical.skills;其余 Capability 保持 workspace / degraded 诚实声明。
  2. 树:
text
<output>/
├── plugin.yaml                 # name 取 Preset 引用名(去 jue-preset- 前缀);version 恒 0.1.0;description 有默认值;均可被 tools.hermes.pluginManifest 覆盖
├── __init__.py                 # 生成:遍历 skills/ 调用 ctx.register_skill
└── skills/<skill-name>/SKILL.md (+ references 等)
  1. Confirm:plugin.yaml、__init__.py、register_skill 与 skill roots 提供结构证据; tirith config validate 继续只用于 workspace。
  2. skill-plugin 结构已实现;workspace 继续作为 Hermes 能力包主路径。

选择解析(不变) ​

  1. CLI --artifact-kind / --artifact
  2. 否则 targets.<adapter>.artifact
  3. auto 使用 Adapter 的稳定默认 project / workspace

非法 / 未实现 kind:写入前失败,不得静默降级。

详细合同 ​

CLI / ProjectConfig ​

bash
jue apply --adapter claude-code --artifact-kind plugin
jue apply --adapter openclaw --artifact-kind compatible-bundle
jue apply --adapter hermes --artifact-kind skill-plugin
jue apply --all
js
export default {
  presets: ["ai-assets"],
  targets: {
    "claude-code": { artifact: "plugin" },
    codex: { artifact: "plugin" },
    openclaw: { artifact: "compatible-bundle" },
    hermes: { artifact: "workspace" } // 或 "skill-plugin"
  },
  tools: {
    openclaw: { bundleFormat: "auto" } // "claude" | "codex" | "cursor" | "auto"
  }
};

hermes: { artifact: "auto" } 使用稳定默认 workspace;skill-plugin 通过 显式 artifact 或 --artifact 选择。

Core ​

runCoreAdapter 传入解析后的 kind;禁止硬编码 "project"。

能力诚实矩阵(bundle / skill-plugin) ​

CanonicalClaude pluginCodex pluginOpenClaw via Claude bundleOpenClaw via Codex bundleHermes skill-plugin
skills支持支持映射为 skills映射为 skillsregister_skill
commands支持degraded当 skill 根degraded/不映射不打包
agents支持支持(TOML)detect-only视 Codex 映射不打包
hookshooks.json.codex/hooks.jsondetect-only可执行(OpenClaw 布局)不打包(Hermes hooks 另面)
mcp.mcp.json.mcp.json合并到 embedded合并到 embedded不打包(用 workspace)
context.globalproject 专用project 专用通常不进 bundle通常不进 bundle不打包

导出前必须把上表中的 detect-only / 不打包项以 degraded/unsupported 或 apply 预检警告暴露,禁止静默丢弃而无提示。

安全 ​

  • Bundle / skill-plugin 不得含密钥与未脱敏 PII。
  • OpenClaw bundle 保持官方窄信任边界(不加载任意 runtime 模块)——故 禁止 为 图省事改写 native openclaw.plugin.json 去「塞」Canonical。
  • Hermes __init__.py 仅允许生成固定的 register_skill 样板,不得嵌入用户 Canonical 正文为可执行代码。
  • 安装到 user 插件目录的 confirm 必须用隔离 HOME / profile,避免污染开发机。

兼容 / 迁移 ​

  • 无 flag / 无 targets:默认行为不变(project/workspace)。
  • packages/docs/agents/openclaw.md 区分 workspace vs compatible bundle vs native plugin 三种表面:compatible bundle 是官方可安装表面,没有 Jue 自创 聚合树,workspace 仍是项目主路径。
  • compatible-bundle 字符串保留(Guide 已用);语义冻结为「Claude/Codex 兼容包」, 不是第三种目录方言。

验收标准 ​

  1. #2:Claude/Codex jue apply --artifact-kind plugin;native 确认能力由 --check 模式探测(Core 路径不调用 confirm)。
  2. OpenClaw:compatible-bundle 产物可被
    openclaw plugins install <dir> 识别为 Format: bundle;
    有 hooks 时 bundleFormat=codex(或 auto)且 hooks 可执行面符合官方表。
  3. Hermes:skill-plugin 生成 thin skill-plugin 结构,并通过 plugin.yaml、 register_skill initializer 与 skill roots 提供确认证据;workspace 仍绿。
  4. --all + targets.enabled/artifact/scope 分端生效;非法 kind 与未实现 scope 预检失败。
  5. smoke:preset-local --entry ai-assets 支持 artifact 模式;离线 pack。
  6. 二次 apply 幂等。

已知边界(已实现后遗留) ​

  1. OpenClaw CLI 是否在所有 CI 环境提供;当前合同为 CLI 可用时 install+inspect, CLI 缺席时返回结构化 unconfirmed。
  2. Hermes skill-plugin 是否增加真实 hermes plugins install/list headless 证据。
  3. Cursor 仅作为显式 bundleFormat: "cursor" 第三基底;auto 不选 Cursor。

实施切片 ​

顺序Issue工作代价
1#2CLI/Core/targets 接线小
2#3(OpenClaw)compatible-bundle 委托 Claude/Codex writer + confirm小(无新布局)
3#3(Hermes skill-plugin)thin skill-plugin(skills;mcp 仍 workspace)中
4#6smoke 矩阵小–中
—明确不做OpenClaw native plugin、Hermes 业务 Python tools避免大代价

实现 Issue 必须链接本 RFC。

Define once. Adapt everywhere.