release-skill 0.7.5 → 0.7.6
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/marketplace.json +1 -1
- 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 +17 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +18 -10
- package/README.zh-CN.md +13 -7
- package/SECURITY.md +12 -6
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +6 -5
- package/adapters/claude/skills/release-prepare/SKILL.md +1 -1
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +6 -5
- package/adapters/codex/skills/release-assess/SKILL.md +1 -1
- package/adapters/codex/skills/release-config/SKILL.md +1 -1
- package/adapters/codex/skills/release-docs/SKILL.md +1 -1
- package/adapters/codex/skills/release-help/SKILL.md +1 -1
- package/adapters/codex/skills/release-marketplace/SKILL.md +1 -1
- package/adapters/codex/skills/release-prepare/SKILL.md +2 -2
- package/adapters/codex/skills/release-publish/SKILL.md +1 -1
- package/adapters/codex/skills/release-reconcile/SKILL.md +1 -1
- package/adapters/codex/skills/release-setup/SKILL.md +1 -1
- package/adapters/codex/skills/release-verify/SKILL.md +1 -1
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +6 -5
- package/adapters/kimi/skills/release-prepare/SKILL.md +1 -1
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +6 -5
- package/adapters/workbuddy/skills/release-prepare/SKILL.md +1 -1
- package/bin/release-skill.bundle.mjs +6 -5
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/references/.render-manifest.json +4 -4
- package/references/02-project-config.md +55 -29
- package/skills/release-prepare/SKILL.md +1 -1
- package/skills-src/release-prepare/SKILL.md +1 -1
- package/src/commands/prepare.mjs +4 -3
- package/src/producers/build-adapters.mjs +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-skill",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "广州市风荷科技有限公司"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"defaultPrompt": [
|
|
21
21
|
"Assess this project for release readiness.",
|
|
22
|
-
"Prepare a release plan for version 0.7.
|
|
22
|
+
"Prepare a release plan for version 0.7.6.",
|
|
23
23
|
"Help me understand the release workflow."
|
|
24
24
|
]
|
|
25
25
|
}
|
package/.kimi-plugin/plugin.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
<!-- release-skill:changelog:start version=0.7.6 locale=en baseline=sha256:16665362b8c0f06b7ed94f2839f5b380216b13ca6ab5e6c51b043985f8a8c8c2 -->
|
|
4
|
+
## [0.7.6] - 2026-08-22
|
|
5
|
+
|
|
6
|
+
v0.7.6 executes every schema-declared prepare hook and corrects the documented postPublish hierarchy while preserving the current hook authorization and Codex adapter-root semantics.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- **Codex adapter contract coverage**: isolated-copy and negative path tests now preserve the existing self-contained adapter root: the host-provided skill path matches `PLUGIN_ROOT/skills/<skill>/SKILL.md`, and the launcher remains `PLUGIN_ROOT/bin/release-skill.mjs`. This is contract hardening, not a runtime protocol change.
|
|
11
|
+
- **Hook authorization remains unchanged**: configuring a hook and invoking its workflow authorizes execution without a separate confirmation point. The legacy acknowledgement flags remain no-effect compatibility inputs; v0.7.6 does not restore a pre-execution confirmation gate.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **Prepare lint hook**: `lint` now runs before `docs`, `build`, `test`, and `typecheck`; a non-zero lint result stops prepare with `GATE_FAILED`. A schema-to-execution-table contract prevents accepted hook keys from becoming silent dead configuration.
|
|
16
|
+
- **postPublish documentation**: the project configuration standard now places `postPublish` inside each `releaseUnits[]` item and carries a schema-validated example.
|
|
17
|
+
<!-- release-skill:changelog:end version=0.7.6 locale=en -->
|
|
18
|
+
|
|
19
|
+
|
|
3
20
|
<!-- release-skill:changelog:start version=0.7.5 locale=en baseline=sha256:39f8f00f21c9071341106ea4becf4e8d10a732bd01b430e244dc4e3c5bf07da2 -->
|
|
4
21
|
## [0.7.5] - 2026-08-22
|
|
5
22
|
|
package/INSTALL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[简体中文](INSTALL.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
<!-- release-skill:release-version: 0.7.
|
|
5
|
+
<!-- release-skill:release-version: 0.7.6 -->
|
|
6
6
|
## Prerequisites
|
|
7
7
|
|
|
8
8
|
- Node.js 22.0.0 or later
|
|
@@ -114,7 +114,7 @@ tag pinned to the exact version (never the bare repository URL, which installs
|
|
|
114
114
|
the latest release or default branch), confirm the trust prompt, then reload:
|
|
115
115
|
|
|
116
116
|
```
|
|
117
|
-
/plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.7.
|
|
117
|
+
/plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.7.6
|
|
118
118
|
/plugins reload
|
|
119
119
|
```
|
|
120
120
|
|
package/INSTALL.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[English](INSTALL.md)
|
|
4
4
|
|
|
5
|
-
<!-- release-skill:release-version: 0.7.
|
|
5
|
+
<!-- release-skill:release-version: 0.7.6 -->
|
|
6
6
|
## 前置条件
|
|
7
7
|
|
|
8
8
|
- Node.js 22.0.0 或更高版本
|
|
@@ -104,7 +104,7 @@ Kimi Code 有交互式插件市场,但**没有可脚本化的非交互安装
|
|
|
104
104
|
(切勿使用裸仓库地址,它会安装最新 release 或默认分支),确认信任提示后重新加载:
|
|
105
105
|
|
|
106
106
|
```
|
|
107
|
-
/plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.7.
|
|
107
|
+
/plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.7.6
|
|
108
108
|
/plugins reload
|
|
109
109
|
```
|
|
110
110
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[简体中文](README.zh-CN.md) · Installation: [English](INSTALL.md) / [简体中文](INSTALL.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
<!-- release-skill:release-version: 0.7.
|
|
5
|
+
<!-- release-skill:release-version: 0.7.6 -->
|
|
6
6
|
Release preparation for Claude Code, CodeBuddy, WorkBuddy, Codex, and Kimi Code, with human-edited files kept intact.
|
|
7
7
|
|
|
8
8
|
release-skill helps a maintainer answer three questions: what will be released,
|
|
@@ -14,17 +14,23 @@ Setup surfaces only the deterministic `compactSummary` review view; the full
|
|
|
14
14
|
report stays in a temporary session directory.
|
|
15
15
|
|
|
16
16
|
<!-- release-skill:managed:start id=latest-release -->
|
|
17
|
-
**0.7.
|
|
17
|
+
**0.7.6** (2026-08-22)
|
|
18
18
|
|
|
19
|
-
v0.7.
|
|
19
|
+
v0.7.6 executes every schema-declared prepare hook and corrects the documented postPublish hierarchy while preserving the current hook authorization and Codex adapter-root semantics.
|
|
20
|
+
|
|
21
|
+
**Changed**
|
|
22
|
+
|
|
23
|
+
- **Codex adapter contract coverage**: isolated-copy and negative path tests now preserve the existing self-contained adapter root: the host-provided skill path matches `PLUGIN_ROOT/skills/<skill>/SKILL.md`, and the launcher remains `PLUGIN_ROOT/bin/release-skill.mjs`. This is contract hardening, not a runtime protocol change.
|
|
24
|
+
- **Hook authorization remains unchanged**: configuring a hook and invoking its workflow authorizes execution without a separate confirmation point. The legacy acknowledgement flags remain no-effect compatibility inputs; v0.7.6 does not restore a pre-execution confirmation gate.
|
|
20
25
|
|
|
21
26
|
**Fixed**
|
|
22
27
|
|
|
23
|
-
- **
|
|
28
|
+
- **Prepare lint hook**: `lint` now runs before `docs`, `build`, `test`, and `typecheck`; a non-zero lint result stops prepare with `GATE_FAILED`. A schema-to-execution-table contract prevents accepted hook keys from becoming silent dead configuration.
|
|
29
|
+
- **postPublish documentation**: the project configuration standard now places `postPublish` inside each `releaseUnits[]` item and carries a schema-validated example.
|
|
24
30
|
<!-- release-skill:managed:end id=latest-release -->
|
|
25
31
|
|
|
26
32
|
<!-- release-skill:capability:external-write-boundary -->
|
|
27
|
-
> **Current boundary:** v0.7.
|
|
33
|
+
> **Current boundary:** v0.7.6 is the current source candidate; v0.7.5 remains
|
|
28
34
|
> the latest published release. v0.4.1 was an earlier published milestone;
|
|
29
35
|
> v0.2.2 previously held published status before the platform verification
|
|
30
36
|
> convergence fix was added.
|
|
@@ -44,8 +50,8 @@ v0.7.5 recognizes registered platform projections that publish a single `skill/`
|
|
|
44
50
|
> publish global preflight.
|
|
45
51
|
|
|
46
52
|
<!-- release-skill:capability:safe-first-command -->
|
|
47
|
-
> **Production path verified since the v0.1.1 milestone; v0.7.
|
|
48
|
-
> source candidate and v0.7.
|
|
53
|
+
> **Production path verified since the v0.1.1 milestone; v0.7.6 is the current
|
|
54
|
+
> source candidate and v0.7.5 is the latest published release.** The npm-installed CLI is the supported user entry. Source checkout
|
|
49
55
|
> is the development/contributor fallback.
|
|
50
56
|
>
|
|
51
57
|
> **Start here:**
|
|
@@ -528,9 +534,11 @@ hooks:
|
|
|
528
534
|
envAllowlist: []
|
|
529
535
|
```
|
|
530
536
|
|
|
531
|
-
Hooks run when `prepare` is invoked
|
|
532
|
-
execution
|
|
533
|
-
|
|
537
|
+
Hooks run when `prepare` is invoked. Configuring the command and invoking the
|
|
538
|
+
workflow authorizes execution without an extra confirmation point. The legacy
|
|
539
|
+
`--acknowledge-hook-side-effects` and `--acknowledge-gate-side-effects` flags
|
|
540
|
+
remain accepted as no-effect compatibility inputs. Gates are the controlled
|
|
541
|
+
extension point for release calibration (see `references/02-project-config.md`).
|
|
534
542
|
|
|
535
543
|
### postPublish hooks
|
|
536
544
|
|
package/README.zh-CN.md
CHANGED
|
@@ -2,23 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
|
|
4
4
|
|
|
5
|
-
<!-- release-skill:release-version: 0.7.
|
|
5
|
+
<!-- release-skill:release-version: 0.7.6 -->
|
|
6
6
|
面向 Claude Code、CodeBuddy、WorkBuddy、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
|
|
7
7
|
|
|
8
8
|
release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终发布的内容是什么。它不重新生成、也不回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节——先冻结并供人工审阅,再从同一份冻结产物发布。`setup` 只显示确定性的 `compactSummary` 审阅视图,完整报告保留在临时会话目录中。
|
|
9
9
|
|
|
10
10
|
<!-- release-skill:managed:start id=latest-release -->
|
|
11
|
-
**0.7.
|
|
11
|
+
**0.7.6** (2026-08-22)
|
|
12
12
|
|
|
13
|
-
v0.7.
|
|
13
|
+
v0.7.6 执行 schema 接受的全部 prepare hook,修正 postPublish 的文档层级,并保持现行 hook 授权与 Codex 适配器根目录语义不变。
|
|
14
|
+
|
|
15
|
+
**变更**
|
|
16
|
+
|
|
17
|
+
- **Codex 适配器契约覆盖**:新增复制隔离与路径负例测试,锁定既有的自包含适配器根目录语义:宿主提供的技能路径匹配 `PLUGIN_ROOT/skills/<skill>/SKILL.md`,入口仍为 `PLUGIN_ROOT/bin/release-skill.mjs`。这只是加强契约测试,不是运行时协议变更。
|
|
18
|
+
- **hook 授权语义保持不变**:配置 hook 并调用对应工作流即授权执行,不增加独立确认点。旧确认参数仍是无效果的兼容输入;v0.7.6 不恢复执行前确认门。
|
|
14
19
|
|
|
15
20
|
**修复**
|
|
16
21
|
|
|
17
|
-
-
|
|
22
|
+
- **prepare lint hook**:`lint` 现在先于 `docs`、`build`、`test` 和 `typecheck` 执行;lint 返回非零退出码时,prepare 以 `GATE_FAILED` 停止。schema 与执行表之间新增覆盖契约,避免合法配置再次变成静默失效的死键。
|
|
23
|
+
- **postPublish 文档**:项目配置标准现在把 `postPublish` 放在各个 `releaseUnits[]` 条目内,并提供经过 schema 校验的完整样例。
|
|
18
24
|
<!-- release-skill:managed:end id=latest-release -->
|
|
19
25
|
|
|
20
26
|
<!-- release-skill:capability:external-write-boundary -->
|
|
21
|
-
> **当前边界:** v0.7.
|
|
27
|
+
> **当前边界:** v0.7.6 是当前源码候选,v0.7.5 是最新已发布版本。v0.4.1 是更早的已发布里程碑(v0.2.2 曾处于已发布状态,后因平台验证收敛修复而更新)。
|
|
22
28
|
> v0.1.1 已完成 GitHub 与 npm 的
|
|
23
29
|
> 真实生产发布,是首次生产验证的历史里程碑,并从冻结 Git ref 完成精确 npm
|
|
24
30
|
> 安装及 Claude/Codex 消费者安装验证;"当前发布版本"与"首次生产验证里程碑"
|
|
@@ -31,7 +37,7 @@ v0.7.5 能识别只发布一个 `skill/` 入口的平台注册投影,消除了
|
|
|
31
37
|
> 远端唯一性检查在 `publish` 全局预检执行。
|
|
32
38
|
|
|
33
39
|
<!-- release-skill:capability:safe-first-command -->
|
|
34
|
-
> **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.7.
|
|
40
|
+
> **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.7.6 是当前源码候选,v0.7.5 是最新已发布版本。**
|
|
35
41
|
> npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
|
|
36
42
|
>
|
|
37
43
|
> **第一条命令:**
|
|
@@ -474,7 +480,7 @@ hooks:
|
|
|
474
480
|
envAllowlist: []
|
|
475
481
|
```
|
|
476
482
|
|
|
477
|
-
hook 在 `prepare`
|
|
483
|
+
hook 在 `prepare` 调用时运行;配置命令并调用工作流即授权执行,不再增加触发前确认点。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 只作为无效果的兼容输入保留。gate 是发布校准的受控扩展点(见 `references/02-project-config.md`)。
|
|
478
484
|
|
|
479
485
|
### postPublish hook
|
|
480
486
|
|
package/SECURITY.md
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
| ------- | --------- |
|
|
7
|
-
| 0.
|
|
7
|
+
| 0.7.x | Yes |
|
|
8
|
+
| 0.6.x and earlier | No |
|
|
8
9
|
|
|
9
10
|
## Reporting a Vulnerability
|
|
10
11
|
|
|
@@ -30,12 +31,17 @@ release-skill is designed with the following security guarantees:
|
|
|
30
31
|
|
|
31
32
|
- **No automatic external writes**: The `prepare` phase never pushes,
|
|
32
33
|
creates releases, or publishes packages itself. User-configured hooks
|
|
33
|
-
may produce arbitrary side effects
|
|
34
|
-
|
|
34
|
+
and gates may produce arbitrary side effects. Configuring a command and
|
|
35
|
+
invoking the workflow authorizes its execution without an extra confirmation
|
|
36
|
+
point. The legacy `--acknowledge-hook-side-effects` and
|
|
37
|
+
`--acknowledge-gate-side-effects` flags remain accepted only as no-effect
|
|
38
|
+
compatibility inputs.
|
|
35
39
|
- **Approval-gated publishing**: The `publish` phase requires an explicit,
|
|
36
|
-
non-expired approval record bound to
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
non-expired approval record bound to an immutable plan v2, its frozen
|
|
41
|
+
artifact, release action, and target version. Approval expires after 24
|
|
42
|
+
hours. Workspace tree or hash drift is retained as audit evidence rather
|
|
43
|
+
than an approval binding, while a remote conflict blocks publish preflight
|
|
44
|
+
instead of changing the approval record.
|
|
39
45
|
- **Checkpoint-based execution**: Every external write is a checkpoint.
|
|
40
46
|
Failure stops subsequent actions and enters a `PARTIAL` state. The system
|
|
41
47
|
never auto-deletes remote tags, overwrites releases, unpublishes npm
|
|
@@ -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.7.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "898adf636ceb9d435fd52c9d6f95d0c1bd041f2bdc3b0347902ac5086460c986";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -97994,6 +97994,7 @@ var init_refresh_service = __esm({
|
|
|
97994
97994
|
// src/commands/prepare.mjs
|
|
97995
97995
|
var prepare_exports = {};
|
|
97996
97996
|
__export(prepare_exports, {
|
|
97997
|
+
HOOK_EXECUTION_ORDER: () => HOOK_EXECUTION_ORDER,
|
|
97997
97998
|
HOOK_OUTPUT_TAIL_MAX_BYTES: () => HOOK_OUTPUT_TAIL_MAX_BYTES,
|
|
97998
97999
|
HOOK_OUTPUT_TAIL_MAX_LINES: () => HOOK_OUTPUT_TAIL_MAX_LINES,
|
|
97999
98000
|
boundedOutputTail: () => boundedOutputTail,
|
|
@@ -98105,11 +98106,10 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
98105
98106
|
return resolvedVersions;
|
|
98106
98107
|
}
|
|
98107
98108
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
98108
|
-
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
98109
98109
|
const hooks = config.hooks ?? {};
|
|
98110
98110
|
const cacheEnabled = options.hookCache !== false;
|
|
98111
98111
|
const records = [];
|
|
98112
|
-
for (const name of
|
|
98112
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
98113
98113
|
const hook = hooks[name];
|
|
98114
98114
|
if (!hook) continue;
|
|
98115
98115
|
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
@@ -100803,7 +100803,7 @@ async function prepareRelease(options) {
|
|
|
100803
100803
|
await lock.release();
|
|
100804
100804
|
}
|
|
100805
100805
|
}
|
|
100806
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100806
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100807
100807
|
var init_prepare = __esm({
|
|
100808
100808
|
async "src/commands/prepare.mjs"() {
|
|
100809
100809
|
init_src2();
|
|
@@ -100843,6 +100843,7 @@ var init_prepare = __esm({
|
|
|
100843
100843
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
100844
100844
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
100845
100845
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
100846
|
+
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
100846
100847
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
100847
100848
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
100848
100849
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -13,7 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
13
13
|
|
|
14
14
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
15
15
|
|
|
16
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
16
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
17
17
|
|
|
18
18
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
19
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-skill",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "广州市风荷科技有限公司"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"defaultPrompt": [
|
|
21
21
|
"Assess this project for release readiness.",
|
|
22
|
-
"Prepare a release plan for version 0.7.
|
|
22
|
+
"Prepare a release plan for version 0.7.6.",
|
|
23
23
|
"Help me understand the release workflow."
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -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.7.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "898adf636ceb9d435fd52c9d6f95d0c1bd041f2bdc3b0347902ac5086460c986";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -97994,6 +97994,7 @@ var init_refresh_service = __esm({
|
|
|
97994
97994
|
// src/commands/prepare.mjs
|
|
97995
97995
|
var prepare_exports = {};
|
|
97996
97996
|
__export(prepare_exports, {
|
|
97997
|
+
HOOK_EXECUTION_ORDER: () => HOOK_EXECUTION_ORDER,
|
|
97997
97998
|
HOOK_OUTPUT_TAIL_MAX_BYTES: () => HOOK_OUTPUT_TAIL_MAX_BYTES,
|
|
97998
97999
|
HOOK_OUTPUT_TAIL_MAX_LINES: () => HOOK_OUTPUT_TAIL_MAX_LINES,
|
|
97999
98000
|
boundedOutputTail: () => boundedOutputTail,
|
|
@@ -98105,11 +98106,10 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
98105
98106
|
return resolvedVersions;
|
|
98106
98107
|
}
|
|
98107
98108
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
98108
|
-
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
98109
98109
|
const hooks = config.hooks ?? {};
|
|
98110
98110
|
const cacheEnabled = options.hookCache !== false;
|
|
98111
98111
|
const records = [];
|
|
98112
|
-
for (const name of
|
|
98112
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
98113
98113
|
const hook = hooks[name];
|
|
98114
98114
|
if (!hook) continue;
|
|
98115
98115
|
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
@@ -100803,7 +100803,7 @@ async function prepareRelease(options) {
|
|
|
100803
100803
|
await lock.release();
|
|
100804
100804
|
}
|
|
100805
100805
|
}
|
|
100806
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100806
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100807
100807
|
var init_prepare = __esm({
|
|
100808
100808
|
async "src/commands/prepare.mjs"() {
|
|
100809
100809
|
init_src2();
|
|
@@ -100843,6 +100843,7 @@ var init_prepare = __esm({
|
|
|
100843
100843
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
100844
100844
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
100845
100845
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
100846
|
+
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
100846
100847
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
100847
100848
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
100848
100849
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -5,7 +5,7 @@ description: Identify project topology and evaluate gaps in public documentation
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: "Config-only workflow profile: route confirms config-only diff, ass
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: "Docs-only workflow profile: route confirms docs-only diff, style-g
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: "Marketplace-only workflow profile: route confirms marketplace-only
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -20,7 +20,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
20
20
|
|
|
21
21
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
22
22
|
|
|
23
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
23
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
24
24
|
|
|
25
25
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
26
26
|
|
|
@@ -5,7 +5,7 @@ description: "从已批准的生产计划发布冻结 Git branch/tag、npm tarba
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: Query remote actual state, handle partial publish successes, safe r
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: "首次接入 release-skill:只读发现发布单元与个性化
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -5,7 +5,7 @@ description: Post-publish verification including remote state recheck, exact npm
|
|
|
5
5
|
|
|
6
6
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 `SKILL.md` 的实际绝对路径,并将该字面量记为 `SKILL_FILE`。
|
|
7
7
|
> `SKILL_FILE` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。
|
|
8
|
-
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md
|
|
8
|
+
> 对 `SKILL_FILE` 执行 `realpath`,取其目录向上两级得到 `PLUGIN_ROOT`;校验真实技能路径匹配 `PLUGIN_ROOT/skills/*/SKILL.md` 且仍位于插件根内(路径包含检查)。
|
|
9
9
|
> 令 `RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs`,对入口执行 `realpath` containment、`lstat` 非符号链接且为普通文件校验。
|
|
10
10
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 `RELEASE_SKILL_ENTRY`,然后执行 `node "$RELEASE_SKILL_ENTRY" ...`;不得依赖前一次 shell 的变量。
|
|
11
11
|
>
|
|
@@ -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.7.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "898adf636ceb9d435fd52c9d6f95d0c1bd041f2bdc3b0347902ac5086460c986";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -97994,6 +97994,7 @@ var init_refresh_service = __esm({
|
|
|
97994
97994
|
// src/commands/prepare.mjs
|
|
97995
97995
|
var prepare_exports = {};
|
|
97996
97996
|
__export(prepare_exports, {
|
|
97997
|
+
HOOK_EXECUTION_ORDER: () => HOOK_EXECUTION_ORDER,
|
|
97997
97998
|
HOOK_OUTPUT_TAIL_MAX_BYTES: () => HOOK_OUTPUT_TAIL_MAX_BYTES,
|
|
97998
97999
|
HOOK_OUTPUT_TAIL_MAX_LINES: () => HOOK_OUTPUT_TAIL_MAX_LINES,
|
|
97999
98000
|
boundedOutputTail: () => boundedOutputTail,
|
|
@@ -98105,11 +98106,10 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
98105
98106
|
return resolvedVersions;
|
|
98106
98107
|
}
|
|
98107
98108
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
98108
|
-
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
98109
98109
|
const hooks = config.hooks ?? {};
|
|
98110
98110
|
const cacheEnabled = options.hookCache !== false;
|
|
98111
98111
|
const records = [];
|
|
98112
|
-
for (const name of
|
|
98112
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
98113
98113
|
const hook = hooks[name];
|
|
98114
98114
|
if (!hook) continue;
|
|
98115
98115
|
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
@@ -100803,7 +100803,7 @@ async function prepareRelease(options) {
|
|
|
100803
100803
|
await lock.release();
|
|
100804
100804
|
}
|
|
100805
100805
|
}
|
|
100806
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100806
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100807
100807
|
var init_prepare = __esm({
|
|
100808
100808
|
async "src/commands/prepare.mjs"() {
|
|
100809
100809
|
init_src2();
|
|
@@ -100843,6 +100843,7 @@ var init_prepare = __esm({
|
|
|
100843
100843
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
100844
100844
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
100845
100845
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
100846
|
+
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
100846
100847
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
100847
100848
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
100848
100849
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -20,7 +20,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
20
20
|
|
|
21
21
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
22
22
|
|
|
23
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
23
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
24
24
|
|
|
25
25
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
26
26
|
|
|
@@ -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.7.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "898adf636ceb9d435fd52c9d6f95d0c1bd041f2bdc3b0347902ac5086460c986";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -97994,6 +97994,7 @@ var init_refresh_service = __esm({
|
|
|
97994
97994
|
// src/commands/prepare.mjs
|
|
97995
97995
|
var prepare_exports = {};
|
|
97996
97996
|
__export(prepare_exports, {
|
|
97997
|
+
HOOK_EXECUTION_ORDER: () => HOOK_EXECUTION_ORDER,
|
|
97997
97998
|
HOOK_OUTPUT_TAIL_MAX_BYTES: () => HOOK_OUTPUT_TAIL_MAX_BYTES,
|
|
97998
97999
|
HOOK_OUTPUT_TAIL_MAX_LINES: () => HOOK_OUTPUT_TAIL_MAX_LINES,
|
|
97999
98000
|
boundedOutputTail: () => boundedOutputTail,
|
|
@@ -98105,11 +98106,10 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
98105
98106
|
return resolvedVersions;
|
|
98106
98107
|
}
|
|
98107
98108
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
98108
|
-
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
98109
98109
|
const hooks = config.hooks ?? {};
|
|
98110
98110
|
const cacheEnabled = options.hookCache !== false;
|
|
98111
98111
|
const records = [];
|
|
98112
|
-
for (const name of
|
|
98112
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
98113
98113
|
const hook = hooks[name];
|
|
98114
98114
|
if (!hook) continue;
|
|
98115
98115
|
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
@@ -100803,7 +100803,7 @@ async function prepareRelease(options) {
|
|
|
100803
100803
|
await lock.release();
|
|
100804
100804
|
}
|
|
100805
100805
|
}
|
|
100806
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100806
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100807
100807
|
var init_prepare = __esm({
|
|
100808
100808
|
async "src/commands/prepare.mjs"() {
|
|
100809
100809
|
init_src2();
|
|
@@ -100843,6 +100843,7 @@ var init_prepare = __esm({
|
|
|
100843
100843
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
100844
100844
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
100845
100845
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
100846
|
+
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
100846
100847
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
100847
100848
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
100848
100849
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -13,7 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
13
13
|
|
|
14
14
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
15
15
|
|
|
16
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
16
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
17
17
|
|
|
18
18
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
19
19
|
|
|
@@ -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.7.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "898adf636ceb9d435fd52c9d6f95d0c1bd041f2bdc3b0347902ac5086460c986";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -97994,6 +97994,7 @@ var init_refresh_service = __esm({
|
|
|
97994
97994
|
// src/commands/prepare.mjs
|
|
97995
97995
|
var prepare_exports = {};
|
|
97996
97996
|
__export(prepare_exports, {
|
|
97997
|
+
HOOK_EXECUTION_ORDER: () => HOOK_EXECUTION_ORDER,
|
|
97997
97998
|
HOOK_OUTPUT_TAIL_MAX_BYTES: () => HOOK_OUTPUT_TAIL_MAX_BYTES,
|
|
97998
97999
|
HOOK_OUTPUT_TAIL_MAX_LINES: () => HOOK_OUTPUT_TAIL_MAX_LINES,
|
|
97999
98000
|
boundedOutputTail: () => boundedOutputTail,
|
|
@@ -98105,11 +98106,10 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
98105
98106
|
return resolvedVersions;
|
|
98106
98107
|
}
|
|
98107
98108
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
98108
|
-
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
98109
98109
|
const hooks = config.hooks ?? {};
|
|
98110
98110
|
const cacheEnabled = options.hookCache !== false;
|
|
98111
98111
|
const records = [];
|
|
98112
|
-
for (const name of
|
|
98112
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
98113
98113
|
const hook = hooks[name];
|
|
98114
98114
|
if (!hook) continue;
|
|
98115
98115
|
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
@@ -100803,7 +100803,7 @@ async function prepareRelease(options) {
|
|
|
100803
100803
|
await lock.release();
|
|
100804
100804
|
}
|
|
100805
100805
|
}
|
|
100806
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100806
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
100807
100807
|
var init_prepare = __esm({
|
|
100808
100808
|
async "src/commands/prepare.mjs"() {
|
|
100809
100809
|
init_src2();
|
|
@@ -100843,6 +100843,7 @@ var init_prepare = __esm({
|
|
|
100843
100843
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
100844
100844
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
100845
100845
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
100846
|
+
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
100846
100847
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
100847
100848
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
100848
100849
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
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.7.
|
|
5
|
+
"version": "0.7.6",
|
|
6
6
|
"logicalRoot": "skills-src/",
|
|
7
|
-
"logicalRootDigest": "
|
|
8
|
-
"projectionDigest": "
|
|
9
|
-
"projectionId": "release-skill:platform:0.7.
|
|
7
|
+
"logicalRootDigest": "7889a5f745d1f51ede024d4df68853128f2440a05f430da77a25b78c7c3d396f",
|
|
8
|
+
"projectionDigest": "9709f8e22722faaca894d067dce7a9534813a6abf241f00e796a5a47b5f69f72",
|
|
9
|
+
"projectionId": "release-skill:platform:0.7.6",
|
|
10
10
|
"manifestRequired": true,
|
|
11
11
|
"projectionSources": {
|
|
12
12
|
"skills-src-root": {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"bytes": 12086
|
|
11
11
|
},
|
|
12
12
|
"02-project-config.md": {
|
|
13
|
-
"digest": "
|
|
14
|
-
"bytes":
|
|
13
|
+
"digest": "ce1986761f2aee9aab2646170cbd9ee3d14b7032db3bfb57b17e7369a45197f2",
|
|
14
|
+
"bytes": 21924
|
|
15
15
|
},
|
|
16
16
|
"03-readme-quality.md": {
|
|
17
17
|
"digest": "d74e41052592443ebbd450d0ace5f9b9b19c7a94db50f952b17c1c5a4c5dc230",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"bytes": 12014
|
|
27
27
|
},
|
|
28
28
|
"06-adapter-contract.md": {
|
|
29
|
-
"digest": "
|
|
30
|
-
"bytes":
|
|
29
|
+
"digest": "e00c175b24764487618dfdf20dc295f12a7e809f7dbfc69f6936a1e97bd02ab8",
|
|
30
|
+
"bytes": 18517
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -70,6 +70,20 @@ releaseUnits: # 发布单元数组,至少 1 个
|
|
|
70
70
|
versionMarkers: # 可选;id 唯一
|
|
71
71
|
- id: <string>
|
|
72
72
|
pattern: <string> # 含 {version} 占位符的精确标记模式
|
|
73
|
+
postPublish: # 可选;发布单元级的发布后分发配置
|
|
74
|
+
commitIdentity:
|
|
75
|
+
name: <string>
|
|
76
|
+
email: <string>
|
|
77
|
+
targets: # 可选;镜像或市场索引目标
|
|
78
|
+
- id: <string>
|
|
79
|
+
kind: payload-mirror # 或 marketplace-index
|
|
80
|
+
remoteUrl: <string> # file:// 或 https://;禁止 ssh
|
|
81
|
+
visibility: public # 或 private / internal
|
|
82
|
+
branch: <string>
|
|
83
|
+
hooks: # 可选;命名 preset 或自定义 command hook
|
|
84
|
+
- id: <string>
|
|
85
|
+
command: [<executable>, <arg>]
|
|
86
|
+
phase: distribute # 或 postVerify
|
|
73
87
|
|
|
74
88
|
verificationGates: # 可选;定义会进入冻结计划摘要
|
|
75
89
|
- id: <stable-id>
|
|
@@ -83,43 +97,55 @@ verificationGates: # 可选;定义会进入冻结计划摘要
|
|
|
83
97
|
envAllowlist: []
|
|
84
98
|
|
|
85
99
|
hooks: # 可选,命令 hooks
|
|
100
|
+
lint: <hook>
|
|
86
101
|
docs: <hook>
|
|
87
102
|
build: <hook>
|
|
88
103
|
test: <hook>
|
|
89
104
|
typecheck: <hook>
|
|
90
|
-
lint: <hook>
|
|
91
|
-
|
|
92
|
-
postPublish: # 可选;发布后分发配置(W2 closure)
|
|
93
|
-
distribute: # 分发行动数组
|
|
94
|
-
- actionType: <string> # "distribute-mirror" | "distribute-marketplace-index"
|
|
95
|
-
adapter: <string> # "distribute-git" | "distribute-marketplace"
|
|
96
|
-
kind: <string> # "payload-mirror" | "marketplace-index-form"
|
|
97
|
-
targetId: <string> # 目标标识
|
|
98
|
-
remoteUrl: <string> # file:// 或 https://;禁止 ssh
|
|
99
|
-
branch: <string> # 分支名,不得以 '-' 开头
|
|
100
|
-
tag: <string> # tag 模板,用于版本验证
|
|
101
|
-
commitIdentity: # 冻结提交身份
|
|
102
|
-
name: <string> # 禁止以 '-' 开头
|
|
103
|
-
email: <string> # RFC 5322 valid
|
|
104
|
-
payloadDir: <string> # 相对路径
|
|
105
|
-
dryRun?: boolean # 可选;只本地执行
|
|
106
|
-
materialize?: { # 可选;缺省时载荷由冻结 publicFiles 经 Foundation 托管投影物化
|
|
107
|
-
command: <string> # 可执行文件
|
|
108
|
-
args: [<string>] # 参数数组,禁止 shell 字符串
|
|
109
|
-
outputMarker?: <string> # 输出标记,用于验证
|
|
110
|
-
requireReport: {} # 前置报告要求
|
|
111
|
-
urlDependsOn: [<string>]> # 依赖动作完成
|
|
112
|
-
onConflict?: <string> # "FAIL" (默认) | "RETRY"
|
|
113
|
-
retryPolicy?: { # 可选;重试策略
|
|
114
|
-
maxAttempts: number
|
|
115
|
-
backoffMs: number
|
|
116
|
-
}
|
|
117
105
|
|
|
118
106
|
policy: # 可选,安全策略
|
|
119
107
|
forbiddenPaths: [<string>]
|
|
120
108
|
forbiddenContentPatterns: [<string>]
|
|
121
109
|
```
|
|
122
110
|
|
|
111
|
+
`postPublish` 只能位于某个 `releaseUnits[]` 条目内。下面的完整结构样例会由 schema 契约测试直接读取并校验,避免文档层级再次漂移:
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
# schema-example: postpublish-release-unit
|
|
115
|
+
apiVersion: release-skill/v1
|
|
116
|
+
kind: ReleaseProject
|
|
117
|
+
project:
|
|
118
|
+
name: postpublish-example
|
|
119
|
+
defaultBranch: main
|
|
120
|
+
releaseUnits:
|
|
121
|
+
- id: postpublish-example
|
|
122
|
+
source: .
|
|
123
|
+
publicRepo: example/postpublish-example
|
|
124
|
+
version:
|
|
125
|
+
source: package.json
|
|
126
|
+
tagTemplate: v{version}
|
|
127
|
+
distributions:
|
|
128
|
+
- type: npm
|
|
129
|
+
package: postpublish-example
|
|
130
|
+
registry: https://registry.npmjs.org
|
|
131
|
+
publisher: example
|
|
132
|
+
publicFiles:
|
|
133
|
+
- from: README.md
|
|
134
|
+
to: README.md
|
|
135
|
+
mode: preserve
|
|
136
|
+
requiredPublicFiles: [README.md]
|
|
137
|
+
previousPublicBaseline:
|
|
138
|
+
mode: none
|
|
139
|
+
postPublish:
|
|
140
|
+
commitIdentity:
|
|
141
|
+
name: release-bot
|
|
142
|
+
email: release-bot@example.com
|
|
143
|
+
hooks:
|
|
144
|
+
- id: notify-downstream
|
|
145
|
+
command: [node, scripts/notify-downstream.mjs]
|
|
146
|
+
phase: postVerify
|
|
147
|
+
```
|
|
148
|
+
|
|
123
149
|
---
|
|
124
150
|
|
|
125
151
|
## 3. 公开源码镜像与分发包
|
|
@@ -218,7 +244,7 @@ squash、rebase 和默认分支上的无关后续提交可以通过;冲突解
|
|
|
218
244
|
| `timeoutMs` | 整数 | 否 | 最小 1000,最大 7200000(2 小时) |
|
|
219
245
|
| `envAllowlist` | 字符串数组 | 否 | 每个元素匹配 `^[A-Z_][A-Z0-9_]*$`;无重复元素 |
|
|
220
246
|
|
|
221
|
-
hook
|
|
247
|
+
hook 执行顺序固定为 `lint → docs → build → test → typecheck`,优先运行成本最低的检查。执行规则如下:
|
|
222
248
|
|
|
223
249
|
- 使用 `execFile`,不使用 `exec` 或 `{ shell: true }`。
|
|
224
250
|
- 通过 `realpath` 解析 cwd,拒绝逃逸到项目根目录之外。
|
|
@@ -254,7 +280,7 @@ hooks:
|
|
|
254
280
|
|
|
255
281
|
`snapshot-verify` 获得冻结公开快照的一次性可写副本;副本销毁后重新摘要原快照,失败时还没有远端写入。`consumer-verify` 只在精确 npm 或 Claude/Codex 隔离安装成功后,从安装根执行;结果摘要进入 verify run,失败不得达到 VERIFIED。
|
|
256
282
|
|
|
257
|
-
gate 与 legacy hook
|
|
283
|
+
gate 与 legacy hook 都是没有网络沙箱的本地进程。在 `.release-skill/project.yaml` 中配置命令即完成授权,调用对应命令时直接执行,不再增加触发前确认点。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 只作为无效果的兼容输入保留。release-skill 会限制环境、路径、超时和证据输出,但不能替项目保证命令不会写文件或访问网络。恢复触发前强制确认门属于后续设计变更,0.7.6 不提供该确认门。Git push、tag、默认分支、GitHub Release 和 npm publish 只能是冻结计划里的 adapter action,不能注册为 hook/gate。
|
|
258
284
|
|
|
259
285
|
### 4.2 首次接入 setup
|
|
260
286
|
|
|
@@ -13,7 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
13
13
|
|
|
14
14
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
15
15
|
|
|
16
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
16
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
17
17
|
|
|
18
18
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
|
|
|
13
13
|
|
|
14
14
|
运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。
|
|
15
15
|
|
|
16
|
-
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook
|
|
16
|
+
**Hook 授权契约(配置时刻即授权,FM-16 处置 A)**: hook 是任意本地进程——在 `.release-skill/project.yaml` 中配置 hook 命令即完成授权,构成「配置时刻即授权」的显式契约。hook 不提供沙箱、无文件系统/网络隔离、触发前无确认点,命令调用本身即授权执行已配置的 hook 和 gate,不再设置额外人工授权环节;hook 可能产生项目目录外的副作用或远端写入,配置者须对其内容负责。旧参数 `--acknowledge-hook-side-effects` 和 `--acknowledge-gate-side-effects` 仍可解析,但只作为无效果的兼容输入,不能改变授权或执行语义。恢复「触发前强制确认门」属于后续加固项(属设计变更,需随新版本引入),当前版本不提供该确认门。
|
|
17
17
|
|
|
18
18
|
**阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
|
|
19
19
|
|
package/src/commands/prepare.mjs
CHANGED
|
@@ -247,7 +247,7 @@ export {
|
|
|
247
247
|
import { boundedOutputTail } from '../core/bounded-output.mjs';
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
|
-
* Run all declared project hooks in order: docs, build, test, typecheck.
|
|
250
|
+
* Run all declared project hooks in order: lint, docs, build, test, typecheck.
|
|
251
251
|
*
|
|
252
252
|
* Incremental cache (T3.2): a hook that opts in with `cacheable: true` and a
|
|
253
253
|
* non-empty `cacheInputs` is fingerprinted by its configuration plus the
|
|
@@ -286,13 +286,14 @@ import { boundedOutputTail } from '../core/bounded-output.mjs';
|
|
|
286
286
|
* @throws {ReleaseError} GATE_FAILED if any hook returns a non-zero exit code,
|
|
287
287
|
* throws, or declares a cacheInputs glob that matches no file.
|
|
288
288
|
*/
|
|
289
|
+
export const HOOK_EXECUTION_ORDER = Object.freeze(['lint', 'docs', 'build', 'test', 'typecheck']);
|
|
290
|
+
|
|
289
291
|
export async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
290
|
-
const hookOrder = ['docs', 'build', 'test', 'typecheck'];
|
|
291
292
|
const hooks = config.hooks ?? {};
|
|
292
293
|
const cacheEnabled = options.hookCache !== false;
|
|
293
294
|
const records = [];
|
|
294
295
|
|
|
295
|
-
for (const name of
|
|
296
|
+
for (const name of HOOK_EXECUTION_ORDER) {
|
|
296
297
|
const hook = hooks[name];
|
|
297
298
|
if (!hook) continue;
|
|
298
299
|
|
|
@@ -317,7 +317,7 @@ async function collectSkills(srcDir, physicalRoot) {
|
|
|
317
317
|
const CODEX_PREAMBLE = `\
|
|
318
318
|
> **Codex 安装入口解析协议**:在调用 CLI 前,Agent 必须从宿主当前已加载技能的元数据中取得本 \`SKILL.md\` 的实际绝对路径,并将该字面量记为 \`SKILL_FILE\`。\n\
|
|
319
319
|
> \`SKILL_FILE\` 不是环境变量;禁止从工作目录、可执行搜索路径、源码仓库或 shell 调用上下文猜测。若宿主未提供该绝对路径,立即停止并报告安装定位失败。\n\
|
|
320
|
-
> 对 \`SKILL_FILE\` 执行 \`realpath\`,取其目录向上两级得到 \`PLUGIN_ROOT\`;校验真实技能路径匹配 \`PLUGIN_ROOT/skills/*/SKILL.md
|
|
320
|
+
> 对 \`SKILL_FILE\` 执行 \`realpath\`,取其目录向上两级得到 \`PLUGIN_ROOT\`;校验真实技能路径匹配 \`PLUGIN_ROOT/skills/*/SKILL.md\` 且仍位于插件根内(路径包含检查)。\n\
|
|
321
321
|
> 令 \`RELEASE_SKILL_ENTRY=PLUGIN_ROOT/bin/release-skill.mjs\`,对入口执行 \`realpath\` containment、\`lstat\` 非符号链接且为普通文件校验。\n\
|
|
322
322
|
> 每一次 shell 工具调用都必须在同一个调用中用上述已验证绝对值设置 \`RELEASE_SKILL_ENTRY\`,然后执行 \`node "$RELEASE_SKILL_ENTRY" ...\`;不得依赖前一次 shell 的变量。\n\
|
|
323
323
|
>\n\
|