release-skill 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codebuddy-plugin/plugin.json +4 -2
  4. package/.codex-plugin/plugin.json +2 -2
  5. package/.kimi-plugin/plugin.json +1 -1
  6. package/CHANGELOG.md +41 -0
  7. package/CONTRIBUTING.md +27 -0
  8. package/INSTALL.md +95 -139
  9. package/INSTALL.zh-CN.md +70 -121
  10. package/README.md +265 -916
  11. package/README.zh-CN.md +222 -537
  12. package/adapters/claude/.claude-plugin/marketplace.json +1 -1
  13. package/adapters/claude/.claude-plugin/plugin.json +1 -1
  14. package/adapters/claude/bin/release-skill.bundle.mjs +18710 -16694
  15. package/adapters/claude/schemas/release-plan.schema.json +137 -0
  16. package/adapters/claude/schemas/release-project.schema.json +93 -0
  17. package/adapters/claude/schemas/release-run.schema.json +70 -2
  18. package/adapters/codex/.codex-plugin/plugin.json +2 -2
  19. package/adapters/codex/bin/release-skill.bundle.mjs +18710 -16694
  20. package/adapters/codex/schemas/release-plan.schema.json +137 -0
  21. package/adapters/codex/schemas/release-project.schema.json +93 -0
  22. package/adapters/codex/schemas/release-run.schema.json +70 -2
  23. package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
  24. package/adapters/kimi/bin/release-skill.bundle.mjs +18710 -16694
  25. package/adapters/kimi/schemas/release-plan.schema.json +137 -0
  26. package/adapters/kimi/schemas/release-project.schema.json +93 -0
  27. package/adapters/kimi/schemas/release-run.schema.json +70 -2
  28. package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
  29. package/adapters/workbuddy/bin/release-skill.bundle.mjs +18710 -16694
  30. package/adapters/workbuddy/schemas/release-plan.schema.json +137 -0
  31. package/adapters/workbuddy/schemas/release-project.schema.json +93 -0
  32. package/adapters/workbuddy/schemas/release-run.schema.json +70 -2
  33. package/bin/release-skill.bundle.mjs +18710 -16694
  34. package/package.json +1 -1
  35. package/schemas/release-plan.schema.json +137 -0
  36. package/schemas/release-project.schema.json +93 -0
  37. package/schemas/release-run.schema.json +70 -2
  38. package/src/adapters/plugin-marketplace.mjs +1602 -605
  39. package/src/commands/prepare.mjs +441 -32
  40. package/src/commands/publish.mjs +107 -75
  41. package/src/commands/reconcile.mjs +92 -327
  42. package/src/commands/setup.mjs +148 -20
  43. package/src/commands/verify.mjs +315 -25
  44. package/src/core/baseline.mjs +21 -1
  45. package/src/core/checkpoints.mjs +50 -7
  46. package/src/core/config.mjs +15 -0
  47. package/src/core/errors.mjs +2 -0
  48. package/src/core/installation-contract.mjs +341 -0
  49. package/src/core/plan.mjs +307 -6
  50. package/src/platforms/codebuddy.mjs +191 -238
  51. package/src/platforms/codex.mjs +369 -0
  52. package/src/platforms/kimi.mjs +164 -119
  53. package/src/platforms/registry.mjs +180 -4
  54. package/src/producers/build-adapters.mjs +9 -2
package/README.zh-CN.md CHANGED
@@ -2,36 +2,37 @@
2
2
 
3
3
  [English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.2.2 -->
6
- 面向 Claude Code、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
5
+ <!-- release-skill:release-version: 0.2.4 -->
6
+ 面向 Claude Code、CodeBuddy、WorkBuddy、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
7
7
 
8
- release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终发布的内容是什么。它先冻结并供人工审阅,再从同一份冻结产物发布,不会在最后一步重新生成 README、重新打包当前工作区或覆盖人工内容。
8
+ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终发布的内容是什么。它不重新生成、也不回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节——先冻结并供人工审阅,再从同一份冻结产物发布。`setup` 只显示确定性的 `compactSummary` 审阅视图,完整报告保留在临时会话目录中。
9
9
 
10
10
  <!-- release-skill:managed:start id=latest-release -->
11
- **0.2.2** (2026-07-26)
11
+ **0.2.4** (2026-07-28)
12
12
 
13
- v0.2.2 闭合 CodeBuddy 平台分发链路并新增外部独立市场分发形态。CodeBuddy/WorkBuddy 经与 kimi 同构的人工 attestation 闭环接入 publish/reconcile/verify 流水线:因 codebuddy CLI 无法钉死冻结 ref(无 ref 选项、安装跟踪默认分支/latest),execute 阶段写手动安装 requirement(绝不 exec CLI),observe/verify 消费结构化人工 attestation 并对安装点做只读校验——缺失、过期、不匹配、路径逃逸一律 fail-closed,严重级别与 kimi 一致(发布后验证不可豁免)。外部市场形态允许 distribution 声明 `marketplaceRepo`,prepare 在线冻结外部市场 HEAD(codex 强冻至 commit sha、claude 弱冻至默认分支名)并做冻结 sha 与索引条目完整性校验,plugin-marketplace 在 `external-marketplace-v1` 载荷契约下新增对应 preflight/observe 分支,inline/kimi/codebuddy/legacy 分支一字不变。安装说明(中英四份)统一以独立市场 `ifoohoo/artifact-skill-set` 为主路径。npm 包名(`release-skill`)、发布身份(`publisher: mzdbxqh`)、公开仓库(`ifoohoo/release-skill`)与公司维护主体保持不变。
14
-
15
- **新增**
16
-
17
- - **CodeBuddy 平台人工 attestation 闭环**:CodeBuddy/WorkBuddy 经与 kimi 同构的人工 attestation 闭环接入发布流水线(`publish`/`reconcile`/`verify`)。因 codebuddy CLI 的 marketplace add/install 均无法钉死冻结 ref(无 ref 选项、安装跟踪默认分支/`latest`,已实测),自动化安装检查点无法保证冻结产物同一性。execute 写手动安装 requirement,绝不 exec CLI;observe/verify 消费结构化人工 attestation 并对安装点做只读校验。缺失、过期、不匹配、路径逃逸的 attestation 一律 fail-closed,严重级别与 kimi 一致(发布后验证不可豁免)。双安装通道(均有实测落盘证据):desktop 经 WorkBuddy 桌面端统一市场 `artifact-skill-set` 安装(`installPath` 须含 `/.workbuddy/plugins/marketplaces/artifact-skill-set/plugins/<plugin>` 尾段,段级检查);cli 以隔离 `HOME=<authorityDir>/codebuddy-home` 运行捆绑 CLI(`installPath` 须 containment 于该隔离 home 的市场插件根)。attestation 增加 `installChannel` + `marketplace` 字段并按通道校验。管线路由:平台 id `codebuddy`,distributionType `codebuddy-plugin`,actionType `codebuddy-marketplace-install`,列于 Tier 3(与 kimi 同层);build adapter 保留历史目录名 `workbuddy`(`adapters/workbuddy/`、`.codebuddy-plugin/plugin.json` 清单,字节不变)。
18
- - **外部独立市场分发形态**:distribution 声明 `marketplaceRepo` 时启用外部形态。prepare 生产循环经 `git ls-remote --symref` 在线冻结外部市场 HEAD(codex 强冻至 commit sha、claude 弱冻至默认分支名),并经 `gh api` 校验外部索引条目(name 匹配、恰一条、claude 形态 `entry.version == 目标版本`);非在线声明外部形态 fail-closed,外部仓库严格只读。冻结动作携带 `repo=marketplaceRepo`、`ref=add-ref`、`marketplaceCommitSha`、`marketplaceLocation=external`、`payloadContract=external-marketplace-v1`;`snapshotPath`/`manifestDigest` 仍绑本单元冻结快照(载荷权威不变)。plan 完整性校验增加外部分支(repo 匹配、`marketplaceLocation`、40-hex `marketplaceCommitSha`、ref 结构安全);kimi/codebuddy 携带 `marketplaceRepo` fail-closed。`plugin-marketplace` 新增外部形态 preflight/observe 分支:`external-marketplace-v1` 走与 `declared-manifest-v1` 相同的整树包含语义(权威为 `.`,宿主新增路径记 `extraInstalledPaths` 而非失败);preflight 跳过快照内市场段,从快照根读 plugin manifest 校验 name/version 与冻结字段;observe 复用既有 strategy 做安装侧条目观察比对(弱冻 claude 版本漂移 fail-closed)。inline/kimi/codebuddy/legacy/`declared-manifest-v1` 分支一字不变。
13
+ v0.2.4 是文档与市场来源整改版本。将默认市场来源纠正为 bundled-family 仓库(ifoohoo/release-skill),消除过时的 v0.1.9 残留,改善 README 双语一致性与导航,并强化版本漂移的防复发门禁。
19
14
 
20
15
  **变更**
21
16
 
22
- - **安装说明统一市场主路径(中英四份)**:README INSTALL(四份文档)将插件安装统一改为以独立市场 `ifoohoo/artifact-skill-set` 为主路径,README 增补工作流概览与平台分发说明。标准与公开参考(`standards/06-adapter-contract.md`、`references/06-adapter-contract.md`)同步至 codebuddy attestation 形态与外部独立市场形态及其时序约束。
17
+ - **默认市场来源纠正**:所有安装文档现使用 bundled-family 仓库 `ifoohoo/release-skill`,而非外部市场 `ifoohoo/artifact-skill-set`。Claude Code 安装命令改为 `/plugin marketplace add ifoohoo/release-skill`,安装名为 `release-skill@release-skill`。
18
+ - **README 结构优化**:中英文 README 均增加目录、文档导航章节,并重组章节流程(快速开始移至保存契约之前)。相较此前显著缩短。
19
+ - **定位句补全**:README 和根工作区 README 现列出所有支持平台(Claude Code、CodeBuddy、WorkBuddy、Codex、Kimi Code)。
20
+ - **防复发门禁扩展**:`sync-version.mjs` TEXT_TARGETS 现覆盖中英文 README 的 safe-first-command 版本陈述,防止未来 v0.1.9 类漂移。
23
21
 
24
22
  **修复**
25
23
 
26
- - **CodeBuddy 插件 manifest `skills` 字段改为数组**:`.codebuddy-plugin/plugin.json` 清单的 `skills` 字段改为数组输出,与 CodeBuddy 宿主期望的形状一致。
27
- - **`verificationGate` 作用域 distribution 枚举补 `codebuddy-plugin`**:`release-project.schema.json` `verificationGate.scope.distribution` 枚举补入 `codebuddy-plugin`(镜像既有 `kimi-plugin` 规则),保持 schema 与运行时门白名单一致;四个适配器内嵌的 schema 副本同步重建。
24
+ - **消除 v0.1.9 残留**:两个 README 的 safe-first-command 块现正确引用当前版本(之前停留在 v0.1.9)。
25
+ - **移除易漂移计数**:将 'All four plugin hosts' / '四种插件宿主' 替换为 'All supported plugin hosts' / '各插件宿主'。
26
+ - **根 README 边界修正**:明确 README/INSTALL/CHANGELOG 是人工维护的源文件,references/schemas/adapters/skills 是生成产物。
27
+ - **CONTRIBUTING 更新**:新增'不要直接编辑生成物'章节,说明 references/、schemas/、adapters/、skills/ 的权威来源和再生命令。
28
+ - **AGENTS.md 语言规则调整**:治理规则文件可使用英文;面向用户的文档仍使用中文。
28
29
  <!-- release-skill:managed:end id=latest-release -->
29
30
 
30
31
  <!-- release-skill:capability:external-write-boundary -->
31
- > **当前边界:** v0.2.2 是当前发布版本(v0.1.9 曾处于已发布、待独立验证状态)。
32
+ > **当前边界:** v0.2.4 是当前发布版本(v0.2.2 曾处于已发布状态,后因平台验证收敛修复而更新)。
32
33
  > v0.1.1 已完成 GitHub 与 npm 的
33
34
  > 真实生产发布,是首次生产验证的历史里程碑,并从冻结 Git ref 完成精确 npm
34
- > 安装及 Claude/Codex 消费者安装验证;“当前发布版本”与“首次生产验证里程碑”
35
+ > 安装及 Claude/Codex 消费者安装验证;"当前发布版本"与"首次生产验证里程碑"
35
36
  > 是两个不同的事实,不得混写成同一含义。同一工作流还通过了本地
36
37
  > 生产等价协议套件:测试运行真实 release-skill CLI 和冻结制品,Git 目标是
37
38
  > 本地 bare remote,`gh`、`npm`、Claude、Codex 使用协议级 fake。该套件没有
@@ -41,7 +42,7 @@ v0.2.2 闭合 CodeBuddy 平台分发链路并新增外部独立市场分发形
41
42
  > 远端唯一性检查在 `publish` 全局预检执行。
42
43
 
43
44
  <!-- release-skill:capability:safe-first-command -->
44
- > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.1.9 是当前发布版本。**
45
+ > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.2.4 是当前发布版本。**
45
46
  > npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
46
47
  >
47
48
  > **第一条命令:**
@@ -55,55 +56,26 @@ v0.2.2 闭合 CodeBuddy 平台分发链路并新增外部独立市场分发形
55
56
  > --confirm-production <planDigest>`;`bound` 前序公开基线必须使用
56
57
  > `prepare --online --production`。没有摘要确认就不会预检或写远端。
57
58
 
58
- ## 发布工作流概览
59
-
60
- release-skill 把发布生命周期建模为一个严格状态机,让每个阶段都有明确的进入和退出条件,且任何阶段都不能跳过。规范定义见 `references/01-state-machine.md`。
61
-
62
- ```text
63
- DISCOVERED -> ASSESSED -> PREPARED -> APPROVED -> PUBLISHING -> PUBLISHED -> VERIFIED
64
- 异常态:NEEDS_INPUT / BLOCKED / PARTIAL
65
- ```
66
-
67
- 每个 CLI 命令对应一次状态转换:
68
-
69
- - `help` 检查环境;`setup` 发现项目,并在摘要确认后仅首次创建配置。
70
- - `assess` 执行只读就绪度评估(`DISCOVERED -> ASSESSED`)。
71
- - `prepare` 运行验证门、冻结一份不可变发布计划,并把配置的公开文件复制进隔离快照(`ASSESSED -> PREPARED`)。它只写入 `.release-skill/` 目录,从不触碰远端服务。
72
- - `approve` 记录人工批准,绑定到计划摘要并带 24 小时有效期(`PREPARED -> APPROVED`)。计划一旦变化,批准自动失效。
73
- - `publish` 按顺序执行外部写操作检查点(`APPROVED -> PUBLISHING -> PUBLISHED`)。
74
- - `reconcile` 从 `PARTIAL` 恢复;`verify` 在全新隔离环境完成消费者安装验证(`PUBLISHED -> VERIFIED`)。
59
+ ## 目录
75
60
 
76
- `PUBLISHED` **不是**终态。只有全新运行的 `verify` 确认远端状态和精确消费者安装都与冻结计划一致时,才会到达 `VERIFIED`。
77
-
78
- **发布检查点顺序。** `publish` 先对所有动作做只读全局预检,再按固定顺序执行并观察:公开快照 branch → 签名/可追溯 tag → npm 发布 → GitHub Release → 配置的 Claude/Codex 插件市场安装 → 运行记录。任一步骤失败都会停止后续检查点并使运行进入 `PARTIAL`。系统绝不自动删除远端 tag、不 unpublish 包、不从头重跑;`reconcile` 查询实际远端状态,跳过已一致的步骤,只重试安全且未完成的动作,远端冲突则交由人工决策。
79
-
80
- ## 为什么人工修改的 README 不会丢失
81
-
82
- release-skill 不重新生成、也不回写项目源文件。`prepare` 从当前工作区把每个公开文件复制到隔离的本地快照,并验证复制前后的字节。README 的 slogan、示例、正文、格式,以及后续任何人工修改都会作为完整文件被保留。
83
-
84
- - 后续 prepare 重新读取当前文件,不会从模板重建。
85
- - 快照必须与源文件逐字节一致。
86
- - 计划变化会产生新的 digest,旧批准不能授权新内容。
87
- - prepare 后再改源文件,publish 会因 baseline 变化在远端写入前停止。保留修改的正确方式是重新 prepare、重新审阅并重新 approve。
88
- - 冻结制品被篡改时,publish 会因 snapshot/tarball/Git object 摘要不符停止。
89
- - 远端 branch、tag、Release 或 npm 版本冲突时交给人工;系统不 force、不覆盖。
90
- - 只有 `publicFiles` 明确列出的文件会被复制;需要发布的翻译 README、图片、演示文件和链接文档都要显式加入配置。
91
- - 发布只冻结当前真相:`prepare` 不会刷新或重写人工文档。维护者必须先更新 README、INSTALL 与 CHANGELOG(包括必须与 `package.json` 版本一致的机器可读 `release-skill:release-version` 标记,以及当前包版本的正式 CHANGELOG 标题),再 prepare、审阅和批准。任一文档版本标记或 CHANGELOG 当前版本条目漂移时,发布前门禁失败关闭。
92
-
93
- 保护规则只有一句话:**复制当前事实,冻结已审阅事实,不重写人工事实。**
61
+ - [快速开始](#快速开始)
62
+ - [发布工作流](#发布工作流)
63
+ - [文档导航](#文档导航)
64
+ - [Skills](#skills)
65
+ - [平台分发](#平台分发)
66
+ - [许可证](#许可证)
94
67
 
95
68
  ## 快速开始
96
69
 
97
- ### 安装 / 前置条件
70
+ ### 安装
98
71
 
99
- - Node.js 22+
100
- - Git 2.30+
101
- - 至少已有一个提交的目标 Git 仓库
72
+ - Node.js 22+、Git 2.30+、至少已有一个提交的目标 Git 仓库。
102
73
 
103
- **从 npm 安装(推荐):**
74
+ **npm(推荐):**
104
75
 
105
76
  ```bash
106
77
  npm install -g release-skill
78
+ release-skill help
107
79
  ```
108
80
 
109
81
  或免安装直接运行:
@@ -112,214 +84,179 @@ npm install -g release-skill
112
84
  npx release-skill help
113
85
  ```
114
86
 
115
- **验证安装:**
116
-
117
- ```bash
118
- release-skill help
119
- ```
87
+ **插件(Claude Code / CodeBuddy / WorkBuddy / Codex):**
120
88
 
121
- **安装为插件(Claude Code / CodeBuddy / WorkBuddy / Codex / Kimi Code):**
89
+ Claude CodeCodeBuddyWorkBuddy Codex bundled-family 市场
90
+ `ifoohoo/release-skill` 安装:
122
91
 
123
- 四种插件宿主都从统一市场 `ifoohoo/artifact-skill-set` 安装——以 Claude
124
- Code 会话为例:
125
-
126
- ```
127
- /plugin marketplace add ifoohoo/artifact-skill-set
128
- /plugin install release-skill@artifact-skill-set
129
92
  ```
130
-
131
- `ifoohoo/artifact-skill-set` 是一个**外部独立市场**:插件仓库只含 plugin
132
- 清单,marketplace 索引集中于外部市场仓库。当发布单元的插件 distribution 声明
133
- `marketplaceRepo` 时,`prepare --online --production` 会冻结外部市场 HEAD
134
- (Codex 钉 commit sha——强冻结;Claude 钉默认分支名——弱冻结),并以本单元自身
135
- 冻结快照整树校验安装载荷。**发布时序:** 须先发布外部市场索引——其条目版本须
136
- 等于目标发布版本——之后 `prepare` 才能冻结到含该条目的市场 sha。各平台完整命令
137
- 见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md),契约与进阶直接仓库安装方式见
138
- `references/06-adapter-contract.md` §2.3/§2.4。
139
-
140
- **开发安装(贡献者回退,从源码 checkout):**
141
-
142
- ```bash
143
- export RELEASE_SKILL_HOME=/absolute/path/to/release-skill
144
- cd "$RELEASE_SKILL_HOME"
145
- npm exec --yes pnpm@10.17.1 -- install --frozen-lockfile
93
+ /plugin marketplace add ifoohoo/release-skill
94
+ /plugin install release-skill@release-skill
146
95
  ```
147
96
 
148
- 然后通过 `node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs"` 调用 CLI。
97
+ > **前置条件:GitHub 访问。** `owner/repo` 简写会让 Claude Code 通过 SSH 克隆。
98
+ > 如不使用 SSH,可传完整 HTTPS 地址——
99
+ > `/plugin marketplace add https://github.com/ifoohoo/release-skill`——
100
+ > 或设置 `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`。
149
101
 
150
- 先保护本地运行数据,避免把计划、审批和冻结制品提交进仓库:
102
+ **Kimi Code:** Kimi Code 没有市场安装接口,需手动安装并钉死到特定 release
103
+ tag——见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md#安装为-kimi-code-插件)。
151
104
 
152
- ```gitignore
153
- .release-skill/*
154
- !.release-skill/project.yaml
155
- ```
105
+ CodeBuddy、Codex 和 Kimi Code 的完整命令见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md)。
156
106
 
157
- ### 首次接入
107
+ ### 主流程
158
108
 
159
- `setup` 默认只读。把完整报告写入临时文件,只查看确定性的 `compactSummary`(紧凑摘要):
109
+ 按以下顺序执行。步骤 1-4 是安全默认(只读或仅本地);步骤 5-9 需要显式人工门禁。
160
110
 
161
111
  ```bash
112
+ CLI=(release-skill) # 或:CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
162
113
  PROJECT=/absolute/path/to/my-project
163
- SETUP_SESSION="$(mktemp -d "${TMPDIR:-/tmp}/release-setup.XXXXXX")"
164
- REPORT="$SETUP_SESSION/discovery.json"
165
- ANSWERS="$SETUP_SESSION/answers.json"
166
- BOUND_REPORT="$SETUP_SESSION/bound.json"
167
- printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
168
-
169
- release-skill setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
170
- node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary){console.error("compactSummary missing");process.exit(2)}process.stdout.write(JSON.stringify(r.compactSummary,null,2)+"\n")' "$REPORT"
114
+ ACTOR=your-name
171
115
  ```
172
116
 
173
- `NEEDS_INPUT` `LOCAL_ONLY_DETECTED` 按设计返回退出码 2。若 `proposalConflicts` 非空,必须停止自动路径,由人工修正冲突的仓库或映射权威事实后重新运行 setup,不得猜测选边。
117
+ 1. **help** 环境检查:
118
+ ```bash
119
+ "${CLI[@]}" help
120
+ ```
121
+ 2. **setup** — 首次接入(只读发现,然后 create-once 配置):
122
+ ```bash
123
+ SETUP_SESSION="$(mktemp -d "${TMPDIR:-/tmp}/release-setup.XXXXXX")"
124
+ REPORT="$SETUP_SESSION/discovery.json"
125
+ ANSWERS="$SETUP_SESSION/answers.json"
126
+ printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
127
+ "${CLI[@]}" setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
128
+ ```
129
+ 若 `proposalConflicts` 非空,必须停止并由人工修正冲突的仓库或映射权威。无冲突时
130
+ 机械提取 `recommendedAnswers`(不得手写完整 answers):
131
+ ```bash
132
+ SETUP_SESSION='<上一步打印的会话目录绝对路径>'
133
+ node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if((r.proposalConflicts??[]).length){console.error("proposal conflicts require human resolution");process.exit(2)}if(!r.recommendedAnswers){console.error("recommendedAnswers missing");process.exit(2)}fs.writeFileSync(process.argv[2],JSON.stringify(r.recommendedAnswers,null,2)+"\n",{flag:"wx",mode:0o600})' "$REPORT" "$ANSWERS"
134
+ ```
135
+ 确认绑定后的 `setupDigest` 一次,然后创建配置:
136
+ ```bash
137
+ SETUP_SESSION='<会话目录绝对路径>'
138
+ PROJECT='<项目绝对路径>'
139
+ ANSWERS="$SETUP_SESSION/answers.json"
140
+ CREATED_REPORT="$SETUP_SESSION/created.json"
141
+ POST_REPORT="$SETUP_SESSION/post-setup.json"
142
+ ASSESS_REPORT="$SETUP_SESSION/assess.json"
143
+ "${CLI[@]}" setup --root "$PROJECT" --answers "$ANSWERS" \
144
+ --write --confirm-setup <已确认的setupDigest> --json > "$CREATED_REPORT"
145
+ "${CLI[@]}" setup --root "$PROJECT" --json > "$POST_REPORT"
146
+ set +e
147
+ "${CLI[@]}" assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
148
+ ASSESS_EXIT=$?
149
+ set -e
150
+ [ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
151
+ node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>JSON.parse(fs.readFileSync(x,"utf8")));if(c.status!=="CONFIG_CREATED"||p.status!=="ALREADY_CONFIGURED"||!["ASSESSED","NEEDS_INPUT","BLOCKED"].includes(a.status)){process.exit(2)}' "$CREATED_REPORT" "$POST_REPORT" "$ASSESS_REPORT"
152
+ node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
153
+ ```
154
+ 写入必须返回 `CONFIG_CREATED`,下一次 setup 必须返回 `ALREADY_CONFIGURED`。
155
+ 已有配置永不重新生成,后续只做经审阅的增量编辑。发现的脚本标记为
156
+ `SIDE_EFFECTS_UNPROVEN`。只有在人工审阅之后才添加项目专属 hook 或 gate:
157
+ 编辑 `projectConfig.hooks`,或编辑 `verificationGates` 并把同一个 id 加入
158
+ `selectedGateIds`,然后重新运行绑定 dry-run。配置已存在时跳过。
159
+ 完整多步流程见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md#首次接入)。
160
+ 3. **assess** — 只读就绪评估:
161
+ ```bash
162
+ "${CLI[@]}" assess --root "$PROJECT" --offline --json
163
+ ```
164
+ 4. **prepare** — 本地快照与计划冻结:
165
+ ```bash
166
+ "${CLI[@]}" prepare --root "$PROJECT" --offline \
167
+ --acknowledge-hook-side-effects \
168
+ --acknowledge-gate-side-effects --json
169
+ ```
170
+ 只有项目配置没有对应 hook 或 snapshot gate 时,才省略相应授权参数。授权前必须审阅可执行文件、参数、工作目录和副作用,不能把授权参数当固定样板。
171
+ 5. **人工审阅:** 检查 `planPath`、`externalActions`、`targetVersion` 和 `planDigest`。
172
+ 6. **prepare --production** — 冻结生产计划:
173
+ ```bash
174
+ PLAN_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
175
+ --acknowledge-hook-side-effects \
176
+ --acknowledge-gate-side-effects --json)
177
+ PLAN_PATH=$(printf '%s\n' "$PLAN_JSON" | jq -r '.planPath')
178
+ PLAN_DIGEST=$(printf '%s\n' "$PLAN_JSON" | jq -r '.planDigest')
179
+ ```
180
+ 7. **approve** — 人工批准(24 小时有效期):
181
+ ```bash
182
+ APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
183
+ --digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
184
+ APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
185
+ ```
186
+ 8. **publish** — 远端写入开始:
187
+ ```bash
188
+ PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
189
+ --plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
190
+ --confirm-production "$PLAN_DIGEST" --json)
191
+ PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
192
+ ```
193
+ `PUBLISHED` **不是**终态。
194
+ 9. **verify** — 消费者安装检查:
195
+ ```bash
196
+ "${CLI[@]}" verify --root "$PROJECT" \
197
+ --plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
198
+ --acknowledge-gate-side-effects --json
199
+ ```
174
200
 
175
- 没有冲突时,机械提取机器提案:
201
+ 示例需要 `jq`。没有 jq 时,直接复制返回的 JSON 字段;不要把尖括号占位符当作 shell 语法。
176
202
 
177
- ```bash
178
- SETUP_SESSION='/上一步打印的会话目录绝对路径'
179
- PROJECT='/上一步打印的项目绝对路径'
180
- REPORT="$SETUP_SESSION/discovery.json"
181
- ANSWERS="$SETUP_SESSION/answers.json"
182
- BOUND_REPORT="$SETUP_SESSION/bound.json"
183
- node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if((r.proposalConflicts??[]).length){console.error("proposal conflicts require human resolution");process.exit(2)}if(!r.recommendedAnswers){console.error("recommendedAnswers missing");process.exit(2)}fs.writeFileSync(process.argv[2],JSON.stringify(r.recommendedAnswers,null,2)+"\n",{flag:"wx",mode:0o600})' "$REPORT" "$ANSWERS"
184
-
185
- release-skill setup --root "$PROJECT" --answers "$ANSWERS" --json > "$BOUND_REPORT"
186
- node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary||!r.setupDigest){console.error("bound setup report incomplete");process.exit(2)}process.stdout.write(JSON.stringify({compactSummary:r.compactSummary,setupDigest:r.setupDigest},null,2)+"\n")' "$BOUND_REPORT"
187
- printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
188
- ```
203
+ ### PARTIAL 恢复与 reconcile
189
204
 
190
- 只审阅这份绑定摘要和精确摘要值,并由用户确认一次。确认后使用其字面量首次创建配置:
205
+ 当 `publish` 在部分检查点成功但在其他检查点失败时,运行进入 `PARTIAL` 状态。**不要从头重跑,也不要删除远端状态。**
191
206
 
192
207
  ```bash
193
- SETUP_SESSION=<上一步打印的会话目录绝对路径>
194
- PROJECT=<上一步打印的项目绝对路径>
195
- ANSWERS="$SETUP_SESSION/answers.json"
196
- CREATED_REPORT="$SETUP_SESSION/created.json"
197
- POST_REPORT="$SETUP_SESSION/post-setup.json"
198
- ASSESS_REPORT="$SETUP_SESSION/assess.json"
199
- release-skill setup --root "$PROJECT" --answers "$ANSWERS" \
200
- --write --confirm-setup <已确认的 setupDigest> --json > "$CREATED_REPORT"
201
- release-skill setup --root "$PROJECT" --json > "$POST_REPORT"
202
- set +e
203
- release-skill assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
204
- ASSESS_EXIT=$?
205
- set -e
206
- [ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
207
- node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>JSON.parse(fs.readFileSync(x,"utf8")));if(c.status!=="CONFIG_CREATED"||p.status!=="ALREADY_CONFIGURED"||!["ASSESSED","NEEDS_INPUT","BLOCKED"].includes(a.status)){process.exit(2)}process.stdout.write(JSON.stringify({created:c.status,postSetup:p.status,assessment:{status:a.status,summary:a.summary,gapCount:(a.gaps??[]).length,blockingCodes:(a.gaps??[]).filter(g=>g.severity==="error").map(g=>g.code)}},null,2)+"\n")' "$CREATED_REPORT" "$POST_REPORT" "$ASSESS_REPORT"
208
- node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
208
+ RECONCILE_JSON=$("${CLI[@]}" reconcile --root "$PROJECT" \
209
+ --run "$PUBLISH_RUN_PATH" \
210
+ --plan "$PLAN_PATH" \
211
+ --approval "$APPROVAL_PATH" \
212
+ --confirm-production "$PLAN_DIGEST" --json)
213
+ RECONCILE_RUN_PATH=$(printf '%s\n' "$RECONCILE_JSON" | jq -r '.runPath')
214
+ "${CLI[@]}" verify --root "$PROJECT" \
215
+ --plan "$PLAN_PATH" --run "$RECONCILE_RUN_PATH" \
216
+ --acknowledge-gate-side-effects --json
209
217
  ```
210
218
 
211
- 写入必须返回 `CONFIG_CREATED`,下一次 setup 必须返回 `ALREADY_CONFIGURED`。已有配置永不重新生成,后续只做经审阅的增量编辑。发现的解释器/包管理器脚本标记为 `SIDE_EFFECTS_UNPROVEN`,不会被自动选中。只有在人工审阅之后才添加项目专属的 hook 或 gate:编辑 `projectConfig.hooks`,或编辑 `verificationGates` 并把同一个 id 加入 `selectedGateIds`,然后重新运行绑定 dry-run。人工维护的文件保持 `mode: preserve`;只有明确的跨单元共享来源才使用 `sourceScope: workspace`。
219
+ `reconcile` 查询实际远端状态,跳过已一致步骤,只重试安全未完成的动作。远端冲突需人工决策。reconcile 成功只返回 `PUBLISHED`,不返回 `VERIFIED`。
212
220
 
213
- #### 进阶:schema 参考——并非首次接入路径
221
+ ## 发布工作流
214
222
 
215
- 下面的 wrapper 仅用于说明 schema。正常 setup 路径中不要手工编写它;按上文机械提取 `recommendedAnswers`。
223
+ release-skill 把发布生命周期建模为严格状态机(规范定义见 `references/01-state-machine.md`):
216
224
 
217
- ```json
218
- {
219
- "projectConfig": {
220
- "apiVersion": "release-skill/v1",
221
- "kind": "ReleaseProject",
222
- "project": { "name": "my-project", "defaultBranch": "main" },
223
- "releaseUnits": [{
224
- "id": "my-project",
225
- "source": ".",
226
- "publicRepo": "owner/my-project",
227
- "version": { "source": "package.json", "tagTemplate": "v{version}" },
228
- "distributions": [{
229
- "type": "npm",
230
- "package": "my-project",
231
- "access": "public",
232
- "provenance": false,
233
- "tag": "latest",
234
- "registry": "https://registry.npmjs.org",
235
- "publisher": "my-npm-username"
236
- }],
237
- "publicFiles": [
238
- { "from": "README.md", "to": "README.md", "mode": "preserve" },
239
- { "from": "package.json", "to": "package.json", "mode": "preserve" }
240
- ],
241
- "requiredPublicFiles": ["README.md", "package.json"],
242
- "previousPublicBaseline": { "mode": "none" },
243
- "production": {
244
- "branchTemplate": "release/{tag}",
245
- "branchStrategy": "create-release-branch"
246
- }
247
- }]
248
- },
249
- "selectedGateIds": []
250
- }
225
+ ```text
226
+ DISCOVERED -> ASSESSED -> PREPARED -> APPROVED -> PUBLISHING -> PUBLISHED -> VERIFIED
227
+ 异常态:NEEDS_INPUT / BLOCKED / PARTIAL
251
228
  ```
252
229
 
253
- 这只是 schema 参考,不是接入模板。正常 setup 必须使用机器提案。`mode: none` 仅在不存在任何公开版本时有效。
230
+ 每个 CLI 命令对应一次状态转换。`PUBLISHED` **不是**终态——只有全新运行的 `verify` 确认远端状态和消费者安装与冻结计划一致时,才到达 `VERIFIED`。
254
231
 
255
- 下面的参考展示经人工审阅的 gate `selectedGateIds` 之间的精确关系。该关系只能作为对提取出的机器提案的增量编辑来应用:
232
+ **保存契约:** release-skill 不重新生成或回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节。后续 prepare 重新读取当前文件,不会从模板重建。只有 `publicFiles` 列出的文件会被复制。`prepare` 不会刷新或重写人工文档——维护者先更新 README、INSTALL 和 CHANGELOG,再 prepare、审阅和批准。
256
233
 
257
- ```json
258
- {
259
- "projectConfig": {
260
- "apiVersion": "release-skill/v1",
261
- "kind": "ReleaseProject",
262
- "project": { "name": "my-project", "defaultBranch": "main" },
263
- "releaseUnits": [{
264
- "id": "my-project",
265
- "source": ".",
266
- "publicRepo": "owner/my-project",
267
- "version": { "source": "package.json", "tagTemplate": "v{version}" },
268
- "distributions": [{
269
- "type": "npm",
270
- "package": "my-project",
271
- "access": "public",
272
- "provenance": false,
273
- "tag": "latest",
274
- "registry": "https://registry.npmjs.org",
275
- "publisher": "my-npm-username"
276
- }],
277
- "publicFiles": [
278
- { "from": "package.json", "to": "package.json", "mode": "preserve" }
279
- ],
280
- "requiredPublicFiles": ["package.json"],
281
- "previousPublicBaseline": { "mode": "none" },
282
- "production": {
283
- "branchTemplate": "release/{tag}",
284
- "branchStrategy": "create-release-branch"
285
- }
286
- }],
287
- "verificationGates": [{
288
- "id": "my-project-script-test",
289
- "phase": "snapshot-verify",
290
- "scope": { "unit": "my-project" },
291
- "command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
292
- "cwd": ".",
293
- "timeoutMs": 30000,
294
- "envAllowlist": []
295
- }]
296
- },
297
- "selectedGateIds": ["my-project-script-test"]
298
- }
299
- ```
234
+ **写入安全:** `setup` 默认只读(摘要确认后仅首次创建配置)。`prepare` 只写 `.release-skill/`。`publish` 是生产写入入口,需要同时提供批准和当前计划摘要。项目 hook 和 gate 是已确认的本地进程,没有操作系统沙箱。
300
235
 
301
- id 必须从当前 `gateCandidates` 复制,不得臆造。示例命令在公开快照内自包含。项目脚本只有在脚本本身及其全部依赖都包含在 `publicFiles` 中时才有效;snapshot gate 看不到父工作区的测试、开发依赖或 `node_modules`,除非它们被显式公开。
236
+ ## 文档导航
302
237
 
303
- ```bash
304
- release-skill setup --root /absolute/path/to/my-project \
305
- --answers /absolute/path/to/setup-answers.json --json
306
- release-skill setup --root /absolute/path/to/my-project \
307
- --answers /absolute/path/to/setup-answers.json \
308
- --write --confirm-setup <setupDigest> --json
309
- ```
238
+ | 文档 | 说明 |
239
+ |---|---|
240
+ | [INSTALL.md](INSTALL.md) / [INSTALL.zh-CN.md](INSTALL.zh-CN.md) | 完整安装指南:npm、插件、源码 checkout、setup 流程、分支策略 |
241
+ | [CHANGELOG.md](CHANGELOG.md) | 发布历史 |
242
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | 贡献指南(含生成产物规则) |
243
+ | [SECURITY.md](SECURITY.md) | 安全策略 |
244
+ | `references/01-state-machine.md` | 规范状态机定义 |
245
+ | `references/02-project-config.md` | 项目配置 schema 参考 |
246
+ | `references/05-evidence-and-errors.md` | 证据格式和错误码 |
247
+ | `references/06-adapter-contract.md` | 适配器和市场契约详情 |
248
+ | [GitHub Issues](https://github.com/ifoohoo/release-skill/issues) | 问题报告和功能请求 |
310
249
 
311
- Setup 只原子创建缺失的 `.release-skill/project.yaml`。这一 create-once 步骤使用 v0.1.3 起随包发布、经 digest 登记的 `darwin-arm64` 原生预编译产物;不支持的平台以 `SAFE_WRITE_UNAVAILABLE` 失败关闭,不会回退到基于路径的写入。`ALREADY_CONFIGURED`/`CONFIG_EXISTS` 表示现有文件仍由人工所有,只能增量编辑。README、slogan、CHANGELOG 和业务脚本永不被生成或覆盖。没有远端渠道的项目会报告 `LOCAL_ONLY_DETECTED`,而不是虚构生产支持。
250
+ ## 配置
312
251
 
313
- 以下是一个最小的人工编写配置。npm 可见性、公开文件边界和远端目标都必须显式声明:
252
+ 最小人工编写配置(完整 schema 和 setup 流程见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md)):
314
253
 
315
254
  ```yaml
316
255
  apiVersion: release-skill/v1
317
256
  kind: ReleaseProject
318
-
319
257
  project:
320
258
  name: my-project
321
259
  defaultBranch: main
322
-
323
260
  releaseUnits:
324
261
  - id: my-project
325
262
  source: .
@@ -334,165 +271,23 @@ releaseUnits:
334
271
  - from: package.json
335
272
  to: package.json
336
273
  mode: preserve
337
- - from: LICENSE
338
- to: LICENSE
339
- mode: preserve
340
- requiredPublicFiles: [README.md, LICENSE, package.json]
274
+ requiredPublicFiles: [README.md, package.json]
341
275
  previousPublicBaseline:
342
- mode: none # 首次发布:不存在更早的公开版本
276
+ mode: none
343
277
  distributions:
344
278
  - type: npm
345
279
  package: my-project
346
- access: public # 或 restricted;选择真实的包策略
347
- provenance: false # 只有在 CI/OIDC 配置完成后才使用 true
280
+ access: public
281
+ provenance: false
348
282
  tag: latest
349
283
  registry: https://registry.npmjs.org
350
284
  publisher: my-npm-username
351
- # 可选:CLI smoke 验证。配置 smokeBin 后,verify 会在隔离目录
352
- # 安装该包并运行指定二进制。不配置 smokeBin 时,verify 只确认
353
- # 安装与 name/version。
354
- # smokeBin: my-project
355
- # smokeArgs: [help, --json]
356
- # smokeExpectedJson:
357
- # command: help
358
- # status: READY
359
285
  production:
360
286
  branchTemplate: release/{tag}
361
287
  branchStrategy: create-release-branch
362
- releaseTitleTemplate: "{unit} {version}"
363
- releaseNotes: "人工维护的发布说明"
364
288
  ```
365
289
 
366
- 每个发布单元都必须声明其前序公开基线。只有当你确认不存在更早的公开版本时才使用 `mode: none`。对于已有公开仓库,绑定精确的不可变 ref commit:
367
-
368
- ```yaml
369
- previousPublicBaseline:
370
- mode: bound
371
- repo: owner/my-project
372
- ref: release/v0.9.0
373
- commit: 0123456789abcdef0123456789abcdef01234567
374
- ```
375
-
376
- `none` 不是绕过冲突检查的手段:publish 仍会在任何写入前检查目标 branch、tag、GitHub Release 与 npm 版本的唯一性。bound 模式的生产 prepare 必须在线运行,以便观察 ref 到 commit 的映射。默认观察器不下载远端文件内容,因此它报告映射差异并标记内容差异不可用。发生漂移时停止,由人工选择 `merge`、`adopt` 或 `reject`。先获取并审阅真实远端 commit;工具不会下载或合并其文件。`merge` 在人工所有的来源中保留本地与远端双方修改;`adopt` 把审阅过的远端字节复制进该来源;`reject` 在调查或修正远端/ref 期间停止本次发布;永远不要为了绕过漂移而改回 `mode: none`。`merge` 或 `adopt` 之后,把 `previousPublicBaseline` 重新绑定到已接受的不可变 `repo`/`ref`/`commit`,再运行新的 `prepare --online --production`、审阅并批准。
377
-
378
- 分支策略应与真实仓库匹配(`create-release-branch`、`advance-existing-branch`、`initialize-default-branch`);三种策略的最小配置示例见[英文 README](README.md)。
379
-
380
- ### 主流程
381
-
382
- 按以下顺序执行。步骤 1–4 是安全默认(只读或仅本地);步骤 5–9 是需要显式人工门禁的生产发布。
383
-
384
- ```bash
385
- # npm 安装的 CLI(推荐):
386
- CLI=(release-skill)
387
- PROJECT=/absolute/path/to/my-project
388
- ACTOR=your-name
389
- # 开发回退(源码 checkout):
390
- # CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
391
- ```
392
-
393
- 1. **环境检查:**
394
- ```bash
395
- "${CLI[@]}" help
396
- ```
397
- 2. **首次接入(仅缺少配置时,只读):**
398
- ```bash
399
- "${CLI[@]}" setup --root "$PROJECT" --json
400
- ```
401
- 按上文机械提取 `compactSummary` 与 `recommendedAnswers`,只确认一次绑定后的 `setupDigest`;配置已存在时跳过。
402
- 3. **就绪评估(只读):**
403
- ```bash
404
- "${CLI[@]}" assess --root "$PROJECT" --offline --json
405
- ```
406
- 4. **本地快照与计划冻结:**
407
- ```bash
408
- "${CLI[@]}" prepare --root "$PROJECT" --offline \
409
- --acknowledge-hook-side-effects \
410
- --acknowledge-gate-side-effects --json
411
- ```
412
- 只有项目配置没有对应 hook 或 snapshot gate 时,才省略相应授权参数。授权前必须审阅可执行文件、参数、工作目录和副作用,不能把授权参数当固定样板。
413
- 5. **人工审阅:** 检查返回的 `planPath`、`externalActions`、`units[].targetVersion` 和 `planDigest`。每个发布单元的快照位于 `<evidenceDir>/snapshots/<unit-id>/`。
414
- 6. **生产计划冻结:**
415
- ```bash
416
- PRODUCTION_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
417
- --acknowledge-hook-side-effects \
418
- --acknowledge-gate-side-effects --json)
419
- printf '%s\n' "$PRODUCTION_JSON" | jq .
420
- PLAN_PATH=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planPath')
421
- PLAN_DIGEST=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planDigest')
422
- ```
423
- 同样,只省略配置不需要的授权,并在授权前逐项审阅项目进程。`prepare --json` 返回的生产权威 `planPath` 指向 `<项目>/.release-skill/plans/<planDigest>.json`,后续必须始终沿用这个返回值。`.release-skill/release-plan.json` 只是可变便利副本,不得传给生产 approve/publish/reconcile。
424
- 7. **批准:**
425
- ```bash
426
- APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
427
- --digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
428
- printf '%s\n' "$APPROVAL_JSON" | jq .
429
- APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
430
- ```
431
- 批准 24 小时失效;`--actor` 只是未经认证的本地审计标签。后续必须使用返回的 immutable `approvalPath` 和 `expiresAt`。
432
- 8. **发布(从此开始写远端):**
433
- ```bash
434
- PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
435
- --plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
436
- --confirm-production "$PLAN_DIGEST" --json)
437
- printf '%s\n' "$PUBLISH_JSON" | jq .
438
- PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
439
- ```
440
- 保存返回的 `runPath`。`PUBLISHED` **不是**终态。
441
- 9. **验证(消费者安装检查):**
442
- ```bash
443
- "${CLI[@]}" verify --root "$PROJECT" \
444
- --plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
445
- --acknowledge-gate-side-effects --json
446
- ```
447
- 只有计划既没有 consumer gate,也没有 npm `smokeBin` 时才省略授权。
448
-
449
- 生产 prepare 会把每个公开快照封存为独立 Git commit/tree,并为 npm 单元生成固定 tarball。`publish` 先对所有动作做只读预检,再按“公开快照 branch → tag → npm → GitHub Release → Claude/Codex 插件市场安装”执行并逐项观察。Kimi Code 没有可脚本化的安装接口,其检查点**失败关闭**:`publish` 在完成自动化写入后落入 `PARTIAL`,并产出版本钉死的手动安装要求。操作者随后用 requirement 给出的隔离 `KIMI_CODE_HOME` 启动 Kimi Code,运行钉死的 `/plugins install <release-tag URL>`,把可信证明(同时绑定冻结**计划**摘要与快照**载荷**摘要)写入按计划摘要命名的目录 `.release-skill/kimi-attestations/<planDigest>/<plugin>/`,再运行 `reconcile`(→ `PUBLISHED`)与 `verify`(→ `VERIFIED`);两者都从同一稳定位置读取证明。安装到日常 `~/.kimi-code` 不被接受。完整流程与证明 JSON 字段见 `INSTALL.zh-CN.md`。`verify` 在隔离目录安装每一个精确 npm `package@version`;配置 `smokeBin` 后还会运行 CLI 并校验输出。只有全部证据与冻结计划一致才进入 `VERIFIED`。默认分支名由每个 unit 的 `production.branchTemplate` 配置;同名远端对象存在时停止,交由人工判断。
450
-
451
- ### 发布文档刷新(可选)
452
-
453
- 发布单元可以声明 `releaseDocuments`,用一份结构化双语说明源确定性刷新 README 受管区域和 CHANGELOG 当前版本条目。核心 CLI 完全离线运行:不联网、不调用大模型、不自动翻译;只改写声明过的受管区域、唯一版本标记的机器值和 CHANGELOG 当前版本受管条目,区域外字节逐字保留。`prepare` 只检查新鲜度,不写工作树。
454
-
455
- ```yaml
456
- # .release-skill/project.yaml(发布单元片段)
457
- releaseUnits:
458
- - id: my-project
459
- source: .
460
- releaseDocuments:
461
- notesSource: release-notes/{version}.yaml
462
- locales: [en, zh-CN]
463
- changelogs:
464
- - path: CHANGELOG.md
465
- locale: en
466
- readmes:
467
- - path: README.md
468
- locale: en
469
- regions: [latest-release]
470
- versionMarkers:
471
- - id: current-version
472
- pattern: '<!-- release-skill:version -->v{version}<!-- /release-skill:version -->'
473
- - path: README.zh-CN.md
474
- locale: zh-CN
475
- regions: [latest-release]
476
- ```
477
-
478
- 1. **只读演练:**
479
- ```bash
480
- "${CLI[@]}" docs refresh --root "$PROJECT" --unit my-project --json
481
- ```
482
- 2. **摘要确认的本地写入(仅在用户明确授权“本地发布文档写入”后执行):**
483
- ```bash
484
- "${CLI[@]}" docs refresh --root "$PROJECT" --unit my-project \
485
- --write --confirm-refresh <refreshDigest> \
486
- --ack-local-document-write --json
487
- ```
488
-
489
- 该授权只覆盖声明的本地发布文档目标,不是 hook、Git 提交、push、publish 或安装的授权:维护者必须审阅刷新结果并提交,然后重新 `prepare`。
490
-
491
- ### 父工作空间 + npm 子单元 + 插件子单元
492
-
493
- 当 monorepo 从不同目录同时产出 npm 包和 Claude/Codex/Kimi Code 插件时,应定义独立的发布单元。只有当某个单元确实以 manifest、marketplace 和 entry Skill 的形式发布插件时,才为其添加插件分发:
494
-
495
- 这里的 `project` 是父工作空间的编排容器,不是公开发布单元。如果工作区根目录也发布自己的仓库或包,再添加一个 `source: .` 的发布单元。`version.source` 相对于该发布单元的 `source` 目录解析(`version.source` is resolved relative to that release unit's `source` directory):因此 `source: packages/app` 的单元写裸 `package.json`,而不是 `packages/app/package.json`。
290
+ `version.source` 相对于该发布单元的 `source` 目录解析(`version.source` is resolved relative to that release unit's `source` directory)。monorepo 中 npm 和插件分开发布时定义多个发布单元:
496
291
 
497
292
  ```yaml
498
293
  apiVersion: release-skill/v1
@@ -500,7 +295,6 @@ kind: ReleaseProject
500
295
  project:
501
296
  name: my-workspace
502
297
  defaultBranch: main
503
-
504
298
  releaseUnits:
505
299
  - id: my-app
506
300
  source: packages/app
@@ -516,28 +310,16 @@ releaseUnits:
516
310
  tag: latest
517
311
  registry: https://registry.npmjs.org
518
312
  publisher: my-npm-username
519
- smokeBin: my-app
520
- smokeArgs: [help, --json]
521
- smokeExpectedJson:
522
- command: help
523
- status: READY
524
313
  publicFiles:
525
- - from: packages/app/README.md
526
- to: README.md
527
- mode: preserve
528
314
  - from: packages/app/package.json
529
315
  to: package.json
530
316
  mode: preserve
531
- - from: packages/app/LICENSE
532
- to: LICENSE
533
- mode: preserve
534
- requiredPublicFiles: [README.md, package.json, LICENSE]
317
+ requiredPublicFiles: [package.json]
535
318
  previousPublicBaseline:
536
319
  mode: none
537
320
  production:
538
321
  branchTemplate: release/{tag}
539
- releaseTitleTemplate: "{unit} {version}"
540
-
322
+ branchStrategy: create-release-branch
541
323
  - id: my-plugin
542
324
  source: packages/plugin
543
325
  publicRepo: owner/my-plugin
@@ -545,114 +327,63 @@ releaseUnits:
545
327
  source: package.json
546
328
  tagTemplate: my-plugin-v{version}
547
329
  distributions:
548
- # 只有当单元确实发布插件时才声明插件消费者。
549
- # CLI smoke 是独立的;只有当插件包同时暴露 CLI 二进制时才声明 smokeBin。
550
330
  - type: claude-plugin
551
331
  plugin: my-plugin
552
332
  marketplace: my-plugin
553
333
  entrySkill: my-plugin-help
554
- timeoutMs: 300000 # 可选;范围 30000-900000;默认 300000
555
- - type: codex-plugin
556
- plugin: my-plugin
557
- marketplace: my-plugin
558
- entrySkill: my-plugin-help
559
- timeoutMs: 300000 # 可选;范围 30000-900000;默认 300000
560
- - type: kimi-plugin
561
- plugin: my-plugin
562
- entrySkill: my-plugin-help
563
- timeoutMs: 300000 # 可选;范围 30000-900000;默认 300000(Kimi 无安装命令;仅约束只读验证)
334
+ marketplaceSourceType: bundled-family
564
335
  publicFiles:
565
- - from: packages/plugin/.claude-plugin/plugin.json
566
- to: .claude-plugin/plugin.json
567
- mode: preserve
568
- - from: packages/plugin/.claude-plugin/marketplace.json
569
- to: .claude-plugin/marketplace.json
570
- mode: preserve
571
- - from: packages/plugin/.codex-plugin/plugin.json
572
- to: .codex-plugin/plugin.json
573
- mode: preserve
574
- - from: packages/plugin/.kimi-plugin/plugin.json
575
- to: .kimi-plugin/plugin.json
576
- mode: preserve
577
- - from: packages/plugin/.agents/plugins/marketplace.json
578
- to: .agents/plugins/marketplace.json
579
- mode: preserve
580
- - from: packages/plugin/skills/my-plugin-help/SKILL.md
581
- to: skills/my-plugin-help/SKILL.md
582
- mode: preserve
583
- - from: packages/plugin/README.md
584
- to: README.md
585
- mode: preserve
586
336
  - from: packages/plugin/package.json
587
337
  to: package.json
588
338
  mode: preserve
589
- - from: packages/plugin/LICENSE
590
- to: LICENSE
591
- mode: preserve
592
- requiredPublicFiles:
593
- - .claude-plugin/plugin.json
594
- - .claude-plugin/marketplace.json
595
- - .codex-plugin/plugin.json
596
- - .kimi-plugin/plugin.json
597
- - .agents/plugins/marketplace.json
598
- - skills/my-plugin-help/SKILL.md
599
- - README.md
600
- - package.json
601
- - LICENSE
339
+ requiredPublicFiles: [package.json]
602
340
  previousPublicBaseline:
603
341
  mode: none
604
342
  production:
605
343
  branchTemplate: release/{tag}
606
- releaseTitleTemplate: "{unit} {version}"
344
+ branchStrategy: create-release-branch
607
345
  ```
608
346
 
609
- 每个插件单元**必须**列出其 Claude/Codex/Kimi Code `plugin.json`、Claude/Codex 的 `marketplace.json`(Kimi Code 没有 marketplace 清单)、entry Skill 以及全部必需公开文件。CLI smoke(`smokeBin`)对插件单元是可选的,只适用于发布的 npm 包暴露 CLI 二进制的情况。
610
-
611
- 插件分发可以声明 `timeoutMs`(范围 30,000–900,000 ms;默认 300,000 ms),用于 marketplace add、插件安装与插件列表命令的子进程超时。真实网络下这些命令可能需要 40–105 秒;默认 300 秒超时可以避免误报 `PARTIAL`。解析后的值会冻结进计划,并随其他动作参数一起批准。没有 `timeoutMs` 的旧计划在执行时按 300,000 ms 兼容处理。
612
-
613
- ### PARTIAL 恢复与 reconcile
614
-
615
- 当 `publish` 在部分检查点成功但在其他检查点失败时,运行进入 `PARTIAL` 状态。**不要从头重跑,也不要删除远端状态。**
347
+ 在提取出的 `recommendedAnswers` 中添加 gate:编辑 `verificationGates` 并在 `selectedGateIds` 中绑定同一 id:
616
348
 
617
- 使用 `reconcile` 检查实际远端状态,跳过已一致的步骤,安全重试未完成的动作:
618
-
619
- ```bash
620
- RECONCILE_JSON=$("${CLI[@]}" reconcile --root "$PROJECT" \
621
- --run "$PUBLISH_RUN_PATH" \
622
- --plan "$PLAN_PATH" \
623
- --approval "$APPROVAL_PATH" \
624
- --confirm-production "$PLAN_DIGEST" --json)
625
- printf '%s\n' "$RECONCILE_JSON" | jq .
626
- RECONCILE_RUN_PATH=$(printf '%s\n' "$RECONCILE_JSON" | jq -r '.runPath')
627
- "${CLI[@]}" verify --root "$PROJECT" \
628
- --plan "$PLAN_PATH" --run "$RECONCILE_RUN_PATH" \
629
- --acknowledge-gate-side-effects --json
349
+ ```json
350
+ {
351
+ "projectConfig": {
352
+ "apiVersion": "release-skill/v1",
353
+ "kind": "ReleaseProject",
354
+ "project": { "name": "my-project", "defaultBranch": "main" },
355
+ "releaseUnits": [{
356
+ "id": "my-project",
357
+ "source": ".",
358
+ "publicRepo": "owner/my-project",
359
+ "version": { "source": "package.json", "tagTemplate": "v{version}" },
360
+ "distributions": [{
361
+ "type": "npm", "package": "my-project", "access": "public",
362
+ "provenance": false, "tag": "latest",
363
+ "registry": "https://registry.npmjs.org", "publisher": "my-npm-username"
364
+ }],
365
+ "publicFiles": [{ "from": "package.json", "to": "package.json", "mode": "preserve" }],
366
+ "requiredPublicFiles": ["package.json"],
367
+ "previousPublicBaseline": { "mode": "none" },
368
+ "production": { "branchTemplate": "release/{tag}", "branchStrategy": "create-release-branch" }
369
+ }],
370
+ "verificationGates": [{
371
+ "id": "my-project-script-test",
372
+ "phase": "snapshot-verify",
373
+ "scope": { "unit": "my-project" },
374
+ "command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
375
+ "cwd": ".",
376
+ "timeoutMs": 30000,
377
+ "envAllowlist": []
378
+ }]
379
+ },
380
+ "selectedGateIds": ["my-project-script-test"]
381
+ }
630
382
  ```
631
383
 
632
- reconcile 成功只返回 `PUBLISHED`,不会返回 `VERIFIED`;只有全新运行的 verify 可以产生终态 `VERIFIED`。
633
-
634
- ## 已验收能力
635
-
636
- - 验证项目配置和发布单元;
637
- - `assess` 在不修改项目的前提下报告就绪度;
638
- - 把配置的公开文件复制到隔离快照;
639
- - 只读发现首次接入候选,经精确 `setupDigest` 确认后仅首次创建配置;
640
- - 在冻结快照副本和精确消费者安装根运行经人工选择的项目 gate;
641
- - 检查必需文件、路径安全、精确字节/权限和明显泄漏;
642
- - 记录 Git/工作区身份,冻结绑定 digest 的发布计划;
643
- - 用计划摘要、有效期和显式 action allowlist 绑定人工批准;
644
- - 从冻结 Git object 和 npm tarball 发布,并核对远端 commit/tree/tag/integrity;
645
- - 从冻结 Git ref 安装配置的 Claude/Codex 插件,证明入口 Skill 和安装载荷摘要;对 Kimi Code(无可脚本化安装接口)产出版本钉死的手动安装要求,仅依据绑定到冻结计划摘要的可信证明来确认入口 Skill 和载荷摘要;
646
- - 为 Claude/Codex distribution 支持外部独立市场(`marketplaceRepo`):`prepare --online --production` 冻结外部市场 HEAD(Codex commit sha / Claude 默认分支名),校验该 sha 处的市场索引条目,并以本单元自身冻结快照整树校验安装载荷(`external-marketplace-v1`),安装侧 CLI list 观察在版本漂移时失败关闭;
647
- - 随 Claude/Codex/Kimi 适配器一并提供生成的自包含 CodeBuddy/WorkBuddy 适配器(`adapters/workbuddy/`,清单 `.codebuddy-plugin/plugin.json`,技能以 `${CODEBUDDY_PLUGIN_ROOT}` 渲染);因 codebuddy CLI 无法钉死冻结 ref 而无自动化 marketplace 安装检查点,故产出手动安装要求,仅依据绑定到冻结计划摘要的可信证明来确认入口 Skill 和载荷摘要;
648
- - 明确区分 `PUBLISHED`(外写完成)与 `VERIFIED`(远端和消费者安装证据完成);
649
- - 中途失败停止后续动作,记录独立 run;不修改冻结 plan,不自动撤销已成功动作。
650
-
651
- ## 个性化验证:hook 与 gate
652
-
653
- `hooks.docs/build/test/typecheck/lint` 在冻结前运行,适合确实需要生成源文件或依赖父工作区的步骤。它们可能修改项目或访问网络,prepare 必须显式传入 `--acknowledge-hook-side-effects`。
384
+ ### hook gate
654
385
 
655
- 每个 hook 都是一个对象,`command` 是可执行文件/参数数组,不是 shell 字符串(`command` is an executable/argument array, not a shell string)。每个 hook 还声明 `cwd`、`timeoutMs` 和 `envAllowlist`:
386
+ `hooks.docs/build/test/typecheck/lint` 在快照冻结前运行。每个 hook 是一个对象——`command` 是可执行文件/参数数组,不是 shell 字符串(`command` is an executable/argument array, not a shell string):
656
387
 
657
388
  ```yaml
658
389
  hooks:
@@ -668,63 +399,7 @@ hooks:
668
399
  envAllowlist: []
669
400
  ```
670
401
 
671
- `verificationGates` 是更适合发布校准的受控扩展点:
672
-
673
- ```yaml
674
- verificationGates:
675
- - id: package-contract
676
- phase: snapshot-verify
677
- scope: { unit: my-project }
678
- command:
679
- - node
680
- - -e
681
- - "const p=require('./package.json'); if (!p.name) process.exit(1)"
682
- cwd: .
683
- timeoutMs: 120000
684
- envAllowlist: [CI]
685
- ```
686
-
687
- `snapshot-verify` 在冻结公开快照的一次性可写副本中执行;`consumer-verify` 在精确 npm/Claude/Codex/Kimi Code 隔离安装根执行。两者都使用命令数组而非 shell 字符串,定义和结果会进入摘要证据,并要求 prepare/verify 显式传入 `--acknowledge-gate-side-effects`。
688
-
689
- push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 hook/gate,只能由冻结计划的受控动作执行。
690
-
691
- ## 当前不会做什么
692
-
693
- <!-- release-skill:capability:unsupported-scope -->
694
- - 不自动生成 README,不覆盖项目源文件;
695
- - 不自动合并冲突,也不要求回滚工作流;
696
- - 不声称已经替项目完成真实生产 canary;
697
- - `prepare --online` 只观察 bound 前序基线;目标唯一性由 publish 全局预检完成;
698
- - 不覆盖已有 branch/tag/Release,不 unpublish npm;
699
- - 不提供自动化 CodeBuddy/WorkBuddy marketplace 安装检查点——codebuddy CLI 无法钉死冻结 ref,安装为手动步骤,经与 Kimi Code 相同的可信证明闭环确认;
700
- - 不承诺 Windows 或广泛的跨平台原生写入;
701
- - 不会隐藏地 commit、push、打 tag、创建 Release 或发布包。
702
-
703
- ### 写入安全
704
-
705
- `setup` 默认只读,写入只允许精确摘要确认后首次创建配置。`assess` 默认只读。`prepare` 会在 `.release-skill/` 下写本地文件,但不会写项目源文件或远端服务。如果配置了 hook,它就是任意本地进程,必须使用 `--acknowledge-hook-side-effects` 明确授权;gate 同样需要 `--acknowledge-gate-side-effects`。
706
-
707
- `publish` 是唯一生产外写入口,必须同时提供 approval 和当前 plan digest。
708
-
709
- ### 失败时怎么办
710
-
711
- | 结果 | 下一步 |
712
- |---|---|
713
- | `NEEDS_INPUT` | 补齐 setup 列出的仓库、tag、渠道、基线和 gate 人工决策。 |
714
- | `LOCAL_ONLY_DETECTED` | 决定建立远端渠道或仅保留本地配置设计;不得冒充生产就绪。 |
715
- | `SETUP_DIGEST_MISMATCH` | 项目事实或 answers 已变化;重新 dry-run、审阅并确认新摘要。 |
716
- | `CONFIG_EXISTS` | setup 不覆盖已有配置;运行 assess 后人工增量修改。 |
717
- | `SAFE_WRITE_UNAVAILABLE` | 当前平台不支持自动 create-once;保留只读报告,由人工首次创建经审阅的配置。 |
718
- | `CONFIG_INVALID` | 修正 `.release-skill/project.yaml`,重新运行 `assess`。 |
719
- | `PUBLIC_FILE_MISSING` | 添加或修正配置中的公开文件。 |
720
- | `FORBIDDEN_CONTENT_DETECTED` | 移除泄漏或私有内容,再次 prepare。 |
721
- | `SNAPSHOT_FIDELITY_FAILED` | 检查源文件和快照路径,重新运行 `prepare`。 |
722
- | `BASELINE_CHANGED` | 保留人工修改,重新 prepare、审阅和 approve。 |
723
- | `prepare` 阶段 `GATE_FAILED` | 修复 snapshot gate 或冻结公开制品,再生成一份新 plan。 |
724
- | `verify` 阶段 `GATE_FAILED` | 若是消费者环境失败,修复环境后从同一 `PUBLISHED` run 重跑 verify;若是已发布制品缺陷,发布新的补丁版本。 |
725
- | `PARTIAL` | 不重跑整套发布、不删除远端;审阅返回的 `runPath` 并运行 `reconcile`。 |
726
- | `PUBLISHED` | 运行 `verify --plan <planPath> --run <publishRunPath>`;此时还不是终态。 |
727
- | `VERIFIED` | 远端状态、精确 npm 安装和插件消费者安装都与冻结计划一致。 |
402
+ hook 仅在人工审阅后、以 `--acknowledge-hook-side-effects` 显式授权后运行。gate 是发布校准的受控扩展点(见 `references/02-project-config.md`)。
728
403
 
729
404
  ## Skills
730
405
 
@@ -738,7 +413,7 @@ push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 ho
738
413
 
739
414
  ## 平台分发
740
415
 
741
- 同一个确定性核心引擎通过 build-only 适配器闭包分发到多个目标。发布单元用 `distributions` 声明要发布给谁;每种分发类型对应一个具体产物:
416
+ 同一个确定性核心引擎通过 build-only 适配器闭包分发到多个目标。发布单元用 `distributions` 声明要发布给谁:
742
417
 
743
418
  | `distributions` 类型 | 物理产物 | 安装方式 |
744
419
  |---|---|---|
@@ -746,9 +421,19 @@ push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 ho
746
421
  | `claude-plugin` | `adapters/claude/` 下的自包含闭包 | 自动化 marketplace 检查点 |
747
422
  | `codex-plugin` | `adapters/codex/` 下的自包含闭包 | 自动化 marketplace 检查点 |
748
423
  | `kimi-plugin` | 自包含闭包(无可脚本化安装接口) | 手动,需可信证明 |
749
- | `codebuddy-plugin` | 生成的 `adapters/workbuddy/`,带 `.codebuddy-plugin/plugin.json`(codebuddy CLI 无法钉死冻结 ref) | 手动,需可信证明 |
424
+ | `codebuddy-plugin` | 生成的 `adapters/workbuddy/`,带 `.codebuddy-plugin/plugin.json` | 手动,需可信证明 |
750
425
 
751
- 每个适配器闭包都自带一份 CLI bundle、skills 和 schemas 的副本,安装后无需外部依赖即可运行。Claude/Codex 的 marketplace 安装检查点是自动化的(preflight、execute、observe、verify);Kimi Code 检查点失败关闭,并产出版本钉死的手动安装要求;CodeBuddy/WorkBuddy 检查点同样失败关闭——因 codebuddy CLI 无法钉死冻结 ref 而无自动化安装检查点——并产出经绑定冻结计划摘要的可信证明确认的手动安装要求。
426
+ 每个适配器闭包都自带 CLI、skills 和 schemas 副本,安装后无需外部依赖即可运行。Claude/Codex 验证是自动化的;Kimi Code CodeBuddy/WorkBuddy 需要绑定冻结计划摘要的可信证明。
427
+
428
+ <!-- release-skill:capability:unsupported-scope -->
429
+ - 不自动生成 README,不覆盖项目源文件;
430
+ - 不自动合并冲突,也不要求回滚工作流;
431
+ - 不声称已经替项目完成真实生产 canary,不声称已完成真实插件市场验证;
432
+ - `prepare --online` 只观察 bound 前序基线;目标唯一性由 publish 全局预检完成;
433
+ - 不覆盖已有 branch/tag/Release,不 unpublish npm;
434
+ - 不提供自动化 CodeBuddy/WorkBuddy marketplace 安装检查点——codebuddy CLI 无法钉死冻结 ref,安装为手动步骤,经与 Kimi Code 相同的可信证明闭环确认;
435
+ - 不承诺 Windows 或广泛的跨平台原生写入;
436
+ - 不会隐藏地 commit、push、打 tag、创建 Release 或发布包。
752
437
 
753
438
  ## 许可证
754
439