release-skill 0.9.26 → 0.9.28
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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +1 -1
- package/.kimi-plugin/plugin.json +1 -1
- package/.qoder-plugin/plugin.json +1 -1
- package/CHANGELOG.md +56 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +16 -10
- package/README.zh-CN.md +16 -10
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/consumer-contract-vectors.json +7 -7
- package/adapters/claude/bin/foundation-resource-binding.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/claude/skills/release-assess/SKILL.md +64 -1
- package/adapters/claude/skills/release-finish/SKILL.md +2 -0
- package/adapters/claude/skills/release-help/SKILL.md +2 -2
- package/adapters/claude/skills/release-setup/SKILL.md +5 -2
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/consumer-contract-vectors.json +7 -7
- package/adapters/codex/bin/foundation-resource-binding.json +1 -1
- package/adapters/codex/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/codex/skills/release-assess/SKILL.md +64 -1
- package/adapters/codex/skills/release-finish/SKILL.md +2 -0
- package/adapters/codex/skills/release-help/SKILL.md +2 -2
- package/adapters/codex/skills/release-setup/SKILL.md +5 -2
- package/adapters/cursor/.cursor-plugin/plugin.json +1 -1
- package/adapters/cursor/bin/consumer-contract-vectors.json +7 -7
- package/adapters/cursor/bin/foundation-resource-binding.json +1 -1
- package/adapters/cursor/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/cursor/skills/release-assess/SKILL.md +64 -1
- package/adapters/cursor/skills/release-finish/SKILL.md +2 -0
- package/adapters/cursor/skills/release-help/SKILL.md +2 -2
- package/adapters/cursor/skills/release-setup/SKILL.md +5 -2
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/consumer-contract-vectors.json +7 -7
- package/adapters/kimi/bin/foundation-resource-binding.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/kimi/skills/release-assess/SKILL.md +64 -1
- package/adapters/kimi/skills/release-finish/SKILL.md +2 -0
- package/adapters/kimi/skills/release-help/SKILL.md +2 -2
- package/adapters/kimi/skills/release-setup/SKILL.md +5 -2
- package/adapters/qoder/.qoder-plugin/plugin.json +1 -1
- package/adapters/qoder/bin/consumer-contract-vectors.json +7 -7
- package/adapters/qoder/bin/foundation-resource-binding.json +1 -1
- package/adapters/qoder/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/qoder/skills/release-assess/SKILL.md +64 -1
- package/adapters/qoder/skills/release-finish/SKILL.md +2 -0
- package/adapters/qoder/skills/release-help/SKILL.md +2 -2
- package/adapters/qoder/skills/release-setup/SKILL.md +5 -2
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/consumer-contract-vectors.json +7 -7
- package/adapters/workbuddy/bin/foundation-resource-binding.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +2631 -1678
- package/adapters/workbuddy/skills/release-assess/SKILL.md +64 -1
- package/adapters/workbuddy/skills/release-finish/SKILL.md +2 -0
- package/adapters/workbuddy/skills/release-help/SKILL.md +2 -2
- package/adapters/workbuddy/skills/release-setup/SKILL.md +5 -2
- package/bin/consumer-contract-vectors.json +7 -7
- package/bin/foundation-resource-binding.json +1 -1
- package/bin/release-skill-cli.mjs +45 -1
- package/bin/release-skill.bundle.mjs +2631 -1678
- package/package.json +4 -4
- package/platform-manifest.json +4 -4
- package/skills/release-assess/SKILL.md +64 -1
- package/skills/release-finish/SKILL.md +2 -0
- package/skills/release-help/SKILL.md +2 -2
- package/skills/release-setup/SKILL.md +5 -2
- package/skills-src/release-assess/SKILL.md +64 -1
- package/skills-src/release-finish/SKILL.md +2 -0
- package/skills-src/release-help/SKILL.md +2 -2
- package/skills-src/release-setup/SKILL.md +5 -2
- package/src/commands/post-release-local.mjs +36 -92
- package/src/commands/setup.mjs +149 -6
- package/src/core/adoption-assessment.mjs +502 -4
- package/src/core/local-host-observation.mjs +225 -0
- package/src/platforms/registry.mjs +12 -4
- package/src/producers/foundation-resource-projection.mjs +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-skill",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.28",
|
|
4
4
|
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "广州市风荷科技有限公司"
|
|
@@ -80,9 +80,9 @@
|
|
|
80
80
|
"ajv-formats": "3.0.1",
|
|
81
81
|
"libnpmpublish": "11.2.0",
|
|
82
82
|
"npm-registry-fetch": "18.0.2",
|
|
83
|
-
"skill-family-contracts": "0.
|
|
84
|
-
"skill-family-engineering-kit": "0.
|
|
85
|
-
"skill-family-harness-node": "0.
|
|
83
|
+
"skill-family-contracts": "0.25.0",
|
|
84
|
+
"skill-family-engineering-kit": "0.25.0",
|
|
85
|
+
"skill-family-harness-node": "0.25.0",
|
|
86
86
|
"yaml": "2.9.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
package/platform-manifest.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
3
|
"platformId": "release-skill",
|
|
4
4
|
"platformName": "release-skill Plugin Platform",
|
|
5
|
-
"version": "0.9.
|
|
5
|
+
"version": "0.9.28",
|
|
6
6
|
"logicalRoot": "skills-src/",
|
|
7
|
-
"logicalRootDigest": "
|
|
8
|
-
"projectionDigest": "
|
|
9
|
-
"projectionId": "release-skill:platform:0.9.
|
|
7
|
+
"logicalRootDigest": "043a4f6c014adeddf4565a9d04839fd4a4f45b24a904fed105945e29197b02a7",
|
|
8
|
+
"projectionDigest": "6031c13a38f988088cdfd35f58e61906a348248cc543f0830f27e2432c6c5311",
|
|
9
|
+
"projectionId": "release-skill:platform:0.9.28",
|
|
10
10
|
"manifestRequired": true,
|
|
11
11
|
"projectionSources": {
|
|
12
12
|
"skills-src-root": {
|
|
@@ -29,12 +29,75 @@ description: "Read-only release governance diagnosis: adoption, project readines
|
|
|
29
29
|
|
|
30
30
|
## 接入检查
|
|
31
31
|
|
|
32
|
+
默认仍调用同一入口,不带新选项时行为与原来一致:
|
|
33
|
+
|
|
32
34
|
```bash
|
|
33
35
|
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --root <path> --json
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
`ADOPTED` 与 `ADOPTED_WITH_SUGGESTIONS` 的退出码是 0,`NOT_CONFIGURED` 的退出码是 1,`PARTIALLY_ADOPTED` 的退出码是 2。未配置时说明首次 `release-setup` 入口,不生成或写入配置;必选缺口按 finding 的 `fieldPath` 与 `action` 处理。声明的 hook 只作为配置和事实读取,不执行。
|
|
37
39
|
|
|
40
|
+
用户要核对已声明宿主是否接线完整时,本 Skill 收集 `schemaVersion=1` 的 JSON 输入文件,再调用同一 CLI:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --root <path> --host-coverage <file> --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
把用户已提供的完整事实写入该文件,不要从源码或接线猜测。发布单元身份写入 `unitId`,项目声明的支持宿主与出处写入 `support.hosts` / `support.source`,本轮纳入、排除和首次安装义务写入 `delivery.include` / `delivery.exclude` / `delivery.installIfMissing`,安装快照写入 `observations`。字段形状如下:
|
|
47
|
+
|
|
48
|
+
- 顶层对象:`schemaVersion` 为整数 1,`units` 必须是数组。
|
|
49
|
+
- 每个单元:`unitId` 为发布单元标识。
|
|
50
|
+
- `support.hosts`:项目声明支持的宿主字符串数组。
|
|
51
|
+
- `support.source`:该支持声明的出处,不是发布源。
|
|
52
|
+
- `delivery.include`:本轮纳入的宿主字符串数组。
|
|
53
|
+
- `delivery.exclude`:本轮排除数组;元素必须是 `{host, reason}` 对象。没有排除时写空数组。
|
|
54
|
+
- `delivery.installIfMissing`:本轮首次安装义务对应的宿主字符串数组。没有该义务时写空数组。
|
|
55
|
+
- `observations`:观察数组。每条含 `host`、`plugin`、`marketplace`、`state`、`source`、`observedAt`。
|
|
56
|
+
- `state` 只能是 `installed`、`not-installed`、`unknown`。
|
|
57
|
+
- `state` 为 `installed` 时必须提供 `version`。安全的默认 `unknown` 记录可以省略 `version`。示例使用 `unknown` 且省略 `version`,不要编造已安装事实或真实版本。
|
|
58
|
+
- 下列 JSON 只说明结构,占位身份不是项目支持或已安装证据。
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"schemaVersion": 1,
|
|
63
|
+
"units": [
|
|
64
|
+
{
|
|
65
|
+
"unitId": "release-unit-id",
|
|
66
|
+
"support": {
|
|
67
|
+
"hosts": ["claude", "codex"],
|
|
68
|
+
"source": "项目声明出处"
|
|
69
|
+
},
|
|
70
|
+
"delivery": {
|
|
71
|
+
"include": ["claude"],
|
|
72
|
+
"exclude": [
|
|
73
|
+
{
|
|
74
|
+
"host": "codex",
|
|
75
|
+
"reason": "本轮不纳入"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"installIfMissing": []
|
|
79
|
+
},
|
|
80
|
+
"observations": [
|
|
81
|
+
{
|
|
82
|
+
"host": "claude",
|
|
83
|
+
"plugin": "plugin-id",
|
|
84
|
+
"marketplace": "marketplace-name",
|
|
85
|
+
"state": "unknown",
|
|
86
|
+
"source": "operator",
|
|
87
|
+
"observedAt": "1970-01-01T00:00:00.000Z"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
需要本机列表观察时,仅在已提供 `--host-coverage` 后再加 `--observe-hosts`。观察只针对输入 `observations` 里给出 `plugin` 与 `marketplace` 的 Claude、Codex;命令和参数来自平台注册表,不接受输入里的可执行文件或 shell。未实现的宿主保持 `unknown`。观察失败、输出对不上或身份冲突时也保持 `unknown`,不得写成未安装或已通过。
|
|
96
|
+
|
|
97
|
+
`--host-coverage` 不能单独用于普通 setup 写入或发现模式,也不能没有 `--assess-adoption`。错误组合以 `MISSING_PARAMETERS` 失败关闭,JSON 仍标明 `hostCoverage.requested=true`,不得把这次请求悄悄丢掉。
|
|
98
|
+
|
|
99
|
+
解释结果时读取 `hostCoverage`:`requested` 表示是否请求了覆盖诊断;`complete` 表示本次事实是否齐全;`results[]` 每项含 `unitId`(发布单元)、`host`、`status`、`reason`、`evidence`。`status` 只能是 `satisfied`、`mandatory-gap`、`not-applicable`、`unknown`。支持范围只看输入的 `support.hosts` 与 `support.source`,不能从项目接线反推。配置不存在时顶层状态仍是 `NOT_CONFIGURED`,但覆盖请求仍要报告,且不得宣称覆盖完成。配置存在而 `complete=false` 时会出现事实缺失的 `mandatory-gap`,聚合为 `PARTIALLY_ADOPTED`。专业结论使用最终 `status`。本 Skill 不安装插件、不改宿主配置、不把安装观察写成已经加载成功。
|
|
100
|
+
|
|
38
101
|
## 项目离线评估
|
|
39
102
|
|
|
40
103
|
使用插件根相对路径运行:
|
|
@@ -88,4 +151,4 @@ offline assess 不访问 GitHub/npm 认证,因此不会以顶层 `AUTH_MISSING
|
|
|
88
151
|
|
|
89
152
|
纯问询或转交时短答:写明实际回答、适用范围或理由、必要限制和下一步。建议保持为建议。
|
|
90
153
|
|
|
91
|
-
|
|
154
|
+
用本轮命令原返回值写紧凑完整诊断,覆盖实际对象与范围、结论与依据、缺口或产物、未覆盖项与下一步。若请求了 `--host-coverage`,须报告 `hostCoverage` 与最终 `status`,不得把未知写成完成。不另建六段报告。`verify-records` 对用户显式给出的记录做本次声明范围内的核对,并报告实际得到的 `CONSISTENT`、`CONTRADICTED` 或 `INSUFFICIENT`。`historicalTerminalStatus` 作为独立历史终态另列,与本次核对结果不能互相替代。`read-proof` 只解释旧证明文件里已有的结论和原检查范围;旧证明可以是未通过或未完成。该入口不重新核对当前记录,不表示当前重验、作者认证或发布完成。已有 JSON 与 `--output` / `--conclusion-output` 产物按原合同呈现。栏目只收录当前命令已经返回的事实。
|
|
@@ -15,6 +15,8 @@ description: 发布达到 VERIFIED 后编排完整收尾:处理分支决定和
|
|
|
15
15
|
|
|
16
16
|
默认只读取冻结计划和 verify 或 postVerify run。没有用户明确同意,不合并分支,不更新插件。用户显式选择 Kimi 更新后,只有标准初始目录信任界面和插件信任界面中的冻结身份都通过核对,才确认当前项目并安装。用户显式选择 Qoder 且冻结计划声明该宿主后,才执行计划绑定的 Hub 更新。
|
|
17
17
|
|
|
18
|
+
宿主覆盖是否接线完整,走 `release-assess` 或 `release-setup` 的只读入口 `setup --assess-adoption --host-coverage <file>`,需要列表观察时再加 `--observe-hosts`。那是诊断,不是本机安装授权。`--observe-hosts` 只读 Claude/Codex 列表,身份来自覆盖输入的 `observations`,不安装、不改配置。本 Skill 仍只在用户明确同意后才更新本机宿主;覆盖诊断结果不能代替 `--update-local-hosts` 与 `--confirm-plan`。
|
|
19
|
+
|
|
18
20
|
## 进入完整收尾
|
|
19
21
|
|
|
20
22
|
从插件根执行:
|
|
@@ -29,9 +29,9 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
29
29
|
|
|
30
30
|
治理诊断只运行 release-skill 自己的只读检查程序,不运行目标 Skill、业务脚本、构建、hook 或发布动作,也不把 `prepare`、`verify`、`release-finish` 当作静态治理入口。用户要求实际接入或发布时,把已有授权带到对应原业务入口;各入口继续执行原有确认、副作用和状态机合同。
|
|
31
31
|
|
|
32
|
-
## 0.9.
|
|
32
|
+
## 0.9.28 能力与证据边界
|
|
33
33
|
|
|
34
|
-
release-skill 0.9.
|
|
34
|
+
release-skill 0.9.28 精确依赖 Foundation 0.25.0 的公开包根 API。本版本新增可选宿主覆盖诊断能力,支持通过 `--host-coverage <file>` 提供输入文件,报告每个宿主在声明范围内的覆盖状态与事实缺口;同时采用 Codex 0.154.0 静态加载规则检查,基于 11 份真实生成 Skill 的原字节在隔离环境中完成诊断,不证明安装、会话选择或业务执行通过。批准、发布和验证状态以对应计划、批准及执行记录为准,不能由本说明推断。
|
|
35
35
|
|
|
36
36
|
在冻结前,`prepare` 或新建 `ship` 状态时可重复传入 `--unit <id>`;未传入则默认选择全部单元。延期单元不进入发布计划,亦不获得发布状态。完整配置、生成物新鲜度检查及顶层 Hook 仍作用于全项目范围。`publicSourceAuthorityReceipt` 的 coordinator 与全部 subjects 必须共同选择。
|
|
37
37
|
|
|
@@ -101,12 +101,15 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --roo
|
|
|
101
101
|
|
|
102
102
|
需要共同证明时另加 `--conclusion-output <absolute-path>`。该文件必须尚未存在;排他写入成功后,报告才含 `conclusionPath`。
|
|
103
103
|
|
|
104
|
-
-
|
|
104
|
+
需要核对已声明宿主覆盖时,先收集 `schemaVersion=1` 的输入文件,再在同一命令上加 `--host-coverage <file>`。本 Skill 只收集输入、调用 CLI 并解释 `hostCoverage`,不在 Skill 内另做比较。可选 `--observe-hosts` 必须与 `--host-coverage` 一起使用,只观察输入身份对应的 Claude 与 Codex 列表;未实现宿主保持 `unknown`。不安装、不写入配置。无新选项时 `hostCoverage.requested` 为 false,旧四态与退出码不变。
|
|
105
|
+
|
|
106
|
+
- 完全只读:评估后仓库不新增任何文件,不修改配置,不执行 hook。不带 `--conclusion-output` 时不另写证明。覆盖诊断同样不安装宿主插件。
|
|
105
107
|
- 报告四态:`NOT_CONFIGURED`、`PARTIALLY_ADOPTED`、`ADOPTED`、`ADOPTED_WITH_SUGGESTIONS`。
|
|
106
108
|
- findings 分四类:`mandatory-gap`(必选缺口,阻断接入)、`satisfied`(已满足)、`optional-suggestion`(可选建议)、`not-applicable`(不适用);每条带 `code`、`fieldPath`、`evidence` 与 `action`。
|
|
107
109
|
- `gateSuggestions` 只列可执行且尚未登记的配置草案。无法安全形成草案的脚本保留在 `gateDiagnostics`,不计入建议数量,也不把状态改成 `ADOPTED_WITH_SUGGESTIONS`。
|
|
108
110
|
- 建议边界:hook 缓存候选只提示 `cacheInputs` 必须由项目自己声明并证明完整,评估不代猜、不代写;hook 耗时只从描述匹配且生产者可信的 started/completed 事件对推导,`timeoutMs` 不是实际成本;任何建议都不改变接入状态。
|
|
109
111
|
- 必选缺口存在时先修复并重跑 `setup --assess-adoption`,再进入发布流程。
|
|
112
|
+
- 覆盖请求在配置缺失或无效时也要出现在报告里,不得把未知或接线不足写成已完成。专业结论使用最终 `status`。
|
|
110
113
|
|
|
111
114
|
## publisher 字段与个人片段泄漏策略
|
|
112
115
|
|
|
@@ -130,4 +133,4 @@ setup 生成的 `.release-skill/project.yaml` 中 `publisher` 是**已批准的
|
|
|
130
133
|
|
|
131
134
|
纯问询或转交时短答:写明实际回答、适用范围或理由、必要限制和下一步。建议保持为建议。
|
|
132
135
|
|
|
133
|
-
首次发现、绑定确认和首次创建,只解释本轮已经得到的 `compactSummary`、绑定摘要、`setupDigest` 和命令实际可见结果。接入评估解释原生状态与 findings
|
|
136
|
+
首次发现、绑定确认和首次创建,只解释本轮已经得到的 `compactSummary`、绑定摘要、`setupDigest` 和命令实际可见结果。接入评估解释原生状态与 findings;若请求了覆盖诊断,同时解释 `hostCoverage` 与最终 `status`。回复沿用既有提取器,使用已打印的紧凑摘要。完整报告只在发现、人工确认和提取期间暂存于会话目录。第4步在固定提取器成功后按原步骤清理会话目录。成功路径的最终回复只用已经打印的紧凑摘要及命令可见结果,不重新读取完整报告。该回复不得把完整报告写成之后仍可读取。发现待确认或绑定待确认时,原会话目录仍按第2、3步保留,不把成功路径的清理提前。已有文件输出按原合同呈现。栏目只收录当前命令已经返回的事实。
|
|
@@ -29,12 +29,75 @@ description: "Read-only release governance diagnosis: adoption, project readines
|
|
|
29
29
|
|
|
30
30
|
## 接入检查
|
|
31
31
|
|
|
32
|
+
默认仍调用同一入口,不带新选项时行为与原来一致:
|
|
33
|
+
|
|
32
34
|
```bash
|
|
33
35
|
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --root <path> --json
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
`ADOPTED` 与 `ADOPTED_WITH_SUGGESTIONS` 的退出码是 0,`NOT_CONFIGURED` 的退出码是 1,`PARTIALLY_ADOPTED` 的退出码是 2。未配置时说明首次 `release-setup` 入口,不生成或写入配置;必选缺口按 finding 的 `fieldPath` 与 `action` 处理。声明的 hook 只作为配置和事实读取,不执行。
|
|
37
39
|
|
|
40
|
+
用户要核对已声明宿主是否接线完整时,本 Skill 收集 `schemaVersion=1` 的 JSON 输入文件,再调用同一 CLI:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --root <path> --host-coverage <file> --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
把用户已提供的完整事实写入该文件,不要从源码或接线猜测。发布单元身份写入 `unitId`,项目声明的支持宿主与出处写入 `support.hosts` / `support.source`,本轮纳入、排除和首次安装义务写入 `delivery.include` / `delivery.exclude` / `delivery.installIfMissing`,安装快照写入 `observations`。字段形状如下:
|
|
47
|
+
|
|
48
|
+
- 顶层对象:`schemaVersion` 为整数 1,`units` 必须是数组。
|
|
49
|
+
- 每个单元:`unitId` 为发布单元标识。
|
|
50
|
+
- `support.hosts`:项目声明支持的宿主字符串数组。
|
|
51
|
+
- `support.source`:该支持声明的出处,不是发布源。
|
|
52
|
+
- `delivery.include`:本轮纳入的宿主字符串数组。
|
|
53
|
+
- `delivery.exclude`:本轮排除数组;元素必须是 `{host, reason}` 对象。没有排除时写空数组。
|
|
54
|
+
- `delivery.installIfMissing`:本轮首次安装义务对应的宿主字符串数组。没有该义务时写空数组。
|
|
55
|
+
- `observations`:观察数组。每条含 `host`、`plugin`、`marketplace`、`state`、`source`、`observedAt`。
|
|
56
|
+
- `state` 只能是 `installed`、`not-installed`、`unknown`。
|
|
57
|
+
- `state` 为 `installed` 时必须提供 `version`。安全的默认 `unknown` 记录可以省略 `version`。示例使用 `unknown` 且省略 `version`,不要编造已安装事实或真实版本。
|
|
58
|
+
- 下列 JSON 只说明结构,占位身份不是项目支持或已安装证据。
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"schemaVersion": 1,
|
|
63
|
+
"units": [
|
|
64
|
+
{
|
|
65
|
+
"unitId": "release-unit-id",
|
|
66
|
+
"support": {
|
|
67
|
+
"hosts": ["claude", "codex"],
|
|
68
|
+
"source": "项目声明出处"
|
|
69
|
+
},
|
|
70
|
+
"delivery": {
|
|
71
|
+
"include": ["claude"],
|
|
72
|
+
"exclude": [
|
|
73
|
+
{
|
|
74
|
+
"host": "codex",
|
|
75
|
+
"reason": "本轮不纳入"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"installIfMissing": []
|
|
79
|
+
},
|
|
80
|
+
"observations": [
|
|
81
|
+
{
|
|
82
|
+
"host": "claude",
|
|
83
|
+
"plugin": "plugin-id",
|
|
84
|
+
"marketplace": "marketplace-name",
|
|
85
|
+
"state": "unknown",
|
|
86
|
+
"source": "operator",
|
|
87
|
+
"observedAt": "1970-01-01T00:00:00.000Z"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
需要本机列表观察时,仅在已提供 `--host-coverage` 后再加 `--observe-hosts`。观察只针对输入 `observations` 里给出 `plugin` 与 `marketplace` 的 Claude、Codex;命令和参数来自平台注册表,不接受输入里的可执行文件或 shell。未实现的宿主保持 `unknown`。观察失败、输出对不上或身份冲突时也保持 `unknown`,不得写成未安装或已通过。
|
|
96
|
+
|
|
97
|
+
`--host-coverage` 不能单独用于普通 setup 写入或发现模式,也不能没有 `--assess-adoption`。错误组合以 `MISSING_PARAMETERS` 失败关闭,JSON 仍标明 `hostCoverage.requested=true`,不得把这次请求悄悄丢掉。
|
|
98
|
+
|
|
99
|
+
解释结果时读取 `hostCoverage`:`requested` 表示是否请求了覆盖诊断;`complete` 表示本次事实是否齐全;`results[]` 每项含 `unitId`(发布单元)、`host`、`status`、`reason`、`evidence`。`status` 只能是 `satisfied`、`mandatory-gap`、`not-applicable`、`unknown`。支持范围只看输入的 `support.hosts` 与 `support.source`,不能从项目接线反推。配置不存在时顶层状态仍是 `NOT_CONFIGURED`,但覆盖请求仍要报告,且不得宣称覆盖完成。配置存在而 `complete=false` 时会出现事实缺失的 `mandatory-gap`,聚合为 `PARTIALLY_ADOPTED`。专业结论使用最终 `status`。本 Skill 不安装插件、不改宿主配置、不把安装观察写成已经加载成功。
|
|
100
|
+
|
|
38
101
|
## 项目离线评估
|
|
39
102
|
|
|
40
103
|
使用插件根相对路径运行:
|
|
@@ -88,4 +151,4 @@ offline assess 不访问 GitHub/npm 认证,因此不会以顶层 `AUTH_MISSING
|
|
|
88
151
|
|
|
89
152
|
纯问询或转交时短答:写明实际回答、适用范围或理由、必要限制和下一步。建议保持为建议。
|
|
90
153
|
|
|
91
|
-
|
|
154
|
+
用本轮命令原返回值写紧凑完整诊断,覆盖实际对象与范围、结论与依据、缺口或产物、未覆盖项与下一步。若请求了 `--host-coverage`,须报告 `hostCoverage` 与最终 `status`,不得把未知写成完成。不另建六段报告。`verify-records` 对用户显式给出的记录做本次声明范围内的核对,并报告实际得到的 `CONSISTENT`、`CONTRADICTED` 或 `INSUFFICIENT`。`historicalTerminalStatus` 作为独立历史终态另列,与本次核对结果不能互相替代。`read-proof` 只解释旧证明文件里已有的结论和原检查范围;旧证明可以是未通过或未完成。该入口不重新核对当前记录,不表示当前重验、作者认证或发布完成。已有 JSON 与 `--output` / `--conclusion-output` 产物按原合同呈现。栏目只收录当前命令已经返回的事实。
|
|
@@ -15,6 +15,8 @@ description: 发布达到 VERIFIED 后编排完整收尾:处理分支决定和
|
|
|
15
15
|
|
|
16
16
|
默认只读取冻结计划和 verify 或 postVerify run。没有用户明确同意,不合并分支,不更新插件。用户显式选择 Kimi 更新后,只有标准初始目录信任界面和插件信任界面中的冻结身份都通过核对,才确认当前项目并安装。用户显式选择 Qoder 且冻结计划声明该宿主后,才执行计划绑定的 Hub 更新。
|
|
17
17
|
|
|
18
|
+
宿主覆盖是否接线完整,走 `release-assess` 或 `release-setup` 的只读入口 `setup --assess-adoption --host-coverage <file>`,需要列表观察时再加 `--observe-hosts`。那是诊断,不是本机安装授权。`--observe-hosts` 只读 Claude/Codex 列表,身份来自覆盖输入的 `observations`,不安装、不改配置。本 Skill 仍只在用户明确同意后才更新本机宿主;覆盖诊断结果不能代替 `--update-local-hosts` 与 `--confirm-plan`。
|
|
19
|
+
|
|
18
20
|
## 进入完整收尾
|
|
19
21
|
|
|
20
22
|
从插件根执行:
|
|
@@ -29,9 +29,9 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
29
29
|
|
|
30
30
|
治理诊断只运行 release-skill 自己的只读检查程序,不运行目标 Skill、业务脚本、构建、hook 或发布动作,也不把 `prepare`、`verify`、`release-finish` 当作静态治理入口。用户要求实际接入或发布时,把已有授权带到对应原业务入口;各入口继续执行原有确认、副作用和状态机合同。
|
|
31
31
|
|
|
32
|
-
## 0.9.
|
|
32
|
+
## 0.9.28 能力与证据边界
|
|
33
33
|
|
|
34
|
-
release-skill 0.9.
|
|
34
|
+
release-skill 0.9.28 精确依赖 Foundation 0.25.0 的公开包根 API。本版本新增可选宿主覆盖诊断能力,支持通过 `--host-coverage <file>` 提供输入文件,报告每个宿主在声明范围内的覆盖状态与事实缺口;同时采用 Codex 0.154.0 静态加载规则检查,基于 11 份真实生成 Skill 的原字节在隔离环境中完成诊断,不证明安装、会话选择或业务执行通过。批准、发布和验证状态以对应计划、批准及执行记录为准,不能由本说明推断。
|
|
35
35
|
|
|
36
36
|
在冻结前,`prepare` 或新建 `ship` 状态时可重复传入 `--unit <id>`;未传入则默认选择全部单元。延期单元不进入发布计划,亦不获得发布状态。完整配置、生成物新鲜度检查及顶层 Hook 仍作用于全项目范围。`publicSourceAuthorityReceipt` 的 coordinator 与全部 subjects 必须共同选择。
|
|
37
37
|
|
|
@@ -101,12 +101,15 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --assess-adoption --roo
|
|
|
101
101
|
|
|
102
102
|
需要共同证明时另加 `--conclusion-output <absolute-path>`。该文件必须尚未存在;排他写入成功后,报告才含 `conclusionPath`。
|
|
103
103
|
|
|
104
|
-
-
|
|
104
|
+
需要核对已声明宿主覆盖时,先收集 `schemaVersion=1` 的输入文件,再在同一命令上加 `--host-coverage <file>`。本 Skill 只收集输入、调用 CLI 并解释 `hostCoverage`,不在 Skill 内另做比较。可选 `--observe-hosts` 必须与 `--host-coverage` 一起使用,只观察输入身份对应的 Claude 与 Codex 列表;未实现宿主保持 `unknown`。不安装、不写入配置。无新选项时 `hostCoverage.requested` 为 false,旧四态与退出码不变。
|
|
105
|
+
|
|
106
|
+
- 完全只读:评估后仓库不新增任何文件,不修改配置,不执行 hook。不带 `--conclusion-output` 时不另写证明。覆盖诊断同样不安装宿主插件。
|
|
105
107
|
- 报告四态:`NOT_CONFIGURED`、`PARTIALLY_ADOPTED`、`ADOPTED`、`ADOPTED_WITH_SUGGESTIONS`。
|
|
106
108
|
- findings 分四类:`mandatory-gap`(必选缺口,阻断接入)、`satisfied`(已满足)、`optional-suggestion`(可选建议)、`not-applicable`(不适用);每条带 `code`、`fieldPath`、`evidence` 与 `action`。
|
|
107
109
|
- `gateSuggestions` 只列可执行且尚未登记的配置草案。无法安全形成草案的脚本保留在 `gateDiagnostics`,不计入建议数量,也不把状态改成 `ADOPTED_WITH_SUGGESTIONS`。
|
|
108
110
|
- 建议边界:hook 缓存候选只提示 `cacheInputs` 必须由项目自己声明并证明完整,评估不代猜、不代写;hook 耗时只从描述匹配且生产者可信的 started/completed 事件对推导,`timeoutMs` 不是实际成本;任何建议都不改变接入状态。
|
|
109
111
|
- 必选缺口存在时先修复并重跑 `setup --assess-adoption`,再进入发布流程。
|
|
112
|
+
- 覆盖请求在配置缺失或无效时也要出现在报告里,不得把未知或接线不足写成已完成。专业结论使用最终 `status`。
|
|
110
113
|
|
|
111
114
|
## publisher 字段与个人片段泄漏策略
|
|
112
115
|
|
|
@@ -130,4 +133,4 @@ setup 生成的 `.release-skill/project.yaml` 中 `publisher` 是**已批准的
|
|
|
130
133
|
|
|
131
134
|
纯问询或转交时短答:写明实际回答、适用范围或理由、必要限制和下一步。建议保持为建议。
|
|
132
135
|
|
|
133
|
-
首次发现、绑定确认和首次创建,只解释本轮已经得到的 `compactSummary`、绑定摘要、`setupDigest` 和命令实际可见结果。接入评估解释原生状态与 findings
|
|
136
|
+
首次发现、绑定确认和首次创建,只解释本轮已经得到的 `compactSummary`、绑定摘要、`setupDigest` 和命令实际可见结果。接入评估解释原生状态与 findings;若请求了覆盖诊断,同时解释 `hostCoverage` 与最终 `status`。回复沿用既有提取器,使用已打印的紧凑摘要。完整报告只在发现、人工确认和提取期间暂存于会话目录。第4步在固定提取器成功后按原步骤清理会话目录。成功路径的最终回复只用已经打印的紧凑摘要及命令可见结果,不重新读取完整报告。该回复不得把完整报告写成之后仍可读取。发现待确认或绑定待确认时,原会话目录仍按第2、3步保留,不把成功路径的清理提前。已有文件输出按原合同呈现。栏目只收录当前命令已经返回的事实。
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
readFileContained,
|
|
7
7
|
readFileStrict,
|
|
8
8
|
resolveContained,
|
|
9
|
-
superviseProcess,
|
|
10
9
|
withTemporaryWorkspace,
|
|
11
10
|
createTemporaryWorkspace,
|
|
12
11
|
createFilesystemRootBinding,
|
|
@@ -22,6 +21,12 @@ import { verifyInstalledMarketplacePayload } from '../adapters/plugin-marketplac
|
|
|
22
21
|
import { normalizePostPublishView, postPublishActionId } from '../core/postpublish.mjs';
|
|
23
22
|
import { loadRun, validateRunLineage } from '../core/run.mjs';
|
|
24
23
|
import { verifyFrozenSnapshot } from '../snapshot/frozen.mjs';
|
|
24
|
+
import {
|
|
25
|
+
attachFoundationFailure,
|
|
26
|
+
hostEnvironment,
|
|
27
|
+
parseHostCommandJson,
|
|
28
|
+
runLocalFinishCommand,
|
|
29
|
+
} from '../core/local-host-observation.mjs';
|
|
25
30
|
|
|
26
31
|
const HOSTS_BY_ACTION = Object.freeze({
|
|
27
32
|
'claude-marketplace-install': ['claude'],
|
|
@@ -39,28 +44,12 @@ const DISTRIBUTION_BY_ACTION = Object.freeze({
|
|
|
39
44
|
|
|
40
45
|
const BRANCH_ACTION_INCLUDED = new Set(['advance-existing-branch', 'initialize-default-branch']);
|
|
41
46
|
const CODEBUDDY_MACOS_PATH = '/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy';
|
|
42
|
-
const SAFE_ENV_KEYS = Object.freeze([
|
|
43
|
-
'PATH', 'HOME', 'USER', 'LANG', 'LC_ALL', 'LC_CTYPE', 'TERM', 'TMPDIR',
|
|
44
|
-
'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY', 'http_proxy', 'https_proxy', 'all_proxy', 'no_proxy',
|
|
45
|
-
'SSL_CERT_FILE', 'SSL_CERT_DIR', 'NODE_EXTRA_CA_CERTS',
|
|
46
|
-
'CLAUDE_CONFIG_DIR', 'CODEX_HOME', 'KIMI_CODE_HOME',
|
|
47
|
-
'CODEBUDDY_CONFIG_DIR', 'WORKBUDDY_CONFIG_DIR',
|
|
48
|
-
]);
|
|
49
47
|
const CODEBUDDY_PLUGIN_LIST_ARGS = Object.freeze(['plugin', 'list', '--json']);
|
|
50
48
|
const CODEBUDDY_MARKETPLACE_LIST_ARGS = Object.freeze(['plugin', 'marketplace', 'list']);
|
|
51
49
|
const QODER_PLUGIN_LIST_ARGS = Object.freeze(['plugins', 'list', '--json']);
|
|
52
50
|
const QODER_MARKETPLACE_LIST_ARGS = Object.freeze(['plugins', 'marketplace', 'list', '--json']);
|
|
53
51
|
const QODER_PAYLOAD_CONTRACT = 'external-marketplace-v1';
|
|
54
52
|
|
|
55
|
-
function attachFoundationFailure(error, { envelope, stdout, stderr }) {
|
|
56
|
-
Object.defineProperties(error, {
|
|
57
|
-
foundationEnvelope: { value: envelope, enumerable: false },
|
|
58
|
-
foundationStdout: { value: stdout, enumerable: false },
|
|
59
|
-
foundationStderr: { value: stderr, enumerable: false },
|
|
60
|
-
});
|
|
61
|
-
return error;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
53
|
function actionTarget(plan, action, host) {
|
|
65
54
|
const parameters = action.parameters ?? {};
|
|
66
55
|
const sourceDescriptor = parameters.sourceDescriptor ?? {};
|
|
@@ -253,13 +242,20 @@ function mergePostReleaseTargets(executableTargets, manualTargets) {
|
|
|
253
242
|
if (!sameHub || !samePlugin) throw new Error(`post-release target identity conflict for ${target.unitId}/${target.host}/${target.plugin}`);
|
|
254
243
|
continue;
|
|
255
244
|
}
|
|
256
|
-
const hubMatchesExecutable = (hub, executable, hubTarget) =>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
245
|
+
const hubMatchesExecutable = (hub, executable, hubTarget) => {
|
|
246
|
+
// Kimi installs the frozen GitHub release, not a marketplace index.
|
|
247
|
+
if (executable.host === 'kimi') {
|
|
248
|
+
return ['version', 'githubHost', 'pluginRepo', 'pluginTag', 'pluginCommit']
|
|
249
|
+
.every((field) => executable[field] === hubTarget[field]);
|
|
250
|
+
}
|
|
251
|
+
return executable.marketplace === hub.name
|
|
252
|
+
&& executable.marketplaceRepo === hub.repo
|
|
253
|
+
&& executable.marketplaceRef === hub.ref
|
|
254
|
+
&& executable.githubHost === hub.githubHost
|
|
255
|
+
&& executable.pluginRepo === hubTarget.pluginRepo
|
|
256
|
+
&& executable.pluginTag === hubTarget.pluginTag
|
|
257
|
+
&& executable.pluginCommit === hubTarget.pluginCommit;
|
|
258
|
+
};
|
|
263
259
|
// When the same frozen plugin is available through both sources, the
|
|
264
260
|
// executable action wins only when both frozen source identities agree.
|
|
265
261
|
if (existing && existing.targetKind !== 'hub-backed' && target.targetKind === 'hub-backed') {
|
|
@@ -589,63 +585,8 @@ export function assertVerifiedReleaseRun(plan, runRecord) {
|
|
|
589
585
|
}
|
|
590
586
|
}
|
|
591
587
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
for (const key of SAFE_ENV_KEYS) {
|
|
595
|
-
if (process.env[key] !== undefined) env[key] = process.env[key];
|
|
596
|
-
}
|
|
597
|
-
env.HOME ??= homedir();
|
|
598
|
-
env.PATH ??= '/usr/bin:/bin';
|
|
599
|
-
env.GIT_TERMINAL_PROMPT = '0';
|
|
600
|
-
if (host === 'codebuddy') env.CODEBUDDY_CONFIG_DIR = join(env.HOME, '.codebuddy');
|
|
601
|
-
if (host === 'workbuddy') {
|
|
602
|
-
env.CODEBUDDY_CONFIG_DIR = join(env.HOME, '.workbuddy');
|
|
603
|
-
env.WORKBUDDY_CONFIG_DIR = join(env.HOME, '.workbuddy');
|
|
604
|
-
env.CODEBUDDY_FORCE_LITE_WB_BUNDLE = '1';
|
|
605
|
-
}
|
|
606
|
-
if (host === 'kimi' && kimiHome) env.KIMI_CODE_HOME = kimiHome;
|
|
607
|
-
return env;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
async function defaultRun(command, args, options = {}) {
|
|
611
|
-
return withTemporaryWorkspace(async (workspace) => {
|
|
612
|
-
const stdoutFile = 'stdout.log';
|
|
613
|
-
const stderrFile = 'stderr.log';
|
|
614
|
-
const envelope = await superviseProcess({
|
|
615
|
-
command,
|
|
616
|
-
args,
|
|
617
|
-
cwd: options.cwd ?? process.cwd(),
|
|
618
|
-
env: options.env ?? hostEnvironment('generic'),
|
|
619
|
-
timeoutPolicy: {
|
|
620
|
-
maxSeconds: Math.max(1, Math.ceil((options.timeout ?? 120_000) / 1000)),
|
|
621
|
-
killGraceSeconds: 5,
|
|
622
|
-
},
|
|
623
|
-
rawSink: { root: workspace.root, stdoutFile, stderrFile },
|
|
624
|
-
outputByteLimits: { stdout: 8 * 1024 * 1024, stderr: 8 * 1024 * 1024 },
|
|
625
|
-
});
|
|
626
|
-
const [stdout, stderr] = await Promise.all([
|
|
627
|
-
workspace.readFile(stdoutFile, { encoding: 'utf8' }),
|
|
628
|
-
workspace.readFile(stderrFile, { encoding: 'utf8' }),
|
|
629
|
-
]);
|
|
630
|
-
if (!envelope.ok) {
|
|
631
|
-
const error = new Error(
|
|
632
|
-
`${command} exited ${envelope.exitStatus}${stderr.trim() ? `: ${stderr.trim()}` : ''}`,
|
|
633
|
-
);
|
|
634
|
-
error.exitStatus = envelope.exitStatus;
|
|
635
|
-
error.hostCommandUnavailable = envelope.processStatus === 'FAILED_TO_START';
|
|
636
|
-
error.details = {
|
|
637
|
-
processStatus: envelope.processStatus,
|
|
638
|
-
terminationReason: envelope.terminationReason,
|
|
639
|
-
watchdogReason: envelope.watchdogReason,
|
|
640
|
-
...(envelope.evidence?.spawnError ? { spawnError: envelope.evidence.spawnError } : {}),
|
|
641
|
-
};
|
|
642
|
-
throw attachFoundationFailure(error, { envelope, stdout, stderr });
|
|
643
|
-
}
|
|
644
|
-
return { stdout, stderr };
|
|
645
|
-
}, { prefix: 'release-skill-host-command-' });
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
export { defaultRun as runLocalFinishCommand };
|
|
588
|
+
const defaultRun = runLocalFinishCommand;
|
|
589
|
+
export { runLocalFinishCommand };
|
|
649
590
|
|
|
650
591
|
async function commandAvailable(command, host, run) {
|
|
651
592
|
try {
|
|
@@ -682,13 +623,7 @@ async function defaultDetect(host, run = defaultRun) {
|
|
|
682
623
|
return { available: true, command: host };
|
|
683
624
|
}
|
|
684
625
|
|
|
685
|
-
|
|
686
|
-
try {
|
|
687
|
-
return JSON.parse(stdout);
|
|
688
|
-
} catch {
|
|
689
|
-
throw new Error(`${label} did not return JSON`);
|
|
690
|
-
}
|
|
691
|
-
}
|
|
626
|
+
const parseJson = parseHostCommandJson;
|
|
692
627
|
|
|
693
628
|
function foundationEnvelopeFromError(error) {
|
|
694
629
|
return error?.foundationEnvelope ?? null;
|
|
@@ -1898,10 +1833,19 @@ async function observeKimiTarget(target, kimiHome, run) {
|
|
|
1898
1833
|
const pluginRoot = await resolveContained(managedRoot, target.plugin);
|
|
1899
1834
|
const declaredRoot = await resolveContained(managedRoot, relative(managedRoot, entry.root));
|
|
1900
1835
|
if (declaredRoot !== pluginRoot) throw new Error('Kimi installed plugin root does not match its managed root');
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1836
|
+
let manifestText;
|
|
1837
|
+
let manifestLabel = 'Kimi installed package manifest';
|
|
1838
|
+
try {
|
|
1839
|
+
manifestText = await readFileContained(pluginRoot, 'package.json', { encoding: 'utf8' });
|
|
1840
|
+
} catch (error) {
|
|
1841
|
+
const missing = error?.code === 'ENOENT'
|
|
1842
|
+
|| error?.details?.causeCode === 'ENOENT'
|
|
1843
|
+
|| error?.details?.kind === 'missing-resource';
|
|
1844
|
+
if (!missing) throw error;
|
|
1845
|
+
manifestLabel = 'Kimi installed plugin manifest';
|
|
1846
|
+
manifestText = await readFileContained(pluginRoot, 'kimi.plugin.json', { encoding: 'utf8' });
|
|
1847
|
+
}
|
|
1848
|
+
const packageJson = parseJson(manifestText, manifestLabel);
|
|
1905
1849
|
const refName = entry.github.ref?.kind === 'tag' ? entry.github.ref.value : undefined;
|
|
1906
1850
|
const revision = entry.github.installedSha;
|
|
1907
1851
|
let gitHeadExact = true;
|