release-skill 0.9.15 → 0.9.16
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/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +31 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +31 -16
- package/README.zh-CN.md +27 -15
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +30 -2
- package/adapters/claude/schemas/release-project.schema.json +18 -0
- package/adapters/claude/skills/release-finish/SKILL.md +58 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +30 -2
- package/adapters/codex/schemas/release-project.schema.json +18 -0
- package/adapters/codex/skills/release-finish/SKILL.md +58 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +30 -2
- package/adapters/kimi/schemas/release-project.schema.json +18 -0
- package/adapters/kimi/skills/release-finish/SKILL.md +58 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +30 -2
- package/adapters/workbuddy/schemas/release-project.schema.json +18 -0
- package/adapters/workbuddy/skills/release-finish/SKILL.md +58 -0
- package/bin/release-skill-cli.mjs +28 -0
- package/bin/release-skill.bundle.mjs +30 -2
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/references/02-project-config.md +16 -0
- package/schemas/release-project.schema.json +18 -0
- package/skills/release-finish/SKILL.md +58 -0
- package/skills-src/release-finish/SKILL.md +58 -0
|
@@ -77,6 +77,64 @@ node "$RELEASE_SKILL_LOCAL_FINISH_ENTRY" \
|
|
|
77
77
|
|
|
78
78
|
完成后报告每个宿主的状态,并提醒用户重启已更新的宿主。本机结果只记录收尾事实,不改变发布状态。
|
|
79
79
|
|
|
80
|
+
## 配置与目录
|
|
81
|
+
|
|
82
|
+
从发布项目目录的 `.release-skill/project.yaml` 读取 `releaseFinish` 和 `project.defaultBranch`。
|
|
83
|
+
文件缺失或无法解析时,报告具体配置问题,不猜默认分支或 setup,也不得把文件缺失当作字段合法缺省;
|
|
84
|
+
已经取得的发布结果仍保留。只有配置文件有效时,整个 `releaseFinish` 或其中字段缺省才按各自合同默认。
|
|
85
|
+
|
|
86
|
+
发布项目目录用于读取配置和执行源码 Git 检查。setup 使用用户明确指定的消费项目目录或已明确的使用
|
|
87
|
+
上下文。只有用户明确把发布源码仓库作为消费项目时,才能在那里执行 setup;同时提供两个目录时不得混用。
|
|
88
|
+
|
|
89
|
+
## 更新后 setup
|
|
90
|
+
|
|
91
|
+
完成现有清单及已授权的宿主处理后,读取发布项目 `.release-skill/project.yaml` 的
|
|
92
|
+
`releaseFinish.setupSkill`。未配置时不增加 setup 提示。配置的技能名只用于匹配入口,不作为 shell 命令执行,
|
|
93
|
+
也不授权安装同名插件。
|
|
94
|
+
|
|
95
|
+
只有本次所选宿主已经成功更新,或现有检查确认它已是目标版本时,才衔接 setup。通过宿主实际技能
|
|
96
|
+
元数据核对目标插件身份、版本和入口;不能从开发仓库、旧会话缓存或同名技能推断新版已加载。当前宿主
|
|
97
|
+
不满足时,可以使用同次更新中另一个已安装并加载目标版本和入口的宿主。
|
|
98
|
+
|
|
99
|
+
目标目录来自用户本次明确指定的消费项目或已明确的使用上下文。目录不明确、宿主需要重启、当前环境
|
|
100
|
+
不能调用可用宿主、入口不存在或归属有歧义时,标为“待执行”,并给出插件与版本、技能名、目标目录和
|
|
101
|
+
已有授权的续接提示。发出提示不代表 setup 已完成。
|
|
102
|
+
|
|
103
|
+
对同一插件版本、同一项目目录和相同共享运行环境,项目级依赖、项目配置和 Git hooks 由一个已加载
|
|
104
|
+
新版插件的宿主检查一次。其余宿主分别核对自身安装、加载和宿主专属配置。不同运行环境不得无条件
|
|
105
|
+
复用项目就绪结论;按目标 setup 的实际合同补查差异。release-finish 不保存去重键、收据或新的状态。
|
|
106
|
+
|
|
107
|
+
调用 setup 前完整读取目标技能及其必读引用,并传入目标项目、插件版本、只读检查意图和已有授权范围。
|
|
108
|
+
已有具体修复授权应传递给 setup;未覆盖的写入不能执行。只读检查、安装结果和配置修复结果分别报告。
|
|
109
|
+
最终自然语言回复列出执行宿主、插件版本、消费项目路径、实际结果和未完成项。任何 setup 结果都不改变
|
|
110
|
+
`VERIFIED`,也不影响其他宿主已经完成的结果。
|
|
111
|
+
|
|
112
|
+
## 源码分支检查
|
|
113
|
+
|
|
114
|
+
宿主更新和 setup 不影响本项检查。读取 `releaseFinish.sourceBranchCheck`;字段或整个
|
|
115
|
+
`releaseFinish` 缺省时按 `remind` 处理。配置为 `skip` 时不运行 Git 命令,只说明项目已关闭
|
|
116
|
+
源码分支检查。
|
|
117
|
+
|
|
118
|
+
`remind` 时,在发布项目目录依次运行两条只读命令:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git branch --show-current
|
|
122
|
+
git status --short --branch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
第一条命令取得当前分支。第二条命令读取工作区改动和现有上游跟踪摘要;不得增加会写入或访问网络的
|
|
126
|
+
参数。当前分支等于 `project.defaultBranch` 且没有文件改动时,说明本地已位于目标分支;输出含
|
|
127
|
+
ahead 或 behind 等跟踪信息时,仍原样概括。分支不一致时说明两个准确名称,并询问用户是否需要处理。
|
|
128
|
+
第一条命令输出为空时,说明处于 detached HEAD,不猜测目标操作。工作区存在改动时说明不建议直接
|
|
129
|
+
切换或清理。任一命令失败时,报告命令、退出结果和无法完成检查的事实。
|
|
130
|
+
|
|
131
|
+
最终自然语言回复至少列出提醒策略、目标分支、当前分支或无法取得的事实、工作区是否有改动、Git
|
|
132
|
+
上游跟踪摘要,以及是否需要用户决定下一步。没有上游信息时,明确说明命令输出未显示上游信息。
|
|
133
|
+
|
|
134
|
+
本项检查不从宿主更新推导出 Git 写入授权,不自动执行 fetch、switch、checkout、merge、rebase、stash、
|
|
135
|
+
reset、clean 或 push。用户跳过宿主更新仍执行默认分支检查。用户已经明确授权同一仓库、分支和操作时,
|
|
136
|
+
按项目 Git 纪律继续,不重复询问相同授权;检查本身不改变 `VERIFIED`,不保存结果,也不产生新的 run。
|
|
137
|
+
|
|
80
138
|
## 临时归属
|
|
81
139
|
|
|
82
140
|
本能力目前只服务发布后的本机收尾,因此保留在 release-skill。第二个技能族需要复用宿主更新或 TUI 驱动,或 Foundation 发布等价公共入口时,再把通用机制上收 Foundation并删除这里的通用部分。release-skill 只保留发布计划到宿主更新输入的领域映射。
|
|
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.16"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "ba44ad70cebc1cc077887bdf71bf36d78b9073c8aeabd0074aac2eb0d5caffea";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -148166,6 +148166,23 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148166
148166
|
root,
|
|
148167
148167
|
...postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}
|
|
148168
148168
|
});
|
|
148169
|
+
if (result2.status === "DISTRIBUTED") {
|
|
148170
|
+
const {
|
|
148171
|
+
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
148172
|
+
unavailablePostReleaseChecklist: unavailablePostReleaseChecklist2
|
|
148173
|
+
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
148174
|
+
let plan;
|
|
148175
|
+
try {
|
|
148176
|
+
plan = JSON.parse(await readFile57(resolve42(planPath), "utf8"));
|
|
148177
|
+
result2.postRelease = derivePostReleaseChecklist2(plan, {
|
|
148178
|
+
root,
|
|
148179
|
+
runPath: result2.runPath,
|
|
148180
|
+
postVerifyComplete: true
|
|
148181
|
+
});
|
|
148182
|
+
} catch (error) {
|
|
148183
|
+
result2.postRelease = unavailablePostReleaseChecklist2(plan, error);
|
|
148184
|
+
}
|
|
148185
|
+
}
|
|
148169
148186
|
if (hasJson) {
|
|
148170
148187
|
console.log(JSON.stringify(result2, null, 2));
|
|
148171
148188
|
} else {
|
|
@@ -148174,6 +148191,17 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148174
148191
|
console.log(` ${cp4.actionId}: ${cp4.status}`);
|
|
148175
148192
|
}
|
|
148176
148193
|
if (result2.runPath) console.log(`PostVerify run: ${result2.runPath}`);
|
|
148194
|
+
if (result2.postRelease?.status === "UNAVAILABLE") {
|
|
148195
|
+
console.warn(`Post-release checklist unavailable: ${result2.postRelease.diagnostic?.message ?? "unknown error"}`);
|
|
148196
|
+
} else if (result2.postRelease?.localHostUpdate?.promptRequired === true) {
|
|
148197
|
+
const localHostUpdate = result2.postRelease.localHostUpdate;
|
|
148198
|
+
console.log(`Post-release: ask whether to update local host plugins (${localHostUpdate.hosts.join(", ")}).`);
|
|
148199
|
+
if (localHostUpdate.available === true && typeof localHostUpdate.runPath === "string") {
|
|
148200
|
+
console.log(`Post-release command: release-skill post-release --plan ${resolve42(planPath)} --run ${localHostUpdate.runPath}`);
|
|
148201
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
148202
|
+
}
|
|
148203
|
+
printHubManualTargets(localHostUpdate.targets);
|
|
148204
|
+
}
|
|
148177
148205
|
}
|
|
148178
148206
|
await exitAfterFlush(result2.status === "DISTRIBUTED" ? 0 : 1);
|
|
148179
148207
|
} catch (err) {
|
|
@@ -44,6 +44,24 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
"releaseFinish": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"description": "Optional local post-release finish settings. Omitted sourceBranchCheck defaults to remind.",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"properties": {
|
|
52
|
+
"sourceBranchCheck": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"enum": [
|
|
55
|
+
"remind",
|
|
56
|
+
"skip"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"setupSkill": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"pattern": "^[a-z0-9][a-z0-9-]*(?::[a-z0-9][a-z0-9-]*)?$"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
47
65
|
"publicSourceAuthorityReceipt": {
|
|
48
66
|
"type": "object",
|
|
49
67
|
"description": "Optional public source-authority receipt uploaded to one coordinator GitHub Release after all subject npm tarballs are frozen.",
|
|
@@ -77,6 +77,64 @@ node "$RELEASE_SKILL_LOCAL_FINISH_ENTRY" \
|
|
|
77
77
|
|
|
78
78
|
完成后报告每个宿主的状态,并提醒用户重启已更新的宿主。本机结果只记录收尾事实,不改变发布状态。
|
|
79
79
|
|
|
80
|
+
## 配置与目录
|
|
81
|
+
|
|
82
|
+
从发布项目目录的 `.release-skill/project.yaml` 读取 `releaseFinish` 和 `project.defaultBranch`。
|
|
83
|
+
文件缺失或无法解析时,报告具体配置问题,不猜默认分支或 setup,也不得把文件缺失当作字段合法缺省;
|
|
84
|
+
已经取得的发布结果仍保留。只有配置文件有效时,整个 `releaseFinish` 或其中字段缺省才按各自合同默认。
|
|
85
|
+
|
|
86
|
+
发布项目目录用于读取配置和执行源码 Git 检查。setup 使用用户明确指定的消费项目目录或已明确的使用
|
|
87
|
+
上下文。只有用户明确把发布源码仓库作为消费项目时,才能在那里执行 setup;同时提供两个目录时不得混用。
|
|
88
|
+
|
|
89
|
+
## 更新后 setup
|
|
90
|
+
|
|
91
|
+
完成现有清单及已授权的宿主处理后,读取发布项目 `.release-skill/project.yaml` 的
|
|
92
|
+
`releaseFinish.setupSkill`。未配置时不增加 setup 提示。配置的技能名只用于匹配入口,不作为 shell 命令执行,
|
|
93
|
+
也不授权安装同名插件。
|
|
94
|
+
|
|
95
|
+
只有本次所选宿主已经成功更新,或现有检查确认它已是目标版本时,才衔接 setup。通过宿主实际技能
|
|
96
|
+
元数据核对目标插件身份、版本和入口;不能从开发仓库、旧会话缓存或同名技能推断新版已加载。当前宿主
|
|
97
|
+
不满足时,可以使用同次更新中另一个已安装并加载目标版本和入口的宿主。
|
|
98
|
+
|
|
99
|
+
目标目录来自用户本次明确指定的消费项目或已明确的使用上下文。目录不明确、宿主需要重启、当前环境
|
|
100
|
+
不能调用可用宿主、入口不存在或归属有歧义时,标为“待执行”,并给出插件与版本、技能名、目标目录和
|
|
101
|
+
已有授权的续接提示。发出提示不代表 setup 已完成。
|
|
102
|
+
|
|
103
|
+
对同一插件版本、同一项目目录和相同共享运行环境,项目级依赖、项目配置和 Git hooks 由一个已加载
|
|
104
|
+
新版插件的宿主检查一次。其余宿主分别核对自身安装、加载和宿主专属配置。不同运行环境不得无条件
|
|
105
|
+
复用项目就绪结论;按目标 setup 的实际合同补查差异。release-finish 不保存去重键、收据或新的状态。
|
|
106
|
+
|
|
107
|
+
调用 setup 前完整读取目标技能及其必读引用,并传入目标项目、插件版本、只读检查意图和已有授权范围。
|
|
108
|
+
已有具体修复授权应传递给 setup;未覆盖的写入不能执行。只读检查、安装结果和配置修复结果分别报告。
|
|
109
|
+
最终自然语言回复列出执行宿主、插件版本、消费项目路径、实际结果和未完成项。任何 setup 结果都不改变
|
|
110
|
+
`VERIFIED`,也不影响其他宿主已经完成的结果。
|
|
111
|
+
|
|
112
|
+
## 源码分支检查
|
|
113
|
+
|
|
114
|
+
宿主更新和 setup 不影响本项检查。读取 `releaseFinish.sourceBranchCheck`;字段或整个
|
|
115
|
+
`releaseFinish` 缺省时按 `remind` 处理。配置为 `skip` 时不运行 Git 命令,只说明项目已关闭
|
|
116
|
+
源码分支检查。
|
|
117
|
+
|
|
118
|
+
`remind` 时,在发布项目目录依次运行两条只读命令:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git branch --show-current
|
|
122
|
+
git status --short --branch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
第一条命令取得当前分支。第二条命令读取工作区改动和现有上游跟踪摘要;不得增加会写入或访问网络的
|
|
126
|
+
参数。当前分支等于 `project.defaultBranch` 且没有文件改动时,说明本地已位于目标分支;输出含
|
|
127
|
+
ahead 或 behind 等跟踪信息时,仍原样概括。分支不一致时说明两个准确名称,并询问用户是否需要处理。
|
|
128
|
+
第一条命令输出为空时,说明处于 detached HEAD,不猜测目标操作。工作区存在改动时说明不建议直接
|
|
129
|
+
切换或清理。任一命令失败时,报告命令、退出结果和无法完成检查的事实。
|
|
130
|
+
|
|
131
|
+
最终自然语言回复至少列出提醒策略、目标分支、当前分支或无法取得的事实、工作区是否有改动、Git
|
|
132
|
+
上游跟踪摘要,以及是否需要用户决定下一步。没有上游信息时,明确说明命令输出未显示上游信息。
|
|
133
|
+
|
|
134
|
+
本项检查不从宿主更新推导出 Git 写入授权,不自动执行 fetch、switch、checkout、merge、rebase、stash、
|
|
135
|
+
reset、clean 或 push。用户跳过宿主更新仍执行默认分支检查。用户已经明确授权同一仓库、分支和操作时,
|
|
136
|
+
按项目 Git 纪律继续,不重复询问相同授权;检查本身不改变 `VERIFIED`,不保存结果,也不产生新的 run。
|
|
137
|
+
|
|
80
138
|
## 临时归属
|
|
81
139
|
|
|
82
140
|
本能力目前只服务发布后的本机收尾,因此保留在 release-skill。第二个技能族需要复用宿主更新或 TUI 驱动,或 Foundation 发布等价公共入口时,再把通用机制上收 Foundation并删除这里的通用部分。release-skill 只保留发布计划到宿主更新输入的领域映射。
|
|
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.16"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "ba44ad70cebc1cc077887bdf71bf36d78b9073c8aeabd0074aac2eb0d5caffea";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -148166,6 +148166,23 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148166
148166
|
root,
|
|
148167
148167
|
...postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}
|
|
148168
148168
|
});
|
|
148169
|
+
if (result2.status === "DISTRIBUTED") {
|
|
148170
|
+
const {
|
|
148171
|
+
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
148172
|
+
unavailablePostReleaseChecklist: unavailablePostReleaseChecklist2
|
|
148173
|
+
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
148174
|
+
let plan;
|
|
148175
|
+
try {
|
|
148176
|
+
plan = JSON.parse(await readFile57(resolve42(planPath), "utf8"));
|
|
148177
|
+
result2.postRelease = derivePostReleaseChecklist2(plan, {
|
|
148178
|
+
root,
|
|
148179
|
+
runPath: result2.runPath,
|
|
148180
|
+
postVerifyComplete: true
|
|
148181
|
+
});
|
|
148182
|
+
} catch (error) {
|
|
148183
|
+
result2.postRelease = unavailablePostReleaseChecklist2(plan, error);
|
|
148184
|
+
}
|
|
148185
|
+
}
|
|
148169
148186
|
if (hasJson) {
|
|
148170
148187
|
console.log(JSON.stringify(result2, null, 2));
|
|
148171
148188
|
} else {
|
|
@@ -148174,6 +148191,17 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148174
148191
|
console.log(` ${cp4.actionId}: ${cp4.status}`);
|
|
148175
148192
|
}
|
|
148176
148193
|
if (result2.runPath) console.log(`PostVerify run: ${result2.runPath}`);
|
|
148194
|
+
if (result2.postRelease?.status === "UNAVAILABLE") {
|
|
148195
|
+
console.warn(`Post-release checklist unavailable: ${result2.postRelease.diagnostic?.message ?? "unknown error"}`);
|
|
148196
|
+
} else if (result2.postRelease?.localHostUpdate?.promptRequired === true) {
|
|
148197
|
+
const localHostUpdate = result2.postRelease.localHostUpdate;
|
|
148198
|
+
console.log(`Post-release: ask whether to update local host plugins (${localHostUpdate.hosts.join(", ")}).`);
|
|
148199
|
+
if (localHostUpdate.available === true && typeof localHostUpdate.runPath === "string") {
|
|
148200
|
+
console.log(`Post-release command: release-skill post-release --plan ${resolve42(planPath)} --run ${localHostUpdate.runPath}`);
|
|
148201
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
148202
|
+
}
|
|
148203
|
+
printHubManualTargets(localHostUpdate.targets);
|
|
148204
|
+
}
|
|
148177
148205
|
}
|
|
148178
148206
|
await exitAfterFlush(result2.status === "DISTRIBUTED" ? 0 : 1);
|
|
148179
148207
|
} catch (err) {
|
|
@@ -44,6 +44,24 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
"releaseFinish": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"description": "Optional local post-release finish settings. Omitted sourceBranchCheck defaults to remind.",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"properties": {
|
|
52
|
+
"sourceBranchCheck": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"enum": [
|
|
55
|
+
"remind",
|
|
56
|
+
"skip"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"setupSkill": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"pattern": "^[a-z0-9][a-z0-9-]*(?::[a-z0-9][a-z0-9-]*)?$"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
47
65
|
"publicSourceAuthorityReceipt": {
|
|
48
66
|
"type": "object",
|
|
49
67
|
"description": "Optional public source-authority receipt uploaded to one coordinator GitHub Release after all subject npm tarballs are frozen.",
|
|
@@ -70,6 +70,64 @@ node "${CODEBUDDY_PLUGIN_ROOT}/bin/release-skill-local-finish.mjs" \
|
|
|
70
70
|
|
|
71
71
|
完成后报告每个宿主的状态,并提醒用户重启已更新的宿主。本机结果只记录收尾事实,不改变发布状态。
|
|
72
72
|
|
|
73
|
+
## 配置与目录
|
|
74
|
+
|
|
75
|
+
从发布项目目录的 `.release-skill/project.yaml` 读取 `releaseFinish` 和 `project.defaultBranch`。
|
|
76
|
+
文件缺失或无法解析时,报告具体配置问题,不猜默认分支或 setup,也不得把文件缺失当作字段合法缺省;
|
|
77
|
+
已经取得的发布结果仍保留。只有配置文件有效时,整个 `releaseFinish` 或其中字段缺省才按各自合同默认。
|
|
78
|
+
|
|
79
|
+
发布项目目录用于读取配置和执行源码 Git 检查。setup 使用用户明确指定的消费项目目录或已明确的使用
|
|
80
|
+
上下文。只有用户明确把发布源码仓库作为消费项目时,才能在那里执行 setup;同时提供两个目录时不得混用。
|
|
81
|
+
|
|
82
|
+
## 更新后 setup
|
|
83
|
+
|
|
84
|
+
完成现有清单及已授权的宿主处理后,读取发布项目 `.release-skill/project.yaml` 的
|
|
85
|
+
`releaseFinish.setupSkill`。未配置时不增加 setup 提示。配置的技能名只用于匹配入口,不作为 shell 命令执行,
|
|
86
|
+
也不授权安装同名插件。
|
|
87
|
+
|
|
88
|
+
只有本次所选宿主已经成功更新,或现有检查确认它已是目标版本时,才衔接 setup。通过宿主实际技能
|
|
89
|
+
元数据核对目标插件身份、版本和入口;不能从开发仓库、旧会话缓存或同名技能推断新版已加载。当前宿主
|
|
90
|
+
不满足时,可以使用同次更新中另一个已安装并加载目标版本和入口的宿主。
|
|
91
|
+
|
|
92
|
+
目标目录来自用户本次明确指定的消费项目或已明确的使用上下文。目录不明确、宿主需要重启、当前环境
|
|
93
|
+
不能调用可用宿主、入口不存在或归属有歧义时,标为“待执行”,并给出插件与版本、技能名、目标目录和
|
|
94
|
+
已有授权的续接提示。发出提示不代表 setup 已完成。
|
|
95
|
+
|
|
96
|
+
对同一插件版本、同一项目目录和相同共享运行环境,项目级依赖、项目配置和 Git hooks 由一个已加载
|
|
97
|
+
新版插件的宿主检查一次。其余宿主分别核对自身安装、加载和宿主专属配置。不同运行环境不得无条件
|
|
98
|
+
复用项目就绪结论;按目标 setup 的实际合同补查差异。release-finish 不保存去重键、收据或新的状态。
|
|
99
|
+
|
|
100
|
+
调用 setup 前完整读取目标技能及其必读引用,并传入目标项目、插件版本、只读检查意图和已有授权范围。
|
|
101
|
+
已有具体修复授权应传递给 setup;未覆盖的写入不能执行。只读检查、安装结果和配置修复结果分别报告。
|
|
102
|
+
最终自然语言回复列出执行宿主、插件版本、消费项目路径、实际结果和未完成项。任何 setup 结果都不改变
|
|
103
|
+
`VERIFIED`,也不影响其他宿主已经完成的结果。
|
|
104
|
+
|
|
105
|
+
## 源码分支检查
|
|
106
|
+
|
|
107
|
+
宿主更新和 setup 不影响本项检查。读取 `releaseFinish.sourceBranchCheck`;字段或整个
|
|
108
|
+
`releaseFinish` 缺省时按 `remind` 处理。配置为 `skip` 时不运行 Git 命令,只说明项目已关闭
|
|
109
|
+
源码分支检查。
|
|
110
|
+
|
|
111
|
+
`remind` 时,在发布项目目录依次运行两条只读命令:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git branch --show-current
|
|
115
|
+
git status --short --branch
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
第一条命令取得当前分支。第二条命令读取工作区改动和现有上游跟踪摘要;不得增加会写入或访问网络的
|
|
119
|
+
参数。当前分支等于 `project.defaultBranch` 且没有文件改动时,说明本地已位于目标分支;输出含
|
|
120
|
+
ahead 或 behind 等跟踪信息时,仍原样概括。分支不一致时说明两个准确名称,并询问用户是否需要处理。
|
|
121
|
+
第一条命令输出为空时,说明处于 detached HEAD,不猜测目标操作。工作区存在改动时说明不建议直接
|
|
122
|
+
切换或清理。任一命令失败时,报告命令、退出结果和无法完成检查的事实。
|
|
123
|
+
|
|
124
|
+
最终自然语言回复至少列出提醒策略、目标分支、当前分支或无法取得的事实、工作区是否有改动、Git
|
|
125
|
+
上游跟踪摘要,以及是否需要用户决定下一步。没有上游信息时,明确说明命令输出未显示上游信息。
|
|
126
|
+
|
|
127
|
+
本项检查不从宿主更新推导出 Git 写入授权,不自动执行 fetch、switch、checkout、merge、rebase、stash、
|
|
128
|
+
reset、clean 或 push。用户跳过宿主更新仍执行默认分支检查。用户已经明确授权同一仓库、分支和操作时,
|
|
129
|
+
按项目 Git 纪律继续,不重复询问相同授权;检查本身不改变 `VERIFIED`,不保存结果,也不产生新的 run。
|
|
130
|
+
|
|
73
131
|
## 临时归属
|
|
74
132
|
|
|
75
133
|
本能力目前只服务发布后的本机收尾,因此保留在 release-skill。第二个技能族需要复用宿主更新或 TUI 驱动,或 Foundation 发布等价公共入口时,再把通用机制上收 Foundation并删除这里的通用部分。release-skill 只保留发布计划到宿主更新输入的领域映射。
|
|
@@ -1711,6 +1711,23 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
1711
1711
|
root,
|
|
1712
1712
|
...(postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}),
|
|
1713
1713
|
});
|
|
1714
|
+
if (result.status === 'DISTRIBUTED') {
|
|
1715
|
+
const {
|
|
1716
|
+
derivePostReleaseChecklist,
|
|
1717
|
+
unavailablePostReleaseChecklist,
|
|
1718
|
+
} = await import('../src/commands/post-release-local.mjs');
|
|
1719
|
+
let plan;
|
|
1720
|
+
try {
|
|
1721
|
+
plan = JSON.parse(await readFile(resolve(planPath), 'utf8'));
|
|
1722
|
+
result.postRelease = derivePostReleaseChecklist(plan, {
|
|
1723
|
+
root,
|
|
1724
|
+
runPath: result.runPath,
|
|
1725
|
+
postVerifyComplete: true,
|
|
1726
|
+
});
|
|
1727
|
+
} catch (error) {
|
|
1728
|
+
result.postRelease = unavailablePostReleaseChecklist(plan, error);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1714
1731
|
|
|
1715
1732
|
if (hasJson) {
|
|
1716
1733
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1720,6 +1737,17 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
1720
1737
|
console.log(` ${cp.actionId}: ${cp.status}`);
|
|
1721
1738
|
}
|
|
1722
1739
|
if (result.runPath) console.log(`PostVerify run: ${result.runPath}`);
|
|
1740
|
+
if (result.postRelease?.status === 'UNAVAILABLE') {
|
|
1741
|
+
console.warn(`Post-release checklist unavailable: ${result.postRelease.diagnostic?.message ?? 'unknown error'}`);
|
|
1742
|
+
} else if (result.postRelease?.localHostUpdate?.promptRequired === true) {
|
|
1743
|
+
const localHostUpdate = result.postRelease.localHostUpdate;
|
|
1744
|
+
console.log(`Post-release: ask whether to update local host plugins (${localHostUpdate.hosts.join(', ')}).`);
|
|
1745
|
+
if (localHostUpdate.available === true && typeof localHostUpdate.runPath === 'string') {
|
|
1746
|
+
console.log(`Post-release command: release-skill post-release --plan ${resolve(planPath)} --run ${localHostUpdate.runPath}`);
|
|
1747
|
+
console.log('Choose --hosts before adding --update-local-hosts to perform a local update.');
|
|
1748
|
+
}
|
|
1749
|
+
printHubManualTargets(localHostUpdate.targets);
|
|
1750
|
+
}
|
|
1723
1751
|
}
|
|
1724
1752
|
|
|
1725
1753
|
await exitAfterFlush(result.status === 'DISTRIBUTED' ? 0 : 1);
|
|
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.16"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "ba44ad70cebc1cc077887bdf71bf36d78b9073c8aeabd0074aac2eb0d5caffea";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -148166,6 +148166,23 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148166
148166
|
root,
|
|
148167
148167
|
...postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}
|
|
148168
148168
|
});
|
|
148169
|
+
if (result2.status === "DISTRIBUTED") {
|
|
148170
|
+
const {
|
|
148171
|
+
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
148172
|
+
unavailablePostReleaseChecklist: unavailablePostReleaseChecklist2
|
|
148173
|
+
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
148174
|
+
let plan;
|
|
148175
|
+
try {
|
|
148176
|
+
plan = JSON.parse(await readFile57(resolve42(planPath), "utf8"));
|
|
148177
|
+
result2.postRelease = derivePostReleaseChecklist2(plan, {
|
|
148178
|
+
root,
|
|
148179
|
+
runPath: result2.runPath,
|
|
148180
|
+
postVerifyComplete: true
|
|
148181
|
+
});
|
|
148182
|
+
} catch (error) {
|
|
148183
|
+
result2.postRelease = unavailablePostReleaseChecklist2(plan, error);
|
|
148184
|
+
}
|
|
148185
|
+
}
|
|
148169
148186
|
if (hasJson) {
|
|
148170
148187
|
console.log(JSON.stringify(result2, null, 2));
|
|
148171
148188
|
} else {
|
|
@@ -148174,6 +148191,17 @@ This command creates an independent postVerify run and never reads or writes shi
|
|
|
148174
148191
|
console.log(` ${cp4.actionId}: ${cp4.status}`);
|
|
148175
148192
|
}
|
|
148176
148193
|
if (result2.runPath) console.log(`PostVerify run: ${result2.runPath}`);
|
|
148194
|
+
if (result2.postRelease?.status === "UNAVAILABLE") {
|
|
148195
|
+
console.warn(`Post-release checklist unavailable: ${result2.postRelease.diagnostic?.message ?? "unknown error"}`);
|
|
148196
|
+
} else if (result2.postRelease?.localHostUpdate?.promptRequired === true) {
|
|
148197
|
+
const localHostUpdate = result2.postRelease.localHostUpdate;
|
|
148198
|
+
console.log(`Post-release: ask whether to update local host plugins (${localHostUpdate.hosts.join(", ")}).`);
|
|
148199
|
+
if (localHostUpdate.available === true && typeof localHostUpdate.runPath === "string") {
|
|
148200
|
+
console.log(`Post-release command: release-skill post-release --plan ${resolve42(planPath)} --run ${localHostUpdate.runPath}`);
|
|
148201
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
148202
|
+
}
|
|
148203
|
+
printHubManualTargets(localHostUpdate.targets);
|
|
148204
|
+
}
|
|
148177
148205
|
}
|
|
148178
148206
|
await exitAfterFlush(result2.status === "DISTRIBUTED" ? 0 : 1);
|
|
148179
148207
|
} catch (err) {
|
package/package.json
CHANGED
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.16",
|
|
6
6
|
"logicalRoot": "skills-src/",
|
|
7
|
-
"logicalRootDigest": "
|
|
8
|
-
"projectionDigest": "
|
|
9
|
-
"projectionId": "release-skill:platform:0.9.
|
|
7
|
+
"logicalRootDigest": "751140ca01cdd95484041547885e6f07fe9c0c496f6eb62f94710105a9f46e50",
|
|
8
|
+
"projectionDigest": "b62f3e4eca6586d899a328debc515a8cd49bf0cf456ac343539c63fb20b14f3c",
|
|
9
|
+
"projectionId": "release-skill:platform:0.9.16",
|
|
10
10
|
"manifestRequired": true,
|
|
11
11
|
"projectionSources": {
|
|
12
12
|
"skills-src-root": {
|
|
@@ -27,6 +27,10 @@ project:
|
|
|
27
27
|
defaultBranch: <string> # workspace 远端默认分支,必填;不限定为 main
|
|
28
28
|
sourceRepository: <owner/repo> # workspace 源仓库;生产发布必填
|
|
29
29
|
|
|
30
|
+
releaseFinish: # 可选;仅控制本地发布收尾
|
|
31
|
+
sourceBranchCheck: remind # remind(缺省)或 skip
|
|
32
|
+
setupSkill: <plugin:skill> # 可选;已加载目标插件提供的 setup 入口
|
|
33
|
+
|
|
30
34
|
publicSourceAuthorityReceipt: # 可选;把源码坐标与多个 npm tarball 绑定为公开 Release asset
|
|
31
35
|
coordinatorUnitId: <release-unit-id>
|
|
32
36
|
subjectUnitIds: [<release-unit-id>]
|
|
@@ -113,6 +117,18 @@ policy: # 可选,安全策略
|
|
|
113
117
|
```
|
|
114
118
|
|
|
115
119
|
`distributions: []` 表示该发布单元不生成 npm 或插件市场动作,不表示跳过公开发布。
|
|
120
|
+
|
|
121
|
+
### 2.1 本地发布收尾
|
|
122
|
+
|
|
123
|
+
`releaseFinish` 只控制 `release-finish` 的本地收尾,不改写冻结计划、发布状态或宿主范围。
|
|
124
|
+
`sourceBranchCheck` 缺省为 `remind`。该值要求收尾时读取当前分支和工作区摘要;设为 `skip`
|
|
125
|
+
时关闭这项提醒。`setupSkill` 可省略;填写时必须是技能入口名,例如 `release-setup` 或
|
|
126
|
+
`skill-family-docs:skill-family-docs-setup`。它只用于匹配已安装并加载的目标插件入口,不能作为
|
|
127
|
+
shell 命令执行。
|
|
128
|
+
|
|
129
|
+
`releaseFinish` 保持闭合。未知字段、`sourceBranchCheck` 的其他值,以及空值、路径、带参数或
|
|
130
|
+
shell 语法的 `setupSkill` 都是配置错误。两个字段彼此独立:关闭分支提醒不会关闭已配置的 setup。
|
|
131
|
+
|
|
116
132
|
生产模式的 `prepare` 仍会冻结 GitHub 快照,并生成 `push-snapshot`、`create-tag` 和
|
|
117
133
|
`github-release`。该单元的 `postPublish` 声明保持独立生效,其中 phase 为
|
|
118
134
|
`postVerify` 的 hook 也不受影响。因此纯插件可以先验证公开 GitHub Release,再向中央
|
|
@@ -44,6 +44,24 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
"releaseFinish": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"description": "Optional local post-release finish settings. Omitted sourceBranchCheck defaults to remind.",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"properties": {
|
|
52
|
+
"sourceBranchCheck": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"enum": [
|
|
55
|
+
"remind",
|
|
56
|
+
"skip"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"setupSkill": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"pattern": "^[a-z0-9][a-z0-9-]*(?::[a-z0-9][a-z0-9-]*)?$"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
47
65
|
"publicSourceAuthorityReceipt": {
|
|
48
66
|
"type": "object",
|
|
49
67
|
"description": "Optional public source-authority receipt uploaded to one coordinator GitHub Release after all subject npm tarballs are frozen.",
|
|
@@ -70,6 +70,64 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill-local-finish.mjs" \
|
|
|
70
70
|
|
|
71
71
|
完成后报告每个宿主的状态,并提醒用户重启已更新的宿主。本机结果只记录收尾事实,不改变发布状态。
|
|
72
72
|
|
|
73
|
+
## 配置与目录
|
|
74
|
+
|
|
75
|
+
从发布项目目录的 `.release-skill/project.yaml` 读取 `releaseFinish` 和 `project.defaultBranch`。
|
|
76
|
+
文件缺失或无法解析时,报告具体配置问题,不猜默认分支或 setup,也不得把文件缺失当作字段合法缺省;
|
|
77
|
+
已经取得的发布结果仍保留。只有配置文件有效时,整个 `releaseFinish` 或其中字段缺省才按各自合同默认。
|
|
78
|
+
|
|
79
|
+
发布项目目录用于读取配置和执行源码 Git 检查。setup 使用用户明确指定的消费项目目录或已明确的使用
|
|
80
|
+
上下文。只有用户明确把发布源码仓库作为消费项目时,才能在那里执行 setup;同时提供两个目录时不得混用。
|
|
81
|
+
|
|
82
|
+
## 更新后 setup
|
|
83
|
+
|
|
84
|
+
完成现有清单及已授权的宿主处理后,读取发布项目 `.release-skill/project.yaml` 的
|
|
85
|
+
`releaseFinish.setupSkill`。未配置时不增加 setup 提示。配置的技能名只用于匹配入口,不作为 shell 命令执行,
|
|
86
|
+
也不授权安装同名插件。
|
|
87
|
+
|
|
88
|
+
只有本次所选宿主已经成功更新,或现有检查确认它已是目标版本时,才衔接 setup。通过宿主实际技能
|
|
89
|
+
元数据核对目标插件身份、版本和入口;不能从开发仓库、旧会话缓存或同名技能推断新版已加载。当前宿主
|
|
90
|
+
不满足时,可以使用同次更新中另一个已安装并加载目标版本和入口的宿主。
|
|
91
|
+
|
|
92
|
+
目标目录来自用户本次明确指定的消费项目或已明确的使用上下文。目录不明确、宿主需要重启、当前环境
|
|
93
|
+
不能调用可用宿主、入口不存在或归属有歧义时,标为“待执行”,并给出插件与版本、技能名、目标目录和
|
|
94
|
+
已有授权的续接提示。发出提示不代表 setup 已完成。
|
|
95
|
+
|
|
96
|
+
对同一插件版本、同一项目目录和相同共享运行环境,项目级依赖、项目配置和 Git hooks 由一个已加载
|
|
97
|
+
新版插件的宿主检查一次。其余宿主分别核对自身安装、加载和宿主专属配置。不同运行环境不得无条件
|
|
98
|
+
复用项目就绪结论;按目标 setup 的实际合同补查差异。release-finish 不保存去重键、收据或新的状态。
|
|
99
|
+
|
|
100
|
+
调用 setup 前完整读取目标技能及其必读引用,并传入目标项目、插件版本、只读检查意图和已有授权范围。
|
|
101
|
+
已有具体修复授权应传递给 setup;未覆盖的写入不能执行。只读检查、安装结果和配置修复结果分别报告。
|
|
102
|
+
最终自然语言回复列出执行宿主、插件版本、消费项目路径、实际结果和未完成项。任何 setup 结果都不改变
|
|
103
|
+
`VERIFIED`,也不影响其他宿主已经完成的结果。
|
|
104
|
+
|
|
105
|
+
## 源码分支检查
|
|
106
|
+
|
|
107
|
+
宿主更新和 setup 不影响本项检查。读取 `releaseFinish.sourceBranchCheck`;字段或整个
|
|
108
|
+
`releaseFinish` 缺省时按 `remind` 处理。配置为 `skip` 时不运行 Git 命令,只说明项目已关闭
|
|
109
|
+
源码分支检查。
|
|
110
|
+
|
|
111
|
+
`remind` 时,在发布项目目录依次运行两条只读命令:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git branch --show-current
|
|
115
|
+
git status --short --branch
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
第一条命令取得当前分支。第二条命令读取工作区改动和现有上游跟踪摘要;不得增加会写入或访问网络的
|
|
119
|
+
参数。当前分支等于 `project.defaultBranch` 且没有文件改动时,说明本地已位于目标分支;输出含
|
|
120
|
+
ahead 或 behind 等跟踪信息时,仍原样概括。分支不一致时说明两个准确名称,并询问用户是否需要处理。
|
|
121
|
+
第一条命令输出为空时,说明处于 detached HEAD,不猜测目标操作。工作区存在改动时说明不建议直接
|
|
122
|
+
切换或清理。任一命令失败时,报告命令、退出结果和无法完成检查的事实。
|
|
123
|
+
|
|
124
|
+
最终自然语言回复至少列出提醒策略、目标分支、当前分支或无法取得的事实、工作区是否有改动、Git
|
|
125
|
+
上游跟踪摘要,以及是否需要用户决定下一步。没有上游信息时,明确说明命令输出未显示上游信息。
|
|
126
|
+
|
|
127
|
+
本项检查不从宿主更新推导出 Git 写入授权,不自动执行 fetch、switch、checkout、merge、rebase、stash、
|
|
128
|
+
reset、clean 或 push。用户跳过宿主更新仍执行默认分支检查。用户已经明确授权同一仓库、分支和操作时,
|
|
129
|
+
按项目 Git 纪律继续,不重复询问相同授权;检查本身不改变 `VERIFIED`,不保存结果,也不产生新的 run。
|
|
130
|
+
|
|
73
131
|
## 临时归属
|
|
74
132
|
|
|
75
133
|
本能力目前只服务发布后的本机收尾,因此保留在 release-skill。第二个技能族需要复用宿主更新或 TUI 驱动,或 Foundation 发布等价公共入口时,再把通用机制上收 Foundation并删除这里的通用部分。release-skill 只保留发布计划到宿主更新输入的领域映射。
|