release-skill 0.9.5 → 0.9.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 +27 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +16 -16
- package/README.zh-CN.md +14 -15
- 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 +172 -10
- package/adapters/claude/skills/release-help/SKILL.md +5 -1
- package/adapters/claude/skills/release-verify/SKILL.md +13 -1
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +172 -10
- package/adapters/codex/skills/release-help/SKILL.md +5 -1
- package/adapters/codex/skills/release-verify/SKILL.md +13 -1
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +172 -10
- package/adapters/kimi/skills/release-help/SKILL.md +5 -1
- package/adapters/kimi/skills/release-verify/SKILL.md +13 -1
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +172 -10
- package/adapters/workbuddy/skills/release-help/SKILL.md +5 -1
- package/adapters/workbuddy/skills/release-verify/SKILL.md +13 -1
- package/bin/release-skill-cli.mjs +130 -6
- package/bin/release-skill.bundle.mjs +172 -10
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/skills/release-help/SKILL.md +5 -1
- package/skills/release-verify/SKILL.md +13 -1
- package/skills-src/release-help/SKILL.md +5 -1
- package/skills-src/release-verify/SKILL.md +13 -1
- package/src/adapters/plugin-marketplace.mjs +54 -5
|
@@ -15,6 +15,11 @@ verify 是发布流程的最终验证阶段,是唯一能将状态提升到 `VE
|
|
|
15
15
|
它执行远端状态重检、精确 npm 安装烟雾测试和消费者插件安装验证。
|
|
16
16
|
verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再次派生运行。
|
|
17
17
|
|
|
18
|
+
计划声明 `postVerify` hook 时,`postverify` 命令负责执行独立的收尾阶段。它接收
|
|
19
|
+
`VERIFIED` verify run、同一计划的 approval,以及逐个传入的 checkpoint approval,
|
|
20
|
+
然后原样调用现有 `postVerifyRelease`。该命令产生独立的 `postverify` run,不读取或写入
|
|
21
|
+
ship state;hook approval 缺失、错误或过期时,在 hook 执行前失败关闭。
|
|
22
|
+
|
|
18
23
|
**注意**: distribute gate (W1) 已经实现并集成在标准 verify 流程中。verify 现在会检查 postPublish 分发状态(git mirror + marketplace index),只有当所有外部动作都完成并通过验证时才达到 VERIFIED。
|
|
19
24
|
|
|
20
25
|
**工作流兼容性**:
|
|
@@ -45,13 +50,17 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
|
|
|
45
50
|
2. 使用插件根相对路径运行 CLI;命令调用本身即授权执行已配置的 verification gate 和 smoke process
|
|
46
51
|
3. 检查 exit code 和结构化状态:`VERIFIED`(全部通过)/ 失败(具体错误)
|
|
47
52
|
4. 只有 `VERIFIED` 才是发布 happy end
|
|
48
|
-
5. 达到 `VERIFIED` 后先检查计划是否声明 `postVerify` hook
|
|
53
|
+
5. 达到 `VERIFIED` 后先检查计划是否声明 `postVerify` hook:直接收尾使用独立的 `postverify --plan --approval --run --hook-approval`,由该命令产生 `DISTRIBUTED` postVerify run;若仍由持久化 ship state 承担编排,则使用 `ship --hook-approval` 完成同一阶段,再把最终 run 路径交给 `release-finish`。没有 postVerify hook 时,把当前 verify run 路径交给 `release-finish`。随后按清单主动询问分支合并和本机宿主插件更新;发布策略已包含分支动作时略过合并询问
|
|
49
54
|
|
|
50
55
|
## 确定性脚本调用
|
|
51
56
|
|
|
52
57
|
```bash
|
|
53
58
|
# 从插件根运行
|
|
54
59
|
node "${CODEBUDDY_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --json
|
|
60
|
+
# 独立执行已 VERIFIED 计划的 postVerify hook;每个 requiresApproval hook 单独传入批准记录
|
|
61
|
+
node "${CODEBUDDY_PLUGIN_ROOT}/bin/release-skill.mjs" postverify --root <path> \
|
|
62
|
+
--plan <plan-path> --approval <approval-path> --run <verified-run-path> \
|
|
63
|
+
--hook-approval <immutable-hook-approval-path> --json
|
|
55
64
|
```
|
|
56
65
|
|
|
57
66
|
## 验证步骤
|
|
@@ -63,6 +72,9 @@ node "${CODEBUDDY_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --pla
|
|
|
63
72
|
5. 对 Claude/Codex marketplace distribution 执行全新隔离消费者安装验证;收集 Kimi/CodeBuddy 的非阻塞 `manualFollowUps`
|
|
64
73
|
6. 全部通过 → `VERIFIED`
|
|
65
74
|
|
|
75
|
+
`postverify` 不属于上述远端验证步骤。它只处理已经达到 `VERIFIED` 的计划,并把
|
|
76
|
+
`postVerify` 阶段的执行结果写入独立 run。
|
|
77
|
+
|
|
66
78
|
## 发布后收尾
|
|
67
79
|
|
|
68
80
|
`VERIFIED` 不代表要自动修改开发分支或本机宿主。进入 `release-finish` 后,只有用户明确同意,才执行对应的本地动作。本机插件更新失败不会改变发布终态。
|
|
@@ -5,7 +5,7 @@ import { basename, dirname, join, resolve } from 'node:path';
|
|
|
5
5
|
import { execFile as execFileCb } from 'node:child_process';
|
|
6
6
|
import { promisify } from 'node:util';
|
|
7
7
|
import { parseNodeMajor, meetsMinimum, computeReadinessStatus } from '../src/core/node-version.mjs';
|
|
8
|
-
import { registerPathRedactor } from '../src/core/errors.mjs';
|
|
8
|
+
import { EXIT_CODE_MAP, MISSING_PARAMETERS, registerPathRedactor } from '../src/core/errors.mjs';
|
|
9
9
|
import { redactSensitivePaths } from '../src/core/redact.mjs';
|
|
10
10
|
|
|
11
11
|
// Process output errors can be emitted immediately after a large console
|
|
@@ -37,7 +37,7 @@ registerPathRedactor(redactSensitivePaths);
|
|
|
37
37
|
|
|
38
38
|
const execFile = promisify(execFileCb);
|
|
39
39
|
|
|
40
|
-
const COMMANDS = new Set(['help', 'setup', 'assess', 'prepare', 'approve', 'publish', 'reconcile', 'verify', 'ship', 'post-release', 'attest', 'hooks', 'artifacts', 'docs', 'distribute', 'route', 'lineage']);
|
|
40
|
+
const COMMANDS = new Set(['help', 'setup', 'assess', 'prepare', 'approve', 'publish', 'reconcile', 'verify', 'postverify', 'ship', 'post-release', 'attest', 'hooks', 'artifacts', 'docs', 'distribute', 'route', 'lineage']);
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Wait until writes already queued on a process output stream have reached
|
|
@@ -307,6 +307,11 @@ function getCapabilityMaturity() {
|
|
|
307
307
|
mode: 'fresh consumer verification (protocol-tested; no OS/network sandbox)',
|
|
308
308
|
description: 'Recheck remote state, exact npm installation, CLI help, and automated Claude/Codex installs before VERIFIED; Kimi/CodeBuddy remain unverified manual follow-ups',
|
|
309
309
|
},
|
|
310
|
+
postverify: {
|
|
311
|
+
available: true,
|
|
312
|
+
mode: 'independent postVerify execution',
|
|
313
|
+
description: 'Run approved postVerify hooks from a VERIFIED run in an independent run; never reads or writes ship state',
|
|
314
|
+
},
|
|
310
315
|
distribute: {
|
|
311
316
|
available: true,
|
|
312
317
|
mode: 'controlled production (protocol-tested; no OS/network sandbox)',
|
|
@@ -340,6 +345,7 @@ Commands:
|
|
|
340
345
|
publish Publish frozen GitHub/npm artifacts after approval
|
|
341
346
|
reconcile Resume PARTIAL state from evidence; conflicts require a human
|
|
342
347
|
verify Fresh remote and consumer verification; only this reaches VERIFIED
|
|
348
|
+
postverify Run approved postVerify hooks from a VERIFIED run in an independent run
|
|
343
349
|
ship Resume one durable prepare -> approve -> publish -> verify flow; completes a parked
|
|
344
350
|
postVerify hook once its checkpoint approval is provided (--hook-approval)
|
|
345
351
|
post-release Inspect optional local finishing work after VERIFIED; update installed host plugins
|
|
@@ -354,10 +360,10 @@ Commands:
|
|
|
354
360
|
|
|
355
361
|
Options:
|
|
356
362
|
--root <path> Project root directory (default: cwd)
|
|
357
|
-
--plan <path> Path to the release plan file
|
|
363
|
+
--plan <path> Path to the release plan file (required for approve/publish/reconcile/verify/postverify)
|
|
358
364
|
--run <path> Path to the release run file, or a run directory whose release-run.json
|
|
359
|
-
is resolved automatically (required for reconcile/verify)
|
|
360
|
-
--approval <path> Path to the approval record
|
|
365
|
+
is resolved automatically (required for reconcile/verify/postverify)
|
|
366
|
+
--approval <path> Path to the release-level approval record (required for publish/postverify)
|
|
361
367
|
--production Prepare immutable Git/npm production artifacts
|
|
362
368
|
--output <path> Override prepare/approve output path (non-production only)
|
|
363
369
|
--run-dir <path> Override prepare run directory; production requires one direct child of .release-skill/runs
|
|
@@ -394,7 +400,7 @@ Options:
|
|
|
394
400
|
--install-path <path> Actual managed plugin path when closure verification requires it
|
|
395
401
|
--install-channel <desktop|cli> CodeBuddy installation channel when required
|
|
396
402
|
--approve Approve the ship plan (boolean; plan digest is auto-resolved)
|
|
397
|
-
--hook-approval <path> Checkpoint approval for
|
|
403
|
+
--hook-approval <path> Checkpoint approval for one requiresApproval hook (ship/distribute/postverify; repeatable)
|
|
398
404
|
--state <path> Override the durable ship state file
|
|
399
405
|
--update-local-hosts Update installed plugins for selected local hosts after VERIFIED
|
|
400
406
|
--hosts <ids> Comma-separated local hosts for post-release update. No local host is updated unless --hosts contains at least one id
|
|
@@ -1539,6 +1545,124 @@ if (command === 'verify') {
|
|
|
1539
1545
|
}
|
|
1540
1546
|
}
|
|
1541
1547
|
|
|
1548
|
+
// --- PostVerify command routing ---
|
|
1549
|
+
if (command === 'postverify') {
|
|
1550
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
1551
|
+
const helpText = `release-skill postverify - Run approved postVerify hooks from a VERIFIED run
|
|
1552
|
+
|
|
1553
|
+
Usage:
|
|
1554
|
+
release-skill postverify [--root <path>] --plan <path> --approval <path> --run <path> [options]
|
|
1555
|
+
|
|
1556
|
+
Required options:
|
|
1557
|
+
--plan <path> Path to the release plan file
|
|
1558
|
+
--approval <path> Path to the release-level approval record
|
|
1559
|
+
--run <path> Path to the VERIFIED verify run file or directory
|
|
1560
|
+
|
|
1561
|
+
Optional options:
|
|
1562
|
+
--root <path> Project root directory (default: cwd)
|
|
1563
|
+
--hook-approval <path> Checkpoint approval for a requiresApproval postVerify hook (repeatable)
|
|
1564
|
+
--json Output results as JSON
|
|
1565
|
+
-h, --help Show this help message and exit
|
|
1566
|
+
|
|
1567
|
+
This command creates an independent postVerify run and never reads or writes ship state.`;
|
|
1568
|
+
if (hasJson) {
|
|
1569
|
+
console.log(JSON.stringify({
|
|
1570
|
+
command: 'postverify',
|
|
1571
|
+
status: 'HELP',
|
|
1572
|
+
usage: 'release-skill postverify [--root <path>] --plan <path> --approval <path> --run <path> [options]',
|
|
1573
|
+
options: {
|
|
1574
|
+
'--root': 'Project root directory (default: cwd)',
|
|
1575
|
+
'--plan': 'Path to the release plan file (required)',
|
|
1576
|
+
'--approval': 'Path to the release-level approval record (required)',
|
|
1577
|
+
'--run': 'Path to the VERIFIED verify run file or directory (required)',
|
|
1578
|
+
'--hook-approval': 'Checkpoint approval for a requiresApproval postVerify hook (repeatable)',
|
|
1579
|
+
'--json': 'Output results as JSON',
|
|
1580
|
+
'-h, --help': 'Show this help message and exit',
|
|
1581
|
+
},
|
|
1582
|
+
message: 'Creates an independent postVerify run and never reads or writes ship state.',
|
|
1583
|
+
}, null, 2));
|
|
1584
|
+
} else {
|
|
1585
|
+
console.log(helpText);
|
|
1586
|
+
}
|
|
1587
|
+
await exitAfterFlush(0);
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
let malformedValuedFlag;
|
|
1591
|
+
const value = (flag) => {
|
|
1592
|
+
let firstValue;
|
|
1593
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
1594
|
+
if (args[i] !== flag) continue;
|
|
1595
|
+
const next = args[i + 1];
|
|
1596
|
+
if (!next || next.startsWith('-')) {
|
|
1597
|
+
malformedValuedFlag ??= flag;
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1600
|
+
firstValue ??= next;
|
|
1601
|
+
}
|
|
1602
|
+
return firstValue;
|
|
1603
|
+
};
|
|
1604
|
+
const root = resolve(value('--root') ?? process.cwd());
|
|
1605
|
+
const planPath = value('--plan');
|
|
1606
|
+
const approvalPath = value('--approval');
|
|
1607
|
+
const runPath = value('--run');
|
|
1608
|
+
const postpublishApprovalPaths = [];
|
|
1609
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
1610
|
+
if (args[i] === '--hook-approval') {
|
|
1611
|
+
const next = args[i + 1];
|
|
1612
|
+
if (!next || next.startsWith('-')) {
|
|
1613
|
+
malformedValuedFlag ??= '--hook-approval';
|
|
1614
|
+
} else {
|
|
1615
|
+
postpublishApprovalPaths.push(resolve(next));
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
if (malformedValuedFlag || !planPath || !approvalPath || !runPath) {
|
|
1621
|
+
const msg = 'postverify requires --plan <path>, --approval <path>, and --run <path>';
|
|
1622
|
+
if (hasJson) {
|
|
1623
|
+
console.log(JSON.stringify({ error: MISSING_PARAMETERS, message: msg, exitCode: EXIT_CODE_MAP[MISSING_PARAMETERS] }));
|
|
1624
|
+
} else {
|
|
1625
|
+
console.error(`Error: ${msg}`);
|
|
1626
|
+
}
|
|
1627
|
+
await exitAfterFlush(EXIT_CODE_MAP[MISSING_PARAMETERS]);
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
try {
|
|
1631
|
+
const { postVerifyRelease } = await import('../src/commands/postverify.mjs');
|
|
1632
|
+
const result = await postVerifyRelease({
|
|
1633
|
+
planPath: resolve(planPath),
|
|
1634
|
+
approvalPath: resolve(approvalPath),
|
|
1635
|
+
sourceRunPath: resolve(runPath),
|
|
1636
|
+
root,
|
|
1637
|
+
...(postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}),
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
if (hasJson) {
|
|
1641
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1642
|
+
} else {
|
|
1643
|
+
console.log(`PostVerify status: ${result.status}`);
|
|
1644
|
+
for (const cp of result.checkpoints ?? []) {
|
|
1645
|
+
console.log(` ${cp.actionId}: ${cp.status}`);
|
|
1646
|
+
}
|
|
1647
|
+
if (result.runPath) console.log(`PostVerify run: ${result.runPath}`);
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
await exitAfterFlush(result.status === 'DISTRIBUTED' ? 0 : 1);
|
|
1651
|
+
} catch (err) {
|
|
1652
|
+
if (hasJson) {
|
|
1653
|
+
console.log(JSON.stringify({
|
|
1654
|
+
error: err.code ?? 'UNKNOWN_ERROR',
|
|
1655
|
+
message: err.message,
|
|
1656
|
+
details: err.details ?? {},
|
|
1657
|
+
exitCode: err.exitCode ?? 1,
|
|
1658
|
+
}));
|
|
1659
|
+
} else {
|
|
1660
|
+
console.error(`Error: ${err.message}`);
|
|
1661
|
+
}
|
|
1662
|
+
await exitAfterFlush(err.exitCode ?? 1);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1542
1666
|
// --- Publish command routing ---
|
|
1543
1667
|
if (command === 'publish') {
|
|
1544
1668
|
|
|
@@ -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.6"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "8fd8e6c5f7796efe9e1f7153382b50c74d78a4b5f836f872837ff2f11e4daeb5";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -109640,6 +109640,39 @@ function transportPayload(entries) {
|
|
|
109640
109640
|
contentDigest
|
|
109641
109641
|
}));
|
|
109642
109642
|
}
|
|
109643
|
+
function foundationPayloadMembers(observation) {
|
|
109644
|
+
return observation.members.map((member) => {
|
|
109645
|
+
if (member.type === "file") {
|
|
109646
|
+
return {
|
|
109647
|
+
path: member.path,
|
|
109648
|
+
type: member.type,
|
|
109649
|
+
mode: member.statMode & ~146,
|
|
109650
|
+
size: member.bytes,
|
|
109651
|
+
contentDigest: member.sha256
|
|
109652
|
+
};
|
|
109653
|
+
}
|
|
109654
|
+
if (member.type === "directory") {
|
|
109655
|
+
return { path: member.path, type: member.type, mode: member.statMode };
|
|
109656
|
+
}
|
|
109657
|
+
return {
|
|
109658
|
+
path: member.path,
|
|
109659
|
+
type: member.type,
|
|
109660
|
+
mode: member.statMode,
|
|
109661
|
+
size: member.bytes,
|
|
109662
|
+
targetBase64: member.targetBase64
|
|
109663
|
+
};
|
|
109664
|
+
});
|
|
109665
|
+
}
|
|
109666
|
+
async function observeMarketplaceInstallTree(installPath) {
|
|
109667
|
+
const canonicalInstallPath = await realpath22(installPath);
|
|
109668
|
+
const rootBinding = await createFilesystemRootBinding(canonicalInstallPath);
|
|
109669
|
+
const observation = await observeFilesystemTree({
|
|
109670
|
+
root: canonicalInstallPath,
|
|
109671
|
+
rootBinding,
|
|
109672
|
+
symlinkPolicy: { mode: "record" }
|
|
109673
|
+
});
|
|
109674
|
+
return foundationPayloadMembers(observation);
|
|
109675
|
+
}
|
|
109643
109676
|
function resolveMarketplaceRoot(platform, marketplaceIndexPath) {
|
|
109644
109677
|
const defaultMarketplace = platform.manifestPaths.marketplace;
|
|
109645
109678
|
if (!defaultMarketplace) {
|
|
@@ -109869,10 +109902,10 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
109869
109902
|
throw new Error(`unsupported marketplace payload contract: ${JSON.stringify(payloadContract)}`);
|
|
109870
109903
|
}
|
|
109871
109904
|
if (payloadContract === PAYLOAD_CONTRACT_DECLARED_MANIFEST || payloadContract === PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE) {
|
|
109872
|
-
const
|
|
109905
|
+
const installedMembers = await observeMarketplaceInstallTree(installPath);
|
|
109873
109906
|
const authorityPayload = transportPayload(authorityEntries);
|
|
109874
109907
|
const installedByPath = new Map(
|
|
109875
|
-
|
|
109908
|
+
installedMembers.map((entry) => [entry.path, entry])
|
|
109876
109909
|
);
|
|
109877
109910
|
const conflicts = [];
|
|
109878
109911
|
for (const authorityEntry of authorityPayload) {
|
|
@@ -109897,11 +109930,19 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
109897
109930
|
);
|
|
109898
109931
|
}
|
|
109899
109932
|
const authorityPaths = new Set(authorityPayload.map((entry) => entry.path));
|
|
109900
|
-
const
|
|
109933
|
+
const extraMembers = installedMembers.filter((entry) => entry.type !== "directory" && !authorityPaths.has(entry.path));
|
|
109934
|
+
const extraPaths = extraMembers.map((entry) => entry.path);
|
|
109901
109935
|
const extraInstalledPaths = extraPaths.slice(0, EXTRA_INSTALLED_PATHS_CAP);
|
|
109936
|
+
const extraInstalledLinks = extraMembers.filter((entry) => entry.type === "symlink").slice(0, EXTRA_INSTALLED_PATHS_CAP).map((entry) => ({
|
|
109937
|
+
path: entry.path,
|
|
109938
|
+
targetBase64: entry.targetBase64,
|
|
109939
|
+
bytes: entry.size,
|
|
109940
|
+
statMode: entry.mode
|
|
109941
|
+
}));
|
|
109902
109942
|
return {
|
|
109903
109943
|
manifestDigest: action.manifestDigest,
|
|
109904
109944
|
extraInstalledPaths,
|
|
109945
|
+
...extraInstalledLinks.length > 0 ? { extraInstalledLinks } : {},
|
|
109905
109946
|
...extraPaths.length > EXTRA_INSTALLED_PATHS_CAP ? { extraInstalledPathsTotal: extraPaths.length } : {}
|
|
109906
109947
|
};
|
|
109907
109948
|
}
|
|
@@ -109917,6 +109958,7 @@ function extraInstalledPathsAudit(binding) {
|
|
|
109917
109958
|
if (!binding || !Array.isArray(binding.extraInstalledPaths)) return {};
|
|
109918
109959
|
return {
|
|
109919
109960
|
extraInstalledPaths: binding.extraInstalledPaths,
|
|
109961
|
+
...Array.isArray(binding.extraInstalledLinks) && binding.extraInstalledLinks.length > 0 ? { extraInstalledLinks: binding.extraInstalledLinks } : {},
|
|
109920
109962
|
...binding.extraInstalledPathsTotal !== void 0 ? { extraInstalledPathsTotal: binding.extraInstalledPathsTotal } : {}
|
|
109921
109963
|
};
|
|
109922
109964
|
}
|
|
@@ -112320,6 +112362,7 @@ var init_plugin_marketplace = __esm({
|
|
|
112320
112362
|
async "src/adapters/plugin-marketplace.mjs"() {
|
|
112321
112363
|
init_contract();
|
|
112322
112364
|
init_installation_contract();
|
|
112365
|
+
init_src2();
|
|
112323
112366
|
init_frozen();
|
|
112324
112367
|
await init_registry2();
|
|
112325
112368
|
await init_kimi();
|
|
@@ -112332,6 +112375,8 @@ var init_plugin_marketplace = __esm({
|
|
|
112332
112375
|
PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE = "external-marketplace-v1";
|
|
112333
112376
|
EXTRA_INSTALLED_PATHS_CAP = 200;
|
|
112334
112377
|
PAYLOAD_CONFLICT_REPORT_CAP = 10;
|
|
112378
|
+
__name(foundationPayloadMembers, "foundationPayloadMembers");
|
|
112379
|
+
__name(observeMarketplaceInstallTree, "observeMarketplaceInstallTree");
|
|
112335
112380
|
CONSUMER_INSTALL_RECIPE_VERSION = "consumer-install-v1";
|
|
112336
112381
|
__name(resolveMarketplaceRoot, "resolveMarketplaceRoot");
|
|
112337
112382
|
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
@@ -145779,7 +145824,7 @@ guardOutputStream(process.stdout);
|
|
|
145779
145824
|
guardOutputStream(process.stderr);
|
|
145780
145825
|
registerPathRedactor(redactSensitivePaths);
|
|
145781
145826
|
var execFile19 = promisify26(execFileCb22);
|
|
145782
|
-
var COMMANDS = /* @__PURE__ */ new Set(["help", "setup", "assess", "prepare", "approve", "publish", "reconcile", "verify", "ship", "post-release", "attest", "hooks", "artifacts", "docs", "distribute", "route", "lineage"]);
|
|
145827
|
+
var COMMANDS = /* @__PURE__ */ new Set(["help", "setup", "assess", "prepare", "approve", "publish", "reconcile", "verify", "postverify", "ship", "post-release", "attest", "hooks", "artifacts", "docs", "distribute", "route", "lineage"]);
|
|
145783
145828
|
function flushOutputStream(stream) {
|
|
145784
145829
|
if (!stream?.writable || stream.destroyed || stream.writableEnded || outputStreamStates.get(stream)?.failed) {
|
|
145785
145830
|
return Promise.resolve();
|
|
@@ -145970,6 +146015,11 @@ function getCapabilityMaturity() {
|
|
|
145970
146015
|
mode: "fresh consumer verification (protocol-tested; no OS/network sandbox)",
|
|
145971
146016
|
description: "Recheck remote state, exact npm installation, CLI help, and automated Claude/Codex installs before VERIFIED; Kimi/CodeBuddy remain unverified manual follow-ups"
|
|
145972
146017
|
},
|
|
146018
|
+
postverify: {
|
|
146019
|
+
available: true,
|
|
146020
|
+
mode: "independent postVerify execution",
|
|
146021
|
+
description: "Run approved postVerify hooks from a VERIFIED run in an independent run; never reads or writes ship state"
|
|
146022
|
+
},
|
|
145973
146023
|
distribute: {
|
|
145974
146024
|
available: true,
|
|
145975
146025
|
mode: "controlled production (protocol-tested; no OS/network sandbox)",
|
|
@@ -146003,6 +146053,7 @@ Commands:
|
|
|
146003
146053
|
publish Publish frozen GitHub/npm artifacts after approval
|
|
146004
146054
|
reconcile Resume PARTIAL state from evidence; conflicts require a human
|
|
146005
146055
|
verify Fresh remote and consumer verification; only this reaches VERIFIED
|
|
146056
|
+
postverify Run approved postVerify hooks from a VERIFIED run in an independent run
|
|
146006
146057
|
ship Resume one durable prepare -> approve -> publish -> verify flow; completes a parked
|
|
146007
146058
|
postVerify hook once its checkpoint approval is provided (--hook-approval)
|
|
146008
146059
|
post-release Inspect optional local finishing work after VERIFIED; update installed host plugins
|
|
@@ -146017,10 +146068,10 @@ Commands:
|
|
|
146017
146068
|
|
|
146018
146069
|
Options:
|
|
146019
146070
|
--root <path> Project root directory (default: cwd)
|
|
146020
|
-
--plan <path> Path to the release plan file
|
|
146071
|
+
--plan <path> Path to the release plan file (required for approve/publish/reconcile/verify/postverify)
|
|
146021
146072
|
--run <path> Path to the release run file, or a run directory whose release-run.json
|
|
146022
|
-
is resolved automatically (required for reconcile/verify)
|
|
146023
|
-
--approval <path> Path to the approval record
|
|
146073
|
+
is resolved automatically (required for reconcile/verify/postverify)
|
|
146074
|
+
--approval <path> Path to the release-level approval record (required for publish/postverify)
|
|
146024
146075
|
--production Prepare immutable Git/npm production artifacts
|
|
146025
146076
|
--output <path> Override prepare/approve output path (non-production only)
|
|
146026
146077
|
--run-dir <path> Override prepare run directory; production requires one direct child of .release-skill/runs
|
|
@@ -146057,7 +146108,7 @@ Options:
|
|
|
146057
146108
|
--install-path <path> Actual managed plugin path when closure verification requires it
|
|
146058
146109
|
--install-channel <desktop|cli> CodeBuddy installation channel when required
|
|
146059
146110
|
--approve Approve the ship plan (boolean; plan digest is auto-resolved)
|
|
146060
|
-
--hook-approval <path> Checkpoint approval for
|
|
146111
|
+
--hook-approval <path> Checkpoint approval for one requiresApproval hook (ship/distribute/postverify; repeatable)
|
|
146061
146112
|
--state <path> Override the durable ship state file
|
|
146062
146113
|
--update-local-hosts Update installed plugins for selected local hosts after VERIFIED
|
|
146063
146114
|
--hosts <ids> Comma-separated local hosts for post-release update. No local host is updated unless --hosts contains at least one id
|
|
@@ -147076,6 +147127,117 @@ if (command === "verify") {
|
|
|
147076
147127
|
await exitAfterFlush(err.exitCode ?? 1);
|
|
147077
147128
|
}
|
|
147078
147129
|
}
|
|
147130
|
+
if (command === "postverify") {
|
|
147131
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
147132
|
+
const helpText = `release-skill postverify - Run approved postVerify hooks from a VERIFIED run
|
|
147133
|
+
|
|
147134
|
+
Usage:
|
|
147135
|
+
release-skill postverify [--root <path>] --plan <path> --approval <path> --run <path> [options]
|
|
147136
|
+
|
|
147137
|
+
Required options:
|
|
147138
|
+
--plan <path> Path to the release plan file
|
|
147139
|
+
--approval <path> Path to the release-level approval record
|
|
147140
|
+
--run <path> Path to the VERIFIED verify run file or directory
|
|
147141
|
+
|
|
147142
|
+
Optional options:
|
|
147143
|
+
--root <path> Project root directory (default: cwd)
|
|
147144
|
+
--hook-approval <path> Checkpoint approval for a requiresApproval postVerify hook (repeatable)
|
|
147145
|
+
--json Output results as JSON
|
|
147146
|
+
-h, --help Show this help message and exit
|
|
147147
|
+
|
|
147148
|
+
This command creates an independent postVerify run and never reads or writes ship state.`;
|
|
147149
|
+
if (hasJson) {
|
|
147150
|
+
console.log(JSON.stringify({
|
|
147151
|
+
command: "postverify",
|
|
147152
|
+
status: "HELP",
|
|
147153
|
+
usage: "release-skill postverify [--root <path>] --plan <path> --approval <path> --run <path> [options]",
|
|
147154
|
+
options: {
|
|
147155
|
+
"--root": "Project root directory (default: cwd)",
|
|
147156
|
+
"--plan": "Path to the release plan file (required)",
|
|
147157
|
+
"--approval": "Path to the release-level approval record (required)",
|
|
147158
|
+
"--run": "Path to the VERIFIED verify run file or directory (required)",
|
|
147159
|
+
"--hook-approval": "Checkpoint approval for a requiresApproval postVerify hook (repeatable)",
|
|
147160
|
+
"--json": "Output results as JSON",
|
|
147161
|
+
"-h, --help": "Show this help message and exit"
|
|
147162
|
+
},
|
|
147163
|
+
message: "Creates an independent postVerify run and never reads or writes ship state."
|
|
147164
|
+
}, null, 2));
|
|
147165
|
+
} else {
|
|
147166
|
+
console.log(helpText);
|
|
147167
|
+
}
|
|
147168
|
+
await exitAfterFlush(0);
|
|
147169
|
+
}
|
|
147170
|
+
let malformedValuedFlag;
|
|
147171
|
+
const value = /* @__PURE__ */ __name((flag) => {
|
|
147172
|
+
let firstValue;
|
|
147173
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
147174
|
+
if (args[i] !== flag) continue;
|
|
147175
|
+
const next = args[i + 1];
|
|
147176
|
+
if (!next || next.startsWith("-")) {
|
|
147177
|
+
malformedValuedFlag ??= flag;
|
|
147178
|
+
continue;
|
|
147179
|
+
}
|
|
147180
|
+
firstValue ??= next;
|
|
147181
|
+
}
|
|
147182
|
+
return firstValue;
|
|
147183
|
+
}, "value");
|
|
147184
|
+
const root = resolve41(value("--root") ?? process.cwd());
|
|
147185
|
+
const planPath = value("--plan");
|
|
147186
|
+
const approvalPath = value("--approval");
|
|
147187
|
+
const runPath = value("--run");
|
|
147188
|
+
const postpublishApprovalPaths = [];
|
|
147189
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
147190
|
+
if (args[i] === "--hook-approval") {
|
|
147191
|
+
const next = args[i + 1];
|
|
147192
|
+
if (!next || next.startsWith("-")) {
|
|
147193
|
+
malformedValuedFlag ??= "--hook-approval";
|
|
147194
|
+
} else {
|
|
147195
|
+
postpublishApprovalPaths.push(resolve41(next));
|
|
147196
|
+
}
|
|
147197
|
+
}
|
|
147198
|
+
}
|
|
147199
|
+
if (malformedValuedFlag || !planPath || !approvalPath || !runPath) {
|
|
147200
|
+
const msg = "postverify requires --plan <path>, --approval <path>, and --run <path>";
|
|
147201
|
+
if (hasJson) {
|
|
147202
|
+
console.log(JSON.stringify({ error: MISSING_PARAMETERS, message: msg, exitCode: EXIT_CODE_MAP[MISSING_PARAMETERS] }));
|
|
147203
|
+
} else {
|
|
147204
|
+
console.error(`Error: ${msg}`);
|
|
147205
|
+
}
|
|
147206
|
+
await exitAfterFlush(EXIT_CODE_MAP[MISSING_PARAMETERS]);
|
|
147207
|
+
}
|
|
147208
|
+
try {
|
|
147209
|
+
const { postVerifyRelease: postVerifyRelease2 } = await init_postverify().then(() => postverify_exports);
|
|
147210
|
+
const result2 = await postVerifyRelease2({
|
|
147211
|
+
planPath: resolve41(planPath),
|
|
147212
|
+
approvalPath: resolve41(approvalPath),
|
|
147213
|
+
sourceRunPath: resolve41(runPath),
|
|
147214
|
+
root,
|
|
147215
|
+
...postpublishApprovalPaths.length > 0 ? { postpublishApprovalPaths } : {}
|
|
147216
|
+
});
|
|
147217
|
+
if (hasJson) {
|
|
147218
|
+
console.log(JSON.stringify(result2, null, 2));
|
|
147219
|
+
} else {
|
|
147220
|
+
console.log(`PostVerify status: ${result2.status}`);
|
|
147221
|
+
for (const cp4 of result2.checkpoints ?? []) {
|
|
147222
|
+
console.log(` ${cp4.actionId}: ${cp4.status}`);
|
|
147223
|
+
}
|
|
147224
|
+
if (result2.runPath) console.log(`PostVerify run: ${result2.runPath}`);
|
|
147225
|
+
}
|
|
147226
|
+
await exitAfterFlush(result2.status === "DISTRIBUTED" ? 0 : 1);
|
|
147227
|
+
} catch (err) {
|
|
147228
|
+
if (hasJson) {
|
|
147229
|
+
console.log(JSON.stringify({
|
|
147230
|
+
error: err.code ?? "UNKNOWN_ERROR",
|
|
147231
|
+
message: err.message,
|
|
147232
|
+
details: err.details ?? {},
|
|
147233
|
+
exitCode: err.exitCode ?? 1
|
|
147234
|
+
}));
|
|
147235
|
+
} else {
|
|
147236
|
+
console.error(`Error: ${err.message}`);
|
|
147237
|
+
}
|
|
147238
|
+
await exitAfterFlush(err.exitCode ?? 1);
|
|
147239
|
+
}
|
|
147240
|
+
}
|
|
147079
147241
|
if (command === "publish") {
|
|
147080
147242
|
const rootIdx = args.indexOf("--root");
|
|
147081
147243
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
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.6",
|
|
6
6
|
"logicalRoot": "skills-src/",
|
|
7
|
-
"logicalRootDigest": "
|
|
8
|
-
"projectionDigest": "
|
|
9
|
-
"projectionId": "release-skill:platform:0.9.
|
|
7
|
+
"logicalRootDigest": "4338c7c5a7efd38ca372049526e5bdd198087491f76702cd21d491741bfad835",
|
|
8
|
+
"projectionDigest": "c4d40afd481d78907d51ef9be1dc2238834d566b9a9792f1d25da19f57368d7d",
|
|
9
|
+
"projectionId": "release-skill:platform:0.9.6",
|
|
10
10
|
"manifestRequired": true,
|
|
11
11
|
"projectionSources": {
|
|
12
12
|
"skills-src-root": {
|
|
@@ -12,7 +12,7 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
12
12
|
## 职责
|
|
13
13
|
|
|
14
14
|
- 依赖和环境检查:Node.js >= 22、Git 决定本地准备就绪度;npm/gh 另行决定生产依赖就绪度
|
|
15
|
-
- 能力说明:缺少配置时走 `help → setup → assess`;已有配置的安全默认路径是 `help → assess → prepare --offline`;日常生产发布优先使用可恢复的 `ship`,兼容的分阶段闭环仍是 `prepare --online --production → approve → publish → verify`。冻结计划批准是正常发布级流程的唯一批准门;声明 `requiresApproval: true` 的 postPublish hook 仍须等待独立 checkpoint 批准。若计划声明 `postVerify` hook
|
|
15
|
+
- 能力说明:缺少配置时走 `help → setup → assess`;已有配置的安全默认路径是 `help → assess → prepare --offline`;日常生产发布优先使用可恢复的 `ship`,兼容的分阶段闭环仍是 `prepare --online --production → approve → publish → verify`。冻结计划批准是正常发布级流程的唯一批准门;声明 `requiresApproval: true` 的 postPublish hook 仍须等待独立 checkpoint 批准。若计划声明 `postVerify` hook,可用 `postverify` 直接执行独立收尾 run,也可由 `ship` 编排该阶段;本机收尾必须等待完成的 postVerify run,不能把仅有 `VERIFIED` 的 verify run 当作本机收尾授权。核心发布流程跨平台,WorkBuddy 本机收尾仅支持 macOS
|
|
16
16
|
- 最小示例:展示从 release-help 到 release-assess 的最短路径
|
|
17
17
|
- 只读诊断:运行 dry-run 检查,不修改任何文件
|
|
18
18
|
- 故障引导:根据错误码指向对应的修复 Skill
|
|
@@ -51,6 +51,10 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> --target-v
|
|
|
51
51
|
# 多发布单元项目显式选择本轮范围;未传 --unit 时仍为全部单元
|
|
52
52
|
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> \
|
|
53
53
|
--target-version <version> --unit <unit-a> --unit <unit-b> --json
|
|
54
|
+
# 对已经 VERIFIED 的计划独立执行 postVerify hook;不读取或写入 ship state
|
|
55
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" postverify --root <path> \
|
|
56
|
+
--plan <plan-path> --approval <approval-path> --run <verified-run-path> \
|
|
57
|
+
--hook-approval <immutable-hook-approval-path> --json
|
|
54
58
|
# 开发阶段执行声明 hooks 并生成 prepare 可复用的内容绑定收据
|
|
55
59
|
# 配置时刻即授权(FM-16 处置 A):hook 是任意本地进程、无隔离、触发前无确认点,
|
|
56
60
|
# 命令调用本身即授权执行配置中的 hooks
|
|
@@ -15,6 +15,11 @@ verify 是发布流程的最终验证阶段,是唯一能将状态提升到 `VE
|
|
|
15
15
|
它执行远端状态重检、精确 npm 安装烟雾测试和消费者插件安装验证。
|
|
16
16
|
verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再次派生运行。
|
|
17
17
|
|
|
18
|
+
计划声明 `postVerify` hook 时,`postverify` 命令负责执行独立的收尾阶段。它接收
|
|
19
|
+
`VERIFIED` verify run、同一计划的 approval,以及逐个传入的 checkpoint approval,
|
|
20
|
+
然后原样调用现有 `postVerifyRelease`。该命令产生独立的 `postverify` run,不读取或写入
|
|
21
|
+
ship state;hook approval 缺失、错误或过期时,在 hook 执行前失败关闭。
|
|
22
|
+
|
|
18
23
|
**注意**: distribute gate (W1) 已经实现并集成在标准 verify 流程中。verify 现在会检查 postPublish 分发状态(git mirror + marketplace index),只有当所有外部动作都完成并通过验证时才达到 VERIFIED。
|
|
19
24
|
|
|
20
25
|
**工作流兼容性**:
|
|
@@ -45,13 +50,17 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
|
|
|
45
50
|
2. 使用插件根相对路径运行 CLI;命令调用本身即授权执行已配置的 verification gate 和 smoke process
|
|
46
51
|
3. 检查 exit code 和结构化状态:`VERIFIED`(全部通过)/ 失败(具体错误)
|
|
47
52
|
4. 只有 `VERIFIED` 才是发布 happy end
|
|
48
|
-
5. 达到 `VERIFIED` 后先检查计划是否声明 `postVerify` hook
|
|
53
|
+
5. 达到 `VERIFIED` 后先检查计划是否声明 `postVerify` hook:直接收尾使用独立的 `postverify --plan --approval --run --hook-approval`,由该命令产生 `DISTRIBUTED` postVerify run;若仍由持久化 ship state 承担编排,则使用 `ship --hook-approval` 完成同一阶段,再把最终 run 路径交给 `release-finish`。没有 postVerify hook 时,把当前 verify run 路径交给 `release-finish`。随后按清单主动询问分支合并和本机宿主插件更新;发布策略已包含分支动作时略过合并询问
|
|
49
54
|
|
|
50
55
|
## 确定性脚本调用
|
|
51
56
|
|
|
52
57
|
```bash
|
|
53
58
|
# 从插件根运行
|
|
54
59
|
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --json
|
|
60
|
+
# 独立执行已 VERIFIED 计划的 postVerify hook;每个 requiresApproval hook 单独传入批准记录
|
|
61
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" postverify --root <path> \
|
|
62
|
+
--plan <plan-path> --approval <approval-path> --run <verified-run-path> \
|
|
63
|
+
--hook-approval <immutable-hook-approval-path> --json
|
|
55
64
|
```
|
|
56
65
|
|
|
57
66
|
## 验证步骤
|
|
@@ -63,6 +72,9 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <
|
|
|
63
72
|
5. 对 Claude/Codex marketplace distribution 执行全新隔离消费者安装验证;收集 Kimi/CodeBuddy 的非阻塞 `manualFollowUps`
|
|
64
73
|
6. 全部通过 → `VERIFIED`
|
|
65
74
|
|
|
75
|
+
`postverify` 不属于上述远端验证步骤。它只处理已经达到 `VERIFIED` 的计划,并把
|
|
76
|
+
`postVerify` 阶段的执行结果写入独立 run。
|
|
77
|
+
|
|
66
78
|
## 发布后收尾
|
|
67
79
|
|
|
68
80
|
`VERIFIED` 不代表要自动修改开发分支或本机宿主。进入 `release-finish` 后,只有用户明确同意,才执行对应的本地动作。本机插件更新失败不会改变发布终态。
|
|
@@ -12,7 +12,7 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
12
12
|
## 职责
|
|
13
13
|
|
|
14
14
|
- 依赖和环境检查:Node.js >= 22、Git 决定本地准备就绪度;npm/gh 另行决定生产依赖就绪度
|
|
15
|
-
- 能力说明:缺少配置时走 `help → setup → assess`;已有配置的安全默认路径是 `help → assess → prepare --offline`;日常生产发布优先使用可恢复的 `ship`,兼容的分阶段闭环仍是 `prepare --online --production → approve → publish → verify`。冻结计划批准是正常发布级流程的唯一批准门;声明 `requiresApproval: true` 的 postPublish hook 仍须等待独立 checkpoint 批准。若计划声明 `postVerify` hook
|
|
15
|
+
- 能力说明:缺少配置时走 `help → setup → assess`;已有配置的安全默认路径是 `help → assess → prepare --offline`;日常生产发布优先使用可恢复的 `ship`,兼容的分阶段闭环仍是 `prepare --online --production → approve → publish → verify`。冻结计划批准是正常发布级流程的唯一批准门;声明 `requiresApproval: true` 的 postPublish hook 仍须等待独立 checkpoint 批准。若计划声明 `postVerify` hook,可用 `postverify` 直接执行独立收尾 run,也可由 `ship` 编排该阶段;本机收尾必须等待完成的 postVerify run,不能把仅有 `VERIFIED` 的 verify run 当作本机收尾授权。核心发布流程跨平台,WorkBuddy 本机收尾仅支持 macOS
|
|
16
16
|
- 最小示例:展示从 release-help 到 release-assess 的最短路径
|
|
17
17
|
- 只读诊断:运行 dry-run 检查,不修改任何文件
|
|
18
18
|
- 故障引导:根据错误码指向对应的修复 Skill
|
|
@@ -51,6 +51,10 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> --target-v
|
|
|
51
51
|
# 多发布单元项目显式选择本轮范围;未传 --unit 时仍为全部单元
|
|
52
52
|
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> \
|
|
53
53
|
--target-version <version> --unit <unit-a> --unit <unit-b> --json
|
|
54
|
+
# 对已经 VERIFIED 的计划独立执行 postVerify hook;不读取或写入 ship state
|
|
55
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" postverify --root <path> \
|
|
56
|
+
--plan <plan-path> --approval <approval-path> --run <verified-run-path> \
|
|
57
|
+
--hook-approval <immutable-hook-approval-path> --json
|
|
54
58
|
# 开发阶段执行声明 hooks 并生成 prepare 可复用的内容绑定收据
|
|
55
59
|
# 配置时刻即授权(FM-16 处置 A):hook 是任意本地进程、无隔离、触发前无确认点,
|
|
56
60
|
# 命令调用本身即授权执行配置中的 hooks
|