release-skill 0.9.4 → 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 +56 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +21 -17
- package/README.zh-CN.md +18 -16
- 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 +1036 -174
- package/adapters/claude/schemas/release-plan.schema.json +36 -0
- package/adapters/claude/schemas/release-project.schema.json +31 -0
- package/adapters/claude/skills/release-finish/SKILL.md +5 -5
- package/adapters/claude/skills/release-help/SKILL.md +7 -3
- package/adapters/claude/skills/release-verify/SKILL.md +14 -1
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1036 -174
- package/adapters/codex/schemas/release-plan.schema.json +36 -0
- package/adapters/codex/schemas/release-project.schema.json +31 -0
- package/adapters/codex/skills/release-finish/SKILL.md +5 -5
- package/adapters/codex/skills/release-help/SKILL.md +7 -3
- package/adapters/codex/skills/release-verify/SKILL.md +14 -1
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +1036 -174
- package/adapters/kimi/schemas/release-plan.schema.json +36 -0
- package/adapters/kimi/schemas/release-project.schema.json +31 -0
- package/adapters/kimi/skills/release-finish/SKILL.md +5 -5
- package/adapters/kimi/skills/release-help/SKILL.md +7 -3
- package/adapters/kimi/skills/release-verify/SKILL.md +14 -1
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +1036 -174
- package/adapters/workbuddy/schemas/release-plan.schema.json +36 -0
- package/adapters/workbuddy/schemas/release-project.schema.json +31 -0
- package/adapters/workbuddy/skills/release-finish/SKILL.md +5 -5
- package/adapters/workbuddy/skills/release-help/SKILL.md +7 -3
- package/adapters/workbuddy/skills/release-verify/SKILL.md +14 -1
- package/bin/release-skill-cli.mjs +217 -26
- package/bin/release-skill.bundle.mjs +1036 -174
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/schemas/release-plan.schema.json +36 -0
- package/schemas/release-project.schema.json +31 -0
- package/skills/release-finish/SKILL.md +5 -5
- package/skills/release-help/SKILL.md +7 -3
- package/skills/release-verify/SKILL.md +14 -1
- package/skills-src/release-finish/SKILL.md +5 -5
- package/skills-src/release-help/SKILL.md +7 -3
- package/skills-src/release-verify/SKILL.md +14 -1
- package/src/adapters/plugin-marketplace.mjs +54 -5
- package/src/commands/post-release-local.mjs +204 -10
- package/src/commands/prepare.mjs +178 -9
- package/src/commands/ship.mjs +26 -11
- package/src/commands/verify.mjs +175 -2
- package/src/core/plan.mjs +45 -1
- package/src/platforms/registry.mjs +97 -0
- package/src/readme/contract.mjs +23 -3
|
@@ -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;
|
|
@@ -19972,8 +19972,8 @@ var require_graceful_fs = __commonJS({
|
|
|
19972
19972
|
fs2.createReadStream = createReadStream2;
|
|
19973
19973
|
fs2.createWriteStream = createWriteStream;
|
|
19974
19974
|
var fs$readFile = fs2.readFile;
|
|
19975
|
-
fs2.readFile =
|
|
19976
|
-
function
|
|
19975
|
+
fs2.readFile = readFile57;
|
|
19976
|
+
function readFile57(path40, options, cb) {
|
|
19977
19977
|
if (typeof options === "function")
|
|
19978
19978
|
cb = options, options = null;
|
|
19979
19979
|
return go$readFile(path40, options, cb);
|
|
@@ -19989,7 +19989,7 @@ var require_graceful_fs = __commonJS({
|
|
|
19989
19989
|
}
|
|
19990
19990
|
__name(go$readFile, "go$readFile");
|
|
19991
19991
|
}
|
|
19992
|
-
__name(
|
|
19992
|
+
__name(readFile57, "readFile");
|
|
19993
19993
|
var fs$writeFile = fs2.writeFile;
|
|
19994
19994
|
fs2.writeFile = writeFile16;
|
|
19995
19995
|
function writeFile16(path40, data, options, cb) {
|
|
@@ -41768,6 +41768,91 @@ function getPlatform(id) {
|
|
|
41768
41768
|
if (!platform) throw new Error(`unknown platform: ${id}`);
|
|
41769
41769
|
return platform;
|
|
41770
41770
|
}
|
|
41771
|
+
function standaloneIdentityCore(platformOrId, fields) {
|
|
41772
|
+
const platform = typeof platformOrId === "string" ? getPlatform(platformOrId) : platformOrId;
|
|
41773
|
+
const id = platform?.id;
|
|
41774
|
+
if (id !== "claude" && id !== "codex") {
|
|
41775
|
+
throw new Error(`standalone-index install identity is unsupported for platform "${id ?? "<unknown>"}"`);
|
|
41776
|
+
}
|
|
41777
|
+
const { name, source, version } = fields;
|
|
41778
|
+
if (typeof name !== "string" || name.length === 0 || !source || typeof source !== "object" || Array.isArray(source) || typeof source.source !== "string" || typeof source.ref !== "string" || source.ref.length === 0 || typeof source.sha !== "string" || !STANDALONE_SHA_RE.test(source.sha)) {
|
|
41779
|
+
throw new Error(`${id} standalone-index install identity has invalid owned fields`);
|
|
41780
|
+
}
|
|
41781
|
+
if (id === "claude") {
|
|
41782
|
+
if (source.source !== "github" || typeof source.repo !== "string" || source.repo.length === 0 || typeof version !== "string" || version.length === 0) {
|
|
41783
|
+
throw new Error("Claude standalone-index install identity requires github repo, ref, sha, and version");
|
|
41784
|
+
}
|
|
41785
|
+
return {
|
|
41786
|
+
name,
|
|
41787
|
+
source: { source: "github", repo: source.repo, ref: source.ref, sha: source.sha },
|
|
41788
|
+
version
|
|
41789
|
+
};
|
|
41790
|
+
}
|
|
41791
|
+
if (source.source !== "url" || typeof source.url !== "string" || source.url.length === 0) {
|
|
41792
|
+
throw new Error("Codex standalone-index install identity requires url, ref, and sha");
|
|
41793
|
+
}
|
|
41794
|
+
return {
|
|
41795
|
+
name,
|
|
41796
|
+
source: { source: "url", url: source.url, ref: source.ref, sha: source.sha }
|
|
41797
|
+
};
|
|
41798
|
+
}
|
|
41799
|
+
function buildExpectedStandaloneIndexInstallIdentity(platformOrId, frozenIdentity = {}) {
|
|
41800
|
+
const platform = typeof platformOrId === "string" ? getPlatform(platformOrId) : platformOrId;
|
|
41801
|
+
const id = platform?.id;
|
|
41802
|
+
const { name, repo, tag, sha, version } = frozenIdentity;
|
|
41803
|
+
if (typeof repo !== "string" || repo.length === 0 || typeof tag !== "string" || tag.length === 0) {
|
|
41804
|
+
throw new Error("standalone-index expected identity requires a plugin repository and tag");
|
|
41805
|
+
}
|
|
41806
|
+
if (id === "claude") {
|
|
41807
|
+
return standaloneIdentityCore(platform, {
|
|
41808
|
+
name,
|
|
41809
|
+
version,
|
|
41810
|
+
source: { source: "github", repo, ref: tag, sha }
|
|
41811
|
+
});
|
|
41812
|
+
}
|
|
41813
|
+
if (id === "codex") {
|
|
41814
|
+
return standaloneIdentityCore(platform, {
|
|
41815
|
+
name,
|
|
41816
|
+
source: { source: "url", url: `https://github.com/${repo}.git`, ref: `refs/tags/${tag}`, sha }
|
|
41817
|
+
});
|
|
41818
|
+
}
|
|
41819
|
+
return standaloneIdentityCore(platform, { name, source: {}, version });
|
|
41820
|
+
}
|
|
41821
|
+
function projectObservedStandaloneIndexInstallIdentity(platformOrId, entry) {
|
|
41822
|
+
const platform = typeof platformOrId === "string" ? getPlatform(platformOrId) : platformOrId;
|
|
41823
|
+
const id = platform?.id;
|
|
41824
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
41825
|
+
throw new Error("standalone-index observed identity requires an entry object");
|
|
41826
|
+
}
|
|
41827
|
+
const source = entry.source;
|
|
41828
|
+
if (!source || typeof source !== "object" || Array.isArray(source)) {
|
|
41829
|
+
throw new Error("standalone-index observed identity requires a source object");
|
|
41830
|
+
}
|
|
41831
|
+
if (id === "claude") {
|
|
41832
|
+
return standaloneIdentityCore(platform, {
|
|
41833
|
+
name: entry.name,
|
|
41834
|
+
version: entry.version,
|
|
41835
|
+
source: {
|
|
41836
|
+
source: source.source,
|
|
41837
|
+
repo: source.repo,
|
|
41838
|
+
ref: source.ref,
|
|
41839
|
+
sha: source.sha
|
|
41840
|
+
}
|
|
41841
|
+
});
|
|
41842
|
+
}
|
|
41843
|
+
if (id === "codex") {
|
|
41844
|
+
return standaloneIdentityCore(platform, {
|
|
41845
|
+
name: entry.name,
|
|
41846
|
+
source: {
|
|
41847
|
+
source: source.source,
|
|
41848
|
+
url: source.url,
|
|
41849
|
+
ref: source.ref,
|
|
41850
|
+
sha: source.sha
|
|
41851
|
+
}
|
|
41852
|
+
});
|
|
41853
|
+
}
|
|
41854
|
+
return standaloneIdentityCore(platform, { name: entry.name, source });
|
|
41855
|
+
}
|
|
41771
41856
|
function resolveSkillProjectionSurfaceHost(surfaceId, registry = PLATFORMS) {
|
|
41772
41857
|
const platform = registry.find((item) => item.skillProjectionSurface === surfaceId);
|
|
41773
41858
|
return platform?.buildAdapter?.name ?? null;
|
|
@@ -41982,7 +42067,7 @@ async function normalizeHostId(hostId, { fallback = false } = {}) {
|
|
|
41982
42067
|
throw err;
|
|
41983
42068
|
}
|
|
41984
42069
|
}
|
|
41985
|
-
var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES, SKILL_PROJECTION_SURFACE_PATTERN, cachedHostsRoot, normalizedHostIds;
|
|
42070
|
+
var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES, SKILL_PROJECTION_SURFACE_PATTERN, STANDALONE_SHA_RE, cachedHostsRoot, normalizedHostIds;
|
|
41986
42071
|
var init_registry2 = __esm({
|
|
41987
42072
|
async "src/platforms/registry.mjs"() {
|
|
41988
42073
|
init_src3();
|
|
@@ -42269,6 +42354,10 @@ var init_registry2 = __esm({
|
|
|
42269
42354
|
VALID_DEGRADATION_POLICIES = /* @__PURE__ */ new Set(["block", "human-attestation", "human-attestation-with-fallback"]);
|
|
42270
42355
|
SKILL_PROJECTION_SURFACE_PATTERN = /^platforms\/[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
42271
42356
|
__name(getPlatform, "getPlatform");
|
|
42357
|
+
STANDALONE_SHA_RE = /^[0-9a-f]{40}$/u;
|
|
42358
|
+
__name(standaloneIdentityCore, "standaloneIdentityCore");
|
|
42359
|
+
__name(buildExpectedStandaloneIndexInstallIdentity, "buildExpectedStandaloneIndexInstallIdentity");
|
|
42360
|
+
__name(projectObservedStandaloneIndexInstallIdentity, "projectObservedStandaloneIndexInstallIdentity");
|
|
42272
42361
|
__name(resolveSkillProjectionSurfaceHost, "resolveSkillProjectionSurfaceHost");
|
|
42273
42362
|
__name(assertRegistry, "assertRegistry");
|
|
42274
42363
|
assertRegistry();
|
|
@@ -43160,6 +43249,7 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
43160
43249
|
}
|
|
43161
43250
|
if (production && externalMarketplace && dist.marketplaceSourceType === "standalone-index") {
|
|
43162
43251
|
const params = action.parameters;
|
|
43252
|
+
const bootstrap = dist.firstReleaseBootstrap === "manual-index-checkpoint";
|
|
43163
43253
|
if (params) {
|
|
43164
43254
|
if (!params.marketplaceIndexPath) {
|
|
43165
43255
|
failures.push(
|
|
@@ -43176,6 +43266,38 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
43176
43266
|
`unit "${unitId}", action "${action.id}": parameters.selectedEntry is required for production standalone-index`
|
|
43177
43267
|
);
|
|
43178
43268
|
}
|
|
43269
|
+
if (bootstrap) {
|
|
43270
|
+
if (params.firstReleaseBootstrap !== "manual-index-checkpoint") {
|
|
43271
|
+
failures.push(
|
|
43272
|
+
`unit "${unitId}", action "${action.id}": parameters.firstReleaseBootstrap must be manual-index-checkpoint for a bootstrap distribution`
|
|
43273
|
+
);
|
|
43274
|
+
}
|
|
43275
|
+
if (params.marketplaceIndexSha !== null) {
|
|
43276
|
+
failures.push(
|
|
43277
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplaceIndexSha must remain null until the manual index checkpoint`
|
|
43278
|
+
);
|
|
43279
|
+
}
|
|
43280
|
+
let expectedEntry = null;
|
|
43281
|
+
try {
|
|
43282
|
+
expectedEntry = buildExpectedStandaloneIndexInstallIdentity(platform, {
|
|
43283
|
+
name: plugin,
|
|
43284
|
+
version: targetVersion,
|
|
43285
|
+
repo: publicRepo,
|
|
43286
|
+
tag: expectedTag,
|
|
43287
|
+
sha: frozen?.commit
|
|
43288
|
+
});
|
|
43289
|
+
} catch {
|
|
43290
|
+
}
|
|
43291
|
+
if (!expectedEntry || canonicalJson2(params.selectedEntry) !== canonicalJson2(expectedEntry)) {
|
|
43292
|
+
failures.push(
|
|
43293
|
+
`unit "${unitId}", action "${action.id}": bootstrap selectedEntry does not match the frozen plugin repository, tag, commit, and version`
|
|
43294
|
+
);
|
|
43295
|
+
}
|
|
43296
|
+
} else if (params.firstReleaseBootstrap !== void 0 || params.marketplaceIndexSha !== void 0) {
|
|
43297
|
+
failures.push(
|
|
43298
|
+
`unit "${unitId}", action "${action.id}": bootstrap-only fields are not allowed without firstReleaseBootstrap`
|
|
43299
|
+
);
|
|
43300
|
+
}
|
|
43179
43301
|
}
|
|
43180
43302
|
}
|
|
43181
43303
|
if (!externalMarketplace && dist.marketplaceSourceType === "bundled-family") {
|
|
@@ -43205,6 +43327,14 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
43205
43327
|
_checkRequired(action, "expected.ref", action.expected?.ref, action.parameters?.ref, unitId, failures);
|
|
43206
43328
|
_checkRequired(action, "expected.marketplaceLocation", action.expected?.marketplaceLocation, "external", unitId, failures);
|
|
43207
43329
|
_checkRequired(action, "expected.marketplaceCommitSha", action.expected?.marketplaceCommitSha, action.parameters?.marketplaceCommitSha, unitId, failures);
|
|
43330
|
+
if (dist.firstReleaseBootstrap === "manual-index-checkpoint") {
|
|
43331
|
+
_checkRequired(action, "expected.firstReleaseBootstrap", action.expected?.firstReleaseBootstrap, "manual-index-checkpoint", unitId, failures);
|
|
43332
|
+
if (action.expected?.marketplaceIndexSha !== null) {
|
|
43333
|
+
failures.push(
|
|
43334
|
+
`unit "${unitId}", action "${action.id}": expected.marketplaceIndexSha must be null until the manual index checkpoint`
|
|
43335
|
+
);
|
|
43336
|
+
}
|
|
43337
|
+
}
|
|
43208
43338
|
} else {
|
|
43209
43339
|
_checkRequired(action, "expected.repo", action.expected?.repo, publicRepo, unitId, failures);
|
|
43210
43340
|
_checkRequired(action, "expected.ref", action.expected?.ref, expectedTag, unitId, failures);
|
|
@@ -59992,7 +60122,7 @@ var require_entry_index = __commonJS({
|
|
|
59992
60122
|
var {
|
|
59993
60123
|
appendFile,
|
|
59994
60124
|
mkdir: mkdir35,
|
|
59995
|
-
readFile:
|
|
60125
|
+
readFile: readFile57,
|
|
59996
60126
|
readdir: readdir34,
|
|
59997
60127
|
rm: rm19,
|
|
59998
60128
|
writeFile: writeFile16
|
|
@@ -60184,7 +60314,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
60184
60314
|
__name(ls, "ls");
|
|
60185
60315
|
module.exports.bucketEntries = bucketEntries;
|
|
60186
60316
|
async function bucketEntries(bucket, filter) {
|
|
60187
|
-
const data = await
|
|
60317
|
+
const data = await readFile57(bucket, "utf8");
|
|
60188
60318
|
return _bucketEntries(data, filter);
|
|
60189
60319
|
}
|
|
60190
60320
|
__name(bucketEntries, "bucketEntries");
|
|
@@ -64494,7 +64624,7 @@ var require_verify = __commonJS({
|
|
|
64494
64624
|
"use strict";
|
|
64495
64625
|
var {
|
|
64496
64626
|
mkdir: mkdir35,
|
|
64497
|
-
readFile:
|
|
64627
|
+
readFile: readFile57,
|
|
64498
64628
|
rm: rm19,
|
|
64499
64629
|
stat: stat22,
|
|
64500
64630
|
truncate,
|
|
@@ -64721,7 +64851,7 @@ var require_verify = __commonJS({
|
|
|
64721
64851
|
__name(writeVerifile, "writeVerifile");
|
|
64722
64852
|
module.exports.lastRun = lastRun;
|
|
64723
64853
|
async function lastRun(cache) {
|
|
64724
|
-
const data = await
|
|
64854
|
+
const data = await readFile57(path40.join(cache, "_lastverified"), { encoding: "utf8" });
|
|
64725
64855
|
return /* @__PURE__ */ new Date(+data);
|
|
64726
64856
|
}
|
|
64727
64857
|
__name(lastRun, "lastRun");
|
|
@@ -76643,11 +76773,11 @@ var require_normalize = __commonJS({
|
|
|
76643
76773
|
// ../../node_modules/.pnpm/@npmcli+package-json@7.0.5/node_modules/@npmcli/package-json/lib/read-package.js
|
|
76644
76774
|
var require_read_package = __commonJS({
|
|
76645
76775
|
"../../node_modules/.pnpm/@npmcli+package-json@7.0.5/node_modules/@npmcli/package-json/lib/read-package.js"(exports, module) {
|
|
76646
|
-
var { readFile:
|
|
76776
|
+
var { readFile: readFile57 } = __require("fs/promises");
|
|
76647
76777
|
var parseJSON = require_lib33();
|
|
76648
76778
|
async function read(filename) {
|
|
76649
76779
|
try {
|
|
76650
|
-
const data = await
|
|
76780
|
+
const data = await readFile57(filename, "utf8");
|
|
76651
76781
|
return data;
|
|
76652
76782
|
} catch (err) {
|
|
76653
76783
|
err.message = `Could not read package.json: ${err}`;
|
|
@@ -76780,7 +76910,7 @@ var require_sort2 = __commonJS({
|
|
|
76780
76910
|
// ../../node_modules/.pnpm/@npmcli+package-json@7.0.5/node_modules/@npmcli/package-json/lib/index.js
|
|
76781
76911
|
var require_lib40 = __commonJS({
|
|
76782
76912
|
"../../node_modules/.pnpm/@npmcli+package-json@7.0.5/node_modules/@npmcli/package-json/lib/index.js"(exports, module) {
|
|
76783
|
-
var { readFile:
|
|
76913
|
+
var { readFile: readFile57, writeFile: writeFile16 } = __require("node:fs/promises");
|
|
76784
76914
|
var { resolve: resolve42 } = __require("node:path");
|
|
76785
76915
|
var parseJSON = require_lib33();
|
|
76786
76916
|
var updateDeps = require_update_dependencies();
|
|
@@ -76906,7 +77036,7 @@ var require_lib40 = __commonJS({
|
|
|
76906
77036
|
const indexFile = resolve42(this.path, "index.js");
|
|
76907
77037
|
let indexFileContent;
|
|
76908
77038
|
try {
|
|
76909
|
-
indexFileContent = await
|
|
77039
|
+
indexFileContent = await readFile57(indexFile, "utf8");
|
|
76910
77040
|
} catch (err) {
|
|
76911
77041
|
throw parseErr;
|
|
76912
77042
|
}
|
|
@@ -89207,7 +89337,7 @@ var require_dist16 = __commonJS({
|
|
|
89207
89337
|
var require_provenance = __commonJS({
|
|
89208
89338
|
"../../node_modules/.pnpm/libnpmpublish@11.2.0/node_modules/libnpmpublish/lib/provenance.js"(exports, module) {
|
|
89209
89339
|
var sigstore = require_dist16();
|
|
89210
|
-
var { readFile:
|
|
89340
|
+
var { readFile: readFile57 } = __require("node:fs/promises");
|
|
89211
89341
|
var ci = require_ci_info();
|
|
89212
89342
|
var { env } = process;
|
|
89213
89343
|
var INTOTO_PAYLOAD_TYPE = "application/vnd.in-toto+json";
|
|
@@ -89399,7 +89529,7 @@ var require_provenance = __commonJS({
|
|
|
89399
89529
|
var verifyProvenance = /* @__PURE__ */ __name(async (subject, provenancePath) => {
|
|
89400
89530
|
let provenanceBundle;
|
|
89401
89531
|
try {
|
|
89402
|
-
provenanceBundle = JSON.parse(await
|
|
89532
|
+
provenanceBundle = JSON.parse(await readFile57(provenancePath));
|
|
89403
89533
|
} catch (err) {
|
|
89404
89534
|
err.message = `Invalid provenance provided: ${err.message}`;
|
|
89405
89535
|
throw err;
|
|
@@ -99484,7 +99614,7 @@ var require_entry_index2 = __commonJS({
|
|
|
99484
99614
|
var {
|
|
99485
99615
|
appendFile,
|
|
99486
99616
|
mkdir: mkdir35,
|
|
99487
|
-
readFile:
|
|
99617
|
+
readFile: readFile57,
|
|
99488
99618
|
readdir: readdir34,
|
|
99489
99619
|
rm: rm19,
|
|
99490
99620
|
writeFile: writeFile16
|
|
@@ -99676,7 +99806,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
99676
99806
|
__name(ls, "ls");
|
|
99677
99807
|
module.exports.bucketEntries = bucketEntries;
|
|
99678
99808
|
async function bucketEntries(bucket, filter) {
|
|
99679
|
-
const data = await
|
|
99809
|
+
const data = await readFile57(bucket, "utf8");
|
|
99680
99810
|
return _bucketEntries(data, filter);
|
|
99681
99811
|
}
|
|
99682
99812
|
__name(bucketEntries, "bucketEntries");
|
|
@@ -105365,7 +105495,7 @@ var require_verify3 = __commonJS({
|
|
|
105365
105495
|
"use strict";
|
|
105366
105496
|
var {
|
|
105367
105497
|
mkdir: mkdir35,
|
|
105368
|
-
readFile:
|
|
105498
|
+
readFile: readFile57,
|
|
105369
105499
|
rm: rm19,
|
|
105370
105500
|
stat: stat22,
|
|
105371
105501
|
truncate,
|
|
@@ -105592,7 +105722,7 @@ var require_verify3 = __commonJS({
|
|
|
105592
105722
|
__name(writeVerifile, "writeVerifile");
|
|
105593
105723
|
module.exports.lastRun = lastRun;
|
|
105594
105724
|
async function lastRun(cache) {
|
|
105595
|
-
const data = await
|
|
105725
|
+
const data = await readFile57(path40.join(cache, "_lastverified"), { encoding: "utf8" });
|
|
105596
105726
|
return /* @__PURE__ */ new Date(+data);
|
|
105597
105727
|
}
|
|
105598
105728
|
__name(lastRun, "lastRun");
|
|
@@ -109510,6 +109640,39 @@ function transportPayload(entries) {
|
|
|
109510
109640
|
contentDigest
|
|
109511
109641
|
}));
|
|
109512
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
|
+
}
|
|
109513
109676
|
function resolveMarketplaceRoot(platform, marketplaceIndexPath) {
|
|
109514
109677
|
const defaultMarketplace = platform.manifestPaths.marketplace;
|
|
109515
109678
|
if (!defaultMarketplace) {
|
|
@@ -109739,10 +109902,10 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
109739
109902
|
throw new Error(`unsupported marketplace payload contract: ${JSON.stringify(payloadContract)}`);
|
|
109740
109903
|
}
|
|
109741
109904
|
if (payloadContract === PAYLOAD_CONTRACT_DECLARED_MANIFEST || payloadContract === PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE) {
|
|
109742
|
-
const
|
|
109905
|
+
const installedMembers = await observeMarketplaceInstallTree(installPath);
|
|
109743
109906
|
const authorityPayload = transportPayload(authorityEntries);
|
|
109744
109907
|
const installedByPath = new Map(
|
|
109745
|
-
|
|
109908
|
+
installedMembers.map((entry) => [entry.path, entry])
|
|
109746
109909
|
);
|
|
109747
109910
|
const conflicts = [];
|
|
109748
109911
|
for (const authorityEntry of authorityPayload) {
|
|
@@ -109767,11 +109930,19 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
109767
109930
|
);
|
|
109768
109931
|
}
|
|
109769
109932
|
const authorityPaths = new Set(authorityPayload.map((entry) => entry.path));
|
|
109770
|
-
const
|
|
109933
|
+
const extraMembers = installedMembers.filter((entry) => entry.type !== "directory" && !authorityPaths.has(entry.path));
|
|
109934
|
+
const extraPaths = extraMembers.map((entry) => entry.path);
|
|
109771
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
|
+
}));
|
|
109772
109942
|
return {
|
|
109773
109943
|
manifestDigest: action.manifestDigest,
|
|
109774
109944
|
extraInstalledPaths,
|
|
109945
|
+
...extraInstalledLinks.length > 0 ? { extraInstalledLinks } : {},
|
|
109775
109946
|
...extraPaths.length > EXTRA_INSTALLED_PATHS_CAP ? { extraInstalledPathsTotal: extraPaths.length } : {}
|
|
109776
109947
|
};
|
|
109777
109948
|
}
|
|
@@ -109787,6 +109958,7 @@ function extraInstalledPathsAudit(binding) {
|
|
|
109787
109958
|
if (!binding || !Array.isArray(binding.extraInstalledPaths)) return {};
|
|
109788
109959
|
return {
|
|
109789
109960
|
extraInstalledPaths: binding.extraInstalledPaths,
|
|
109961
|
+
...Array.isArray(binding.extraInstalledLinks) && binding.extraInstalledLinks.length > 0 ? { extraInstalledLinks: binding.extraInstalledLinks } : {},
|
|
109790
109962
|
...binding.extraInstalledPathsTotal !== void 0 ? { extraInstalledPathsTotal: binding.extraInstalledPathsTotal } : {}
|
|
109791
109963
|
};
|
|
109792
109964
|
}
|
|
@@ -112190,6 +112362,7 @@ var init_plugin_marketplace = __esm({
|
|
|
112190
112362
|
async "src/adapters/plugin-marketplace.mjs"() {
|
|
112191
112363
|
init_contract();
|
|
112192
112364
|
init_installation_contract();
|
|
112365
|
+
init_src2();
|
|
112193
112366
|
init_frozen();
|
|
112194
112367
|
await init_registry2();
|
|
112195
112368
|
await init_kimi();
|
|
@@ -112202,6 +112375,8 @@ var init_plugin_marketplace = __esm({
|
|
|
112202
112375
|
PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE = "external-marketplace-v1";
|
|
112203
112376
|
EXTRA_INSTALLED_PATHS_CAP = 200;
|
|
112204
112377
|
PAYLOAD_CONFLICT_REPORT_CAP = 10;
|
|
112378
|
+
__name(foundationPayloadMembers, "foundationPayloadMembers");
|
|
112379
|
+
__name(observeMarketplaceInstallTree, "observeMarketplaceInstallTree");
|
|
112205
112380
|
CONSUMER_INSTALL_RECIPE_VERSION = "consumer-install-v1";
|
|
112206
112381
|
__name(resolveMarketplaceRoot, "resolveMarketplaceRoot");
|
|
112207
112382
|
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
@@ -112391,6 +112566,136 @@ async function verifyPublicSourceAuthorityReceiptOffline({ plan, root }) {
|
|
|
112391
112566
|
function defaultClock() {
|
|
112392
112567
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
112393
112568
|
}
|
|
112569
|
+
function parseMarketplaceHead(stdout) {
|
|
112570
|
+
if (typeof stdout !== "string") return null;
|
|
112571
|
+
let sha = null;
|
|
112572
|
+
let defaultBranch = null;
|
|
112573
|
+
for (const line of stdout.trim().split("\n").filter(Boolean)) {
|
|
112574
|
+
const tab = line.indexOf(" ");
|
|
112575
|
+
if (tab < 0) continue;
|
|
112576
|
+
const left = line.slice(0, tab);
|
|
112577
|
+
const right = line.slice(tab + 1);
|
|
112578
|
+
if (right !== "HEAD") continue;
|
|
112579
|
+
if (left.startsWith("ref: refs/heads/")) defaultBranch = left.slice("ref: refs/heads/".length);
|
|
112580
|
+
else if (EXTERNAL_MARKETPLACE_SHA_RE2.test(left)) sha = left;
|
|
112581
|
+
}
|
|
112582
|
+
return sha && defaultBranch ? { sha, defaultBranch } : null;
|
|
112583
|
+
}
|
|
112584
|
+
async function defaultObserveMarketplaceHead(repo, { githubHost = "github.com" } = {}) {
|
|
112585
|
+
try {
|
|
112586
|
+
const { stdout } = await execFile6("git", [
|
|
112587
|
+
"ls-remote",
|
|
112588
|
+
"--symref",
|
|
112589
|
+
`https://${githubHost}/${repo}.git`,
|
|
112590
|
+
"HEAD"
|
|
112591
|
+
], { shell: false, encoding: "utf8", timeout: 3e4 });
|
|
112592
|
+
const parsed = parseMarketplaceHead(stdout);
|
|
112593
|
+
return parsed ? { status: "observed", ...parsed } : { status: "unknown", error: "could not resolve marketplace HEAD" };
|
|
112594
|
+
} catch (error) {
|
|
112595
|
+
return { status: "unknown", error: error.message };
|
|
112596
|
+
}
|
|
112597
|
+
}
|
|
112598
|
+
function decodeMarketplaceIndex(content) {
|
|
112599
|
+
if (typeof content !== "string") return null;
|
|
112600
|
+
try {
|
|
112601
|
+
return JSON.parse(Buffer.from(content.replace(/\s/g, ""), "base64").toString("utf8"));
|
|
112602
|
+
} catch {
|
|
112603
|
+
return null;
|
|
112604
|
+
}
|
|
112605
|
+
}
|
|
112606
|
+
async function defaultFetchMarketplaceIndex(repo, path40, ref, { githubHost = "github.com" } = {}) {
|
|
112607
|
+
try {
|
|
112608
|
+
const { stdout } = await execFile6("gh", [
|
|
112609
|
+
"api",
|
|
112610
|
+
`repos/${repo}/contents/${path40}?ref=${ref}`,
|
|
112611
|
+
"--jq",
|
|
112612
|
+
".content"
|
|
112613
|
+
], {
|
|
112614
|
+
shell: false,
|
|
112615
|
+
encoding: "utf8",
|
|
112616
|
+
timeout: 3e4,
|
|
112617
|
+
env: { ...process.env, GH_HOST: githubHost }
|
|
112618
|
+
});
|
|
112619
|
+
const index = decodeMarketplaceIndex(stdout);
|
|
112620
|
+
return index && typeof index === "object" ? { status: "fetched", index } : { status: "unknown", error: "could not decode marketplace index" };
|
|
112621
|
+
} catch (error) {
|
|
112622
|
+
return { status: "unknown", error: error.message };
|
|
112623
|
+
}
|
|
112624
|
+
}
|
|
112625
|
+
async function verifyFirstReleaseBootstrapIndexes({
|
|
112626
|
+
actions,
|
|
112627
|
+
plan,
|
|
112628
|
+
evidence,
|
|
112629
|
+
observeHeadFn,
|
|
112630
|
+
fetchIndexFn
|
|
112631
|
+
}) {
|
|
112632
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
112633
|
+
for (const action of actions) {
|
|
112634
|
+
if (action.parameters?.firstReleaseBootstrap !== FIRST_RELEASE_BOOTSTRAP_MODE) continue;
|
|
112635
|
+
const params = action.parameters;
|
|
112636
|
+
const githubHost = params.githubHost ?? "github.com";
|
|
112637
|
+
const failDeferred = /* @__PURE__ */ __name(async (reason, observed2 = null) => {
|
|
112638
|
+
await evidence.append({
|
|
112639
|
+
phase: "verify-marketplace-bootstrap-index",
|
|
112640
|
+
actionId: action.id,
|
|
112641
|
+
actionType: action.type,
|
|
112642
|
+
status: "needs-input",
|
|
112643
|
+
reason,
|
|
112644
|
+
...observed2 ? { observed: observed2 } : {}
|
|
112645
|
+
});
|
|
112646
|
+
throw new ReleaseError(
|
|
112647
|
+
CONSUMER_VERIFICATION_DEFERRED,
|
|
112648
|
+
`first-release bootstrap marketplace index is not an exact match for action "${action.id}"; complete the manual index checkpoint and retry verify with the same plan`,
|
|
112649
|
+
{ actionId: action.id, reason, observed: observed2, nextState: "NEEDS_MANUAL_ATTESTATIONS" }
|
|
112650
|
+
);
|
|
112651
|
+
}, "failDeferred");
|
|
112652
|
+
const observed = await observeHeadFn(params.repo, { githubHost });
|
|
112653
|
+
if (observed?.status !== "observed" || !EXTERNAL_MARKETPLACE_SHA_RE2.test(observed.sha ?? "") || !observed.defaultBranch) {
|
|
112654
|
+
await failDeferred(`could not observe current marketplace HEAD: ${observed?.error ?? "unknown"}`, observed);
|
|
112655
|
+
}
|
|
112656
|
+
const path40 = params.marketplaceIndexPath;
|
|
112657
|
+
const fetched = await fetchIndexFn(params.repo, path40, observed.sha, { githubHost });
|
|
112658
|
+
if (fetched?.status !== "fetched" || !fetched.index || typeof fetched.index !== "object") {
|
|
112659
|
+
await failDeferred(`could not read marketplace index at ${observed.sha}: ${fetched?.error ?? "unknown"}`, observed);
|
|
112660
|
+
}
|
|
112661
|
+
const index = fetched.index;
|
|
112662
|
+
if (index.name !== params.marketplaceName) {
|
|
112663
|
+
await failDeferred(`marketplace name mismatch: expected ${params.marketplaceName}, got ${index.name}`, { ...observed, name: index.name });
|
|
112664
|
+
}
|
|
112665
|
+
if (!Array.isArray(index.plugins)) {
|
|
112666
|
+
await failDeferred("marketplace index plugins must be an array", { ...observed, pluginsType: typeof index.plugins });
|
|
112667
|
+
}
|
|
112668
|
+
const entries = index.plugins.filter((entry) => entry && entry.name === params.plugin);
|
|
112669
|
+
let projectedEntry = null;
|
|
112670
|
+
if (entries.length === 1) {
|
|
112671
|
+
try {
|
|
112672
|
+
projectedEntry = projectObservedStandaloneIndexInstallIdentity(params.consumer, entries[0]);
|
|
112673
|
+
} catch {
|
|
112674
|
+
projectedEntry = null;
|
|
112675
|
+
}
|
|
112676
|
+
}
|
|
112677
|
+
if (entries.length !== 1 || !projectedEntry || canonicalJson2(projectedEntry) !== canonicalJson2(params.selectedEntry)) {
|
|
112678
|
+
await failDeferred("marketplace selectedEntry is missing, duplicated, or does not exactly match the plan-bound expected entry", {
|
|
112679
|
+
...observed,
|
|
112680
|
+
entryCount: entries.length,
|
|
112681
|
+
selectedEntry: projectedEntry ?? entries[0] ?? null
|
|
112682
|
+
});
|
|
112683
|
+
}
|
|
112684
|
+
bindings.set(action.id, {
|
|
112685
|
+
marketplaceIndexSha: observed.sha,
|
|
112686
|
+
marketplaceIndexRef: action.type === "claude-marketplace-install" ? observed.defaultBranch : observed.sha
|
|
112687
|
+
});
|
|
112688
|
+
await evidence.append({
|
|
112689
|
+
phase: "verify-marketplace-bootstrap-index",
|
|
112690
|
+
actionId: action.id,
|
|
112691
|
+
actionType: action.type,
|
|
112692
|
+
status: "observed",
|
|
112693
|
+
marketplaceIndexSha: observed.sha,
|
|
112694
|
+
marketplaceIndexRef: action.type === "claude-marketplace-install" ? observed.defaultBranch : observed.sha
|
|
112695
|
+
});
|
|
112696
|
+
}
|
|
112697
|
+
return bindings;
|
|
112698
|
+
}
|
|
112394
112699
|
function isValidDigest2(digest3) {
|
|
112395
112700
|
return typeof digest3 === "string" && /^[a-f0-9]{64}$/.test(digest3);
|
|
112396
112701
|
}
|
|
@@ -112925,7 +113230,9 @@ async function verifyRelease(options) {
|
|
|
112925
113230
|
previousVerifyRun,
|
|
112926
113231
|
execFn,
|
|
112927
113232
|
configPath: configPathOpt,
|
|
112928
|
-
runPluginVerificationFn
|
|
113233
|
+
runPluginVerificationFn,
|
|
113234
|
+
observeFirstReleaseMarketplaceHeadFn,
|
|
113235
|
+
fetchFirstReleaseMarketplaceIndexFn
|
|
112929
113236
|
} = options ?? {};
|
|
112930
113237
|
const clockFn = typeof clockOpt === "function" ? clockOpt : defaultClock;
|
|
112931
113238
|
if (!sourceRunPath) {
|
|
@@ -113139,6 +113446,13 @@ async function verifyRelease(options) {
|
|
|
113139
113446
|
const consumerGateResults = [];
|
|
113140
113447
|
const consumerVerificationReceipts = [];
|
|
113141
113448
|
const actions = plan.externalActions ?? [];
|
|
113449
|
+
const bootstrapIndexBindings = await verifyFirstReleaseBootstrapIndexes({
|
|
113450
|
+
actions,
|
|
113451
|
+
plan,
|
|
113452
|
+
evidence,
|
|
113453
|
+
observeHeadFn: observeFirstReleaseMarketplaceHeadFn ?? defaultObserveMarketplaceHead,
|
|
113454
|
+
fetchIndexFn: fetchFirstReleaseMarketplaceIndexFn ?? defaultFetchMarketplaceIndex
|
|
113455
|
+
});
|
|
113142
113456
|
const trustedVerifyRuns = [];
|
|
113143
113457
|
const planDir = dirname10(planPath);
|
|
113144
113458
|
const releaseDir = basename9(planDir) === "plans" ? dirname10(planDir) : planDir;
|
|
@@ -113335,10 +113649,21 @@ async function verifyRelease(options) {
|
|
|
113335
113649
|
root,
|
|
113336
113650
|
runDir
|
|
113337
113651
|
};
|
|
113652
|
+
const bootstrapBinding = bootstrapIndexBindings.get(action.id) ?? null;
|
|
113338
113653
|
const actionInput = {
|
|
113339
113654
|
actionType: adapterActionType,
|
|
113340
113655
|
...action.parameters
|
|
113341
113656
|
};
|
|
113657
|
+
if (bootstrapBinding) {
|
|
113658
|
+
actionInput.marketplaceCommitSha = bootstrapBinding.marketplaceIndexSha;
|
|
113659
|
+
actionInput.marketplaceIndexSha = bootstrapBinding.marketplaceIndexSha;
|
|
113660
|
+
actionInput.ref = bootstrapBinding.marketplaceIndexRef;
|
|
113661
|
+
actionInput.sourceDescriptor = {
|
|
113662
|
+
...actionInput.sourceDescriptor,
|
|
113663
|
+
marketplaceCommitSha: bootstrapBinding.marketplaceIndexSha,
|
|
113664
|
+
ref: bootstrapBinding.marketplaceIndexRef
|
|
113665
|
+
};
|
|
113666
|
+
}
|
|
113342
113667
|
const unit = (plan.units ?? []).find((u) => u.id === action.unitId);
|
|
113343
113668
|
const typeToDist = {
|
|
113344
113669
|
"claude-marketplace-install": "claude-plugin",
|
|
@@ -113392,6 +113717,7 @@ async function verifyRelease(options) {
|
|
|
113392
113717
|
actionType: action.type,
|
|
113393
113718
|
status: VERIFICATION_RESOLVED_TYPES.NOT_REQUIRED_UNCHANGED,
|
|
113394
113719
|
installationContractDigest: currentDigest,
|
|
113720
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {},
|
|
113395
113721
|
reason: "\u5B89\u88C5\u5951\u7EA6\u6458\u8981\u672A\u53D8\u5316\uFF0C\u8DF3\u8FC7\u9A8C\u8BC1"
|
|
113396
113722
|
});
|
|
113397
113723
|
consumerVerificationReceipts.push({
|
|
@@ -113409,7 +113735,8 @@ async function verifyRelease(options) {
|
|
|
113409
113735
|
actionId: action.id,
|
|
113410
113736
|
actionType: action.type,
|
|
113411
113737
|
status: VERIFICATION_RESOLVED_TYPES.NOT_REQUIRED_UNCHANGED,
|
|
113412
|
-
installationContractDigest: currentDigest
|
|
113738
|
+
installationContractDigest: currentDigest,
|
|
113739
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {}
|
|
113413
113740
|
});
|
|
113414
113741
|
return;
|
|
113415
113742
|
}
|
|
@@ -113428,8 +113755,14 @@ async function verifyRelease(options) {
|
|
|
113428
113755
|
{ actionId: action.id }
|
|
113429
113756
|
);
|
|
113430
113757
|
}
|
|
113758
|
+
const expectedInput = bootstrapBinding ? {
|
|
113759
|
+
...action.expected,
|
|
113760
|
+
marketplaceCommitSha: bootstrapBinding.marketplaceIndexSha,
|
|
113761
|
+
marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha,
|
|
113762
|
+
ref: bootstrapBinding.marketplaceIndexRef
|
|
113763
|
+
} : action.expected;
|
|
113431
113764
|
const verifyResult = await adapter.verify(
|
|
113432
|
-
{ ...actionInput, expected:
|
|
113765
|
+
{ ...actionInput, expected: expectedInput },
|
|
113433
113766
|
marketplaceContext
|
|
113434
113767
|
);
|
|
113435
113768
|
const isHumanConfirmed = verifyResult.observation?.humanConfirmed === true;
|
|
@@ -113440,6 +113773,7 @@ async function verifyRelease(options) {
|
|
|
113440
113773
|
status: resolvedStatus,
|
|
113441
113774
|
observation: verifyResult.observation,
|
|
113442
113775
|
error: verifyResult.error,
|
|
113776
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {},
|
|
113443
113777
|
...dist?.installationContractDigest ? { installationContractDigest: dist.installationContractDigest } : {}
|
|
113444
113778
|
};
|
|
113445
113779
|
adapterChecks.push(check);
|
|
@@ -113459,7 +113793,8 @@ async function verifyRelease(options) {
|
|
|
113459
113793
|
phase: "verify-marketplace",
|
|
113460
113794
|
actionId: action.id,
|
|
113461
113795
|
actionType: action.type,
|
|
113462
|
-
status: check.status
|
|
113796
|
+
status: check.status,
|
|
113797
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {}
|
|
113463
113798
|
});
|
|
113464
113799
|
if (check.status === "FAILED") {
|
|
113465
113800
|
throw new ReleaseError(
|
|
@@ -113899,7 +114234,7 @@ async function verifyRelease(options) {
|
|
|
113899
114234
|
throw err;
|
|
113900
114235
|
}
|
|
113901
114236
|
}
|
|
113902
|
-
var execFile6, VERIFICATION_RESOLVED_TYPES, ADAPTER_ACTION_TYPE_MAP2, defaultNpmExecutor;
|
|
114237
|
+
var execFile6, VERIFICATION_RESOLVED_TYPES, ADAPTER_ACTION_TYPE_MAP2, FIRST_RELEASE_BOOTSTRAP_MODE, EXTERNAL_MARKETPLACE_SHA_RE2, defaultNpmExecutor;
|
|
113903
114238
|
var init_verify = __esm({
|
|
113904
114239
|
async "src/commands/verify.mjs"() {
|
|
113905
114240
|
init_src2();
|
|
@@ -113918,6 +114253,7 @@ var init_verify = __esm({
|
|
|
113918
114253
|
init_frozen_marker();
|
|
113919
114254
|
await init_foundation_plugin_verification();
|
|
113920
114255
|
init_public_path();
|
|
114256
|
+
init_digest();
|
|
113921
114257
|
init_npm();
|
|
113922
114258
|
init_verification_gates();
|
|
113923
114259
|
await init_skill_resource_closure();
|
|
@@ -113948,6 +114284,13 @@ var init_verify = __esm({
|
|
|
113948
114284
|
"codebuddy-marketplace-install": "codebuddy-marketplace-install"
|
|
113949
114285
|
};
|
|
113950
114286
|
__name(defaultClock, "defaultClock");
|
|
114287
|
+
FIRST_RELEASE_BOOTSTRAP_MODE = "manual-index-checkpoint";
|
|
114288
|
+
EXTERNAL_MARKETPLACE_SHA_RE2 = /^[0-9a-f]{40}$/;
|
|
114289
|
+
__name(parseMarketplaceHead, "parseMarketplaceHead");
|
|
114290
|
+
__name(defaultObserveMarketplaceHead, "defaultObserveMarketplaceHead");
|
|
114291
|
+
__name(decodeMarketplaceIndex, "decodeMarketplaceIndex");
|
|
114292
|
+
__name(defaultFetchMarketplaceIndex, "defaultFetchMarketplaceIndex");
|
|
114293
|
+
__name(verifyFirstReleaseBootstrapIndexes, "verifyFirstReleaseBootstrapIndexes");
|
|
113951
114294
|
__name(isValidDigest2, "isValidDigest");
|
|
113952
114295
|
__name(collectMissingManualAttestations, "collectMissingManualAttestations");
|
|
113953
114296
|
__name(matchesSubset2, "matchesSubset");
|
|
@@ -121372,6 +121715,17 @@ function extractManifestSkillNames(skills) {
|
|
|
121372
121715
|
function findSkillNames(content, manifestSkillNames) {
|
|
121373
121716
|
return manifestSkillNames.filter((name) => content.includes(name));
|
|
121374
121717
|
}
|
|
121718
|
+
function hasInstallCommand(content) {
|
|
121719
|
+
if (/npm\s+install|npx\s+release-skill|npm\s+i\s+release-skill/i.test(content)) {
|
|
121720
|
+
return true;
|
|
121721
|
+
}
|
|
121722
|
+
const codeBlocks = [
|
|
121723
|
+
...[...content.matchAll(/```[^\n]*\n([\s\S]*?)```/g)].map((match) => match[1]),
|
|
121724
|
+
...[...content.matchAll(/`([^`\n]+)`/g)].map((match) => match[1])
|
|
121725
|
+
];
|
|
121726
|
+
const pluginInstall = /^(?:[$>]\s*)?(?:codex\s+plugin\s+add|claude\s+plugin\s+install)\s+\S+/i;
|
|
121727
|
+
return codeBlocks.some((block) => block.split("\n").some((line) => pluginInstall.test(line.trim())));
|
|
121728
|
+
}
|
|
121375
121729
|
async function evaluateReadme({ snapshotDir, pluginManifest }) {
|
|
121376
121730
|
const findings = [];
|
|
121377
121731
|
const enPath = path39.join(snapshotDir, "README.md");
|
|
@@ -121412,7 +121766,7 @@ async function evaluateReadme({ snapshotDir, pluginManifest }) {
|
|
|
121412
121766
|
safeFirstCommand: enMarkers.has("safe-first-command")
|
|
121413
121767
|
};
|
|
121414
121768
|
const readabilityChecks = {
|
|
121415
|
-
hasInstall: enContent ?
|
|
121769
|
+
hasInstall: enContent ? hasInstallCommand(enContent) : false,
|
|
121416
121770
|
hasMinimalExample: enContent ? /```[\s\S]*?(release-skill|assess|prepare|help)[\s\S]*?```/i.test(enContent) : false,
|
|
121417
121771
|
hasFailureDiagnosis: enContent ? /CONFIG_INVALID|PARTIAL|GATE_FAILED|if.*fail|如果.*失败|故障|troubleshoot/i.test(enContent) : false,
|
|
121418
121772
|
hasNextSteps: enContent ? /next.*step|下一步|后续|see.*also|参阅|进一步/i.test(enContent) : false
|
|
@@ -121472,6 +121826,7 @@ var init_contract2 = __esm({
|
|
|
121472
121826
|
__name(resolveSkillName, "resolveSkillName");
|
|
121473
121827
|
__name(extractManifestSkillNames, "extractManifestSkillNames");
|
|
121474
121828
|
__name(findSkillNames, "findSkillNames");
|
|
121829
|
+
__name(hasInstallCommand, "hasInstallCommand");
|
|
121475
121830
|
__name(evaluateReadme, "evaluateReadme");
|
|
121476
121831
|
}
|
|
121477
121832
|
});
|
|
@@ -127335,6 +127690,7 @@ __export(prepare_exports, {
|
|
|
127335
127690
|
decodeExternalMarketplaceIndex: () => decodeExternalMarketplaceIndex,
|
|
127336
127691
|
observeOriginAhead: () => observeOriginAhead,
|
|
127337
127692
|
parseExternalMarketplaceLsRemote: () => parseExternalMarketplaceLsRemote,
|
|
127693
|
+
parseFirstReleasePluginRepositoryRefs: () => parseFirstReleasePluginRepositoryRefs,
|
|
127338
127694
|
prepareRelease: () => prepareRelease,
|
|
127339
127695
|
readHeadCommitTimestamp: () => readHeadCommitTimestamp,
|
|
127340
127696
|
readLatestFrozenPlan: () => readLatestFrozenPlan,
|
|
@@ -128204,7 +128560,7 @@ function parseExternalMarketplaceLsRemote(stdout) {
|
|
|
128204
128560
|
if (right !== "HEAD") continue;
|
|
128205
128561
|
if (left.startsWith("ref: refs/heads/")) {
|
|
128206
128562
|
defaultBranch = left.slice("ref: refs/heads/".length);
|
|
128207
|
-
} else if (
|
|
128563
|
+
} else if (EXTERNAL_MARKETPLACE_SHA_RE3.test(left)) {
|
|
128208
128564
|
sha = left;
|
|
128209
128565
|
}
|
|
128210
128566
|
}
|
|
@@ -128259,13 +128615,74 @@ async function defaultFetchExternalMarketplaceIndex(repo, manifestPath, ref, { g
|
|
|
128259
128615
|
return { status: "unknown", error: error.message };
|
|
128260
128616
|
}
|
|
128261
128617
|
}
|
|
128618
|
+
function parseFirstReleasePluginRepositoryRefs(stdout, tag) {
|
|
128619
|
+
if (typeof stdout !== "string" || typeof tag !== "string" || tag.length === 0) {
|
|
128620
|
+
return { hasRefs: false, tagExists: false };
|
|
128621
|
+
}
|
|
128622
|
+
const refs = [];
|
|
128623
|
+
let hasRefs = false;
|
|
128624
|
+
for (const line of stdout.trim().split("\n").filter(Boolean)) {
|
|
128625
|
+
const tabIndex = line.indexOf(" ");
|
|
128626
|
+
if (tabIndex < 0) continue;
|
|
128627
|
+
const sha = line.slice(0, tabIndex);
|
|
128628
|
+
const ref = line.slice(tabIndex + 1);
|
|
128629
|
+
if (EXTERNAL_MARKETPLACE_SHA_RE3.test(sha)) {
|
|
128630
|
+
hasRefs = true;
|
|
128631
|
+
if (ref && ref !== "HEAD") refs.push(ref);
|
|
128632
|
+
}
|
|
128633
|
+
}
|
|
128634
|
+
const target = `refs/tags/${tag}`;
|
|
128635
|
+
return {
|
|
128636
|
+
hasRefs,
|
|
128637
|
+
tagExists: refs.includes(target) || refs.includes(`${target}^{}`)
|
|
128638
|
+
};
|
|
128639
|
+
}
|
|
128640
|
+
async function defaultObserveFirstReleasePluginRepository(repo, tag, { githubHost = "github.com" } = {}) {
|
|
128641
|
+
const url = `https://${githubHost}/${repo}.git`;
|
|
128642
|
+
let repositoryRefs;
|
|
128643
|
+
try {
|
|
128644
|
+
const { stdout } = await execFile9(
|
|
128645
|
+
"git",
|
|
128646
|
+
["ls-remote", "--symref", url],
|
|
128647
|
+
{ shell: false, encoding: "utf8", timeout: 3e4 }
|
|
128648
|
+
);
|
|
128649
|
+
repositoryRefs = parseFirstReleasePluginRepositoryRefs(String(stdout ?? ""), tag);
|
|
128650
|
+
} catch (error) {
|
|
128651
|
+
return { status: "unknown", error: error.message };
|
|
128652
|
+
}
|
|
128653
|
+
let releaseExists = false;
|
|
128654
|
+
try {
|
|
128655
|
+
await execFile9(
|
|
128656
|
+
"gh",
|
|
128657
|
+
["api", `repos/${repo}/releases/tags/${tag}`],
|
|
128658
|
+
{
|
|
128659
|
+
shell: false,
|
|
128660
|
+
encoding: "utf8",
|
|
128661
|
+
timeout: 3e4,
|
|
128662
|
+
env: { ...process.env, GH_HOST: githubHost }
|
|
128663
|
+
}
|
|
128664
|
+
);
|
|
128665
|
+
releaseExists = true;
|
|
128666
|
+
} catch (error) {
|
|
128667
|
+
const diagnostic = `${error?.stderr ?? ""} ${error?.message ?? ""}`;
|
|
128668
|
+
if (!/\b404\b|not found/i.test(diagnostic)) {
|
|
128669
|
+
return { status: "unknown", error: error.message };
|
|
128670
|
+
}
|
|
128671
|
+
}
|
|
128672
|
+
return { status: repositoryRefs.hasRefs ? "non-empty" : "empty", tagExists: repositoryRefs.tagExists, releaseExists };
|
|
128673
|
+
}
|
|
128674
|
+
function isFirstReleaseBootstrap(dist) {
|
|
128675
|
+
return dist?.firstReleaseBootstrap === FIRST_RELEASE_BOOTSTRAP_MODE2;
|
|
128676
|
+
}
|
|
128262
128677
|
async function resolveExternalMarketplaceFreezes({
|
|
128263
128678
|
unitResults,
|
|
128264
128679
|
resolvedVersions,
|
|
128265
128680
|
offline,
|
|
128266
128681
|
evidence,
|
|
128267
128682
|
observeHeadFn,
|
|
128268
|
-
fetchIndexFn
|
|
128683
|
+
fetchIndexFn,
|
|
128684
|
+
productionAssets = null,
|
|
128685
|
+
observePluginRepositoryFn = defaultObserveFirstReleasePluginRepository
|
|
128269
128686
|
}) {
|
|
128270
128687
|
const freezes = /* @__PURE__ */ new Map();
|
|
128271
128688
|
for (let index = 0; index < unitResults.length; index += 1) {
|
|
@@ -128273,8 +128690,24 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128273
128690
|
const version = resolvedVersions[index];
|
|
128274
128691
|
const githubHost = unit.production?.githubHost ?? "github.com";
|
|
128275
128692
|
for (const dist of unit.distributions ?? []) {
|
|
128693
|
+
if (isFirstReleaseBootstrap(dist) && dist.marketplaceSourceType !== "standalone-index") {
|
|
128694
|
+
throw new ReleaseError(
|
|
128695
|
+
GATE_FAILED,
|
|
128696
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires marketplaceSourceType standalone-index`,
|
|
128697
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128698
|
+
);
|
|
128699
|
+
}
|
|
128276
128700
|
if (dist.marketplaceSourceType !== "standalone-index") continue;
|
|
128277
|
-
if (!dist.marketplaceRepo)
|
|
128701
|
+
if (!dist.marketplaceRepo) {
|
|
128702
|
+
if (isFirstReleaseBootstrap(dist)) {
|
|
128703
|
+
throw new ReleaseError(
|
|
128704
|
+
GATE_FAILED,
|
|
128705
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires marketplaceRepo`,
|
|
128706
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128707
|
+
);
|
|
128708
|
+
}
|
|
128709
|
+
continue;
|
|
128710
|
+
}
|
|
128278
128711
|
const platform = PLATFORMS.find((p) => p.distributionType === dist.type);
|
|
128279
128712
|
if (!platform) {
|
|
128280
128713
|
throw new ReleaseError(
|
|
@@ -128290,8 +128723,15 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128290
128723
|
{ unitId: unit.id, marketplaceSourceType: dist.marketplaceSourceType }
|
|
128291
128724
|
);
|
|
128292
128725
|
}
|
|
128726
|
+
if (isFirstReleaseBootstrap(dist) && dist.type !== "claude-plugin" && dist.type !== "codex-plugin") {
|
|
128727
|
+
throw new ReleaseError(
|
|
128728
|
+
GATE_FAILED,
|
|
128729
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap is supported only for claude-plugin or codex-plugin standalone-index distributions`,
|
|
128730
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128731
|
+
);
|
|
128732
|
+
}
|
|
128293
128733
|
const observed = await observeHeadFn(dist.marketplaceRepo, { githubHost });
|
|
128294
|
-
if (observed.status !== "observed" || !
|
|
128734
|
+
if (observed.status !== "observed" || !EXTERNAL_MARKETPLACE_SHA_RE3.test(observed.sha ?? "") || !observed.defaultBranch) {
|
|
128295
128735
|
throw new ReleaseError(
|
|
128296
128736
|
GATE_FAILED,
|
|
128297
128737
|
`unit "${unit.id}" could not freeze external marketplace "${dist.marketplaceRepo}" HEAD: ${observed.error ?? "unknown"}`,
|
|
@@ -128323,21 +128763,61 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128323
128763
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128324
128764
|
);
|
|
128325
128765
|
}
|
|
128326
|
-
|
|
128327
|
-
|
|
128766
|
+
if (!Array.isArray(marketplaceIndex.plugins)) {
|
|
128767
|
+
throw new ReleaseError(
|
|
128768
|
+
GATE_FAILED,
|
|
128769
|
+
`unit "${unit.id}" ${dist.type} external marketplace index plugins must be an array`,
|
|
128770
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128771
|
+
);
|
|
128772
|
+
}
|
|
128773
|
+
const pluginEntries = marketplaceIndex.plugins.filter((entry) => entry && entry.name === dist.plugin);
|
|
128774
|
+
if (isFirstReleaseBootstrap(dist) && pluginEntries.length > 0) {
|
|
128775
|
+
throw new ReleaseError(
|
|
128776
|
+
GATE_FAILED,
|
|
128777
|
+
`unit "${unit.id}" first-release bootstrap requires the marketplace entry to be absent, found ${pluginEntries.length} matching entries`,
|
|
128778
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128779
|
+
);
|
|
128780
|
+
}
|
|
128781
|
+
if (pluginEntries.length !== 1 && !isFirstReleaseBootstrap(dist)) {
|
|
128328
128782
|
throw new ReleaseError(
|
|
128329
128783
|
GATE_FAILED,
|
|
128330
128784
|
`unit "${unit.id}" external marketplace index must contain exactly one plugin entry named "${dist.plugin}", found ${pluginEntries.length}`,
|
|
128331
128785
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128332
128786
|
);
|
|
128333
128787
|
}
|
|
128334
|
-
|
|
128788
|
+
let selectedEntry = pluginEntries[0];
|
|
128789
|
+
if (!isFirstReleaseBootstrap(dist) && platform.marketplaceEntryCarriesVersion && selectedEntry.version !== version) {
|
|
128335
128790
|
throw new ReleaseError(
|
|
128336
128791
|
GATE_FAILED,
|
|
128337
128792
|
`unit "${unit.id}" external marketplace index entry version "${pluginEntries[0].version}" does not match target version "${version}"`,
|
|
128338
128793
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128339
128794
|
);
|
|
128340
128795
|
}
|
|
128796
|
+
if (isFirstReleaseBootstrap(dist)) {
|
|
128797
|
+
const asset = productionAssets?.[index];
|
|
128798
|
+
if (!asset || !EXTERNAL_MARKETPLACE_SHA_RE3.test(asset.commit ?? "") || !asset.tag) {
|
|
128799
|
+
throw new ReleaseError(
|
|
128800
|
+
GATE_FAILED,
|
|
128801
|
+
`unit "${unit.id}" first-release bootstrap requires a frozen plugin tag and commit`,
|
|
128802
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128803
|
+
);
|
|
128804
|
+
}
|
|
128805
|
+
const pluginState = await observePluginRepositoryFn(unit.publicRepo, asset.tag, { githubHost });
|
|
128806
|
+
if (pluginState?.status !== "empty" || pluginState.tagExists !== false || pluginState.releaseExists !== false) {
|
|
128807
|
+
throw new ReleaseError(
|
|
128808
|
+
GATE_FAILED,
|
|
128809
|
+
`unit "${unit.id}" first-release bootstrap requires an empty plugin repository without the target tag or release`,
|
|
128810
|
+
{ unitId: unit.id, publicRepo: unit.publicRepo, tag: asset.tag, observed: pluginState }
|
|
128811
|
+
);
|
|
128812
|
+
}
|
|
128813
|
+
selectedEntry = buildExpectedStandaloneIndexInstallIdentity(platform, {
|
|
128814
|
+
name: dist.plugin,
|
|
128815
|
+
repo: unit.publicRepo,
|
|
128816
|
+
tag: asset.tag,
|
|
128817
|
+
sha: asset.commit,
|
|
128818
|
+
version
|
|
128819
|
+
});
|
|
128820
|
+
}
|
|
128341
128821
|
const marketplaceRef = platform.marketplaceRefForm === "name" ? observed.defaultBranch : sha;
|
|
128342
128822
|
freezes.set(`${unit.id} ${dist.type}`, {
|
|
128343
128823
|
// 向后兼容字段(buildExternalActions 使用 repo / ref / marketplace)
|
|
@@ -128350,7 +128830,8 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128350
128830
|
marketplaceRef,
|
|
128351
128831
|
marketplaceIndexPath: manifestPath,
|
|
128352
128832
|
marketplaceName: marketplaceIndex.name,
|
|
128353
|
-
selectedEntry
|
|
128833
|
+
selectedEntry,
|
|
128834
|
+
...isFirstReleaseBootstrap(dist) ? { firstReleaseBootstrap: FIRST_RELEASE_BOOTSTRAP_MODE2, marketplaceIndexSha: null } : {}
|
|
128354
128835
|
});
|
|
128355
128836
|
await evidence.append({
|
|
128356
128837
|
phase: "external-marketplace-freeze",
|
|
@@ -128362,7 +128843,8 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128362
128843
|
marketplaceRef,
|
|
128363
128844
|
marketplaceIndexPath: manifestPath,
|
|
128364
128845
|
marketplaceName: marketplaceIndex.name,
|
|
128365
|
-
selectedEntry
|
|
128846
|
+
selectedEntry,
|
|
128847
|
+
...isFirstReleaseBootstrap(dist) ? { firstReleaseBootstrap: FIRST_RELEASE_BOOTSTRAP_MODE2, marketplaceIndexSha: null } : {},
|
|
128366
128848
|
defaultBranch: observed.defaultBranch
|
|
128367
128849
|
});
|
|
128368
128850
|
}
|
|
@@ -128697,7 +129179,11 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
128697
129179
|
...externalMarketplace && freeze ? {
|
|
128698
129180
|
marketplaceIndexPath: freeze.marketplaceIndexPath,
|
|
128699
129181
|
marketplaceName: freeze.marketplaceName,
|
|
128700
|
-
selectedEntry: freeze.selectedEntry
|
|
129182
|
+
selectedEntry: freeze.selectedEntry,
|
|
129183
|
+
...freeze.firstReleaseBootstrap ? {
|
|
129184
|
+
firstReleaseBootstrap: freeze.firstReleaseBootstrap,
|
|
129185
|
+
marketplaceIndexSha: null
|
|
129186
|
+
} : {}
|
|
128701
129187
|
} : {}
|
|
128702
129188
|
},
|
|
128703
129189
|
expected: {
|
|
@@ -128712,7 +129198,11 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
128712
129198
|
entrySkill: dist.entrySkill,
|
|
128713
129199
|
entrySkillFound: true,
|
|
128714
129200
|
manifestDigest: asset.manifestDigest,
|
|
128715
|
-
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {}
|
|
129201
|
+
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {},
|
|
129202
|
+
...externalMarketplace && freeze?.firstReleaseBootstrap ? {
|
|
129203
|
+
firstReleaseBootstrap: freeze.firstReleaseBootstrap,
|
|
129204
|
+
marketplaceIndexSha: null
|
|
129205
|
+
} : {}
|
|
128716
129206
|
},
|
|
128717
129207
|
status: "PENDING"
|
|
128718
129208
|
});
|
|
@@ -130340,13 +130830,26 @@ async function prepareRelease(options) {
|
|
|
130340
130830
|
skipSkillResourceClosure,
|
|
130341
130831
|
workflow
|
|
130342
130832
|
});
|
|
130833
|
+
for (const { unit } of unitResults) {
|
|
130834
|
+
for (const dist of unit.distributions ?? []) {
|
|
130835
|
+
if (isFirstReleaseBootstrap(dist) && (!production || offline)) {
|
|
130836
|
+
throw new ReleaseError(
|
|
130837
|
+
GATE_FAILED,
|
|
130838
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires online production prepare`,
|
|
130839
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
130840
|
+
);
|
|
130841
|
+
}
|
|
130842
|
+
}
|
|
130843
|
+
}
|
|
130343
130844
|
const externalMarketplaceFreezes = production ? await resolveExternalMarketplaceFreezes({
|
|
130344
130845
|
unitResults,
|
|
130345
130846
|
resolvedVersions,
|
|
130346
130847
|
offline,
|
|
130347
130848
|
evidence,
|
|
130348
130849
|
observeHeadFn: options.observeExternalMarketplaceHeadFn ?? defaultObserveExternalMarketplaceHead,
|
|
130349
|
-
fetchIndexFn: options.fetchExternalMarketplaceIndexFn ?? defaultFetchExternalMarketplaceIndex
|
|
130850
|
+
fetchIndexFn: options.fetchExternalMarketplaceIndexFn ?? defaultFetchExternalMarketplaceIndex,
|
|
130851
|
+
productionAssets,
|
|
130852
|
+
observePluginRepositoryFn: options.observeFirstReleasePluginRepositoryFn ?? defaultObserveFirstReleasePluginRepository
|
|
130350
130853
|
}) : /* @__PURE__ */ new Map();
|
|
130351
130854
|
const units = await Promise.all(unitResults.map(async ({ unit, manifest }, idx) => {
|
|
130352
130855
|
const unitVersion = resolvedVersions[idx];
|
|
@@ -130426,6 +130929,10 @@ async function prepareRelease(options) {
|
|
|
130426
130929
|
frozenDist.marketplaceIndexPath = freeze.marketplaceIndexPath;
|
|
130427
130930
|
frozenDist.marketplaceName = freeze.marketplaceName;
|
|
130428
130931
|
frozenDist.selectedEntry = freeze.selectedEntry;
|
|
130932
|
+
if (freeze.firstReleaseBootstrap) {
|
|
130933
|
+
frozenDist.firstReleaseBootstrap = freeze.firstReleaseBootstrap;
|
|
130934
|
+
frozenDist.marketplaceIndexSha = null;
|
|
130935
|
+
}
|
|
130429
130936
|
}
|
|
130430
130937
|
}
|
|
130431
130938
|
return frozenDist;
|
|
@@ -130795,7 +131302,7 @@ async function prepareRelease(options) {
|
|
|
130795
131302
|
await lock.release();
|
|
130796
131303
|
}
|
|
130797
131304
|
}
|
|
130798
|
-
var execFile9, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER,
|
|
131305
|
+
var execFile9, CONSUMER_INSTALL_RECIPE_VERSION2, FIRST_RELEASE_BOOTSTRAP_MODE2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE3;
|
|
130799
131306
|
var init_prepare = __esm({
|
|
130800
131307
|
async "src/commands/prepare.mjs"() {
|
|
130801
131308
|
init_src2();
|
|
@@ -130836,6 +131343,7 @@ var init_prepare = __esm({
|
|
|
130836
131343
|
init_bounded_output();
|
|
130837
131344
|
execFile9 = promisify12(execFileCb12);
|
|
130838
131345
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
131346
|
+
FIRST_RELEASE_BOOTSTRAP_MODE2 = "manual-index-checkpoint";
|
|
130839
131347
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
130840
131348
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
130841
131349
|
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
@@ -130854,11 +131362,14 @@ var init_prepare = __esm({
|
|
|
130854
131362
|
__name(enumerateFrozenTagPaths, "enumerateFrozenTagPaths");
|
|
130855
131363
|
__name(collectPostPublishCommandCandidates, "collectPostPublishCommandCandidates");
|
|
130856
131364
|
__name(assertPrivateExecutionDeclarations, "assertPrivateExecutionDeclarations");
|
|
130857
|
-
|
|
131365
|
+
EXTERNAL_MARKETPLACE_SHA_RE3 = /^[0-9a-f]{40}$/;
|
|
130858
131366
|
__name(parseExternalMarketplaceLsRemote, "parseExternalMarketplaceLsRemote");
|
|
130859
131367
|
__name(decodeExternalMarketplaceIndex, "decodeExternalMarketplaceIndex");
|
|
130860
131368
|
__name(defaultObserveExternalMarketplaceHead, "defaultObserveExternalMarketplaceHead");
|
|
130861
131369
|
__name(defaultFetchExternalMarketplaceIndex, "defaultFetchExternalMarketplaceIndex");
|
|
131370
|
+
__name(parseFirstReleasePluginRepositoryRefs, "parseFirstReleasePluginRepositoryRefs");
|
|
131371
|
+
__name(defaultObserveFirstReleasePluginRepository, "defaultObserveFirstReleasePluginRepository");
|
|
131372
|
+
__name(isFirstReleaseBootstrap, "isFirstReleaseBootstrap");
|
|
130862
131373
|
__name(resolveExternalMarketplaceFreezes, "resolveExternalMarketplaceFreezes");
|
|
130863
131374
|
__name(buildExternalActions, "buildExternalActions");
|
|
130864
131375
|
__name(computeSourceAuthorityClosure, "computeSourceAuthorityClosure");
|
|
@@ -130948,12 +131459,13 @@ var init_hooks2 = __esm({
|
|
|
130948
131459
|
// src/commands/post-release-local.mjs
|
|
130949
131460
|
var post_release_local_exports = {};
|
|
130950
131461
|
__export(post_release_local_exports, {
|
|
131462
|
+
assertLocalFinishRun: () => assertLocalFinishRun,
|
|
130951
131463
|
assertVerifiedReleaseRun: () => assertVerifiedReleaseRun,
|
|
130952
131464
|
derivePostReleaseChecklist: () => derivePostReleaseChecklist,
|
|
130953
131465
|
unavailablePostReleaseChecklist: () => unavailablePostReleaseChecklist,
|
|
130954
131466
|
updateLocalHostPlugins: () => updateLocalHostPlugins
|
|
130955
131467
|
});
|
|
130956
|
-
import { access as access2 } from "node:fs/promises";
|
|
131468
|
+
import { access as access2, readFile as readFile36 } from "node:fs/promises";
|
|
130957
131469
|
import { homedir } from "node:os";
|
|
130958
131470
|
import { join as join27, relative as relative27 } from "node:path";
|
|
130959
131471
|
function attachFoundationFailure(error, { envelope, stdout }) {
|
|
@@ -131047,13 +131559,35 @@ function assertExecutableTarget(target) {
|
|
|
131047
131559
|
throw new Error(`local host update requires the frozen public commit for unit ${target.unitId}`);
|
|
131048
131560
|
}
|
|
131049
131561
|
}
|
|
131050
|
-
function
|
|
131562
|
+
function buildShipNextStep({ root, statePath, unitIds }) {
|
|
131563
|
+
const argv = ["release-skill", "ship"];
|
|
131564
|
+
if (typeof root === "string" && root.length > 0) argv.push("--root", root);
|
|
131565
|
+
if (typeof statePath === "string" && statePath.length > 0) argv.push("--state", statePath);
|
|
131566
|
+
if (Array.isArray(unitIds) && unitIds.length > 0) {
|
|
131567
|
+
for (const unitId of unitIds) argv.push("--unit", unitId);
|
|
131568
|
+
}
|
|
131569
|
+
return {
|
|
131570
|
+
code: "COMPLETE_POST_VERIFY",
|
|
131571
|
+
message: "Complete the postVerify phase with ship before running post-release.",
|
|
131572
|
+
argv
|
|
131573
|
+
};
|
|
131574
|
+
}
|
|
131575
|
+
function derivePostReleaseChecklist(plan, {
|
|
131576
|
+
runPath,
|
|
131577
|
+
root,
|
|
131578
|
+
statePath,
|
|
131579
|
+
unitIds,
|
|
131580
|
+
postVerifyComplete = false
|
|
131581
|
+
} = {}) {
|
|
131051
131582
|
if (!plan || typeof plan !== "object" || typeof plan.digest !== "string") {
|
|
131052
131583
|
throw new Error("a frozen release plan with digest is required");
|
|
131053
131584
|
}
|
|
131054
131585
|
const units = plan.units ?? [];
|
|
131055
131586
|
const uncovered = units.filter((unit) => !BRANCH_ACTION_INCLUDED.has(unit.productionConfig?.branchStrategy));
|
|
131056
131587
|
const targets = pluginTargets(plan);
|
|
131588
|
+
const hasPendingPostVerify = postVerifyHooks(plan).length > 0 && !postVerifyComplete && targets.length > 0;
|
|
131589
|
+
const hasStatePath = typeof statePath === "string" && statePath.length > 0;
|
|
131590
|
+
const selectedUnitIds = Array.isArray(unitIds) ? unitIds : void 0;
|
|
131057
131591
|
return {
|
|
131058
131592
|
command: "post-release",
|
|
131059
131593
|
status: "AWAITING_USER_DECISION",
|
|
@@ -131069,13 +131603,143 @@ function derivePostReleaseChecklist(plan) {
|
|
|
131069
131603
|
}))
|
|
131070
131604
|
},
|
|
131071
131605
|
localHostUpdate: {
|
|
131072
|
-
promptRequired: targets.length > 0,
|
|
131073
|
-
available: targets.length > 0,
|
|
131606
|
+
promptRequired: targets.length > 0 && !hasPendingPostVerify,
|
|
131607
|
+
available: targets.length > 0 && !hasPendingPostVerify,
|
|
131608
|
+
...!hasPendingPostVerify && runPath ? { runPath } : {},
|
|
131609
|
+
...hasPendingPostVerify ? {
|
|
131610
|
+
...hasStatePath ? { nextSteps: [buildShipNextStep({ root, statePath, unitIds: selectedUnitIds })] } : {}
|
|
131611
|
+
} : {},
|
|
131074
131612
|
hosts: [...new Set(targets.map((target) => target.host))].sort(),
|
|
131075
131613
|
targets
|
|
131076
131614
|
}
|
|
131077
131615
|
};
|
|
131078
131616
|
}
|
|
131617
|
+
function postVerifyHooks(plan) {
|
|
131618
|
+
if (plan?.planVersion === void 0) return [];
|
|
131619
|
+
return normalizePostPublishView(plan).flatMap((declaration) => (declaration.hooks ?? []).filter((hook) => hook.phase === "postVerify").map((hook) => ({
|
|
131620
|
+
actionId: postPublishActionId({ planVersion: plan.planVersion, unitId: declaration.unitId, localId: hook.id }),
|
|
131621
|
+
hook,
|
|
131622
|
+
unitId: declaration.unitId
|
|
131623
|
+
})));
|
|
131624
|
+
}
|
|
131625
|
+
function localFinishEvidenceError(message, { cause, root, statePath, unitIds } = {}) {
|
|
131626
|
+
const error = new Error(`local host update evidence is not ready: ${message}; next step: obtain approval if required, then complete the postVerify phase with ship before rerunning post-release`);
|
|
131627
|
+
error.code = "LOCAL_FINISH_EVIDENCE_NOT_READY";
|
|
131628
|
+
const hasStatePath = typeof statePath === "string" && statePath.length > 0;
|
|
131629
|
+
error.details = {
|
|
131630
|
+
cause: {
|
|
131631
|
+
code: cause?.code ?? "LOCAL_FINISH_EVIDENCE_NOT_READY",
|
|
131632
|
+
message: cause?.message ?? message
|
|
131633
|
+
},
|
|
131634
|
+
...hasStatePath ? {
|
|
131635
|
+
nextSteps: [buildShipNextStep({ root, statePath, unitIds })]
|
|
131636
|
+
} : {}
|
|
131637
|
+
};
|
|
131638
|
+
return error;
|
|
131639
|
+
}
|
|
131640
|
+
async function updateLocalHostPlugins({
|
|
131641
|
+
plan: _suppliedPlan,
|
|
131642
|
+
planPath,
|
|
131643
|
+
runPath,
|
|
131644
|
+
runRecord: _suppliedRunRecord,
|
|
131645
|
+
production: _suppliedProduction,
|
|
131646
|
+
root = process.cwd(),
|
|
131647
|
+
statePath,
|
|
131648
|
+
unitIds,
|
|
131649
|
+
...options
|
|
131650
|
+
} = {}) {
|
|
131651
|
+
if (!planPath || !runPath) {
|
|
131652
|
+
throw localFinishEvidenceError(
|
|
131653
|
+
"planPath and runPath are required before local host updates",
|
|
131654
|
+
{ root, statePath, unitIds }
|
|
131655
|
+
);
|
|
131656
|
+
}
|
|
131657
|
+
let plan;
|
|
131658
|
+
let runRecord;
|
|
131659
|
+
try {
|
|
131660
|
+
plan = JSON.parse(await readFile36(planPath, "utf8"));
|
|
131661
|
+
runRecord = await loadRun(runPath, {
|
|
131662
|
+
requireDigest: true,
|
|
131663
|
+
authorityPlanPath: planPath
|
|
131664
|
+
});
|
|
131665
|
+
} catch (cause) {
|
|
131666
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds });
|
|
131667
|
+
}
|
|
131668
|
+
await assertLocalFinishRun({
|
|
131669
|
+
plan,
|
|
131670
|
+
planPath,
|
|
131671
|
+
runPath,
|
|
131672
|
+
runRecord,
|
|
131673
|
+
production: Boolean(plan.production),
|
|
131674
|
+
root,
|
|
131675
|
+
statePath,
|
|
131676
|
+
unitIds
|
|
131677
|
+
});
|
|
131678
|
+
return updateLocalHostPluginsInternal({
|
|
131679
|
+
plan,
|
|
131680
|
+
root,
|
|
131681
|
+
...options
|
|
131682
|
+
});
|
|
131683
|
+
}
|
|
131684
|
+
async function assertLocalFinishRun({
|
|
131685
|
+
plan,
|
|
131686
|
+
planPath,
|
|
131687
|
+
runPath,
|
|
131688
|
+
runRecord,
|
|
131689
|
+
production = false,
|
|
131690
|
+
root,
|
|
131691
|
+
statePath,
|
|
131692
|
+
unitIds
|
|
131693
|
+
} = {}) {
|
|
131694
|
+
const hooks = postVerifyHooks(plan);
|
|
131695
|
+
if (hooks.length === 0) {
|
|
131696
|
+
try {
|
|
131697
|
+
await validateRunLineage(runRecord, { plan, planPath, runPath, production });
|
|
131698
|
+
assertVerifiedReleaseRun(plan, runRecord);
|
|
131699
|
+
} catch (cause) {
|
|
131700
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131701
|
+
}
|
|
131702
|
+
return { runPath, phase: "verify" };
|
|
131703
|
+
}
|
|
131704
|
+
if (runRecord?.command !== "postverify" || runRecord?.status !== "DISTRIBUTED") {
|
|
131705
|
+
throw localFinishEvidenceError("the plan declares postVerify hooks, so the supplied verify run cannot authorize local-finish", { root, statePath, unitIds, plan });
|
|
131706
|
+
}
|
|
131707
|
+
if (runRecord.planDigest !== plan?.digest) {
|
|
131708
|
+
throw localFinishEvidenceError("postVerify run is not bound to the frozen plan", { root, statePath, unitIds, plan });
|
|
131709
|
+
}
|
|
131710
|
+
if (typeof runRecord.sourceRunPath !== "string" || typeof runRecord.sourceRunId !== "string" || typeof runRecord.sourceRunDigest !== "string") {
|
|
131711
|
+
throw localFinishEvidenceError("completed postVerify run has incomplete verify-run lineage", { root, statePath, unitIds, plan });
|
|
131712
|
+
}
|
|
131713
|
+
const checkpoints = Array.isArray(runRecord.checkpoints) ? runRecord.checkpoints : null;
|
|
131714
|
+
const expectedIds = hooks.map(({ actionId }) => actionId);
|
|
131715
|
+
const actualIds = checkpoints?.map((checkpoint) => checkpoint?.actionId) ?? [];
|
|
131716
|
+
if (!checkpoints || actualIds.length !== expectedIds.length || new Set(actualIds).size !== actualIds.length || actualIds.some((id) => !expectedIds.includes(id)) || expectedIds.some((id) => !actualIds.includes(id)) || checkpoints.some((checkpoint) => checkpoint.actionType !== "postpublish-hook" || !["succeeded", "NO_CHANGE"].includes(checkpoint.status))) {
|
|
131717
|
+
throw localFinishEvidenceError("postVerify checkpoints must match each declared hook exactly and be succeeded or NO_CHANGE", { root, statePath, unitIds, plan });
|
|
131718
|
+
}
|
|
131719
|
+
let sourceRun;
|
|
131720
|
+
try {
|
|
131721
|
+
sourceRun = await loadRun(runRecord.sourceRunPath, {
|
|
131722
|
+
requireDigest: true,
|
|
131723
|
+
authorityPlanPath: planPath
|
|
131724
|
+
});
|
|
131725
|
+
} catch (cause) {
|
|
131726
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131727
|
+
}
|
|
131728
|
+
if (sourceRun.command !== "verify" || sourceRun.status !== "VERIFIED" || sourceRun.runId !== runRecord.sourceRunId || sourceRun.runDigest !== runRecord.sourceRunDigest || sourceRun.planDigest !== plan.digest) {
|
|
131729
|
+
throw localFinishEvidenceError("postVerify lineage does not point to the same-plan VERIFIED run", { root, statePath, unitIds, plan });
|
|
131730
|
+
}
|
|
131731
|
+
try {
|
|
131732
|
+
await validateRunLineage(sourceRun, {
|
|
131733
|
+
plan,
|
|
131734
|
+
planPath,
|
|
131735
|
+
runPath: runRecord.sourceRunPath,
|
|
131736
|
+
production
|
|
131737
|
+
});
|
|
131738
|
+
} catch (cause) {
|
|
131739
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131740
|
+
}
|
|
131741
|
+
return { runPath, sourceRunPath: runRecord.sourceRunPath, phase: "postverify" };
|
|
131742
|
+
}
|
|
131079
131743
|
function unavailablePostReleaseChecklist(plan, error) {
|
|
131080
131744
|
return {
|
|
131081
131745
|
command: "post-release",
|
|
@@ -131101,7 +131765,11 @@ function hostEnvironment(host, { kimiHome } = {}) {
|
|
|
131101
131765
|
env.HOME ??= homedir();
|
|
131102
131766
|
env.PATH ??= "/usr/bin:/bin";
|
|
131103
131767
|
env.GIT_TERMINAL_PROMPT = "0";
|
|
131104
|
-
if (host === "
|
|
131768
|
+
if (host === "codebuddy") env.CODEBUDDY_CONFIG_DIR = join27(env.HOME, ".codebuddy");
|
|
131769
|
+
if (host === "workbuddy") {
|
|
131770
|
+
env.CODEBUDDY_CONFIG_DIR = join27(env.HOME, ".workbuddy");
|
|
131771
|
+
env.WORKBUDDY_CONFIG_DIR = join27(env.HOME, ".workbuddy");
|
|
131772
|
+
}
|
|
131105
131773
|
if (host === "kimi" && kimiHome) env.KIMI_CONFIG_DIR = kimiHome;
|
|
131106
131774
|
return env;
|
|
131107
131775
|
}
|
|
@@ -131152,12 +131820,17 @@ async function commandAvailable(command2, host, run6) {
|
|
|
131152
131820
|
}
|
|
131153
131821
|
}
|
|
131154
131822
|
async function defaultDetect(host, run6 = defaultRun) {
|
|
131155
|
-
if (host === "codebuddy"
|
|
131156
|
-
for (const command2 of ["codebuddy", "cbc"
|
|
131823
|
+
if (host === "codebuddy") {
|
|
131824
|
+
for (const command2 of ["codebuddy", "cbc"]) {
|
|
131157
131825
|
if (await commandAvailable(command2, host, run6)) return { available: true, command: command2 };
|
|
131158
131826
|
}
|
|
131159
131827
|
return { available: false, reason: "CodeBuddy/WorkBuddy CLI not found" };
|
|
131160
131828
|
}
|
|
131829
|
+
if (host === "workbuddy") {
|
|
131830
|
+
if (process.platform !== "darwin") return { available: false, status: "SKIPPED_UNSUPPORTED_PLATFORM", reason: "WorkBuddy local update is supported only on macOS" };
|
|
131831
|
+
if (await commandAvailable(CODEBUDDY_MACOS_PATH, host, run6)) return { available: true, command: CODEBUDDY_MACOS_PATH };
|
|
131832
|
+
return { available: false, reason: "WorkBuddy embedded CLI not found" };
|
|
131833
|
+
}
|
|
131161
131834
|
if (host === "kimi") {
|
|
131162
131835
|
if (!await commandAvailable("kimi", host, run6)) return { available: false, reason: "kimi CLI not found" };
|
|
131163
131836
|
try {
|
|
@@ -131690,7 +132363,7 @@ function failedHostResult(target, error) {
|
|
|
131690
132363
|
...publicDetails !== void 0 ? { details: publicDetails } : {}
|
|
131691
132364
|
};
|
|
131692
132365
|
}
|
|
131693
|
-
async function
|
|
132366
|
+
async function updateLocalHostPluginsInternal({
|
|
131694
132367
|
plan,
|
|
131695
132368
|
root = process.cwd(),
|
|
131696
132369
|
confirmPlanDigest,
|
|
@@ -131701,7 +132374,7 @@ async function updateLocalHostPlugins({
|
|
|
131701
132374
|
verifyInstalledPayload = verifyInstalledMarketplacePayload
|
|
131702
132375
|
} = {}) {
|
|
131703
132376
|
const effectiveKimiHome = kimiHome ?? process.env.KIMI_CONFIG_DIR ?? join27(homedir(), ".kimi-code");
|
|
131704
|
-
const checklist = derivePostReleaseChecklist(plan);
|
|
132377
|
+
const checklist = derivePostReleaseChecklist(plan, { postVerifyComplete: true });
|
|
131705
132378
|
if (confirmPlanDigest !== plan.digest) {
|
|
131706
132379
|
throw new Error("plan digest confirmation does not match the frozen release plan");
|
|
131707
132380
|
}
|
|
@@ -131718,7 +132391,7 @@ async function updateLocalHostPlugins({
|
|
|
131718
132391
|
results.push({
|
|
131719
132392
|
host: target.host,
|
|
131720
132393
|
unitId: target.unitId,
|
|
131721
|
-
status: "SKIPPED_NOT_INSTALLED",
|
|
132394
|
+
status: detected?.status ?? "SKIPPED_NOT_INSTALLED",
|
|
131722
132395
|
reason: detected?.reason ?? "host unavailable"
|
|
131723
132396
|
});
|
|
131724
132397
|
continue;
|
|
@@ -131753,6 +132426,8 @@ var init_post_release_local = __esm({
|
|
|
131753
132426
|
await init_registry2();
|
|
131754
132427
|
init_codebuddy();
|
|
131755
132428
|
await init_plugin_marketplace();
|
|
132429
|
+
init_postpublish();
|
|
132430
|
+
await init_run();
|
|
131756
132431
|
HOSTS_BY_ACTION = Object.freeze({
|
|
131757
132432
|
"claude-marketplace-install": ["claude"],
|
|
131758
132433
|
"codex-marketplace-install": ["codex"],
|
|
@@ -131787,7 +132462,9 @@ var init_post_release_local = __esm({
|
|
|
131787
132462
|
"NODE_EXTRA_CA_CERTS",
|
|
131788
132463
|
"CLAUDE_CONFIG_DIR",
|
|
131789
132464
|
"CODEX_HOME",
|
|
131790
|
-
"KIMI_CONFIG_DIR"
|
|
132465
|
+
"KIMI_CONFIG_DIR",
|
|
132466
|
+
"CODEBUDDY_CONFIG_DIR",
|
|
132467
|
+
"WORKBUDDY_CONFIG_DIR"
|
|
131791
132468
|
]);
|
|
131792
132469
|
CODEBUDDY_PLUGIN_LIST_ARGS = Object.freeze(["plugin", "list", "--json"]);
|
|
131793
132470
|
CODEBUDDY_MARKETPLACE_LIST_ARGS = Object.freeze(["plugin", "marketplace", "list"]);
|
|
@@ -131795,7 +132472,12 @@ var init_post_release_local = __esm({
|
|
|
131795
132472
|
__name(actionTarget, "actionTarget");
|
|
131796
132473
|
__name(pluginTargets, "pluginTargets");
|
|
131797
132474
|
__name(assertExecutableTarget, "assertExecutableTarget");
|
|
132475
|
+
__name(buildShipNextStep, "buildShipNextStep");
|
|
131798
132476
|
__name(derivePostReleaseChecklist, "derivePostReleaseChecklist");
|
|
132477
|
+
__name(postVerifyHooks, "postVerifyHooks");
|
|
132478
|
+
__name(localFinishEvidenceError, "localFinishEvidenceError");
|
|
132479
|
+
__name(updateLocalHostPlugins, "updateLocalHostPlugins");
|
|
132480
|
+
__name(assertLocalFinishRun, "assertLocalFinishRun");
|
|
131799
132481
|
__name(unavailablePostReleaseChecklist, "unavailablePostReleaseChecklist");
|
|
131800
132482
|
__name(assertVerifiedReleaseRun, "assertVerifiedReleaseRun");
|
|
131801
132483
|
__name(hostEnvironment, "hostEnvironment");
|
|
@@ -131825,7 +132507,7 @@ var init_post_release_local = __esm({
|
|
|
131825
132507
|
__name(runKimiUpdate, "runKimiUpdate");
|
|
131826
132508
|
__name(aggregateStatus, "aggregateStatus");
|
|
131827
132509
|
__name(failedHostResult, "failedHostResult");
|
|
131828
|
-
__name(
|
|
132510
|
+
__name(updateLocalHostPluginsInternal, "updateLocalHostPluginsInternal");
|
|
131829
132511
|
}
|
|
131830
132512
|
});
|
|
131831
132513
|
|
|
@@ -131835,7 +132517,7 @@ __export(approve_exports, {
|
|
|
131835
132517
|
approvePlan: () => approvePlan,
|
|
131836
132518
|
approvePostPublishHook: () => approvePostPublishHook
|
|
131837
132519
|
});
|
|
131838
|
-
import { readFile as
|
|
132520
|
+
import { readFile as readFile37, writeFile as writeFile8 } from "node:fs/promises";
|
|
131839
132521
|
import { resolve as resolve33, dirname as dirname17, basename as basename13 } from "node:path";
|
|
131840
132522
|
function defaultClock2() {
|
|
131841
132523
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -131859,7 +132541,7 @@ async function approvePlan(options) {
|
|
|
131859
132541
|
}
|
|
131860
132542
|
let planRaw;
|
|
131861
132543
|
try {
|
|
131862
|
-
planRaw = await
|
|
132544
|
+
planRaw = await readFile37(planPath, "utf8");
|
|
131863
132545
|
} catch (err) {
|
|
131864
132546
|
throw new ReleaseError(
|
|
131865
132547
|
GATE_FAILED,
|
|
@@ -131987,7 +132669,7 @@ async function approvePlan(options) {
|
|
|
131987
132669
|
await writeFile8(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
131988
132670
|
} catch (error) {
|
|
131989
132671
|
if (error.code !== "EEXIST") throw error;
|
|
131990
|
-
const existing = await
|
|
132672
|
+
const existing = await readFile37(immutableApprovalPath, "utf8");
|
|
131991
132673
|
if (existing !== json) {
|
|
131992
132674
|
throw new ReleaseError(
|
|
131993
132675
|
GATE_FAILED,
|
|
@@ -132038,7 +132720,7 @@ async function approvePostPublishHook(options) {
|
|
|
132038
132720
|
}
|
|
132039
132721
|
let planRaw;
|
|
132040
132722
|
try {
|
|
132041
|
-
planRaw = await
|
|
132723
|
+
planRaw = await readFile37(planPath, "utf8");
|
|
132042
132724
|
} catch (err) {
|
|
132043
132725
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
132044
132726
|
}
|
|
@@ -132098,7 +132780,7 @@ async function approvePostPublishHook(options) {
|
|
|
132098
132780
|
await writeFile8(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
132099
132781
|
} catch (error) {
|
|
132100
132782
|
if (error.code !== "EEXIST") throw error;
|
|
132101
|
-
const existing = await
|
|
132783
|
+
const existing = await readFile37(immutableApprovalPath, "utf8");
|
|
132102
132784
|
if (existing !== json) {
|
|
132103
132785
|
throw new ReleaseError(
|
|
132104
132786
|
GATE_FAILED,
|
|
@@ -132249,7 +132931,7 @@ __export(publish_exports, {
|
|
|
132249
132931
|
classifyPreObservation: () => classifyPreObservation,
|
|
132250
132932
|
publishRelease: () => publishRelease
|
|
132251
132933
|
});
|
|
132252
|
-
import { readFile as
|
|
132934
|
+
import { readFile as readFile38, mkdir as mkdir22 } from "node:fs/promises";
|
|
132253
132935
|
import { isAbsolute as isAbsolute23, join as join28, relative as relative28 } from "node:path";
|
|
132254
132936
|
function assertInsideAssetRoot(assetRoot, candidate, label) {
|
|
132255
132937
|
const rel = relative28(assetRoot, candidate);
|
|
@@ -132482,7 +133164,7 @@ async function publishRelease(options) {
|
|
|
132482
133164
|
const captureBaselineActual = typeof captureBaselineFn === "function" ? captureBaselineFn : captureBaseline;
|
|
132483
133165
|
let planRaw;
|
|
132484
133166
|
try {
|
|
132485
|
-
planRaw = await
|
|
133167
|
+
planRaw = await readFile38(planPath, "utf8");
|
|
132486
133168
|
} catch (err) {
|
|
132487
133169
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
132488
133170
|
}
|
|
@@ -132673,7 +133355,7 @@ async function publishRelease(options) {
|
|
|
132673
133355
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
132674
133356
|
let approvalRaw;
|
|
132675
133357
|
try {
|
|
132676
|
-
approvalRaw = await
|
|
133358
|
+
approvalRaw = await readFile38(approvalPath, "utf8");
|
|
132677
133359
|
} catch (err) {
|
|
132678
133360
|
throw new ReleaseError(
|
|
132679
133361
|
GATE_FAILED,
|
|
@@ -133310,7 +133992,7 @@ var reconcile_exports = {};
|
|
|
133310
133992
|
__export(reconcile_exports, {
|
|
133311
133993
|
reconcileRelease: () => reconcileRelease
|
|
133312
133994
|
});
|
|
133313
|
-
import { readFile as
|
|
133995
|
+
import { readFile as readFile39, mkdir as mkdir23 } from "node:fs/promises";
|
|
133314
133996
|
import { join as join29 } from "node:path";
|
|
133315
133997
|
function defaultClock5() {
|
|
133316
133998
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -133339,7 +134021,7 @@ async function reconcileRelease(options) {
|
|
|
133339
134021
|
}
|
|
133340
134022
|
let planRaw;
|
|
133341
134023
|
try {
|
|
133342
|
-
planRaw = await
|
|
134024
|
+
planRaw = await readFile39(planPath, "utf8");
|
|
133343
134025
|
} catch (err) {
|
|
133344
134026
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
133345
134027
|
}
|
|
@@ -133462,7 +134144,7 @@ async function reconcileRelease(options) {
|
|
|
133462
134144
|
{ sourceRunId: sourceRun.runId }
|
|
133463
134145
|
);
|
|
133464
134146
|
}
|
|
133465
|
-
const sourceApprovalRaw = await
|
|
134147
|
+
const sourceApprovalRaw = await readFile39(consumedApprovalPath, "utf8").catch((error) => {
|
|
133466
134148
|
throw new ReleaseError(GATE_FAILED, "source run approval authority is unavailable", {
|
|
133467
134149
|
sourceRunId: sourceRun.runId,
|
|
133468
134150
|
cause: error.code
|
|
@@ -133624,7 +134306,7 @@ async function reconcileRelease(options) {
|
|
|
133624
134306
|
if (approvalPath) {
|
|
133625
134307
|
let approvalRaw;
|
|
133626
134308
|
try {
|
|
133627
|
-
approvalRaw = await
|
|
134309
|
+
approvalRaw = await readFile39(approvalPath, "utf8");
|
|
133628
134310
|
} catch (err) {
|
|
133629
134311
|
throw new ReleaseError(
|
|
133630
134312
|
GATE_FAILED,
|
|
@@ -135090,7 +135772,7 @@ var init_notify_handoff = __esm({
|
|
|
135090
135772
|
// src/core/proposal-inbox.mjs
|
|
135091
135773
|
import { execFile as execFileCb14 } from "node:child_process";
|
|
135092
135774
|
import { promisify as promisify14 } from "node:util";
|
|
135093
|
-
import { mkdir as mkdir26, mkdtemp as mkdtemp8, readFile as
|
|
135775
|
+
import { mkdir as mkdir26, mkdtemp as mkdtemp8, readFile as readFile40, rm as rm12, writeFile as writeFile11 } from "node:fs/promises";
|
|
135094
135776
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
135095
135777
|
import { dirname as dirname19, join as join32 } from "node:path";
|
|
135096
135778
|
function defaultExec2(command2, args2, options = {}) {
|
|
@@ -135270,7 +135952,7 @@ async function observeProposalInboxGitPush(params) {
|
|
|
135270
135952
|
const targetPath2 = join32(cloneDir, proposalPath);
|
|
135271
135953
|
let existing = null;
|
|
135272
135954
|
try {
|
|
135273
|
-
existing = await
|
|
135955
|
+
existing = await readFile40(targetPath2, "utf8");
|
|
135274
135956
|
} catch {
|
|
135275
135957
|
existing = null;
|
|
135276
135958
|
}
|
|
@@ -135431,7 +136113,7 @@ async function deliverProposalLocalFile(params) {
|
|
|
135431
136113
|
const targetPath2 = join32(workspaceRealpath, proposalPath);
|
|
135432
136114
|
let existing = null;
|
|
135433
136115
|
try {
|
|
135434
|
-
existing = await
|
|
136116
|
+
existing = await readFile40(targetPath2, "utf8");
|
|
135435
136117
|
} catch {
|
|
135436
136118
|
existing = null;
|
|
135437
136119
|
}
|
|
@@ -135928,7 +136610,7 @@ var init_preset_gitwrite = __esm({
|
|
|
135928
136610
|
});
|
|
135929
136611
|
|
|
135930
136612
|
// src/core/marketplace-registry-entry.mjs
|
|
135931
|
-
import { readFile as
|
|
136613
|
+
import { readFile as readFile41 } from "node:fs/promises";
|
|
135932
136614
|
import { join as join34 } from "node:path";
|
|
135933
136615
|
function updateRegistryEntry(registry, params) {
|
|
135934
136616
|
const { entryKey, fieldsFromPlan, contextProjection } = params ?? {};
|
|
@@ -135994,7 +136676,7 @@ async function executeMarketplaceRegistryEntryHook(params) {
|
|
|
135994
136676
|
const absoluteRegistry = join34(worktree, registryPath);
|
|
135995
136677
|
let raw;
|
|
135996
136678
|
try {
|
|
135997
|
-
raw = await
|
|
136679
|
+
raw = await readFile41(absoluteRegistry, "utf8");
|
|
135998
136680
|
} catch {
|
|
135999
136681
|
throw new ReleaseError(
|
|
136000
136682
|
REMOTE_CONFLICT,
|
|
@@ -136046,7 +136728,7 @@ var init_marketplace_registry_entry = __esm({
|
|
|
136046
136728
|
});
|
|
136047
136729
|
|
|
136048
136730
|
// src/core/docs-refresh-preset.mjs
|
|
136049
|
-
import { mkdir as mkdir27, readFile as
|
|
136731
|
+
import { mkdir as mkdir27, readFile as readFile42, writeFile as writeFile12 } from "node:fs/promises";
|
|
136050
136732
|
import { dirname as dirname20, isAbsolute as isAbsolute24, join as join35, relative as relative29, resolve as resolve34 } from "node:path";
|
|
136051
136733
|
function resolvePayloadSource(payloadDir, from) {
|
|
136052
136734
|
const sourcePath = resolve34(payloadDir, from);
|
|
@@ -136084,7 +136766,7 @@ async function executeDocsRefreshHook(params) {
|
|
|
136084
136766
|
const mutate = /* @__PURE__ */ __name(async (worktree) => {
|
|
136085
136767
|
for (const mapping of mappings) {
|
|
136086
136768
|
const sourcePath = resolvePayloadSource(payloadDir, mapping.from);
|
|
136087
|
-
let content = await
|
|
136769
|
+
let content = await readFile42(sourcePath).catch(() => null);
|
|
136088
136770
|
if (content === null) {
|
|
136089
136771
|
throw new ReleaseError(
|
|
136090
136772
|
GATE_FAILED,
|
|
@@ -136301,7 +136983,7 @@ __export(distribute_exports, {
|
|
|
136301
136983
|
});
|
|
136302
136984
|
import { execFile as execFileCb16 } from "node:child_process";
|
|
136303
136985
|
import { promisify as promisify16 } from "node:util";
|
|
136304
|
-
import { realpath as realpath32, lstat as lstat43, mkdir as mkdir28, readFile as
|
|
136986
|
+
import { realpath as realpath32, lstat as lstat43, mkdir as mkdir28, readFile as readFile43, rm as rm15 } from "node:fs/promises";
|
|
136305
136987
|
import { mkdtemp as mkdtemp10 } from "node:fs/promises";
|
|
136306
136988
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
136307
136989
|
import { isAbsolute as isAbsolute25, join as join36, relative as relative30, resolve as resolve35 } from "node:path";
|
|
@@ -136400,7 +137082,7 @@ async function distributeRelease(options) {
|
|
|
136400
137082
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
136401
137083
|
let planRaw;
|
|
136402
137084
|
try {
|
|
136403
|
-
planRaw = await
|
|
137085
|
+
planRaw = await readFile43(planPath, "utf8");
|
|
136404
137086
|
} catch (err) {
|
|
136405
137087
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
136406
137088
|
}
|
|
@@ -136515,7 +137197,7 @@ async function distributeRelease(options) {
|
|
|
136515
137197
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
136516
137198
|
let approvalRaw;
|
|
136517
137199
|
try {
|
|
136518
|
-
approvalRaw = await
|
|
137200
|
+
approvalRaw = await readFile43(approvalPath, "utf8");
|
|
136519
137201
|
} catch (err) {
|
|
136520
137202
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
136521
137203
|
}
|
|
@@ -136627,7 +137309,7 @@ async function distributeRelease(options) {
|
|
|
136627
137309
|
for (const hookApprovalPath of hookApprovalPaths) {
|
|
136628
137310
|
let hookApprovalRaw;
|
|
136629
137311
|
try {
|
|
136630
|
-
hookApprovalRaw = await
|
|
137312
|
+
hookApprovalRaw = await readFile43(hookApprovalPath, "utf8");
|
|
136631
137313
|
} catch (err) {
|
|
136632
137314
|
await failBlocked(new ReleaseError(
|
|
136633
137315
|
GATE_FAILED,
|
|
@@ -137732,7 +138414,7 @@ __export(postverify_exports, {
|
|
|
137732
138414
|
});
|
|
137733
138415
|
import { execFile as execFileCb17 } from "node:child_process";
|
|
137734
138416
|
import { promisify as promisify17 } from "node:util";
|
|
137735
|
-
import { mkdir as mkdir29, readFile as
|
|
138417
|
+
import { mkdir as mkdir29, readFile as readFile44, realpath as realpath33, rm as rm16 } from "node:fs/promises";
|
|
137736
138418
|
import { mkdtemp as mkdtemp11 } from "node:fs/promises";
|
|
137737
138419
|
import { tmpdir as tmpdir9 } from "node:os";
|
|
137738
138420
|
import { join as join37 } from "node:path";
|
|
@@ -137765,7 +138447,7 @@ async function postVerifyRelease(options) {
|
|
|
137765
138447
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
137766
138448
|
let planRaw;
|
|
137767
138449
|
try {
|
|
137768
|
-
planRaw = await
|
|
138450
|
+
planRaw = await readFile44(planPath, "utf8");
|
|
137769
138451
|
} catch (err) {
|
|
137770
138452
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
137771
138453
|
}
|
|
@@ -137799,7 +138481,7 @@ async function postVerifyRelease(options) {
|
|
|
137799
138481
|
}
|
|
137800
138482
|
let approvalRaw;
|
|
137801
138483
|
try {
|
|
137802
|
-
approvalRaw = await
|
|
138484
|
+
approvalRaw = await readFile44(approvalPath, "utf8");
|
|
137803
138485
|
} catch (err) {
|
|
137804
138486
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
137805
138487
|
}
|
|
@@ -137872,16 +138554,16 @@ async function postVerifyRelease(options) {
|
|
|
137872
138554
|
validatePostPublishDeclaration(declaration, { unitId: declaration.unitId });
|
|
137873
138555
|
await verifyExecutionBundle({ planPath, postPublish: declaration });
|
|
137874
138556
|
const declaredHooks = declaration.hooks ?? [];
|
|
137875
|
-
const
|
|
137876
|
-
prepared.push({ declaration, postVerifyHooks:
|
|
138557
|
+
const postVerifyHooks3 = declaredHooks.filter((hook) => (hook.phase ?? "distribute") === "postVerify");
|
|
138558
|
+
prepared.push({ declaration, postVerifyHooks: postVerifyHooks3 });
|
|
137877
138559
|
}
|
|
137878
|
-
const
|
|
138560
|
+
const postVerifyHooks2 = prepared.flatMap((prep) => prep.postVerifyHooks);
|
|
137879
138561
|
const approvedHookIds = /* @__PURE__ */ new Set();
|
|
137880
138562
|
const hookApprovalPaths = postpublishApprovalPaths ?? [];
|
|
137881
138563
|
for (const hookApprovalPath of hookApprovalPaths) {
|
|
137882
138564
|
let hookApprovalRaw;
|
|
137883
138565
|
try {
|
|
137884
|
-
hookApprovalRaw = await
|
|
138566
|
+
hookApprovalRaw = await readFile44(hookApprovalPath, "utf8");
|
|
137885
138567
|
} catch (err) {
|
|
137886
138568
|
throw new ReleaseError(
|
|
137887
138569
|
GATE_FAILED,
|
|
@@ -138036,7 +138718,7 @@ async function postVerifyRelease(options) {
|
|
|
138036
138718
|
status: "started",
|
|
138037
138719
|
sourceVerifyRunId: verifyRun.runId,
|
|
138038
138720
|
sourcePublishRunId: publishRun.runId,
|
|
138039
|
-
hookCount:
|
|
138721
|
+
hookCount: postVerifyHooks2.length,
|
|
138040
138722
|
dryRun: dryRun === true
|
|
138041
138723
|
});
|
|
138042
138724
|
await snapshot(DISTRIBUTING2);
|
|
@@ -138516,7 +139198,7 @@ var release_metadata_exports = {};
|
|
|
138516
139198
|
__export(release_metadata_exports, {
|
|
138517
139199
|
updatePreviousPublicBaselines: () => updatePreviousPublicBaselines
|
|
138518
139200
|
});
|
|
138519
|
-
import { lstat as lstat44, readFile as
|
|
139201
|
+
import { lstat as lstat44, readFile as readFile45 } from "node:fs/promises";
|
|
138520
139202
|
import { resolve as resolve36 } from "node:path";
|
|
138521
139203
|
function assertOid(value, label) {
|
|
138522
139204
|
if (typeof value !== "string" || !/^[a-f0-9]{40,64}$/.test(value)) {
|
|
@@ -138532,8 +139214,8 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
138532
139214
|
let configStat;
|
|
138533
139215
|
try {
|
|
138534
139216
|
[plan, configRaw, configStat] = await Promise.all([
|
|
138535
|
-
|
|
138536
|
-
|
|
139217
|
+
readFile45(planPath, "utf8").then(JSON.parse),
|
|
139218
|
+
readFile45(configPath, "utf8"),
|
|
138537
139219
|
lstat44(configPath)
|
|
138538
139220
|
]);
|
|
138539
139221
|
} catch (error) {
|
|
@@ -138618,7 +139300,7 @@ var ship_exports = {};
|
|
|
138618
139300
|
__export(ship_exports, {
|
|
138619
139301
|
advanceShip: () => advanceShip
|
|
138620
139302
|
});
|
|
138621
|
-
import { readFile as
|
|
139303
|
+
import { readFile as readFile46, lstat as lstat45, mkdir as mkdir30 } from "node:fs/promises";
|
|
138622
139304
|
import { basename as basename14, dirname as dirname21, resolve as resolve37 } from "node:path";
|
|
138623
139305
|
function normalizeNewShipUnitIds(releaseUnits, requestedUnitIds) {
|
|
138624
139306
|
if (requestedUnitIds === void 0) return void 0;
|
|
@@ -138674,7 +139356,7 @@ function assertFrozenPlanUnitScope({ statePath, stateUnitIds, expectedUnitIds, p
|
|
|
138674
139356
|
}
|
|
138675
139357
|
async function readFrozenPlanForUnitScope(planPath, statePath, stateUnitIds) {
|
|
138676
139358
|
try {
|
|
138677
|
-
return JSON.parse(await
|
|
139359
|
+
return JSON.parse(await readFile46(planPath, "utf8"));
|
|
138678
139360
|
} catch (error) {
|
|
138679
139361
|
throw unitScopeMismatch(
|
|
138680
139362
|
statePath,
|
|
@@ -138702,7 +139384,7 @@ async function readState(path40) {
|
|
|
138702
139384
|
if (!stat22.isFile() || stat22.isSymbolicLink()) {
|
|
138703
139385
|
throw new Error("ship state must be a regular non-symlink file");
|
|
138704
139386
|
}
|
|
138705
|
-
const state = JSON.parse(await
|
|
139387
|
+
const state = JSON.parse(await readFile46(path40, "utf8"));
|
|
138706
139388
|
const { stateDigest, ...body } = state;
|
|
138707
139389
|
if (typeof stateDigest !== "string" || stateDigest !== sha256Hex(canonicalJson2(body)) || body.statePath !== path40) {
|
|
138708
139390
|
throw new Error("ship state digest or authority path does not match");
|
|
@@ -138751,7 +139433,8 @@ async function defaultDependencies() {
|
|
|
138751
139433
|
readMaxApprovalMs: /* @__PURE__ */ __name(() => MAX_APPROVAL_MS, "readMaxApprovalMs")
|
|
138752
139434
|
};
|
|
138753
139435
|
}
|
|
138754
|
-
function publicState2(state) {
|
|
139436
|
+
function publicState2(state, { postRelease } = {}) {
|
|
139437
|
+
const visiblePostRelease = postRelease === void 0 ? state.postRelease : postRelease;
|
|
138755
139438
|
return {
|
|
138756
139439
|
command: "ship",
|
|
138757
139440
|
status: state.status,
|
|
@@ -138776,7 +139459,7 @@ function publicState2(state) {
|
|
|
138776
139459
|
...state.requirements ? { requirements: state.requirements } : {},
|
|
138777
139460
|
...state.manualFollowUps ? { manualFollowUps: state.manualFollowUps } : {},
|
|
138778
139461
|
...state.metadataUpdate ? { metadataUpdate: state.metadataUpdate } : {},
|
|
138779
|
-
...
|
|
139462
|
+
...visiblePostRelease ? { postRelease: visiblePostRelease } : {},
|
|
138780
139463
|
externalActionsIncludedInPlanApproval: true,
|
|
138781
139464
|
verificationGatesIncludedInPlanApproval: true,
|
|
138782
139465
|
postPublishCheckpointApprovalsIncludedInPlanApproval: false
|
|
@@ -138800,7 +139483,7 @@ function projectActionTarget(action) {
|
|
|
138800
139483
|
}
|
|
138801
139484
|
async function buildApprovalSummary(planPath, maxApprovalMs = MAX_APPROVAL_MS) {
|
|
138802
139485
|
try {
|
|
138803
|
-
const plan = JSON.parse(await
|
|
139486
|
+
const plan = JSON.parse(await readFile46(planPath, "utf8"));
|
|
138804
139487
|
const approvalWindowHours = deriveApprovalWindowHours(maxApprovalMs);
|
|
138805
139488
|
const actions = (plan.externalActions ?? []).map((action) => ({
|
|
138806
139489
|
id: action.id,
|
|
@@ -138865,19 +139548,19 @@ async function buildApprovalSummary(planPath, maxApprovalMs = MAX_APPROVAL_MS) {
|
|
|
138865
139548
|
);
|
|
138866
139549
|
}
|
|
138867
139550
|
}
|
|
138868
|
-
async function allUnclosedPostVerifyHooksUngated(state,
|
|
138869
|
-
if (!Array.isArray(
|
|
138870
|
-
let candidates =
|
|
139551
|
+
async function allUnclosedPostVerifyHooksUngated(state, postVerifyHooks2, planVersion) {
|
|
139552
|
+
if (!Array.isArray(postVerifyHooks2) || postVerifyHooks2.length === 0) return false;
|
|
139553
|
+
let candidates = postVerifyHooks2;
|
|
138871
139554
|
if (state.postVerify?.runPath) {
|
|
138872
139555
|
try {
|
|
138873
|
-
const record = JSON.parse(await
|
|
139556
|
+
const record = JSON.parse(await readFile46(state.postVerify.runPath, "utf8"));
|
|
138874
139557
|
const checkpoints = Array.isArray(record.checkpoints) ? record.checkpoints : [];
|
|
138875
139558
|
const closedIds = new Set(
|
|
138876
139559
|
checkpoints.filter((cp4) => cp4?.actionType === "postpublish-hook" && (cp4.status === "succeeded" || cp4.status === "NO_CHANGE")).map((cp4) => cp4.actionId)
|
|
138877
139560
|
);
|
|
138878
|
-
candidates =
|
|
139561
|
+
candidates = postVerifyHooks2.filter(({ hook, unitId }) => !closedIds.has(postPublishActionId({ planVersion, unitId, localId: hook.id })));
|
|
138879
139562
|
} catch {
|
|
138880
|
-
candidates =
|
|
139563
|
+
candidates = postVerifyHooks2;
|
|
138881
139564
|
}
|
|
138882
139565
|
}
|
|
138883
139566
|
if (candidates.length === 0) return false;
|
|
@@ -139021,7 +139704,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139021
139704
|
});
|
|
139022
139705
|
let frozenPlan = null;
|
|
139023
139706
|
if (Array.isArray(state.selectedUnitIds) || deps.preflightGitTransports) {
|
|
139024
|
-
frozenPlan = Array.isArray(state.selectedUnitIds) ? await readFrozenPlanForUnitScope(prepared.planPath, statePath, state.selectedUnitIds) : JSON.parse(await
|
|
139707
|
+
frozenPlan = Array.isArray(state.selectedUnitIds) ? await readFrozenPlanForUnitScope(prepared.planPath, statePath, state.selectedUnitIds) : JSON.parse(await readFile46(prepared.planPath, "utf8"));
|
|
139025
139708
|
}
|
|
139026
139709
|
if (Array.isArray(state.selectedUnitIds)) {
|
|
139027
139710
|
assertFrozenPlanUnitScope({
|
|
@@ -139118,7 +139801,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139118
139801
|
}
|
|
139119
139802
|
let postVerifyRanThisCall = false;
|
|
139120
139803
|
if (state.status === "PUBLISHED" || state.status === "NEEDS_MANUAL_ATTESTATIONS") {
|
|
139121
|
-
const plan = JSON.parse(await
|
|
139804
|
+
const plan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139122
139805
|
const hasDistributeWork = normalizePostPublishView(plan).some((declaration) => (declaration.targets?.length ?? 0) > 0 || (declaration.hooks?.length ?? 0) > 0);
|
|
139123
139806
|
const needsDistribution = hasDistributeWork;
|
|
139124
139807
|
if (needsDistribution && deps.distributeRelease) {
|
|
@@ -139173,15 +139856,6 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139173
139856
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
139174
139857
|
};
|
|
139175
139858
|
await writeJsonAtomic(statePath, state);
|
|
139176
|
-
if (verified.status === "VERIFIED") {
|
|
139177
|
-
try {
|
|
139178
|
-
state.postRelease = derivePostReleaseChecklist(plan);
|
|
139179
|
-
} catch (error) {
|
|
139180
|
-
state.postRelease = unavailablePostReleaseChecklist(plan, error);
|
|
139181
|
-
}
|
|
139182
|
-
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
139183
|
-
await writeJsonAtomic(statePath, state);
|
|
139184
|
-
}
|
|
139185
139859
|
} catch (error) {
|
|
139186
139860
|
if (error?.code !== CONSUMER_VERIFICATION_DEFERRED) throw error;
|
|
139187
139861
|
state = {
|
|
@@ -139192,8 +139866,8 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139192
139866
|
};
|
|
139193
139867
|
await writeJsonAtomic(statePath, state);
|
|
139194
139868
|
}
|
|
139195
|
-
const
|
|
139196
|
-
if (state.status === "VERIFIED" &&
|
|
139869
|
+
const postVerifyHooks2 = normalizePostPublishView(plan).flatMap((declaration) => declaration.hooks ?? []).filter((hook) => hook.phase === "postVerify");
|
|
139870
|
+
if (state.status === "VERIFIED" && postVerifyHooks2.length > 0 && deps.postVerifyRelease) {
|
|
139197
139871
|
postVerifyRanThisCall = true;
|
|
139198
139872
|
let postVerifyOutcome;
|
|
139199
139873
|
try {
|
|
@@ -139227,7 +139901,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139227
139901
|
}
|
|
139228
139902
|
const reentryApprovalPaths = options.postpublishApprovalPaths ?? [];
|
|
139229
139903
|
if (state.status === "VERIFIED" && deps.postVerifyRelease && !postVerifyRanThisCall && (!state.postVerify || state.postVerify.status !== "DISTRIBUTED")) {
|
|
139230
|
-
const reentryPlan = JSON.parse(await
|
|
139904
|
+
const reentryPlan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139231
139905
|
const reentryPostVerifyHooks = normalizePostPublishView(reentryPlan).flatMap((declaration) => (declaration.hooks ?? []).map((hook) => ({ hook, unitId: declaration.unitId }))).filter(({ hook }) => hook.phase === "postVerify");
|
|
139232
139906
|
const approvallessRetryAllowed = reentryApprovalPaths.length === 0 && await allUnclosedPostVerifyHooksUngated(state, reentryPostVerifyHooks, reentryPlan.planVersion);
|
|
139233
139907
|
if (reentryPostVerifyHooks.length > 0 && (reentryApprovalPaths.length > 0 || approvallessRetryAllowed)) {
|
|
@@ -139261,6 +139935,24 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139261
139935
|
await writeJsonAtomic(statePath, state);
|
|
139262
139936
|
}
|
|
139263
139937
|
}
|
|
139938
|
+
if (state.status === "VERIFIED") {
|
|
139939
|
+
const finalPlan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139940
|
+
const hasPostVerify = normalizePostPublishView(finalPlan).some((declaration) => (declaration.hooks ?? []).some((hook) => hook.phase === "postVerify"));
|
|
139941
|
+
const localFinishRunPath = hasPostVerify ? state.postVerify?.status === "DISTRIBUTED" ? state.postVerify.runPath : void 0 : state.verifyRunPath;
|
|
139942
|
+
let postRelease;
|
|
139943
|
+
try {
|
|
139944
|
+
postRelease = derivePostReleaseChecklist(finalPlan, {
|
|
139945
|
+
root,
|
|
139946
|
+
statePath,
|
|
139947
|
+
unitIds: state.selectedUnitIds,
|
|
139948
|
+
runPath: localFinishRunPath,
|
|
139949
|
+
postVerifyComplete: !hasPostVerify || state.postVerify?.status === "DISTRIBUTED"
|
|
139950
|
+
});
|
|
139951
|
+
} catch (error) {
|
|
139952
|
+
postRelease = unavailablePostReleaseChecklist(finalPlan, error);
|
|
139953
|
+
}
|
|
139954
|
+
return publicState2(state, { postRelease });
|
|
139955
|
+
}
|
|
139264
139956
|
return publicState2(state);
|
|
139265
139957
|
}
|
|
139266
139958
|
var HOUR_MS, ACTION_TARGET_FIELDS;
|
|
@@ -140232,7 +140924,7 @@ var attest_exports = {};
|
|
|
140232
140924
|
__export(attest_exports, {
|
|
140233
140925
|
recordManualAttestation: () => recordManualAttestation
|
|
140234
140926
|
});
|
|
140235
|
-
import { readFile as
|
|
140927
|
+
import { readFile as readFile47 } from "node:fs/promises";
|
|
140236
140928
|
import { resolve as resolve38, join as join39 } from "node:path";
|
|
140237
140929
|
async function validateInstalledConsumerClosure({
|
|
140238
140930
|
root,
|
|
@@ -140250,7 +140942,7 @@ async function validateInstalledConsumerClosure({
|
|
|
140250
140942
|
]);
|
|
140251
140943
|
let plan;
|
|
140252
140944
|
try {
|
|
140253
|
-
plan = JSON.parse(await
|
|
140945
|
+
plan = JSON.parse(await readFile47(planPath, "utf8"));
|
|
140254
140946
|
} catch (error) {
|
|
140255
140947
|
throw new ReleaseError(
|
|
140256
140948
|
GATE_FAILED,
|
|
@@ -140324,7 +141016,7 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
140324
141016
|
const requirementPath = join39(authorityDir, descriptor.requirementFile);
|
|
140325
141017
|
let requirement;
|
|
140326
141018
|
try {
|
|
140327
|
-
requirement = JSON.parse(await
|
|
141019
|
+
requirement = JSON.parse(await readFile47(requirementPath, "utf8"));
|
|
140328
141020
|
} catch (error) {
|
|
140329
141021
|
throw new ReleaseError(
|
|
140330
141022
|
GATE_FAILED,
|
|
@@ -140408,7 +141100,7 @@ var init_attest = __esm({
|
|
|
140408
141100
|
});
|
|
140409
141101
|
|
|
140410
141102
|
// src/artifacts/policy.mjs
|
|
140411
|
-
import { readFile as
|
|
141103
|
+
import { readFile as readFile48 } from "node:fs/promises";
|
|
140412
141104
|
import { join as join40 } from "node:path";
|
|
140413
141105
|
import { createHash as createHash19 } from "node:crypto";
|
|
140414
141106
|
function validateArtifactPolicy(policy) {
|
|
@@ -140508,7 +141200,7 @@ async function parseSafeYamlWithinRoot(root, policyPath) {
|
|
|
140508
141200
|
const fullPath = join40(root, policyPath);
|
|
140509
141201
|
let content;
|
|
140510
141202
|
try {
|
|
140511
|
-
content = await
|
|
141203
|
+
content = await readFile48(fullPath, "utf8");
|
|
140512
141204
|
} catch (err) {
|
|
140513
141205
|
throw new ReleaseError(
|
|
140514
141206
|
ARTIFACT_POLICY_INVALID,
|
|
@@ -140619,7 +141311,7 @@ var init_policy = __esm({
|
|
|
140619
141311
|
});
|
|
140620
141312
|
|
|
140621
141313
|
// src/artifacts/entry.mjs
|
|
140622
|
-
import { lstat as lstat46, readdir as readdir30, readFile as
|
|
141314
|
+
import { lstat as lstat46, readdir as readdir30, readFile as readFile49 } from "node:fs/promises";
|
|
140623
141315
|
import { join as join41 } from "node:path";
|
|
140624
141316
|
import { promisify as promisify21 } from "node:util";
|
|
140625
141317
|
import { execFile as execFile14 } from "node:child_process";
|
|
@@ -140664,7 +141356,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
140664
141356
|
const subEntries = await enumerateTreeEntries(root, absPath, relPath);
|
|
140665
141357
|
entries.push(...subEntries);
|
|
140666
141358
|
} else {
|
|
140667
|
-
const content = await
|
|
141359
|
+
const content = await readFile49(absPath);
|
|
140668
141360
|
entries.push(
|
|
140669
141361
|
Object.freeze({
|
|
140670
141362
|
path: relPath,
|
|
@@ -140727,7 +141419,7 @@ async function readEntry({ root, path: path40, source = "worktree" } = {}) {
|
|
|
140727
141419
|
{ path: path40, nlink: st.nlink }
|
|
140728
141420
|
);
|
|
140729
141421
|
}
|
|
140730
|
-
const content = await
|
|
141422
|
+
const content = await readFile49(absPath);
|
|
140731
141423
|
return Object.freeze({
|
|
140732
141424
|
kind: "regular",
|
|
140733
141425
|
path: path40,
|
|
@@ -140991,7 +141683,7 @@ var init_graph = __esm({
|
|
|
140991
141683
|
});
|
|
140992
141684
|
|
|
140993
141685
|
// src/artifacts/producer-registry.mjs
|
|
140994
|
-
import { readFile as
|
|
141686
|
+
import { readFile as readFile50, readdir as readdir31, stat as stat19, mkdir as mkdir32, writeFile as writeFile14, rm as rm18 } from "node:fs/promises";
|
|
140995
141687
|
import { join as join42 } from "node:path";
|
|
140996
141688
|
import { mkdtemp as mkdtemp13 } from "node:fs/promises";
|
|
140997
141689
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
@@ -141023,7 +141715,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
141023
141715
|
const lockfilePath = join42(new URL("../../..", import.meta.url).pathname, "pnpm-lock.yaml");
|
|
141024
141716
|
let lockfileBytes;
|
|
141025
141717
|
try {
|
|
141026
|
-
lockfileBytes = await
|
|
141718
|
+
lockfileBytes = await readFile50(lockfilePath);
|
|
141027
141719
|
} catch {
|
|
141028
141720
|
lockfileBytes = Buffer.from("");
|
|
141029
141721
|
}
|
|
@@ -141040,7 +141732,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
141040
141732
|
const allModuleBytes = await Promise.all(
|
|
141041
141733
|
allModulePaths.map(async (p) => {
|
|
141042
141734
|
try {
|
|
141043
|
-
return await
|
|
141735
|
+
return await readFile50(p);
|
|
141044
141736
|
} catch {
|
|
141045
141737
|
return Buffer.from("");
|
|
141046
141738
|
}
|
|
@@ -141066,7 +141758,7 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
141066
141758
|
if (st.isDirectory()) {
|
|
141067
141759
|
entries.push(...await readDirEntries(absPath, relPath));
|
|
141068
141760
|
} else {
|
|
141069
|
-
const content = await
|
|
141761
|
+
const content = await readFile50(absPath);
|
|
141070
141762
|
entries.push(Object.freeze({
|
|
141071
141763
|
path: relPath,
|
|
141072
141764
|
type: "blob",
|
|
@@ -141593,7 +142285,7 @@ var init_state = __esm({
|
|
|
141593
142285
|
});
|
|
141594
142286
|
|
|
141595
142287
|
// src/artifacts/artifact-plan.mjs
|
|
141596
|
-
import { writeFile as writeFile15, mkdir as mkdir33, readFile as
|
|
142288
|
+
import { writeFile as writeFile15, mkdir as mkdir33, readFile as readFile51, rename as rename5, open as open14 } from "node:fs/promises";
|
|
141597
142289
|
import { dirname as dirname23 } from "node:path";
|
|
141598
142290
|
function assemblePlan({
|
|
141599
142291
|
operation,
|
|
@@ -142282,7 +142974,7 @@ var init_adoption = __esm({
|
|
|
142282
142974
|
// src/artifacts/inspect.mjs
|
|
142283
142975
|
import { promisify as promisify24 } from "node:util";
|
|
142284
142976
|
import { execFile as execFile17 } from "node:child_process";
|
|
142285
|
-
import { readdir as readdir32, stat as stat20, readFile as
|
|
142977
|
+
import { readdir as readdir32, stat as stat20, readFile as readFile52 } from "node:fs/promises";
|
|
142286
142978
|
import { join as join43 } from "node:path";
|
|
142287
142979
|
async function hasNestedGitRoots(root) {
|
|
142288
142980
|
try {
|
|
@@ -142554,7 +143246,7 @@ var init_inspect = __esm({
|
|
|
142554
143246
|
});
|
|
142555
143247
|
|
|
142556
143248
|
// src/artifacts/resolution.mjs
|
|
142557
|
-
import { mkdir as mkdir34, open as open15, readFile as
|
|
143249
|
+
import { mkdir as mkdir34, open as open15, readFile as readFile53, stat as stat21, lstat as lstat47, chmod as chmod6 } from "node:fs/promises";
|
|
142558
143250
|
import { join as join44, resolve as resolve39, relative as relative31, isAbsolute as isAbsolute27, basename as basename15 } from "node:path";
|
|
142559
143251
|
function decodeBuffer(value, label) {
|
|
142560
143252
|
if (value == null) return null;
|
|
@@ -142886,7 +143578,7 @@ async function submitResolution({
|
|
|
142886
143578
|
async function readAndValidateResolvedFile(resolvedPath) {
|
|
142887
143579
|
let content;
|
|
142888
143580
|
try {
|
|
142889
|
-
content = await
|
|
143581
|
+
content = await readFile53(resolvedPath);
|
|
142890
143582
|
} catch (err) {
|
|
142891
143583
|
throw new ReleaseError(MISSING_PARAMETERS, `cannot read resolved file: ${err.message}`, { resolvedPath, cause: err.code });
|
|
142892
143584
|
}
|
|
@@ -143054,7 +143746,7 @@ var artifacts_exports = {};
|
|
|
143054
143746
|
__export(artifacts_exports, {
|
|
143055
143747
|
runArtifactsCommand: () => runArtifactsCommand
|
|
143056
143748
|
});
|
|
143057
|
-
import { readFile as
|
|
143749
|
+
import { readFile as readFile54 } from "node:fs/promises";
|
|
143058
143750
|
import { join as join45 } from "node:path";
|
|
143059
143751
|
async function runArtifactsCommand({ subcommand, args: args2, root } = {}) {
|
|
143060
143752
|
if (!VALID_SUBCOMMANDS.has(subcommand)) {
|
|
@@ -143183,7 +143875,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
143183
143875
|
{ subcommand: "adopt" }
|
|
143184
143876
|
);
|
|
143185
143877
|
}
|
|
143186
|
-
const planRaw = await
|
|
143878
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143187
143879
|
const plan = JSON.parse(planRaw);
|
|
143188
143880
|
if (expectedDigest && plan.planDigest !== expectedDigest) {
|
|
143189
143881
|
throw new ReleaseError(
|
|
@@ -143198,7 +143890,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
143198
143890
|
if (artifact.path) {
|
|
143199
143891
|
const entry = await readEntry({ root, path: artifact.path, source: "worktree" });
|
|
143200
143892
|
if (entry.kind === "regular") {
|
|
143201
|
-
const bytes = await
|
|
143893
|
+
const bytes = await readFile54(join45(root, artifact.path));
|
|
143202
143894
|
currentEntries.set(artifact.id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
143203
143895
|
} else {
|
|
143204
143896
|
currentEntries.set(artifact.id, entry);
|
|
@@ -143263,7 +143955,7 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
143263
143955
|
{ subcommand: "bootstrap" }
|
|
143264
143956
|
);
|
|
143265
143957
|
}
|
|
143266
|
-
const planRaw = await
|
|
143958
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143267
143959
|
const adoptionPlan = JSON.parse(planRaw);
|
|
143268
143960
|
const currentEntries = /* @__PURE__ */ new Map();
|
|
143269
143961
|
for (const id of new Set((adoptionPlan.protectedHunks ?? []).map((h) => h.artifactId))) {
|
|
@@ -143275,12 +143967,12 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
143275
143967
|
if (entry.kind !== "regular") {
|
|
143276
143968
|
throw new ReleaseError("PLAN_STALE", `artifact is no longer a regular file: ${id}`, { id });
|
|
143277
143969
|
}
|
|
143278
|
-
const bytes = await
|
|
143970
|
+
const bytes = await readFile54(join45(root, artifactPath));
|
|
143279
143971
|
currentEntries.set(id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
143280
143972
|
}
|
|
143281
143973
|
let replacementBytes;
|
|
143282
143974
|
if (action === "replace" && replacementPath) {
|
|
143283
|
-
replacementBytes = await
|
|
143975
|
+
replacementBytes = await readFile54(replacementPath);
|
|
143284
143976
|
}
|
|
143285
143977
|
const updated = await discardBootstrapHunk({
|
|
143286
143978
|
adoptionPlan,
|
|
@@ -143318,7 +144010,7 @@ async function handleResolve({ args: args2, root }) {
|
|
|
143318
144010
|
{ subcommand: "resolve" }
|
|
143319
144011
|
);
|
|
143320
144012
|
}
|
|
143321
|
-
const planRaw = await
|
|
144013
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143322
144014
|
const plan = JSON.parse(planRaw);
|
|
143323
144015
|
if (plan.planDigest !== expectedDigest) {
|
|
143324
144016
|
throw new ReleaseError(
|
|
@@ -144136,7 +144828,7 @@ __export(route_exports, {
|
|
|
144136
144828
|
resolvePreviousReleaseCommit: () => resolvePreviousReleaseCommit
|
|
144137
144829
|
});
|
|
144138
144830
|
import { execFileSync } from "node:child_process";
|
|
144139
|
-
import { lstat as lstat48, readdir as readdir33, readFile as
|
|
144831
|
+
import { lstat as lstat48, readdir as readdir33, readFile as readFile55 } from "node:fs/promises";
|
|
144140
144832
|
import { relative as relative32, resolve as resolve40, basename as basename16, dirname as dirname24, join as join46 } from "node:path";
|
|
144141
144833
|
function classifyPath(path40) {
|
|
144142
144834
|
if (typeof path40 !== "string" || path40.length === 0) return "ignore";
|
|
@@ -144223,7 +144915,7 @@ async function resolvePreviousReleaseCommit(root) {
|
|
|
144223
144915
|
if (!file.endsWith(".json")) continue;
|
|
144224
144916
|
let plan;
|
|
144225
144917
|
try {
|
|
144226
|
-
plan = JSON.parse(await
|
|
144918
|
+
plan = JSON.parse(await readFile55(resolve40(plansDir, file), "utf8"));
|
|
144227
144919
|
} catch {
|
|
144228
144920
|
continue;
|
|
144229
144921
|
}
|
|
@@ -144349,7 +145041,7 @@ async function readRunRouting(root, options = {}) {
|
|
|
144349
145041
|
let authorityMissing = false;
|
|
144350
145042
|
let markerlessRunDebris = false;
|
|
144351
145043
|
try {
|
|
144352
|
-
await
|
|
145044
|
+
await readFile55(runPath);
|
|
144353
145045
|
authorityExists = true;
|
|
144354
145046
|
} catch (error) {
|
|
144355
145047
|
if (error.code === "ENOENT") {
|
|
@@ -144504,7 +145196,7 @@ async function isMarkerlessRunDebris(runDirectory) {
|
|
|
144504
145196
|
const evidenceFiles = await readDirectory(join46(runDirectory, "evidence", evidenceEntry.name));
|
|
144505
145197
|
if (!evidenceFiles || evidenceFiles.length !== 1 || evidenceFiles[0].name !== "release-skill-install-evidence.json" || !evidenceFiles[0].isFile() || evidenceFiles[0].isSymbolicLink()) return false;
|
|
144506
145198
|
try {
|
|
144507
|
-
const evidenceRecord = JSON.parse(await
|
|
145199
|
+
const evidenceRecord = JSON.parse(await readFile55(
|
|
144508
145200
|
join46(runDirectory, "evidence", evidenceEntry.name, evidenceFiles[0].name),
|
|
144509
145201
|
"utf8"
|
|
144510
145202
|
));
|
|
@@ -144589,8 +145281,8 @@ async function isProvenPreAuthorityFailure(runDir, runName) {
|
|
|
144589
145281
|
let summary;
|
|
144590
145282
|
let events;
|
|
144591
145283
|
try {
|
|
144592
|
-
summary = JSON.parse(await
|
|
144593
|
-
events = (await
|
|
145284
|
+
summary = JSON.parse(await readFile55(summaryPath, "utf8"));
|
|
145285
|
+
events = (await readFile55(evidencePath, "utf8")).trim().split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
144594
145286
|
} catch {
|
|
144595
145287
|
return false;
|
|
144596
145288
|
}
|
|
@@ -144675,7 +145367,7 @@ async function readLegacyPostverifyRecovery(runPath) {
|
|
|
144675
145367
|
if (run6.command !== "postverify" || run6.status !== "DISTRIBUTED") {
|
|
144676
145368
|
throw new ReleaseError(GATE_FAILED, "legacy postverify status is not terminal DISTRIBUTED");
|
|
144677
145369
|
}
|
|
144678
|
-
const planRaw = await
|
|
145370
|
+
const planRaw = await readFile55(run6.planPath, "utf8");
|
|
144679
145371
|
const plan = JSON.parse(planRaw);
|
|
144680
145372
|
validatePlan(plan);
|
|
144681
145373
|
if (!plan.digest || plan.digest !== computePlanDigest(plan)) {
|
|
@@ -144706,7 +145398,7 @@ async function readLegacyPostverifyRecovery(runPath) {
|
|
|
144706
145398
|
runPath: run6.sourceRunPath,
|
|
144707
145399
|
production
|
|
144708
145400
|
});
|
|
144709
|
-
const summary = JSON.parse(await
|
|
145401
|
+
const summary = JSON.parse(await readFile55(join46(resolve40(runPath, ".."), "summary.json"), "utf8"));
|
|
144710
145402
|
if (!summary || summary.status !== run6.status) {
|
|
144711
145403
|
throw new ReleaseError(GATE_FAILED, "legacy postverify summary status does not match its sealed run status");
|
|
144712
145404
|
}
|
|
@@ -145080,7 +145772,7 @@ Workflow Profiles:
|
|
|
145080
145772
|
});
|
|
145081
145773
|
|
|
145082
145774
|
// bin/release-skill-cli.mjs
|
|
145083
|
-
import { readFile as
|
|
145775
|
+
import { readFile as readFile56 } from "node:fs/promises";
|
|
145084
145776
|
import { basename as basename17, dirname as dirname25, join as join47, resolve as resolve41 } from "node:path";
|
|
145085
145777
|
import { execFile as execFileCb22 } from "node:child_process";
|
|
145086
145778
|
import { promisify as promisify26 } from "node:util";
|
|
@@ -145132,7 +145824,7 @@ guardOutputStream(process.stdout);
|
|
|
145132
145824
|
guardOutputStream(process.stderr);
|
|
145133
145825
|
registerPathRedactor(redactSensitivePaths);
|
|
145134
145826
|
var execFile19 = promisify26(execFileCb22);
|
|
145135
|
-
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"]);
|
|
145136
145828
|
function flushOutputStream(stream) {
|
|
145137
145829
|
if (!stream?.writable || stream.destroyed || stream.writableEnded || outputStreamStates.get(stream)?.failed) {
|
|
145138
145830
|
return Promise.resolve();
|
|
@@ -145163,6 +145855,27 @@ async function exitAfterFlush(exitCode) {
|
|
|
145163
145855
|
process.exit(exitCode);
|
|
145164
145856
|
}
|
|
145165
145857
|
__name(exitAfterFlush, "exitAfterFlush");
|
|
145858
|
+
function publicErrorDetails(error) {
|
|
145859
|
+
const details = error?.details;
|
|
145860
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return {};
|
|
145861
|
+
const output = {};
|
|
145862
|
+
if (details.cause && typeof details.cause === "object" && !Array.isArray(details.cause)) {
|
|
145863
|
+
const cause = {};
|
|
145864
|
+
if (typeof details.cause.code === "string") cause.code = details.cause.code;
|
|
145865
|
+
if (typeof details.cause.message === "string") cause.message = details.cause.message;
|
|
145866
|
+
if (Object.keys(cause).length > 0) output.cause = cause;
|
|
145867
|
+
}
|
|
145868
|
+
if (Array.isArray(details.nextSteps)) {
|
|
145869
|
+
const nextSteps = details.nextSteps.filter((step) => step && typeof step === "object" && !Array.isArray(step)).map((step) => ({
|
|
145870
|
+
...typeof step.code === "string" ? { code: step.code } : {},
|
|
145871
|
+
...typeof step.message === "string" ? { message: step.message } : {},
|
|
145872
|
+
...Array.isArray(step.argv) && step.argv.every((arg) => typeof arg === "string") ? { argv: [...step.argv] } : {}
|
|
145873
|
+
})).filter((step) => Object.keys(step).length > 0);
|
|
145874
|
+
if (nextSteps.length > 0) output.nextSteps = nextSteps;
|
|
145875
|
+
}
|
|
145876
|
+
return output;
|
|
145877
|
+
}
|
|
145878
|
+
__name(publicErrorDetails, "publicErrorDetails");
|
|
145166
145879
|
async function checkDependency(command2, versionArgs = ["--version"]) {
|
|
145167
145880
|
try {
|
|
145168
145881
|
const { stdout } = await execFile19(command2, versionArgs, {
|
|
@@ -145302,6 +146015,11 @@ function getCapabilityMaturity() {
|
|
|
145302
146015
|
mode: "fresh consumer verification (protocol-tested; no OS/network sandbox)",
|
|
145303
146016
|
description: "Recheck remote state, exact npm installation, CLI help, and automated Claude/Codex installs before VERIFIED; Kimi/CodeBuddy remain unverified manual follow-ups"
|
|
145304
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
|
+
},
|
|
145305
146023
|
distribute: {
|
|
145306
146024
|
available: true,
|
|
145307
146025
|
mode: "controlled production (protocol-tested; no OS/network sandbox)",
|
|
@@ -145335,6 +146053,7 @@ Commands:
|
|
|
145335
146053
|
publish Publish frozen GitHub/npm artifacts after approval
|
|
145336
146054
|
reconcile Resume PARTIAL state from evidence; conflicts require a human
|
|
145337
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
|
|
145338
146057
|
ship Resume one durable prepare -> approve -> publish -> verify flow; completes a parked
|
|
145339
146058
|
postVerify hook once its checkpoint approval is provided (--hook-approval)
|
|
145340
146059
|
post-release Inspect optional local finishing work after VERIFIED; update installed host plugins
|
|
@@ -145349,10 +146068,10 @@ Commands:
|
|
|
145349
146068
|
|
|
145350
146069
|
Options:
|
|
145351
146070
|
--root <path> Project root directory (default: cwd)
|
|
145352
|
-
--plan <path> Path to the release plan file
|
|
146071
|
+
--plan <path> Path to the release plan file (required for approve/publish/reconcile/verify/postverify)
|
|
145353
146072
|
--run <path> Path to the release run file, or a run directory whose release-run.json
|
|
145354
|
-
is resolved automatically (required for reconcile/verify)
|
|
145355
|
-
--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)
|
|
145356
146075
|
--production Prepare immutable Git/npm production artifacts
|
|
145357
146076
|
--output <path> Override prepare/approve output path (non-production only)
|
|
145358
146077
|
--run-dir <path> Override prepare run directory; production requires one direct child of .release-skill/runs
|
|
@@ -145389,7 +146108,7 @@ Options:
|
|
|
145389
146108
|
--install-path <path> Actual managed plugin path when closure verification requires it
|
|
145390
146109
|
--install-channel <desktop|cli> CodeBuddy installation channel when required
|
|
145391
146110
|
--approve Approve the ship plan (boolean; plan digest is auto-resolved)
|
|
145392
|
-
--hook-approval <path> Checkpoint approval for
|
|
146111
|
+
--hook-approval <path> Checkpoint approval for one requiresApproval hook (ship/distribute/postverify; repeatable)
|
|
145393
146112
|
--state <path> Override the durable ship state file
|
|
145394
146113
|
--update-local-hosts Update installed plugins for selected local hosts after VERIFIED
|
|
145395
146114
|
--hosts <ids> Comma-separated local hosts for post-release update. No local host is updated unless --hosts contains at least one id
|
|
@@ -145871,9 +146590,15 @@ if (command === "ship") {
|
|
|
145871
146590
|
} else {
|
|
145872
146591
|
console.log("Post-release: branch advancement was already included; skip the merge question.");
|
|
145873
146592
|
}
|
|
145874
|
-
|
|
146593
|
+
const localHostUpdate = result2.postRelease.localHostUpdate;
|
|
146594
|
+
if (localHostUpdate?.available === true && typeof localHostUpdate.runPath === "string") {
|
|
145875
146595
|
console.log(`Post-release: ask whether to update local host plugins (${result2.postRelease.localHostUpdate.hosts.join(", ")}).`);
|
|
145876
|
-
console.log(`Post-release command: release-skill post-release --plan ${result2.planPath} --run ${
|
|
146596
|
+
console.log(`Post-release command: release-skill post-release --plan ${result2.planPath} --run ${localHostUpdate.runPath}`);
|
|
146597
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
146598
|
+
} else {
|
|
146599
|
+
for (const step of localHostUpdate?.nextSteps ?? []) {
|
|
146600
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
146601
|
+
}
|
|
145877
146602
|
}
|
|
145878
146603
|
}
|
|
145879
146604
|
for (const followUp of result2.manualFollowUps ?? []) {
|
|
@@ -146217,55 +146942,68 @@ if (command === "post-release") {
|
|
|
146217
146942
|
const planPath = value("--plan") ? resolve41(value("--plan")) : void 0;
|
|
146218
146943
|
const runPath = value("--run") ? resolve41(value("--run")) : void 0;
|
|
146219
146944
|
if (!planPath || !runPath) {
|
|
146220
|
-
const message = "post-release requires --plan <path> and --run <
|
|
146945
|
+
const message = "post-release requires --plan <path> and --run <verify-or-postverify-run-path>";
|
|
146221
146946
|
if (hasJson) console.log(JSON.stringify({ error: "MISSING_PARAMETERS", message, exitCode: 1 }));
|
|
146222
146947
|
else console.error(`Error: ${message}`);
|
|
146223
146948
|
await exitAfterFlush(1);
|
|
146224
146949
|
}
|
|
146225
146950
|
try {
|
|
146226
146951
|
const {
|
|
146227
|
-
assertVerifiedReleaseRun: assertVerifiedReleaseRun2,
|
|
146228
146952
|
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
146229
146953
|
updateLocalHostPlugins: updateLocalHostPlugins2
|
|
146230
146954
|
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
146231
146955
|
const { validatePlan: validatePlan2 } = await init_plan().then(() => plan_exports);
|
|
146232
146956
|
const {
|
|
146233
146957
|
loadRun: loadRun2,
|
|
146234
|
-
resolveRunPath: resolveRunPath2
|
|
146235
|
-
validateRunLineage: validateRunLineage2
|
|
146958
|
+
resolveRunPath: resolveRunPath2
|
|
146236
146959
|
} = await init_run().then(() => run_exports);
|
|
146237
|
-
const plan = JSON.parse(await
|
|
146960
|
+
const plan = JSON.parse(await readFile56(planPath, "utf8"));
|
|
146238
146961
|
validatePlan2(plan);
|
|
146962
|
+
const updateRequested = args.includes("--update-local-hosts");
|
|
146239
146963
|
const resolvedRunPath = await resolveRunPath2(runPath);
|
|
146240
146964
|
const runRecord = await loadRun2(resolvedRunPath, {
|
|
146241
146965
|
requireDigest: true,
|
|
146242
146966
|
authorityPlanPath: planPath
|
|
146243
146967
|
});
|
|
146244
|
-
|
|
146245
|
-
|
|
146246
|
-
|
|
146247
|
-
|
|
146248
|
-
|
|
146249
|
-
|
|
146250
|
-
|
|
146251
|
-
|
|
146968
|
+
if (!updateRequested) {
|
|
146969
|
+
const { assertLocalFinishRun: assertLocalFinishRun2 } = await init_post_release_local().then(() => post_release_local_exports);
|
|
146970
|
+
await assertLocalFinishRun2({
|
|
146971
|
+
plan,
|
|
146972
|
+
planPath,
|
|
146973
|
+
runPath: resolvedRunPath,
|
|
146974
|
+
runRecord,
|
|
146975
|
+
production: Boolean(plan.production),
|
|
146976
|
+
root: resolve41(value("--root") ?? process.cwd())
|
|
146977
|
+
});
|
|
146978
|
+
}
|
|
146252
146979
|
const hostsIndex = args.indexOf("--hosts");
|
|
146253
146980
|
const rawHosts = hostsIndex !== -1 && args[hostsIndex + 1] && !args[hostsIndex + 1].startsWith("--") ? args[hostsIndex + 1] : "";
|
|
146254
146981
|
const selectedHosts = rawHosts.split(",").map((host) => host.trim()).filter(Boolean);
|
|
146255
146982
|
const result2 = updateRequested ? await updateLocalHostPlugins2({
|
|
146256
|
-
|
|
146983
|
+
planPath,
|
|
146984
|
+
runPath: resolvedRunPath,
|
|
146257
146985
|
root: resolve41(value("--root") ?? process.cwd()),
|
|
146258
146986
|
confirmPlanDigest: value("--confirm-plan"),
|
|
146259
146987
|
selectedHosts
|
|
146260
|
-
}) : derivePostReleaseChecklist2(plan
|
|
146988
|
+
}) : derivePostReleaseChecklist2(plan, {
|
|
146989
|
+
runPath: runRecord.command === "postverify" && runRecord.status === "DISTRIBUTED" ? resolvedRunPath : runRecord.command === "verify" ? resolvedRunPath : void 0,
|
|
146990
|
+
root: resolve41(value("--root") ?? process.cwd()),
|
|
146991
|
+
postVerifyComplete: runRecord.command === "postverify" && runRecord.status === "DISTRIBUTED"
|
|
146992
|
+
});
|
|
146261
146993
|
if (hasJson) {
|
|
146262
146994
|
console.log(JSON.stringify(result2, null, 2));
|
|
146263
146995
|
} else if (!updateRequested) {
|
|
146264
146996
|
console.log(`Post-release status: ${result2.status}`);
|
|
146265
146997
|
if (result2.merge.promptRequired) console.log("Ask whether the user wants to merge the remaining branch.");
|
|
146266
146998
|
else console.log("Branch advancement was already included in the release workflow; skip the merge question.");
|
|
146267
|
-
if (result2.localHostUpdate.
|
|
146999
|
+
if (result2.localHostUpdate.available === true && typeof result2.localHostUpdate.runPath === "string") {
|
|
146268
147000
|
console.log(`Ask whether to update local host plugins: ${result2.localHostUpdate.hosts.join(", ")}`);
|
|
147001
|
+
console.log(`Post-release command: release-skill post-release --plan ${planPath} --run ${result2.localHostUpdate.runPath}`);
|
|
147002
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
147003
|
+
} else {
|
|
147004
|
+
for (const step of result2.localHostUpdate.nextSteps ?? []) {
|
|
147005
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
147006
|
+
}
|
|
146269
147007
|
}
|
|
146270
147008
|
} else {
|
|
146271
147009
|
console.log(`Local host update: ${result2.status}`);
|
|
@@ -146281,9 +147019,15 @@ if (command === "post-release") {
|
|
|
146281
147019
|
console.log(JSON.stringify({
|
|
146282
147020
|
error: err.code ?? "POST_RELEASE_FAILED",
|
|
146283
147021
|
message: err.message,
|
|
147022
|
+
details: publicErrorDetails(err),
|
|
146284
147023
|
exitCode: err.exitCode ?? 1
|
|
146285
147024
|
}));
|
|
146286
|
-
} else
|
|
147025
|
+
} else {
|
|
147026
|
+
console.error(`Error: ${err.message}`);
|
|
147027
|
+
for (const step of err.details?.nextSteps ?? []) {
|
|
147028
|
+
console.error(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
147029
|
+
}
|
|
147030
|
+
}
|
|
146287
147031
|
await exitAfterFlush(err.exitCode ?? 1);
|
|
146288
147032
|
}
|
|
146289
147033
|
}
|
|
@@ -146330,9 +147074,9 @@ if (command === "verify") {
|
|
|
146330
147074
|
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
146331
147075
|
unavailablePostReleaseChecklist: unavailablePostReleaseChecklist2
|
|
146332
147076
|
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
146333
|
-
const plan = JSON.parse(await
|
|
147077
|
+
const plan = JSON.parse(await readFile56(planPath, "utf8"));
|
|
146334
147078
|
try {
|
|
146335
|
-
result2.postRelease = derivePostReleaseChecklist2(plan);
|
|
147079
|
+
result2.postRelease = derivePostReleaseChecklist2(plan, { root, runPath: result2.runPath });
|
|
146336
147080
|
} catch (error) {
|
|
146337
147081
|
result2.postRelease = unavailablePostReleaseChecklist2(plan, error);
|
|
146338
147082
|
}
|
|
@@ -146357,8 +147101,14 @@ if (command === "verify") {
|
|
|
146357
147101
|
} else if (result2.postRelease?.merge.promptRequired) {
|
|
146358
147102
|
console.log("Post-release: ask whether to merge the remaining branch.");
|
|
146359
147103
|
}
|
|
146360
|
-
if (result2.postRelease?.localHostUpdate.
|
|
147104
|
+
if (result2.postRelease?.localHostUpdate?.available === true && typeof result2.postRelease.localHostUpdate.runPath === "string") {
|
|
146361
147105
|
console.log(`Post-release: ask whether to update local host plugins (${result2.postRelease.localHostUpdate.hosts.join(", ")}).`);
|
|
147106
|
+
console.log(`Post-release command: release-skill post-release --plan ${planPath} --run ${result2.postRelease.localHostUpdate.runPath}`);
|
|
147107
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
147108
|
+
} else {
|
|
147109
|
+
for (const step of result2.postRelease?.localHostUpdate?.nextSteps ?? []) {
|
|
147110
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
147111
|
+
}
|
|
146362
147112
|
}
|
|
146363
147113
|
}
|
|
146364
147114
|
await exitAfterFlush(result2.status === "VERIFIED" ? 0 : 1);
|
|
@@ -146367,6 +147117,7 @@ if (command === "verify") {
|
|
|
146367
147117
|
const errOutput = {
|
|
146368
147118
|
error: err.code ?? "UNKNOWN_ERROR",
|
|
146369
147119
|
message: err.message,
|
|
147120
|
+
details: err.details ?? {},
|
|
146370
147121
|
exitCode: err.exitCode ?? 1
|
|
146371
147122
|
};
|
|
146372
147123
|
console.log(JSON.stringify(errOutput));
|
|
@@ -146376,6 +147127,117 @@ if (command === "verify") {
|
|
|
146376
147127
|
await exitAfterFlush(err.exitCode ?? 1);
|
|
146377
147128
|
}
|
|
146378
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
|
+
}
|
|
146379
147241
|
if (command === "publish") {
|
|
146380
147242
|
const rootIdx = args.indexOf("--root");
|
|
146381
147243
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|