release-skill 0.9.4 → 0.9.5
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 +29 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +20 -16
- package/README.zh-CN.md +19 -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 +866 -166
- 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 +3 -3
- package/adapters/claude/skills/release-verify/SKILL.md +2 -1
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +866 -166
- 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 +3 -3
- package/adapters/codex/skills/release-verify/SKILL.md +2 -1
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +866 -166
- 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 +3 -3
- package/adapters/kimi/skills/release-verify/SKILL.md +2 -1
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +866 -166
- 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 +3 -3
- package/adapters/workbuddy/skills/release-verify/SKILL.md +2 -1
- package/bin/release-skill-cli.mjs +87 -20
- package/bin/release-skill.bundle.mjs +866 -166
- 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 +3 -3
- package/skills/release-verify/SKILL.md +2 -1
- package/skills-src/release-finish/SKILL.md +5 -5
- package/skills-src/release-help/SKILL.md +3 -3
- package/skills-src/release-verify/SKILL.md +2 -1
- 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.5"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "cbcc967eb1306a8f2e88e404a9ffbdb8bfaf0ffb8863fe8c5521cbb4d44346c1";
|
|
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");
|
|
@@ -112391,6 +112521,136 @@ async function verifyPublicSourceAuthorityReceiptOffline({ plan, root }) {
|
|
|
112391
112521
|
function defaultClock() {
|
|
112392
112522
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
112393
112523
|
}
|
|
112524
|
+
function parseMarketplaceHead(stdout) {
|
|
112525
|
+
if (typeof stdout !== "string") return null;
|
|
112526
|
+
let sha = null;
|
|
112527
|
+
let defaultBranch = null;
|
|
112528
|
+
for (const line of stdout.trim().split("\n").filter(Boolean)) {
|
|
112529
|
+
const tab = line.indexOf(" ");
|
|
112530
|
+
if (tab < 0) continue;
|
|
112531
|
+
const left = line.slice(0, tab);
|
|
112532
|
+
const right = line.slice(tab + 1);
|
|
112533
|
+
if (right !== "HEAD") continue;
|
|
112534
|
+
if (left.startsWith("ref: refs/heads/")) defaultBranch = left.slice("ref: refs/heads/".length);
|
|
112535
|
+
else if (EXTERNAL_MARKETPLACE_SHA_RE2.test(left)) sha = left;
|
|
112536
|
+
}
|
|
112537
|
+
return sha && defaultBranch ? { sha, defaultBranch } : null;
|
|
112538
|
+
}
|
|
112539
|
+
async function defaultObserveMarketplaceHead(repo, { githubHost = "github.com" } = {}) {
|
|
112540
|
+
try {
|
|
112541
|
+
const { stdout } = await execFile6("git", [
|
|
112542
|
+
"ls-remote",
|
|
112543
|
+
"--symref",
|
|
112544
|
+
`https://${githubHost}/${repo}.git`,
|
|
112545
|
+
"HEAD"
|
|
112546
|
+
], { shell: false, encoding: "utf8", timeout: 3e4 });
|
|
112547
|
+
const parsed = parseMarketplaceHead(stdout);
|
|
112548
|
+
return parsed ? { status: "observed", ...parsed } : { status: "unknown", error: "could not resolve marketplace HEAD" };
|
|
112549
|
+
} catch (error) {
|
|
112550
|
+
return { status: "unknown", error: error.message };
|
|
112551
|
+
}
|
|
112552
|
+
}
|
|
112553
|
+
function decodeMarketplaceIndex(content) {
|
|
112554
|
+
if (typeof content !== "string") return null;
|
|
112555
|
+
try {
|
|
112556
|
+
return JSON.parse(Buffer.from(content.replace(/\s/g, ""), "base64").toString("utf8"));
|
|
112557
|
+
} catch {
|
|
112558
|
+
return null;
|
|
112559
|
+
}
|
|
112560
|
+
}
|
|
112561
|
+
async function defaultFetchMarketplaceIndex(repo, path40, ref, { githubHost = "github.com" } = {}) {
|
|
112562
|
+
try {
|
|
112563
|
+
const { stdout } = await execFile6("gh", [
|
|
112564
|
+
"api",
|
|
112565
|
+
`repos/${repo}/contents/${path40}?ref=${ref}`,
|
|
112566
|
+
"--jq",
|
|
112567
|
+
".content"
|
|
112568
|
+
], {
|
|
112569
|
+
shell: false,
|
|
112570
|
+
encoding: "utf8",
|
|
112571
|
+
timeout: 3e4,
|
|
112572
|
+
env: { ...process.env, GH_HOST: githubHost }
|
|
112573
|
+
});
|
|
112574
|
+
const index = decodeMarketplaceIndex(stdout);
|
|
112575
|
+
return index && typeof index === "object" ? { status: "fetched", index } : { status: "unknown", error: "could not decode marketplace index" };
|
|
112576
|
+
} catch (error) {
|
|
112577
|
+
return { status: "unknown", error: error.message };
|
|
112578
|
+
}
|
|
112579
|
+
}
|
|
112580
|
+
async function verifyFirstReleaseBootstrapIndexes({
|
|
112581
|
+
actions,
|
|
112582
|
+
plan,
|
|
112583
|
+
evidence,
|
|
112584
|
+
observeHeadFn,
|
|
112585
|
+
fetchIndexFn
|
|
112586
|
+
}) {
|
|
112587
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
112588
|
+
for (const action of actions) {
|
|
112589
|
+
if (action.parameters?.firstReleaseBootstrap !== FIRST_RELEASE_BOOTSTRAP_MODE) continue;
|
|
112590
|
+
const params = action.parameters;
|
|
112591
|
+
const githubHost = params.githubHost ?? "github.com";
|
|
112592
|
+
const failDeferred = /* @__PURE__ */ __name(async (reason, observed2 = null) => {
|
|
112593
|
+
await evidence.append({
|
|
112594
|
+
phase: "verify-marketplace-bootstrap-index",
|
|
112595
|
+
actionId: action.id,
|
|
112596
|
+
actionType: action.type,
|
|
112597
|
+
status: "needs-input",
|
|
112598
|
+
reason,
|
|
112599
|
+
...observed2 ? { observed: observed2 } : {}
|
|
112600
|
+
});
|
|
112601
|
+
throw new ReleaseError(
|
|
112602
|
+
CONSUMER_VERIFICATION_DEFERRED,
|
|
112603
|
+
`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`,
|
|
112604
|
+
{ actionId: action.id, reason, observed: observed2, nextState: "NEEDS_MANUAL_ATTESTATIONS" }
|
|
112605
|
+
);
|
|
112606
|
+
}, "failDeferred");
|
|
112607
|
+
const observed = await observeHeadFn(params.repo, { githubHost });
|
|
112608
|
+
if (observed?.status !== "observed" || !EXTERNAL_MARKETPLACE_SHA_RE2.test(observed.sha ?? "") || !observed.defaultBranch) {
|
|
112609
|
+
await failDeferred(`could not observe current marketplace HEAD: ${observed?.error ?? "unknown"}`, observed);
|
|
112610
|
+
}
|
|
112611
|
+
const path40 = params.marketplaceIndexPath;
|
|
112612
|
+
const fetched = await fetchIndexFn(params.repo, path40, observed.sha, { githubHost });
|
|
112613
|
+
if (fetched?.status !== "fetched" || !fetched.index || typeof fetched.index !== "object") {
|
|
112614
|
+
await failDeferred(`could not read marketplace index at ${observed.sha}: ${fetched?.error ?? "unknown"}`, observed);
|
|
112615
|
+
}
|
|
112616
|
+
const index = fetched.index;
|
|
112617
|
+
if (index.name !== params.marketplaceName) {
|
|
112618
|
+
await failDeferred(`marketplace name mismatch: expected ${params.marketplaceName}, got ${index.name}`, { ...observed, name: index.name });
|
|
112619
|
+
}
|
|
112620
|
+
if (!Array.isArray(index.plugins)) {
|
|
112621
|
+
await failDeferred("marketplace index plugins must be an array", { ...observed, pluginsType: typeof index.plugins });
|
|
112622
|
+
}
|
|
112623
|
+
const entries = index.plugins.filter((entry) => entry && entry.name === params.plugin);
|
|
112624
|
+
let projectedEntry = null;
|
|
112625
|
+
if (entries.length === 1) {
|
|
112626
|
+
try {
|
|
112627
|
+
projectedEntry = projectObservedStandaloneIndexInstallIdentity(params.consumer, entries[0]);
|
|
112628
|
+
} catch {
|
|
112629
|
+
projectedEntry = null;
|
|
112630
|
+
}
|
|
112631
|
+
}
|
|
112632
|
+
if (entries.length !== 1 || !projectedEntry || canonicalJson2(projectedEntry) !== canonicalJson2(params.selectedEntry)) {
|
|
112633
|
+
await failDeferred("marketplace selectedEntry is missing, duplicated, or does not exactly match the plan-bound expected entry", {
|
|
112634
|
+
...observed,
|
|
112635
|
+
entryCount: entries.length,
|
|
112636
|
+
selectedEntry: projectedEntry ?? entries[0] ?? null
|
|
112637
|
+
});
|
|
112638
|
+
}
|
|
112639
|
+
bindings.set(action.id, {
|
|
112640
|
+
marketplaceIndexSha: observed.sha,
|
|
112641
|
+
marketplaceIndexRef: action.type === "claude-marketplace-install" ? observed.defaultBranch : observed.sha
|
|
112642
|
+
});
|
|
112643
|
+
await evidence.append({
|
|
112644
|
+
phase: "verify-marketplace-bootstrap-index",
|
|
112645
|
+
actionId: action.id,
|
|
112646
|
+
actionType: action.type,
|
|
112647
|
+
status: "observed",
|
|
112648
|
+
marketplaceIndexSha: observed.sha,
|
|
112649
|
+
marketplaceIndexRef: action.type === "claude-marketplace-install" ? observed.defaultBranch : observed.sha
|
|
112650
|
+
});
|
|
112651
|
+
}
|
|
112652
|
+
return bindings;
|
|
112653
|
+
}
|
|
112394
112654
|
function isValidDigest2(digest3) {
|
|
112395
112655
|
return typeof digest3 === "string" && /^[a-f0-9]{64}$/.test(digest3);
|
|
112396
112656
|
}
|
|
@@ -112925,7 +113185,9 @@ async function verifyRelease(options) {
|
|
|
112925
113185
|
previousVerifyRun,
|
|
112926
113186
|
execFn,
|
|
112927
113187
|
configPath: configPathOpt,
|
|
112928
|
-
runPluginVerificationFn
|
|
113188
|
+
runPluginVerificationFn,
|
|
113189
|
+
observeFirstReleaseMarketplaceHeadFn,
|
|
113190
|
+
fetchFirstReleaseMarketplaceIndexFn
|
|
112929
113191
|
} = options ?? {};
|
|
112930
113192
|
const clockFn = typeof clockOpt === "function" ? clockOpt : defaultClock;
|
|
112931
113193
|
if (!sourceRunPath) {
|
|
@@ -113139,6 +113401,13 @@ async function verifyRelease(options) {
|
|
|
113139
113401
|
const consumerGateResults = [];
|
|
113140
113402
|
const consumerVerificationReceipts = [];
|
|
113141
113403
|
const actions = plan.externalActions ?? [];
|
|
113404
|
+
const bootstrapIndexBindings = await verifyFirstReleaseBootstrapIndexes({
|
|
113405
|
+
actions,
|
|
113406
|
+
plan,
|
|
113407
|
+
evidence,
|
|
113408
|
+
observeHeadFn: observeFirstReleaseMarketplaceHeadFn ?? defaultObserveMarketplaceHead,
|
|
113409
|
+
fetchIndexFn: fetchFirstReleaseMarketplaceIndexFn ?? defaultFetchMarketplaceIndex
|
|
113410
|
+
});
|
|
113142
113411
|
const trustedVerifyRuns = [];
|
|
113143
113412
|
const planDir = dirname10(planPath);
|
|
113144
113413
|
const releaseDir = basename9(planDir) === "plans" ? dirname10(planDir) : planDir;
|
|
@@ -113335,10 +113604,21 @@ async function verifyRelease(options) {
|
|
|
113335
113604
|
root,
|
|
113336
113605
|
runDir
|
|
113337
113606
|
};
|
|
113607
|
+
const bootstrapBinding = bootstrapIndexBindings.get(action.id) ?? null;
|
|
113338
113608
|
const actionInput = {
|
|
113339
113609
|
actionType: adapterActionType,
|
|
113340
113610
|
...action.parameters
|
|
113341
113611
|
};
|
|
113612
|
+
if (bootstrapBinding) {
|
|
113613
|
+
actionInput.marketplaceCommitSha = bootstrapBinding.marketplaceIndexSha;
|
|
113614
|
+
actionInput.marketplaceIndexSha = bootstrapBinding.marketplaceIndexSha;
|
|
113615
|
+
actionInput.ref = bootstrapBinding.marketplaceIndexRef;
|
|
113616
|
+
actionInput.sourceDescriptor = {
|
|
113617
|
+
...actionInput.sourceDescriptor,
|
|
113618
|
+
marketplaceCommitSha: bootstrapBinding.marketplaceIndexSha,
|
|
113619
|
+
ref: bootstrapBinding.marketplaceIndexRef
|
|
113620
|
+
};
|
|
113621
|
+
}
|
|
113342
113622
|
const unit = (plan.units ?? []).find((u) => u.id === action.unitId);
|
|
113343
113623
|
const typeToDist = {
|
|
113344
113624
|
"claude-marketplace-install": "claude-plugin",
|
|
@@ -113392,6 +113672,7 @@ async function verifyRelease(options) {
|
|
|
113392
113672
|
actionType: action.type,
|
|
113393
113673
|
status: VERIFICATION_RESOLVED_TYPES.NOT_REQUIRED_UNCHANGED,
|
|
113394
113674
|
installationContractDigest: currentDigest,
|
|
113675
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {},
|
|
113395
113676
|
reason: "\u5B89\u88C5\u5951\u7EA6\u6458\u8981\u672A\u53D8\u5316\uFF0C\u8DF3\u8FC7\u9A8C\u8BC1"
|
|
113396
113677
|
});
|
|
113397
113678
|
consumerVerificationReceipts.push({
|
|
@@ -113409,7 +113690,8 @@ async function verifyRelease(options) {
|
|
|
113409
113690
|
actionId: action.id,
|
|
113410
113691
|
actionType: action.type,
|
|
113411
113692
|
status: VERIFICATION_RESOLVED_TYPES.NOT_REQUIRED_UNCHANGED,
|
|
113412
|
-
installationContractDigest: currentDigest
|
|
113693
|
+
installationContractDigest: currentDigest,
|
|
113694
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {}
|
|
113413
113695
|
});
|
|
113414
113696
|
return;
|
|
113415
113697
|
}
|
|
@@ -113428,8 +113710,14 @@ async function verifyRelease(options) {
|
|
|
113428
113710
|
{ actionId: action.id }
|
|
113429
113711
|
);
|
|
113430
113712
|
}
|
|
113713
|
+
const expectedInput = bootstrapBinding ? {
|
|
113714
|
+
...action.expected,
|
|
113715
|
+
marketplaceCommitSha: bootstrapBinding.marketplaceIndexSha,
|
|
113716
|
+
marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha,
|
|
113717
|
+
ref: bootstrapBinding.marketplaceIndexRef
|
|
113718
|
+
} : action.expected;
|
|
113431
113719
|
const verifyResult = await adapter.verify(
|
|
113432
|
-
{ ...actionInput, expected:
|
|
113720
|
+
{ ...actionInput, expected: expectedInput },
|
|
113433
113721
|
marketplaceContext
|
|
113434
113722
|
);
|
|
113435
113723
|
const isHumanConfirmed = verifyResult.observation?.humanConfirmed === true;
|
|
@@ -113440,6 +113728,7 @@ async function verifyRelease(options) {
|
|
|
113440
113728
|
status: resolvedStatus,
|
|
113441
113729
|
observation: verifyResult.observation,
|
|
113442
113730
|
error: verifyResult.error,
|
|
113731
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {},
|
|
113443
113732
|
...dist?.installationContractDigest ? { installationContractDigest: dist.installationContractDigest } : {}
|
|
113444
113733
|
};
|
|
113445
113734
|
adapterChecks.push(check);
|
|
@@ -113459,7 +113748,8 @@ async function verifyRelease(options) {
|
|
|
113459
113748
|
phase: "verify-marketplace",
|
|
113460
113749
|
actionId: action.id,
|
|
113461
113750
|
actionType: action.type,
|
|
113462
|
-
status: check.status
|
|
113751
|
+
status: check.status,
|
|
113752
|
+
...bootstrapBinding ? { marketplaceIndexSha: bootstrapBinding.marketplaceIndexSha, marketplaceIndexRef: bootstrapBinding.marketplaceIndexRef } : {}
|
|
113463
113753
|
});
|
|
113464
113754
|
if (check.status === "FAILED") {
|
|
113465
113755
|
throw new ReleaseError(
|
|
@@ -113899,7 +114189,7 @@ async function verifyRelease(options) {
|
|
|
113899
114189
|
throw err;
|
|
113900
114190
|
}
|
|
113901
114191
|
}
|
|
113902
|
-
var execFile6, VERIFICATION_RESOLVED_TYPES, ADAPTER_ACTION_TYPE_MAP2, defaultNpmExecutor;
|
|
114192
|
+
var execFile6, VERIFICATION_RESOLVED_TYPES, ADAPTER_ACTION_TYPE_MAP2, FIRST_RELEASE_BOOTSTRAP_MODE, EXTERNAL_MARKETPLACE_SHA_RE2, defaultNpmExecutor;
|
|
113903
114193
|
var init_verify = __esm({
|
|
113904
114194
|
async "src/commands/verify.mjs"() {
|
|
113905
114195
|
init_src2();
|
|
@@ -113918,6 +114208,7 @@ var init_verify = __esm({
|
|
|
113918
114208
|
init_frozen_marker();
|
|
113919
114209
|
await init_foundation_plugin_verification();
|
|
113920
114210
|
init_public_path();
|
|
114211
|
+
init_digest();
|
|
113921
114212
|
init_npm();
|
|
113922
114213
|
init_verification_gates();
|
|
113923
114214
|
await init_skill_resource_closure();
|
|
@@ -113948,6 +114239,13 @@ var init_verify = __esm({
|
|
|
113948
114239
|
"codebuddy-marketplace-install": "codebuddy-marketplace-install"
|
|
113949
114240
|
};
|
|
113950
114241
|
__name(defaultClock, "defaultClock");
|
|
114242
|
+
FIRST_RELEASE_BOOTSTRAP_MODE = "manual-index-checkpoint";
|
|
114243
|
+
EXTERNAL_MARKETPLACE_SHA_RE2 = /^[0-9a-f]{40}$/;
|
|
114244
|
+
__name(parseMarketplaceHead, "parseMarketplaceHead");
|
|
114245
|
+
__name(defaultObserveMarketplaceHead, "defaultObserveMarketplaceHead");
|
|
114246
|
+
__name(decodeMarketplaceIndex, "decodeMarketplaceIndex");
|
|
114247
|
+
__name(defaultFetchMarketplaceIndex, "defaultFetchMarketplaceIndex");
|
|
114248
|
+
__name(verifyFirstReleaseBootstrapIndexes, "verifyFirstReleaseBootstrapIndexes");
|
|
113951
114249
|
__name(isValidDigest2, "isValidDigest");
|
|
113952
114250
|
__name(collectMissingManualAttestations, "collectMissingManualAttestations");
|
|
113953
114251
|
__name(matchesSubset2, "matchesSubset");
|
|
@@ -121372,6 +121670,17 @@ function extractManifestSkillNames(skills) {
|
|
|
121372
121670
|
function findSkillNames(content, manifestSkillNames) {
|
|
121373
121671
|
return manifestSkillNames.filter((name) => content.includes(name));
|
|
121374
121672
|
}
|
|
121673
|
+
function hasInstallCommand(content) {
|
|
121674
|
+
if (/npm\s+install|npx\s+release-skill|npm\s+i\s+release-skill/i.test(content)) {
|
|
121675
|
+
return true;
|
|
121676
|
+
}
|
|
121677
|
+
const codeBlocks = [
|
|
121678
|
+
...[...content.matchAll(/```[^\n]*\n([\s\S]*?)```/g)].map((match) => match[1]),
|
|
121679
|
+
...[...content.matchAll(/`([^`\n]+)`/g)].map((match) => match[1])
|
|
121680
|
+
];
|
|
121681
|
+
const pluginInstall = /^(?:[$>]\s*)?(?:codex\s+plugin\s+add|claude\s+plugin\s+install)\s+\S+/i;
|
|
121682
|
+
return codeBlocks.some((block) => block.split("\n").some((line) => pluginInstall.test(line.trim())));
|
|
121683
|
+
}
|
|
121375
121684
|
async function evaluateReadme({ snapshotDir, pluginManifest }) {
|
|
121376
121685
|
const findings = [];
|
|
121377
121686
|
const enPath = path39.join(snapshotDir, "README.md");
|
|
@@ -121412,7 +121721,7 @@ async function evaluateReadme({ snapshotDir, pluginManifest }) {
|
|
|
121412
121721
|
safeFirstCommand: enMarkers.has("safe-first-command")
|
|
121413
121722
|
};
|
|
121414
121723
|
const readabilityChecks = {
|
|
121415
|
-
hasInstall: enContent ?
|
|
121724
|
+
hasInstall: enContent ? hasInstallCommand(enContent) : false,
|
|
121416
121725
|
hasMinimalExample: enContent ? /```[\s\S]*?(release-skill|assess|prepare|help)[\s\S]*?```/i.test(enContent) : false,
|
|
121417
121726
|
hasFailureDiagnosis: enContent ? /CONFIG_INVALID|PARTIAL|GATE_FAILED|if.*fail|如果.*失败|故障|troubleshoot/i.test(enContent) : false,
|
|
121418
121727
|
hasNextSteps: enContent ? /next.*step|下一步|后续|see.*also|参阅|进一步/i.test(enContent) : false
|
|
@@ -121472,6 +121781,7 @@ var init_contract2 = __esm({
|
|
|
121472
121781
|
__name(resolveSkillName, "resolveSkillName");
|
|
121473
121782
|
__name(extractManifestSkillNames, "extractManifestSkillNames");
|
|
121474
121783
|
__name(findSkillNames, "findSkillNames");
|
|
121784
|
+
__name(hasInstallCommand, "hasInstallCommand");
|
|
121475
121785
|
__name(evaluateReadme, "evaluateReadme");
|
|
121476
121786
|
}
|
|
121477
121787
|
});
|
|
@@ -127335,6 +127645,7 @@ __export(prepare_exports, {
|
|
|
127335
127645
|
decodeExternalMarketplaceIndex: () => decodeExternalMarketplaceIndex,
|
|
127336
127646
|
observeOriginAhead: () => observeOriginAhead,
|
|
127337
127647
|
parseExternalMarketplaceLsRemote: () => parseExternalMarketplaceLsRemote,
|
|
127648
|
+
parseFirstReleasePluginRepositoryRefs: () => parseFirstReleasePluginRepositoryRefs,
|
|
127338
127649
|
prepareRelease: () => prepareRelease,
|
|
127339
127650
|
readHeadCommitTimestamp: () => readHeadCommitTimestamp,
|
|
127340
127651
|
readLatestFrozenPlan: () => readLatestFrozenPlan,
|
|
@@ -128204,7 +128515,7 @@ function parseExternalMarketplaceLsRemote(stdout) {
|
|
|
128204
128515
|
if (right !== "HEAD") continue;
|
|
128205
128516
|
if (left.startsWith("ref: refs/heads/")) {
|
|
128206
128517
|
defaultBranch = left.slice("ref: refs/heads/".length);
|
|
128207
|
-
} else if (
|
|
128518
|
+
} else if (EXTERNAL_MARKETPLACE_SHA_RE3.test(left)) {
|
|
128208
128519
|
sha = left;
|
|
128209
128520
|
}
|
|
128210
128521
|
}
|
|
@@ -128259,13 +128570,74 @@ async function defaultFetchExternalMarketplaceIndex(repo, manifestPath, ref, { g
|
|
|
128259
128570
|
return { status: "unknown", error: error.message };
|
|
128260
128571
|
}
|
|
128261
128572
|
}
|
|
128573
|
+
function parseFirstReleasePluginRepositoryRefs(stdout, tag) {
|
|
128574
|
+
if (typeof stdout !== "string" || typeof tag !== "string" || tag.length === 0) {
|
|
128575
|
+
return { hasRefs: false, tagExists: false };
|
|
128576
|
+
}
|
|
128577
|
+
const refs = [];
|
|
128578
|
+
let hasRefs = false;
|
|
128579
|
+
for (const line of stdout.trim().split("\n").filter(Boolean)) {
|
|
128580
|
+
const tabIndex = line.indexOf(" ");
|
|
128581
|
+
if (tabIndex < 0) continue;
|
|
128582
|
+
const sha = line.slice(0, tabIndex);
|
|
128583
|
+
const ref = line.slice(tabIndex + 1);
|
|
128584
|
+
if (EXTERNAL_MARKETPLACE_SHA_RE3.test(sha)) {
|
|
128585
|
+
hasRefs = true;
|
|
128586
|
+
if (ref && ref !== "HEAD") refs.push(ref);
|
|
128587
|
+
}
|
|
128588
|
+
}
|
|
128589
|
+
const target = `refs/tags/${tag}`;
|
|
128590
|
+
return {
|
|
128591
|
+
hasRefs,
|
|
128592
|
+
tagExists: refs.includes(target) || refs.includes(`${target}^{}`)
|
|
128593
|
+
};
|
|
128594
|
+
}
|
|
128595
|
+
async function defaultObserveFirstReleasePluginRepository(repo, tag, { githubHost = "github.com" } = {}) {
|
|
128596
|
+
const url = `https://${githubHost}/${repo}.git`;
|
|
128597
|
+
let repositoryRefs;
|
|
128598
|
+
try {
|
|
128599
|
+
const { stdout } = await execFile9(
|
|
128600
|
+
"git",
|
|
128601
|
+
["ls-remote", "--symref", url],
|
|
128602
|
+
{ shell: false, encoding: "utf8", timeout: 3e4 }
|
|
128603
|
+
);
|
|
128604
|
+
repositoryRefs = parseFirstReleasePluginRepositoryRefs(String(stdout ?? ""), tag);
|
|
128605
|
+
} catch (error) {
|
|
128606
|
+
return { status: "unknown", error: error.message };
|
|
128607
|
+
}
|
|
128608
|
+
let releaseExists = false;
|
|
128609
|
+
try {
|
|
128610
|
+
await execFile9(
|
|
128611
|
+
"gh",
|
|
128612
|
+
["api", `repos/${repo}/releases/tags/${tag}`],
|
|
128613
|
+
{
|
|
128614
|
+
shell: false,
|
|
128615
|
+
encoding: "utf8",
|
|
128616
|
+
timeout: 3e4,
|
|
128617
|
+
env: { ...process.env, GH_HOST: githubHost }
|
|
128618
|
+
}
|
|
128619
|
+
);
|
|
128620
|
+
releaseExists = true;
|
|
128621
|
+
} catch (error) {
|
|
128622
|
+
const diagnostic = `${error?.stderr ?? ""} ${error?.message ?? ""}`;
|
|
128623
|
+
if (!/\b404\b|not found/i.test(diagnostic)) {
|
|
128624
|
+
return { status: "unknown", error: error.message };
|
|
128625
|
+
}
|
|
128626
|
+
}
|
|
128627
|
+
return { status: repositoryRefs.hasRefs ? "non-empty" : "empty", tagExists: repositoryRefs.tagExists, releaseExists };
|
|
128628
|
+
}
|
|
128629
|
+
function isFirstReleaseBootstrap(dist) {
|
|
128630
|
+
return dist?.firstReleaseBootstrap === FIRST_RELEASE_BOOTSTRAP_MODE2;
|
|
128631
|
+
}
|
|
128262
128632
|
async function resolveExternalMarketplaceFreezes({
|
|
128263
128633
|
unitResults,
|
|
128264
128634
|
resolvedVersions,
|
|
128265
128635
|
offline,
|
|
128266
128636
|
evidence,
|
|
128267
128637
|
observeHeadFn,
|
|
128268
|
-
fetchIndexFn
|
|
128638
|
+
fetchIndexFn,
|
|
128639
|
+
productionAssets = null,
|
|
128640
|
+
observePluginRepositoryFn = defaultObserveFirstReleasePluginRepository
|
|
128269
128641
|
}) {
|
|
128270
128642
|
const freezes = /* @__PURE__ */ new Map();
|
|
128271
128643
|
for (let index = 0; index < unitResults.length; index += 1) {
|
|
@@ -128273,8 +128645,24 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128273
128645
|
const version = resolvedVersions[index];
|
|
128274
128646
|
const githubHost = unit.production?.githubHost ?? "github.com";
|
|
128275
128647
|
for (const dist of unit.distributions ?? []) {
|
|
128648
|
+
if (isFirstReleaseBootstrap(dist) && dist.marketplaceSourceType !== "standalone-index") {
|
|
128649
|
+
throw new ReleaseError(
|
|
128650
|
+
GATE_FAILED,
|
|
128651
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires marketplaceSourceType standalone-index`,
|
|
128652
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128653
|
+
);
|
|
128654
|
+
}
|
|
128276
128655
|
if (dist.marketplaceSourceType !== "standalone-index") continue;
|
|
128277
|
-
if (!dist.marketplaceRepo)
|
|
128656
|
+
if (!dist.marketplaceRepo) {
|
|
128657
|
+
if (isFirstReleaseBootstrap(dist)) {
|
|
128658
|
+
throw new ReleaseError(
|
|
128659
|
+
GATE_FAILED,
|
|
128660
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires marketplaceRepo`,
|
|
128661
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128662
|
+
);
|
|
128663
|
+
}
|
|
128664
|
+
continue;
|
|
128665
|
+
}
|
|
128278
128666
|
const platform = PLATFORMS.find((p) => p.distributionType === dist.type);
|
|
128279
128667
|
if (!platform) {
|
|
128280
128668
|
throw new ReleaseError(
|
|
@@ -128290,8 +128678,15 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128290
128678
|
{ unitId: unit.id, marketplaceSourceType: dist.marketplaceSourceType }
|
|
128291
128679
|
);
|
|
128292
128680
|
}
|
|
128681
|
+
if (isFirstReleaseBootstrap(dist) && dist.type !== "claude-plugin" && dist.type !== "codex-plugin") {
|
|
128682
|
+
throw new ReleaseError(
|
|
128683
|
+
GATE_FAILED,
|
|
128684
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap is supported only for claude-plugin or codex-plugin standalone-index distributions`,
|
|
128685
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128686
|
+
);
|
|
128687
|
+
}
|
|
128293
128688
|
const observed = await observeHeadFn(dist.marketplaceRepo, { githubHost });
|
|
128294
|
-
if (observed.status !== "observed" || !
|
|
128689
|
+
if (observed.status !== "observed" || !EXTERNAL_MARKETPLACE_SHA_RE3.test(observed.sha ?? "") || !observed.defaultBranch) {
|
|
128295
128690
|
throw new ReleaseError(
|
|
128296
128691
|
GATE_FAILED,
|
|
128297
128692
|
`unit "${unit.id}" could not freeze external marketplace "${dist.marketplaceRepo}" HEAD: ${observed.error ?? "unknown"}`,
|
|
@@ -128323,21 +128718,61 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128323
128718
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128324
128719
|
);
|
|
128325
128720
|
}
|
|
128326
|
-
|
|
128327
|
-
|
|
128721
|
+
if (!Array.isArray(marketplaceIndex.plugins)) {
|
|
128722
|
+
throw new ReleaseError(
|
|
128723
|
+
GATE_FAILED,
|
|
128724
|
+
`unit "${unit.id}" ${dist.type} external marketplace index plugins must be an array`,
|
|
128725
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128726
|
+
);
|
|
128727
|
+
}
|
|
128728
|
+
const pluginEntries = marketplaceIndex.plugins.filter((entry) => entry && entry.name === dist.plugin);
|
|
128729
|
+
if (isFirstReleaseBootstrap(dist) && pluginEntries.length > 0) {
|
|
128730
|
+
throw new ReleaseError(
|
|
128731
|
+
GATE_FAILED,
|
|
128732
|
+
`unit "${unit.id}" first-release bootstrap requires the marketplace entry to be absent, found ${pluginEntries.length} matching entries`,
|
|
128733
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128734
|
+
);
|
|
128735
|
+
}
|
|
128736
|
+
if (pluginEntries.length !== 1 && !isFirstReleaseBootstrap(dist)) {
|
|
128328
128737
|
throw new ReleaseError(
|
|
128329
128738
|
GATE_FAILED,
|
|
128330
128739
|
`unit "${unit.id}" external marketplace index must contain exactly one plugin entry named "${dist.plugin}", found ${pluginEntries.length}`,
|
|
128331
128740
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128332
128741
|
);
|
|
128333
128742
|
}
|
|
128334
|
-
|
|
128743
|
+
let selectedEntry = pluginEntries[0];
|
|
128744
|
+
if (!isFirstReleaseBootstrap(dist) && platform.marketplaceEntryCarriesVersion && selectedEntry.version !== version) {
|
|
128335
128745
|
throw new ReleaseError(
|
|
128336
128746
|
GATE_FAILED,
|
|
128337
128747
|
`unit "${unit.id}" external marketplace index entry version "${pluginEntries[0].version}" does not match target version "${version}"`,
|
|
128338
128748
|
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
128339
128749
|
);
|
|
128340
128750
|
}
|
|
128751
|
+
if (isFirstReleaseBootstrap(dist)) {
|
|
128752
|
+
const asset = productionAssets?.[index];
|
|
128753
|
+
if (!asset || !EXTERNAL_MARKETPLACE_SHA_RE3.test(asset.commit ?? "") || !asset.tag) {
|
|
128754
|
+
throw new ReleaseError(
|
|
128755
|
+
GATE_FAILED,
|
|
128756
|
+
`unit "${unit.id}" first-release bootstrap requires a frozen plugin tag and commit`,
|
|
128757
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
128758
|
+
);
|
|
128759
|
+
}
|
|
128760
|
+
const pluginState = await observePluginRepositoryFn(unit.publicRepo, asset.tag, { githubHost });
|
|
128761
|
+
if (pluginState?.status !== "empty" || pluginState.tagExists !== false || pluginState.releaseExists !== false) {
|
|
128762
|
+
throw new ReleaseError(
|
|
128763
|
+
GATE_FAILED,
|
|
128764
|
+
`unit "${unit.id}" first-release bootstrap requires an empty plugin repository without the target tag or release`,
|
|
128765
|
+
{ unitId: unit.id, publicRepo: unit.publicRepo, tag: asset.tag, observed: pluginState }
|
|
128766
|
+
);
|
|
128767
|
+
}
|
|
128768
|
+
selectedEntry = buildExpectedStandaloneIndexInstallIdentity(platform, {
|
|
128769
|
+
name: dist.plugin,
|
|
128770
|
+
repo: unit.publicRepo,
|
|
128771
|
+
tag: asset.tag,
|
|
128772
|
+
sha: asset.commit,
|
|
128773
|
+
version
|
|
128774
|
+
});
|
|
128775
|
+
}
|
|
128341
128776
|
const marketplaceRef = platform.marketplaceRefForm === "name" ? observed.defaultBranch : sha;
|
|
128342
128777
|
freezes.set(`${unit.id} ${dist.type}`, {
|
|
128343
128778
|
// 向后兼容字段(buildExternalActions 使用 repo / ref / marketplace)
|
|
@@ -128350,7 +128785,8 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128350
128785
|
marketplaceRef,
|
|
128351
128786
|
marketplaceIndexPath: manifestPath,
|
|
128352
128787
|
marketplaceName: marketplaceIndex.name,
|
|
128353
|
-
selectedEntry
|
|
128788
|
+
selectedEntry,
|
|
128789
|
+
...isFirstReleaseBootstrap(dist) ? { firstReleaseBootstrap: FIRST_RELEASE_BOOTSTRAP_MODE2, marketplaceIndexSha: null } : {}
|
|
128354
128790
|
});
|
|
128355
128791
|
await evidence.append({
|
|
128356
128792
|
phase: "external-marketplace-freeze",
|
|
@@ -128362,7 +128798,8 @@ async function resolveExternalMarketplaceFreezes({
|
|
|
128362
128798
|
marketplaceRef,
|
|
128363
128799
|
marketplaceIndexPath: manifestPath,
|
|
128364
128800
|
marketplaceName: marketplaceIndex.name,
|
|
128365
|
-
selectedEntry
|
|
128801
|
+
selectedEntry,
|
|
128802
|
+
...isFirstReleaseBootstrap(dist) ? { firstReleaseBootstrap: FIRST_RELEASE_BOOTSTRAP_MODE2, marketplaceIndexSha: null } : {},
|
|
128366
128803
|
defaultBranch: observed.defaultBranch
|
|
128367
128804
|
});
|
|
128368
128805
|
}
|
|
@@ -128697,7 +129134,11 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
128697
129134
|
...externalMarketplace && freeze ? {
|
|
128698
129135
|
marketplaceIndexPath: freeze.marketplaceIndexPath,
|
|
128699
129136
|
marketplaceName: freeze.marketplaceName,
|
|
128700
|
-
selectedEntry: freeze.selectedEntry
|
|
129137
|
+
selectedEntry: freeze.selectedEntry,
|
|
129138
|
+
...freeze.firstReleaseBootstrap ? {
|
|
129139
|
+
firstReleaseBootstrap: freeze.firstReleaseBootstrap,
|
|
129140
|
+
marketplaceIndexSha: null
|
|
129141
|
+
} : {}
|
|
128701
129142
|
} : {}
|
|
128702
129143
|
},
|
|
128703
129144
|
expected: {
|
|
@@ -128712,7 +129153,11 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
128712
129153
|
entrySkill: dist.entrySkill,
|
|
128713
129154
|
entrySkillFound: true,
|
|
128714
129155
|
manifestDigest: asset.manifestDigest,
|
|
128715
|
-
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {}
|
|
129156
|
+
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {},
|
|
129157
|
+
...externalMarketplace && freeze?.firstReleaseBootstrap ? {
|
|
129158
|
+
firstReleaseBootstrap: freeze.firstReleaseBootstrap,
|
|
129159
|
+
marketplaceIndexSha: null
|
|
129160
|
+
} : {}
|
|
128716
129161
|
},
|
|
128717
129162
|
status: "PENDING"
|
|
128718
129163
|
});
|
|
@@ -130340,13 +130785,26 @@ async function prepareRelease(options) {
|
|
|
130340
130785
|
skipSkillResourceClosure,
|
|
130341
130786
|
workflow
|
|
130342
130787
|
});
|
|
130788
|
+
for (const { unit } of unitResults) {
|
|
130789
|
+
for (const dist of unit.distributions ?? []) {
|
|
130790
|
+
if (isFirstReleaseBootstrap(dist) && (!production || offline)) {
|
|
130791
|
+
throw new ReleaseError(
|
|
130792
|
+
GATE_FAILED,
|
|
130793
|
+
`unit "${unit.id}" ${dist.type} first-release bootstrap requires online production prepare`,
|
|
130794
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
130795
|
+
);
|
|
130796
|
+
}
|
|
130797
|
+
}
|
|
130798
|
+
}
|
|
130343
130799
|
const externalMarketplaceFreezes = production ? await resolveExternalMarketplaceFreezes({
|
|
130344
130800
|
unitResults,
|
|
130345
130801
|
resolvedVersions,
|
|
130346
130802
|
offline,
|
|
130347
130803
|
evidence,
|
|
130348
130804
|
observeHeadFn: options.observeExternalMarketplaceHeadFn ?? defaultObserveExternalMarketplaceHead,
|
|
130349
|
-
fetchIndexFn: options.fetchExternalMarketplaceIndexFn ?? defaultFetchExternalMarketplaceIndex
|
|
130805
|
+
fetchIndexFn: options.fetchExternalMarketplaceIndexFn ?? defaultFetchExternalMarketplaceIndex,
|
|
130806
|
+
productionAssets,
|
|
130807
|
+
observePluginRepositoryFn: options.observeFirstReleasePluginRepositoryFn ?? defaultObserveFirstReleasePluginRepository
|
|
130350
130808
|
}) : /* @__PURE__ */ new Map();
|
|
130351
130809
|
const units = await Promise.all(unitResults.map(async ({ unit, manifest }, idx) => {
|
|
130352
130810
|
const unitVersion = resolvedVersions[idx];
|
|
@@ -130426,6 +130884,10 @@ async function prepareRelease(options) {
|
|
|
130426
130884
|
frozenDist.marketplaceIndexPath = freeze.marketplaceIndexPath;
|
|
130427
130885
|
frozenDist.marketplaceName = freeze.marketplaceName;
|
|
130428
130886
|
frozenDist.selectedEntry = freeze.selectedEntry;
|
|
130887
|
+
if (freeze.firstReleaseBootstrap) {
|
|
130888
|
+
frozenDist.firstReleaseBootstrap = freeze.firstReleaseBootstrap;
|
|
130889
|
+
frozenDist.marketplaceIndexSha = null;
|
|
130890
|
+
}
|
|
130429
130891
|
}
|
|
130430
130892
|
}
|
|
130431
130893
|
return frozenDist;
|
|
@@ -130795,7 +131257,7 @@ async function prepareRelease(options) {
|
|
|
130795
131257
|
await lock.release();
|
|
130796
131258
|
}
|
|
130797
131259
|
}
|
|
130798
|
-
var execFile9, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_EXECUTION_ORDER,
|
|
131260
|
+
var execFile9, CONSUMER_INSTALL_RECIPE_VERSION2, FIRST_RELEASE_BOOTSTRAP_MODE2, HOOK_EXECUTION_ORDER, EXTERNAL_MARKETPLACE_SHA_RE3;
|
|
130799
131261
|
var init_prepare = __esm({
|
|
130800
131262
|
async "src/commands/prepare.mjs"() {
|
|
130801
131263
|
init_src2();
|
|
@@ -130836,6 +131298,7 @@ var init_prepare = __esm({
|
|
|
130836
131298
|
init_bounded_output();
|
|
130837
131299
|
execFile9 = promisify12(execFileCb12);
|
|
130838
131300
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
131301
|
+
FIRST_RELEASE_BOOTSTRAP_MODE2 = "manual-index-checkpoint";
|
|
130839
131302
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
130840
131303
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
130841
131304
|
HOOK_EXECUTION_ORDER = Object.freeze(["lint", "docs", "build", "test", "typecheck"]);
|
|
@@ -130854,11 +131317,14 @@ var init_prepare = __esm({
|
|
|
130854
131317
|
__name(enumerateFrozenTagPaths, "enumerateFrozenTagPaths");
|
|
130855
131318
|
__name(collectPostPublishCommandCandidates, "collectPostPublishCommandCandidates");
|
|
130856
131319
|
__name(assertPrivateExecutionDeclarations, "assertPrivateExecutionDeclarations");
|
|
130857
|
-
|
|
131320
|
+
EXTERNAL_MARKETPLACE_SHA_RE3 = /^[0-9a-f]{40}$/;
|
|
130858
131321
|
__name(parseExternalMarketplaceLsRemote, "parseExternalMarketplaceLsRemote");
|
|
130859
131322
|
__name(decodeExternalMarketplaceIndex, "decodeExternalMarketplaceIndex");
|
|
130860
131323
|
__name(defaultObserveExternalMarketplaceHead, "defaultObserveExternalMarketplaceHead");
|
|
130861
131324
|
__name(defaultFetchExternalMarketplaceIndex, "defaultFetchExternalMarketplaceIndex");
|
|
131325
|
+
__name(parseFirstReleasePluginRepositoryRefs, "parseFirstReleasePluginRepositoryRefs");
|
|
131326
|
+
__name(defaultObserveFirstReleasePluginRepository, "defaultObserveFirstReleasePluginRepository");
|
|
131327
|
+
__name(isFirstReleaseBootstrap, "isFirstReleaseBootstrap");
|
|
130862
131328
|
__name(resolveExternalMarketplaceFreezes, "resolveExternalMarketplaceFreezes");
|
|
130863
131329
|
__name(buildExternalActions, "buildExternalActions");
|
|
130864
131330
|
__name(computeSourceAuthorityClosure, "computeSourceAuthorityClosure");
|
|
@@ -130948,12 +131414,13 @@ var init_hooks2 = __esm({
|
|
|
130948
131414
|
// src/commands/post-release-local.mjs
|
|
130949
131415
|
var post_release_local_exports = {};
|
|
130950
131416
|
__export(post_release_local_exports, {
|
|
131417
|
+
assertLocalFinishRun: () => assertLocalFinishRun,
|
|
130951
131418
|
assertVerifiedReleaseRun: () => assertVerifiedReleaseRun,
|
|
130952
131419
|
derivePostReleaseChecklist: () => derivePostReleaseChecklist,
|
|
130953
131420
|
unavailablePostReleaseChecklist: () => unavailablePostReleaseChecklist,
|
|
130954
131421
|
updateLocalHostPlugins: () => updateLocalHostPlugins
|
|
130955
131422
|
});
|
|
130956
|
-
import { access as access2 } from "node:fs/promises";
|
|
131423
|
+
import { access as access2, readFile as readFile36 } from "node:fs/promises";
|
|
130957
131424
|
import { homedir } from "node:os";
|
|
130958
131425
|
import { join as join27, relative as relative27 } from "node:path";
|
|
130959
131426
|
function attachFoundationFailure(error, { envelope, stdout }) {
|
|
@@ -131047,13 +131514,35 @@ function assertExecutableTarget(target) {
|
|
|
131047
131514
|
throw new Error(`local host update requires the frozen public commit for unit ${target.unitId}`);
|
|
131048
131515
|
}
|
|
131049
131516
|
}
|
|
131050
|
-
function
|
|
131517
|
+
function buildShipNextStep({ root, statePath, unitIds }) {
|
|
131518
|
+
const argv = ["release-skill", "ship"];
|
|
131519
|
+
if (typeof root === "string" && root.length > 0) argv.push("--root", root);
|
|
131520
|
+
if (typeof statePath === "string" && statePath.length > 0) argv.push("--state", statePath);
|
|
131521
|
+
if (Array.isArray(unitIds) && unitIds.length > 0) {
|
|
131522
|
+
for (const unitId of unitIds) argv.push("--unit", unitId);
|
|
131523
|
+
}
|
|
131524
|
+
return {
|
|
131525
|
+
code: "COMPLETE_POST_VERIFY",
|
|
131526
|
+
message: "Complete the postVerify phase with ship before running post-release.",
|
|
131527
|
+
argv
|
|
131528
|
+
};
|
|
131529
|
+
}
|
|
131530
|
+
function derivePostReleaseChecklist(plan, {
|
|
131531
|
+
runPath,
|
|
131532
|
+
root,
|
|
131533
|
+
statePath,
|
|
131534
|
+
unitIds,
|
|
131535
|
+
postVerifyComplete = false
|
|
131536
|
+
} = {}) {
|
|
131051
131537
|
if (!plan || typeof plan !== "object" || typeof plan.digest !== "string") {
|
|
131052
131538
|
throw new Error("a frozen release plan with digest is required");
|
|
131053
131539
|
}
|
|
131054
131540
|
const units = plan.units ?? [];
|
|
131055
131541
|
const uncovered = units.filter((unit) => !BRANCH_ACTION_INCLUDED.has(unit.productionConfig?.branchStrategy));
|
|
131056
131542
|
const targets = pluginTargets(plan);
|
|
131543
|
+
const hasPendingPostVerify = postVerifyHooks(plan).length > 0 && !postVerifyComplete && targets.length > 0;
|
|
131544
|
+
const hasStatePath = typeof statePath === "string" && statePath.length > 0;
|
|
131545
|
+
const selectedUnitIds = Array.isArray(unitIds) ? unitIds : void 0;
|
|
131057
131546
|
return {
|
|
131058
131547
|
command: "post-release",
|
|
131059
131548
|
status: "AWAITING_USER_DECISION",
|
|
@@ -131069,13 +131558,143 @@ function derivePostReleaseChecklist(plan) {
|
|
|
131069
131558
|
}))
|
|
131070
131559
|
},
|
|
131071
131560
|
localHostUpdate: {
|
|
131072
|
-
promptRequired: targets.length > 0,
|
|
131073
|
-
available: targets.length > 0,
|
|
131561
|
+
promptRequired: targets.length > 0 && !hasPendingPostVerify,
|
|
131562
|
+
available: targets.length > 0 && !hasPendingPostVerify,
|
|
131563
|
+
...!hasPendingPostVerify && runPath ? { runPath } : {},
|
|
131564
|
+
...hasPendingPostVerify ? {
|
|
131565
|
+
...hasStatePath ? { nextSteps: [buildShipNextStep({ root, statePath, unitIds: selectedUnitIds })] } : {}
|
|
131566
|
+
} : {},
|
|
131074
131567
|
hosts: [...new Set(targets.map((target) => target.host))].sort(),
|
|
131075
131568
|
targets
|
|
131076
131569
|
}
|
|
131077
131570
|
};
|
|
131078
131571
|
}
|
|
131572
|
+
function postVerifyHooks(plan) {
|
|
131573
|
+
if (plan?.planVersion === void 0) return [];
|
|
131574
|
+
return normalizePostPublishView(plan).flatMap((declaration) => (declaration.hooks ?? []).filter((hook) => hook.phase === "postVerify").map((hook) => ({
|
|
131575
|
+
actionId: postPublishActionId({ planVersion: plan.planVersion, unitId: declaration.unitId, localId: hook.id }),
|
|
131576
|
+
hook,
|
|
131577
|
+
unitId: declaration.unitId
|
|
131578
|
+
})));
|
|
131579
|
+
}
|
|
131580
|
+
function localFinishEvidenceError(message, { cause, root, statePath, unitIds } = {}) {
|
|
131581
|
+
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`);
|
|
131582
|
+
error.code = "LOCAL_FINISH_EVIDENCE_NOT_READY";
|
|
131583
|
+
const hasStatePath = typeof statePath === "string" && statePath.length > 0;
|
|
131584
|
+
error.details = {
|
|
131585
|
+
cause: {
|
|
131586
|
+
code: cause?.code ?? "LOCAL_FINISH_EVIDENCE_NOT_READY",
|
|
131587
|
+
message: cause?.message ?? message
|
|
131588
|
+
},
|
|
131589
|
+
...hasStatePath ? {
|
|
131590
|
+
nextSteps: [buildShipNextStep({ root, statePath, unitIds })]
|
|
131591
|
+
} : {}
|
|
131592
|
+
};
|
|
131593
|
+
return error;
|
|
131594
|
+
}
|
|
131595
|
+
async function updateLocalHostPlugins({
|
|
131596
|
+
plan: _suppliedPlan,
|
|
131597
|
+
planPath,
|
|
131598
|
+
runPath,
|
|
131599
|
+
runRecord: _suppliedRunRecord,
|
|
131600
|
+
production: _suppliedProduction,
|
|
131601
|
+
root = process.cwd(),
|
|
131602
|
+
statePath,
|
|
131603
|
+
unitIds,
|
|
131604
|
+
...options
|
|
131605
|
+
} = {}) {
|
|
131606
|
+
if (!planPath || !runPath) {
|
|
131607
|
+
throw localFinishEvidenceError(
|
|
131608
|
+
"planPath and runPath are required before local host updates",
|
|
131609
|
+
{ root, statePath, unitIds }
|
|
131610
|
+
);
|
|
131611
|
+
}
|
|
131612
|
+
let plan;
|
|
131613
|
+
let runRecord;
|
|
131614
|
+
try {
|
|
131615
|
+
plan = JSON.parse(await readFile36(planPath, "utf8"));
|
|
131616
|
+
runRecord = await loadRun(runPath, {
|
|
131617
|
+
requireDigest: true,
|
|
131618
|
+
authorityPlanPath: planPath
|
|
131619
|
+
});
|
|
131620
|
+
} catch (cause) {
|
|
131621
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds });
|
|
131622
|
+
}
|
|
131623
|
+
await assertLocalFinishRun({
|
|
131624
|
+
plan,
|
|
131625
|
+
planPath,
|
|
131626
|
+
runPath,
|
|
131627
|
+
runRecord,
|
|
131628
|
+
production: Boolean(plan.production),
|
|
131629
|
+
root,
|
|
131630
|
+
statePath,
|
|
131631
|
+
unitIds
|
|
131632
|
+
});
|
|
131633
|
+
return updateLocalHostPluginsInternal({
|
|
131634
|
+
plan,
|
|
131635
|
+
root,
|
|
131636
|
+
...options
|
|
131637
|
+
});
|
|
131638
|
+
}
|
|
131639
|
+
async function assertLocalFinishRun({
|
|
131640
|
+
plan,
|
|
131641
|
+
planPath,
|
|
131642
|
+
runPath,
|
|
131643
|
+
runRecord,
|
|
131644
|
+
production = false,
|
|
131645
|
+
root,
|
|
131646
|
+
statePath,
|
|
131647
|
+
unitIds
|
|
131648
|
+
} = {}) {
|
|
131649
|
+
const hooks = postVerifyHooks(plan);
|
|
131650
|
+
if (hooks.length === 0) {
|
|
131651
|
+
try {
|
|
131652
|
+
await validateRunLineage(runRecord, { plan, planPath, runPath, production });
|
|
131653
|
+
assertVerifiedReleaseRun(plan, runRecord);
|
|
131654
|
+
} catch (cause) {
|
|
131655
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131656
|
+
}
|
|
131657
|
+
return { runPath, phase: "verify" };
|
|
131658
|
+
}
|
|
131659
|
+
if (runRecord?.command !== "postverify" || runRecord?.status !== "DISTRIBUTED") {
|
|
131660
|
+
throw localFinishEvidenceError("the plan declares postVerify hooks, so the supplied verify run cannot authorize local-finish", { root, statePath, unitIds, plan });
|
|
131661
|
+
}
|
|
131662
|
+
if (runRecord.planDigest !== plan?.digest) {
|
|
131663
|
+
throw localFinishEvidenceError("postVerify run is not bound to the frozen plan", { root, statePath, unitIds, plan });
|
|
131664
|
+
}
|
|
131665
|
+
if (typeof runRecord.sourceRunPath !== "string" || typeof runRecord.sourceRunId !== "string" || typeof runRecord.sourceRunDigest !== "string") {
|
|
131666
|
+
throw localFinishEvidenceError("completed postVerify run has incomplete verify-run lineage", { root, statePath, unitIds, plan });
|
|
131667
|
+
}
|
|
131668
|
+
const checkpoints = Array.isArray(runRecord.checkpoints) ? runRecord.checkpoints : null;
|
|
131669
|
+
const expectedIds = hooks.map(({ actionId }) => actionId);
|
|
131670
|
+
const actualIds = checkpoints?.map((checkpoint) => checkpoint?.actionId) ?? [];
|
|
131671
|
+
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))) {
|
|
131672
|
+
throw localFinishEvidenceError("postVerify checkpoints must match each declared hook exactly and be succeeded or NO_CHANGE", { root, statePath, unitIds, plan });
|
|
131673
|
+
}
|
|
131674
|
+
let sourceRun;
|
|
131675
|
+
try {
|
|
131676
|
+
sourceRun = await loadRun(runRecord.sourceRunPath, {
|
|
131677
|
+
requireDigest: true,
|
|
131678
|
+
authorityPlanPath: planPath
|
|
131679
|
+
});
|
|
131680
|
+
} catch (cause) {
|
|
131681
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131682
|
+
}
|
|
131683
|
+
if (sourceRun.command !== "verify" || sourceRun.status !== "VERIFIED" || sourceRun.runId !== runRecord.sourceRunId || sourceRun.runDigest !== runRecord.sourceRunDigest || sourceRun.planDigest !== plan.digest) {
|
|
131684
|
+
throw localFinishEvidenceError("postVerify lineage does not point to the same-plan VERIFIED run", { root, statePath, unitIds, plan });
|
|
131685
|
+
}
|
|
131686
|
+
try {
|
|
131687
|
+
await validateRunLineage(sourceRun, {
|
|
131688
|
+
plan,
|
|
131689
|
+
planPath,
|
|
131690
|
+
runPath: runRecord.sourceRunPath,
|
|
131691
|
+
production
|
|
131692
|
+
});
|
|
131693
|
+
} catch (cause) {
|
|
131694
|
+
throw localFinishEvidenceError(cause.message, { cause, root, statePath, unitIds, plan });
|
|
131695
|
+
}
|
|
131696
|
+
return { runPath, sourceRunPath: runRecord.sourceRunPath, phase: "postverify" };
|
|
131697
|
+
}
|
|
131079
131698
|
function unavailablePostReleaseChecklist(plan, error) {
|
|
131080
131699
|
return {
|
|
131081
131700
|
command: "post-release",
|
|
@@ -131101,7 +131720,11 @@ function hostEnvironment(host, { kimiHome } = {}) {
|
|
|
131101
131720
|
env.HOME ??= homedir();
|
|
131102
131721
|
env.PATH ??= "/usr/bin:/bin";
|
|
131103
131722
|
env.GIT_TERMINAL_PROMPT = "0";
|
|
131104
|
-
if (host === "
|
|
131723
|
+
if (host === "codebuddy") env.CODEBUDDY_CONFIG_DIR = join27(env.HOME, ".codebuddy");
|
|
131724
|
+
if (host === "workbuddy") {
|
|
131725
|
+
env.CODEBUDDY_CONFIG_DIR = join27(env.HOME, ".workbuddy");
|
|
131726
|
+
env.WORKBUDDY_CONFIG_DIR = join27(env.HOME, ".workbuddy");
|
|
131727
|
+
}
|
|
131105
131728
|
if (host === "kimi" && kimiHome) env.KIMI_CONFIG_DIR = kimiHome;
|
|
131106
131729
|
return env;
|
|
131107
131730
|
}
|
|
@@ -131152,12 +131775,17 @@ async function commandAvailable(command2, host, run6) {
|
|
|
131152
131775
|
}
|
|
131153
131776
|
}
|
|
131154
131777
|
async function defaultDetect(host, run6 = defaultRun) {
|
|
131155
|
-
if (host === "codebuddy"
|
|
131156
|
-
for (const command2 of ["codebuddy", "cbc"
|
|
131778
|
+
if (host === "codebuddy") {
|
|
131779
|
+
for (const command2 of ["codebuddy", "cbc"]) {
|
|
131157
131780
|
if (await commandAvailable(command2, host, run6)) return { available: true, command: command2 };
|
|
131158
131781
|
}
|
|
131159
131782
|
return { available: false, reason: "CodeBuddy/WorkBuddy CLI not found" };
|
|
131160
131783
|
}
|
|
131784
|
+
if (host === "workbuddy") {
|
|
131785
|
+
if (process.platform !== "darwin") return { available: false, status: "SKIPPED_UNSUPPORTED_PLATFORM", reason: "WorkBuddy local update is supported only on macOS" };
|
|
131786
|
+
if (await commandAvailable(CODEBUDDY_MACOS_PATH, host, run6)) return { available: true, command: CODEBUDDY_MACOS_PATH };
|
|
131787
|
+
return { available: false, reason: "WorkBuddy embedded CLI not found" };
|
|
131788
|
+
}
|
|
131161
131789
|
if (host === "kimi") {
|
|
131162
131790
|
if (!await commandAvailable("kimi", host, run6)) return { available: false, reason: "kimi CLI not found" };
|
|
131163
131791
|
try {
|
|
@@ -131690,7 +132318,7 @@ function failedHostResult(target, error) {
|
|
|
131690
132318
|
...publicDetails !== void 0 ? { details: publicDetails } : {}
|
|
131691
132319
|
};
|
|
131692
132320
|
}
|
|
131693
|
-
async function
|
|
132321
|
+
async function updateLocalHostPluginsInternal({
|
|
131694
132322
|
plan,
|
|
131695
132323
|
root = process.cwd(),
|
|
131696
132324
|
confirmPlanDigest,
|
|
@@ -131701,7 +132329,7 @@ async function updateLocalHostPlugins({
|
|
|
131701
132329
|
verifyInstalledPayload = verifyInstalledMarketplacePayload
|
|
131702
132330
|
} = {}) {
|
|
131703
132331
|
const effectiveKimiHome = kimiHome ?? process.env.KIMI_CONFIG_DIR ?? join27(homedir(), ".kimi-code");
|
|
131704
|
-
const checklist = derivePostReleaseChecklist(plan);
|
|
132332
|
+
const checklist = derivePostReleaseChecklist(plan, { postVerifyComplete: true });
|
|
131705
132333
|
if (confirmPlanDigest !== plan.digest) {
|
|
131706
132334
|
throw new Error("plan digest confirmation does not match the frozen release plan");
|
|
131707
132335
|
}
|
|
@@ -131718,7 +132346,7 @@ async function updateLocalHostPlugins({
|
|
|
131718
132346
|
results.push({
|
|
131719
132347
|
host: target.host,
|
|
131720
132348
|
unitId: target.unitId,
|
|
131721
|
-
status: "SKIPPED_NOT_INSTALLED",
|
|
132349
|
+
status: detected?.status ?? "SKIPPED_NOT_INSTALLED",
|
|
131722
132350
|
reason: detected?.reason ?? "host unavailable"
|
|
131723
132351
|
});
|
|
131724
132352
|
continue;
|
|
@@ -131753,6 +132381,8 @@ var init_post_release_local = __esm({
|
|
|
131753
132381
|
await init_registry2();
|
|
131754
132382
|
init_codebuddy();
|
|
131755
132383
|
await init_plugin_marketplace();
|
|
132384
|
+
init_postpublish();
|
|
132385
|
+
await init_run();
|
|
131756
132386
|
HOSTS_BY_ACTION = Object.freeze({
|
|
131757
132387
|
"claude-marketplace-install": ["claude"],
|
|
131758
132388
|
"codex-marketplace-install": ["codex"],
|
|
@@ -131787,7 +132417,9 @@ var init_post_release_local = __esm({
|
|
|
131787
132417
|
"NODE_EXTRA_CA_CERTS",
|
|
131788
132418
|
"CLAUDE_CONFIG_DIR",
|
|
131789
132419
|
"CODEX_HOME",
|
|
131790
|
-
"KIMI_CONFIG_DIR"
|
|
132420
|
+
"KIMI_CONFIG_DIR",
|
|
132421
|
+
"CODEBUDDY_CONFIG_DIR",
|
|
132422
|
+
"WORKBUDDY_CONFIG_DIR"
|
|
131791
132423
|
]);
|
|
131792
132424
|
CODEBUDDY_PLUGIN_LIST_ARGS = Object.freeze(["plugin", "list", "--json"]);
|
|
131793
132425
|
CODEBUDDY_MARKETPLACE_LIST_ARGS = Object.freeze(["plugin", "marketplace", "list"]);
|
|
@@ -131795,7 +132427,12 @@ var init_post_release_local = __esm({
|
|
|
131795
132427
|
__name(actionTarget, "actionTarget");
|
|
131796
132428
|
__name(pluginTargets, "pluginTargets");
|
|
131797
132429
|
__name(assertExecutableTarget, "assertExecutableTarget");
|
|
132430
|
+
__name(buildShipNextStep, "buildShipNextStep");
|
|
131798
132431
|
__name(derivePostReleaseChecklist, "derivePostReleaseChecklist");
|
|
132432
|
+
__name(postVerifyHooks, "postVerifyHooks");
|
|
132433
|
+
__name(localFinishEvidenceError, "localFinishEvidenceError");
|
|
132434
|
+
__name(updateLocalHostPlugins, "updateLocalHostPlugins");
|
|
132435
|
+
__name(assertLocalFinishRun, "assertLocalFinishRun");
|
|
131799
132436
|
__name(unavailablePostReleaseChecklist, "unavailablePostReleaseChecklist");
|
|
131800
132437
|
__name(assertVerifiedReleaseRun, "assertVerifiedReleaseRun");
|
|
131801
132438
|
__name(hostEnvironment, "hostEnvironment");
|
|
@@ -131825,7 +132462,7 @@ var init_post_release_local = __esm({
|
|
|
131825
132462
|
__name(runKimiUpdate, "runKimiUpdate");
|
|
131826
132463
|
__name(aggregateStatus, "aggregateStatus");
|
|
131827
132464
|
__name(failedHostResult, "failedHostResult");
|
|
131828
|
-
__name(
|
|
132465
|
+
__name(updateLocalHostPluginsInternal, "updateLocalHostPluginsInternal");
|
|
131829
132466
|
}
|
|
131830
132467
|
});
|
|
131831
132468
|
|
|
@@ -131835,7 +132472,7 @@ __export(approve_exports, {
|
|
|
131835
132472
|
approvePlan: () => approvePlan,
|
|
131836
132473
|
approvePostPublishHook: () => approvePostPublishHook
|
|
131837
132474
|
});
|
|
131838
|
-
import { readFile as
|
|
132475
|
+
import { readFile as readFile37, writeFile as writeFile8 } from "node:fs/promises";
|
|
131839
132476
|
import { resolve as resolve33, dirname as dirname17, basename as basename13 } from "node:path";
|
|
131840
132477
|
function defaultClock2() {
|
|
131841
132478
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -131859,7 +132496,7 @@ async function approvePlan(options) {
|
|
|
131859
132496
|
}
|
|
131860
132497
|
let planRaw;
|
|
131861
132498
|
try {
|
|
131862
|
-
planRaw = await
|
|
132499
|
+
planRaw = await readFile37(planPath, "utf8");
|
|
131863
132500
|
} catch (err) {
|
|
131864
132501
|
throw new ReleaseError(
|
|
131865
132502
|
GATE_FAILED,
|
|
@@ -131987,7 +132624,7 @@ async function approvePlan(options) {
|
|
|
131987
132624
|
await writeFile8(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
131988
132625
|
} catch (error) {
|
|
131989
132626
|
if (error.code !== "EEXIST") throw error;
|
|
131990
|
-
const existing = await
|
|
132627
|
+
const existing = await readFile37(immutableApprovalPath, "utf8");
|
|
131991
132628
|
if (existing !== json) {
|
|
131992
132629
|
throw new ReleaseError(
|
|
131993
132630
|
GATE_FAILED,
|
|
@@ -132038,7 +132675,7 @@ async function approvePostPublishHook(options) {
|
|
|
132038
132675
|
}
|
|
132039
132676
|
let planRaw;
|
|
132040
132677
|
try {
|
|
132041
|
-
planRaw = await
|
|
132678
|
+
planRaw = await readFile37(planPath, "utf8");
|
|
132042
132679
|
} catch (err) {
|
|
132043
132680
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
132044
132681
|
}
|
|
@@ -132098,7 +132735,7 @@ async function approvePostPublishHook(options) {
|
|
|
132098
132735
|
await writeFile8(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
132099
132736
|
} catch (error) {
|
|
132100
132737
|
if (error.code !== "EEXIST") throw error;
|
|
132101
|
-
const existing = await
|
|
132738
|
+
const existing = await readFile37(immutableApprovalPath, "utf8");
|
|
132102
132739
|
if (existing !== json) {
|
|
132103
132740
|
throw new ReleaseError(
|
|
132104
132741
|
GATE_FAILED,
|
|
@@ -132249,7 +132886,7 @@ __export(publish_exports, {
|
|
|
132249
132886
|
classifyPreObservation: () => classifyPreObservation,
|
|
132250
132887
|
publishRelease: () => publishRelease
|
|
132251
132888
|
});
|
|
132252
|
-
import { readFile as
|
|
132889
|
+
import { readFile as readFile38, mkdir as mkdir22 } from "node:fs/promises";
|
|
132253
132890
|
import { isAbsolute as isAbsolute23, join as join28, relative as relative28 } from "node:path";
|
|
132254
132891
|
function assertInsideAssetRoot(assetRoot, candidate, label) {
|
|
132255
132892
|
const rel = relative28(assetRoot, candidate);
|
|
@@ -132482,7 +133119,7 @@ async function publishRelease(options) {
|
|
|
132482
133119
|
const captureBaselineActual = typeof captureBaselineFn === "function" ? captureBaselineFn : captureBaseline;
|
|
132483
133120
|
let planRaw;
|
|
132484
133121
|
try {
|
|
132485
|
-
planRaw = await
|
|
133122
|
+
planRaw = await readFile38(planPath, "utf8");
|
|
132486
133123
|
} catch (err) {
|
|
132487
133124
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
132488
133125
|
}
|
|
@@ -132673,7 +133310,7 @@ async function publishRelease(options) {
|
|
|
132673
133310
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
132674
133311
|
let approvalRaw;
|
|
132675
133312
|
try {
|
|
132676
|
-
approvalRaw = await
|
|
133313
|
+
approvalRaw = await readFile38(approvalPath, "utf8");
|
|
132677
133314
|
} catch (err) {
|
|
132678
133315
|
throw new ReleaseError(
|
|
132679
133316
|
GATE_FAILED,
|
|
@@ -133310,7 +133947,7 @@ var reconcile_exports = {};
|
|
|
133310
133947
|
__export(reconcile_exports, {
|
|
133311
133948
|
reconcileRelease: () => reconcileRelease
|
|
133312
133949
|
});
|
|
133313
|
-
import { readFile as
|
|
133950
|
+
import { readFile as readFile39, mkdir as mkdir23 } from "node:fs/promises";
|
|
133314
133951
|
import { join as join29 } from "node:path";
|
|
133315
133952
|
function defaultClock5() {
|
|
133316
133953
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -133339,7 +133976,7 @@ async function reconcileRelease(options) {
|
|
|
133339
133976
|
}
|
|
133340
133977
|
let planRaw;
|
|
133341
133978
|
try {
|
|
133342
|
-
planRaw = await
|
|
133979
|
+
planRaw = await readFile39(planPath, "utf8");
|
|
133343
133980
|
} catch (err) {
|
|
133344
133981
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
133345
133982
|
}
|
|
@@ -133462,7 +134099,7 @@ async function reconcileRelease(options) {
|
|
|
133462
134099
|
{ sourceRunId: sourceRun.runId }
|
|
133463
134100
|
);
|
|
133464
134101
|
}
|
|
133465
|
-
const sourceApprovalRaw = await
|
|
134102
|
+
const sourceApprovalRaw = await readFile39(consumedApprovalPath, "utf8").catch((error) => {
|
|
133466
134103
|
throw new ReleaseError(GATE_FAILED, "source run approval authority is unavailable", {
|
|
133467
134104
|
sourceRunId: sourceRun.runId,
|
|
133468
134105
|
cause: error.code
|
|
@@ -133624,7 +134261,7 @@ async function reconcileRelease(options) {
|
|
|
133624
134261
|
if (approvalPath) {
|
|
133625
134262
|
let approvalRaw;
|
|
133626
134263
|
try {
|
|
133627
|
-
approvalRaw = await
|
|
134264
|
+
approvalRaw = await readFile39(approvalPath, "utf8");
|
|
133628
134265
|
} catch (err) {
|
|
133629
134266
|
throw new ReleaseError(
|
|
133630
134267
|
GATE_FAILED,
|
|
@@ -135090,7 +135727,7 @@ var init_notify_handoff = __esm({
|
|
|
135090
135727
|
// src/core/proposal-inbox.mjs
|
|
135091
135728
|
import { execFile as execFileCb14 } from "node:child_process";
|
|
135092
135729
|
import { promisify as promisify14 } from "node:util";
|
|
135093
|
-
import { mkdir as mkdir26, mkdtemp as mkdtemp8, readFile as
|
|
135730
|
+
import { mkdir as mkdir26, mkdtemp as mkdtemp8, readFile as readFile40, rm as rm12, writeFile as writeFile11 } from "node:fs/promises";
|
|
135094
135731
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
135095
135732
|
import { dirname as dirname19, join as join32 } from "node:path";
|
|
135096
135733
|
function defaultExec2(command2, args2, options = {}) {
|
|
@@ -135270,7 +135907,7 @@ async function observeProposalInboxGitPush(params) {
|
|
|
135270
135907
|
const targetPath2 = join32(cloneDir, proposalPath);
|
|
135271
135908
|
let existing = null;
|
|
135272
135909
|
try {
|
|
135273
|
-
existing = await
|
|
135910
|
+
existing = await readFile40(targetPath2, "utf8");
|
|
135274
135911
|
} catch {
|
|
135275
135912
|
existing = null;
|
|
135276
135913
|
}
|
|
@@ -135431,7 +136068,7 @@ async function deliverProposalLocalFile(params) {
|
|
|
135431
136068
|
const targetPath2 = join32(workspaceRealpath, proposalPath);
|
|
135432
136069
|
let existing = null;
|
|
135433
136070
|
try {
|
|
135434
|
-
existing = await
|
|
136071
|
+
existing = await readFile40(targetPath2, "utf8");
|
|
135435
136072
|
} catch {
|
|
135436
136073
|
existing = null;
|
|
135437
136074
|
}
|
|
@@ -135928,7 +136565,7 @@ var init_preset_gitwrite = __esm({
|
|
|
135928
136565
|
});
|
|
135929
136566
|
|
|
135930
136567
|
// src/core/marketplace-registry-entry.mjs
|
|
135931
|
-
import { readFile as
|
|
136568
|
+
import { readFile as readFile41 } from "node:fs/promises";
|
|
135932
136569
|
import { join as join34 } from "node:path";
|
|
135933
136570
|
function updateRegistryEntry(registry, params) {
|
|
135934
136571
|
const { entryKey, fieldsFromPlan, contextProjection } = params ?? {};
|
|
@@ -135994,7 +136631,7 @@ async function executeMarketplaceRegistryEntryHook(params) {
|
|
|
135994
136631
|
const absoluteRegistry = join34(worktree, registryPath);
|
|
135995
136632
|
let raw;
|
|
135996
136633
|
try {
|
|
135997
|
-
raw = await
|
|
136634
|
+
raw = await readFile41(absoluteRegistry, "utf8");
|
|
135998
136635
|
} catch {
|
|
135999
136636
|
throw new ReleaseError(
|
|
136000
136637
|
REMOTE_CONFLICT,
|
|
@@ -136046,7 +136683,7 @@ var init_marketplace_registry_entry = __esm({
|
|
|
136046
136683
|
});
|
|
136047
136684
|
|
|
136048
136685
|
// src/core/docs-refresh-preset.mjs
|
|
136049
|
-
import { mkdir as mkdir27, readFile as
|
|
136686
|
+
import { mkdir as mkdir27, readFile as readFile42, writeFile as writeFile12 } from "node:fs/promises";
|
|
136050
136687
|
import { dirname as dirname20, isAbsolute as isAbsolute24, join as join35, relative as relative29, resolve as resolve34 } from "node:path";
|
|
136051
136688
|
function resolvePayloadSource(payloadDir, from) {
|
|
136052
136689
|
const sourcePath = resolve34(payloadDir, from);
|
|
@@ -136084,7 +136721,7 @@ async function executeDocsRefreshHook(params) {
|
|
|
136084
136721
|
const mutate = /* @__PURE__ */ __name(async (worktree) => {
|
|
136085
136722
|
for (const mapping of mappings) {
|
|
136086
136723
|
const sourcePath = resolvePayloadSource(payloadDir, mapping.from);
|
|
136087
|
-
let content = await
|
|
136724
|
+
let content = await readFile42(sourcePath).catch(() => null);
|
|
136088
136725
|
if (content === null) {
|
|
136089
136726
|
throw new ReleaseError(
|
|
136090
136727
|
GATE_FAILED,
|
|
@@ -136301,7 +136938,7 @@ __export(distribute_exports, {
|
|
|
136301
136938
|
});
|
|
136302
136939
|
import { execFile as execFileCb16 } from "node:child_process";
|
|
136303
136940
|
import { promisify as promisify16 } from "node:util";
|
|
136304
|
-
import { realpath as realpath32, lstat as lstat43, mkdir as mkdir28, readFile as
|
|
136941
|
+
import { realpath as realpath32, lstat as lstat43, mkdir as mkdir28, readFile as readFile43, rm as rm15 } from "node:fs/promises";
|
|
136305
136942
|
import { mkdtemp as mkdtemp10 } from "node:fs/promises";
|
|
136306
136943
|
import { tmpdir as tmpdir8 } from "node:os";
|
|
136307
136944
|
import { isAbsolute as isAbsolute25, join as join36, relative as relative30, resolve as resolve35 } from "node:path";
|
|
@@ -136400,7 +137037,7 @@ async function distributeRelease(options) {
|
|
|
136400
137037
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
136401
137038
|
let planRaw;
|
|
136402
137039
|
try {
|
|
136403
|
-
planRaw = await
|
|
137040
|
+
planRaw = await readFile43(planPath, "utf8");
|
|
136404
137041
|
} catch (err) {
|
|
136405
137042
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
136406
137043
|
}
|
|
@@ -136515,7 +137152,7 @@ async function distributeRelease(options) {
|
|
|
136515
137152
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
136516
137153
|
let approvalRaw;
|
|
136517
137154
|
try {
|
|
136518
|
-
approvalRaw = await
|
|
137155
|
+
approvalRaw = await readFile43(approvalPath, "utf8");
|
|
136519
137156
|
} catch (err) {
|
|
136520
137157
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
136521
137158
|
}
|
|
@@ -136627,7 +137264,7 @@ async function distributeRelease(options) {
|
|
|
136627
137264
|
for (const hookApprovalPath of hookApprovalPaths) {
|
|
136628
137265
|
let hookApprovalRaw;
|
|
136629
137266
|
try {
|
|
136630
|
-
hookApprovalRaw = await
|
|
137267
|
+
hookApprovalRaw = await readFile43(hookApprovalPath, "utf8");
|
|
136631
137268
|
} catch (err) {
|
|
136632
137269
|
await failBlocked(new ReleaseError(
|
|
136633
137270
|
GATE_FAILED,
|
|
@@ -137732,7 +138369,7 @@ __export(postverify_exports, {
|
|
|
137732
138369
|
});
|
|
137733
138370
|
import { execFile as execFileCb17 } from "node:child_process";
|
|
137734
138371
|
import { promisify as promisify17 } from "node:util";
|
|
137735
|
-
import { mkdir as mkdir29, readFile as
|
|
138372
|
+
import { mkdir as mkdir29, readFile as readFile44, realpath as realpath33, rm as rm16 } from "node:fs/promises";
|
|
137736
138373
|
import { mkdtemp as mkdtemp11 } from "node:fs/promises";
|
|
137737
138374
|
import { tmpdir as tmpdir9 } from "node:os";
|
|
137738
138375
|
import { join as join37 } from "node:path";
|
|
@@ -137765,7 +138402,7 @@ async function postVerifyRelease(options) {
|
|
|
137765
138402
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
137766
138403
|
let planRaw;
|
|
137767
138404
|
try {
|
|
137768
|
-
planRaw = await
|
|
138405
|
+
planRaw = await readFile44(planPath, "utf8");
|
|
137769
138406
|
} catch (err) {
|
|
137770
138407
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
137771
138408
|
}
|
|
@@ -137799,7 +138436,7 @@ async function postVerifyRelease(options) {
|
|
|
137799
138436
|
}
|
|
137800
138437
|
let approvalRaw;
|
|
137801
138438
|
try {
|
|
137802
|
-
approvalRaw = await
|
|
138439
|
+
approvalRaw = await readFile44(approvalPath, "utf8");
|
|
137803
138440
|
} catch (err) {
|
|
137804
138441
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
137805
138442
|
}
|
|
@@ -137872,16 +138509,16 @@ async function postVerifyRelease(options) {
|
|
|
137872
138509
|
validatePostPublishDeclaration(declaration, { unitId: declaration.unitId });
|
|
137873
138510
|
await verifyExecutionBundle({ planPath, postPublish: declaration });
|
|
137874
138511
|
const declaredHooks = declaration.hooks ?? [];
|
|
137875
|
-
const
|
|
137876
|
-
prepared.push({ declaration, postVerifyHooks:
|
|
138512
|
+
const postVerifyHooks3 = declaredHooks.filter((hook) => (hook.phase ?? "distribute") === "postVerify");
|
|
138513
|
+
prepared.push({ declaration, postVerifyHooks: postVerifyHooks3 });
|
|
137877
138514
|
}
|
|
137878
|
-
const
|
|
138515
|
+
const postVerifyHooks2 = prepared.flatMap((prep) => prep.postVerifyHooks);
|
|
137879
138516
|
const approvedHookIds = /* @__PURE__ */ new Set();
|
|
137880
138517
|
const hookApprovalPaths = postpublishApprovalPaths ?? [];
|
|
137881
138518
|
for (const hookApprovalPath of hookApprovalPaths) {
|
|
137882
138519
|
let hookApprovalRaw;
|
|
137883
138520
|
try {
|
|
137884
|
-
hookApprovalRaw = await
|
|
138521
|
+
hookApprovalRaw = await readFile44(hookApprovalPath, "utf8");
|
|
137885
138522
|
} catch (err) {
|
|
137886
138523
|
throw new ReleaseError(
|
|
137887
138524
|
GATE_FAILED,
|
|
@@ -138036,7 +138673,7 @@ async function postVerifyRelease(options) {
|
|
|
138036
138673
|
status: "started",
|
|
138037
138674
|
sourceVerifyRunId: verifyRun.runId,
|
|
138038
138675
|
sourcePublishRunId: publishRun.runId,
|
|
138039
|
-
hookCount:
|
|
138676
|
+
hookCount: postVerifyHooks2.length,
|
|
138040
138677
|
dryRun: dryRun === true
|
|
138041
138678
|
});
|
|
138042
138679
|
await snapshot(DISTRIBUTING2);
|
|
@@ -138516,7 +139153,7 @@ var release_metadata_exports = {};
|
|
|
138516
139153
|
__export(release_metadata_exports, {
|
|
138517
139154
|
updatePreviousPublicBaselines: () => updatePreviousPublicBaselines
|
|
138518
139155
|
});
|
|
138519
|
-
import { lstat as lstat44, readFile as
|
|
139156
|
+
import { lstat as lstat44, readFile as readFile45 } from "node:fs/promises";
|
|
138520
139157
|
import { resolve as resolve36 } from "node:path";
|
|
138521
139158
|
function assertOid(value, label) {
|
|
138522
139159
|
if (typeof value !== "string" || !/^[a-f0-9]{40,64}$/.test(value)) {
|
|
@@ -138532,8 +139169,8 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
138532
139169
|
let configStat;
|
|
138533
139170
|
try {
|
|
138534
139171
|
[plan, configRaw, configStat] = await Promise.all([
|
|
138535
|
-
|
|
138536
|
-
|
|
139172
|
+
readFile45(planPath, "utf8").then(JSON.parse),
|
|
139173
|
+
readFile45(configPath, "utf8"),
|
|
138537
139174
|
lstat44(configPath)
|
|
138538
139175
|
]);
|
|
138539
139176
|
} catch (error) {
|
|
@@ -138618,7 +139255,7 @@ var ship_exports = {};
|
|
|
138618
139255
|
__export(ship_exports, {
|
|
138619
139256
|
advanceShip: () => advanceShip
|
|
138620
139257
|
});
|
|
138621
|
-
import { readFile as
|
|
139258
|
+
import { readFile as readFile46, lstat as lstat45, mkdir as mkdir30 } from "node:fs/promises";
|
|
138622
139259
|
import { basename as basename14, dirname as dirname21, resolve as resolve37 } from "node:path";
|
|
138623
139260
|
function normalizeNewShipUnitIds(releaseUnits, requestedUnitIds) {
|
|
138624
139261
|
if (requestedUnitIds === void 0) return void 0;
|
|
@@ -138674,7 +139311,7 @@ function assertFrozenPlanUnitScope({ statePath, stateUnitIds, expectedUnitIds, p
|
|
|
138674
139311
|
}
|
|
138675
139312
|
async function readFrozenPlanForUnitScope(planPath, statePath, stateUnitIds) {
|
|
138676
139313
|
try {
|
|
138677
|
-
return JSON.parse(await
|
|
139314
|
+
return JSON.parse(await readFile46(planPath, "utf8"));
|
|
138678
139315
|
} catch (error) {
|
|
138679
139316
|
throw unitScopeMismatch(
|
|
138680
139317
|
statePath,
|
|
@@ -138702,7 +139339,7 @@ async function readState(path40) {
|
|
|
138702
139339
|
if (!stat22.isFile() || stat22.isSymbolicLink()) {
|
|
138703
139340
|
throw new Error("ship state must be a regular non-symlink file");
|
|
138704
139341
|
}
|
|
138705
|
-
const state = JSON.parse(await
|
|
139342
|
+
const state = JSON.parse(await readFile46(path40, "utf8"));
|
|
138706
139343
|
const { stateDigest, ...body } = state;
|
|
138707
139344
|
if (typeof stateDigest !== "string" || stateDigest !== sha256Hex(canonicalJson2(body)) || body.statePath !== path40) {
|
|
138708
139345
|
throw new Error("ship state digest or authority path does not match");
|
|
@@ -138751,7 +139388,8 @@ async function defaultDependencies() {
|
|
|
138751
139388
|
readMaxApprovalMs: /* @__PURE__ */ __name(() => MAX_APPROVAL_MS, "readMaxApprovalMs")
|
|
138752
139389
|
};
|
|
138753
139390
|
}
|
|
138754
|
-
function publicState2(state) {
|
|
139391
|
+
function publicState2(state, { postRelease } = {}) {
|
|
139392
|
+
const visiblePostRelease = postRelease === void 0 ? state.postRelease : postRelease;
|
|
138755
139393
|
return {
|
|
138756
139394
|
command: "ship",
|
|
138757
139395
|
status: state.status,
|
|
@@ -138776,7 +139414,7 @@ function publicState2(state) {
|
|
|
138776
139414
|
...state.requirements ? { requirements: state.requirements } : {},
|
|
138777
139415
|
...state.manualFollowUps ? { manualFollowUps: state.manualFollowUps } : {},
|
|
138778
139416
|
...state.metadataUpdate ? { metadataUpdate: state.metadataUpdate } : {},
|
|
138779
|
-
...
|
|
139417
|
+
...visiblePostRelease ? { postRelease: visiblePostRelease } : {},
|
|
138780
139418
|
externalActionsIncludedInPlanApproval: true,
|
|
138781
139419
|
verificationGatesIncludedInPlanApproval: true,
|
|
138782
139420
|
postPublishCheckpointApprovalsIncludedInPlanApproval: false
|
|
@@ -138800,7 +139438,7 @@ function projectActionTarget(action) {
|
|
|
138800
139438
|
}
|
|
138801
139439
|
async function buildApprovalSummary(planPath, maxApprovalMs = MAX_APPROVAL_MS) {
|
|
138802
139440
|
try {
|
|
138803
|
-
const plan = JSON.parse(await
|
|
139441
|
+
const plan = JSON.parse(await readFile46(planPath, "utf8"));
|
|
138804
139442
|
const approvalWindowHours = deriveApprovalWindowHours(maxApprovalMs);
|
|
138805
139443
|
const actions = (plan.externalActions ?? []).map((action) => ({
|
|
138806
139444
|
id: action.id,
|
|
@@ -138865,19 +139503,19 @@ async function buildApprovalSummary(planPath, maxApprovalMs = MAX_APPROVAL_MS) {
|
|
|
138865
139503
|
);
|
|
138866
139504
|
}
|
|
138867
139505
|
}
|
|
138868
|
-
async function allUnclosedPostVerifyHooksUngated(state,
|
|
138869
|
-
if (!Array.isArray(
|
|
138870
|
-
let candidates =
|
|
139506
|
+
async function allUnclosedPostVerifyHooksUngated(state, postVerifyHooks2, planVersion) {
|
|
139507
|
+
if (!Array.isArray(postVerifyHooks2) || postVerifyHooks2.length === 0) return false;
|
|
139508
|
+
let candidates = postVerifyHooks2;
|
|
138871
139509
|
if (state.postVerify?.runPath) {
|
|
138872
139510
|
try {
|
|
138873
|
-
const record = JSON.parse(await
|
|
139511
|
+
const record = JSON.parse(await readFile46(state.postVerify.runPath, "utf8"));
|
|
138874
139512
|
const checkpoints = Array.isArray(record.checkpoints) ? record.checkpoints : [];
|
|
138875
139513
|
const closedIds = new Set(
|
|
138876
139514
|
checkpoints.filter((cp4) => cp4?.actionType === "postpublish-hook" && (cp4.status === "succeeded" || cp4.status === "NO_CHANGE")).map((cp4) => cp4.actionId)
|
|
138877
139515
|
);
|
|
138878
|
-
candidates =
|
|
139516
|
+
candidates = postVerifyHooks2.filter(({ hook, unitId }) => !closedIds.has(postPublishActionId({ planVersion, unitId, localId: hook.id })));
|
|
138879
139517
|
} catch {
|
|
138880
|
-
candidates =
|
|
139518
|
+
candidates = postVerifyHooks2;
|
|
138881
139519
|
}
|
|
138882
139520
|
}
|
|
138883
139521
|
if (candidates.length === 0) return false;
|
|
@@ -139021,7 +139659,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139021
139659
|
});
|
|
139022
139660
|
let frozenPlan = null;
|
|
139023
139661
|
if (Array.isArray(state.selectedUnitIds) || deps.preflightGitTransports) {
|
|
139024
|
-
frozenPlan = Array.isArray(state.selectedUnitIds) ? await readFrozenPlanForUnitScope(prepared.planPath, statePath, state.selectedUnitIds) : JSON.parse(await
|
|
139662
|
+
frozenPlan = Array.isArray(state.selectedUnitIds) ? await readFrozenPlanForUnitScope(prepared.planPath, statePath, state.selectedUnitIds) : JSON.parse(await readFile46(prepared.planPath, "utf8"));
|
|
139025
139663
|
}
|
|
139026
139664
|
if (Array.isArray(state.selectedUnitIds)) {
|
|
139027
139665
|
assertFrozenPlanUnitScope({
|
|
@@ -139118,7 +139756,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139118
139756
|
}
|
|
139119
139757
|
let postVerifyRanThisCall = false;
|
|
139120
139758
|
if (state.status === "PUBLISHED" || state.status === "NEEDS_MANUAL_ATTESTATIONS") {
|
|
139121
|
-
const plan = JSON.parse(await
|
|
139759
|
+
const plan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139122
139760
|
const hasDistributeWork = normalizePostPublishView(plan).some((declaration) => (declaration.targets?.length ?? 0) > 0 || (declaration.hooks?.length ?? 0) > 0);
|
|
139123
139761
|
const needsDistribution = hasDistributeWork;
|
|
139124
139762
|
if (needsDistribution && deps.distributeRelease) {
|
|
@@ -139173,15 +139811,6 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139173
139811
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
139174
139812
|
};
|
|
139175
139813
|
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
139814
|
} catch (error) {
|
|
139186
139815
|
if (error?.code !== CONSUMER_VERIFICATION_DEFERRED) throw error;
|
|
139187
139816
|
state = {
|
|
@@ -139192,8 +139821,8 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139192
139821
|
};
|
|
139193
139822
|
await writeJsonAtomic(statePath, state);
|
|
139194
139823
|
}
|
|
139195
|
-
const
|
|
139196
|
-
if (state.status === "VERIFIED" &&
|
|
139824
|
+
const postVerifyHooks2 = normalizePostPublishView(plan).flatMap((declaration) => declaration.hooks ?? []).filter((hook) => hook.phase === "postVerify");
|
|
139825
|
+
if (state.status === "VERIFIED" && postVerifyHooks2.length > 0 && deps.postVerifyRelease) {
|
|
139197
139826
|
postVerifyRanThisCall = true;
|
|
139198
139827
|
let postVerifyOutcome;
|
|
139199
139828
|
try {
|
|
@@ -139227,7 +139856,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139227
139856
|
}
|
|
139228
139857
|
const reentryApprovalPaths = options.postpublishApprovalPaths ?? [];
|
|
139229
139858
|
if (state.status === "VERIFIED" && deps.postVerifyRelease && !postVerifyRanThisCall && (!state.postVerify || state.postVerify.status !== "DISTRIBUTED")) {
|
|
139230
|
-
const reentryPlan = JSON.parse(await
|
|
139859
|
+
const reentryPlan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139231
139860
|
const reentryPostVerifyHooks = normalizePostPublishView(reentryPlan).flatMap((declaration) => (declaration.hooks ?? []).map((hook) => ({ hook, unitId: declaration.unitId }))).filter(({ hook }) => hook.phase === "postVerify");
|
|
139232
139861
|
const approvallessRetryAllowed = reentryApprovalPaths.length === 0 && await allUnclosedPostVerifyHooksUngated(state, reentryPostVerifyHooks, reentryPlan.planVersion);
|
|
139233
139862
|
if (reentryPostVerifyHooks.length > 0 && (reentryApprovalPaths.length > 0 || approvallessRetryAllowed)) {
|
|
@@ -139261,6 +139890,24 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
139261
139890
|
await writeJsonAtomic(statePath, state);
|
|
139262
139891
|
}
|
|
139263
139892
|
}
|
|
139893
|
+
if (state.status === "VERIFIED") {
|
|
139894
|
+
const finalPlan = JSON.parse(await readFile46(state.planPath, "utf8"));
|
|
139895
|
+
const hasPostVerify = normalizePostPublishView(finalPlan).some((declaration) => (declaration.hooks ?? []).some((hook) => hook.phase === "postVerify"));
|
|
139896
|
+
const localFinishRunPath = hasPostVerify ? state.postVerify?.status === "DISTRIBUTED" ? state.postVerify.runPath : void 0 : state.verifyRunPath;
|
|
139897
|
+
let postRelease;
|
|
139898
|
+
try {
|
|
139899
|
+
postRelease = derivePostReleaseChecklist(finalPlan, {
|
|
139900
|
+
root,
|
|
139901
|
+
statePath,
|
|
139902
|
+
unitIds: state.selectedUnitIds,
|
|
139903
|
+
runPath: localFinishRunPath,
|
|
139904
|
+
postVerifyComplete: !hasPostVerify || state.postVerify?.status === "DISTRIBUTED"
|
|
139905
|
+
});
|
|
139906
|
+
} catch (error) {
|
|
139907
|
+
postRelease = unavailablePostReleaseChecklist(finalPlan, error);
|
|
139908
|
+
}
|
|
139909
|
+
return publicState2(state, { postRelease });
|
|
139910
|
+
}
|
|
139264
139911
|
return publicState2(state);
|
|
139265
139912
|
}
|
|
139266
139913
|
var HOUR_MS, ACTION_TARGET_FIELDS;
|
|
@@ -140232,7 +140879,7 @@ var attest_exports = {};
|
|
|
140232
140879
|
__export(attest_exports, {
|
|
140233
140880
|
recordManualAttestation: () => recordManualAttestation
|
|
140234
140881
|
});
|
|
140235
|
-
import { readFile as
|
|
140882
|
+
import { readFile as readFile47 } from "node:fs/promises";
|
|
140236
140883
|
import { resolve as resolve38, join as join39 } from "node:path";
|
|
140237
140884
|
async function validateInstalledConsumerClosure({
|
|
140238
140885
|
root,
|
|
@@ -140250,7 +140897,7 @@ async function validateInstalledConsumerClosure({
|
|
|
140250
140897
|
]);
|
|
140251
140898
|
let plan;
|
|
140252
140899
|
try {
|
|
140253
|
-
plan = JSON.parse(await
|
|
140900
|
+
plan = JSON.parse(await readFile47(planPath, "utf8"));
|
|
140254
140901
|
} catch (error) {
|
|
140255
140902
|
throw new ReleaseError(
|
|
140256
140903
|
GATE_FAILED,
|
|
@@ -140324,7 +140971,7 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
140324
140971
|
const requirementPath = join39(authorityDir, descriptor.requirementFile);
|
|
140325
140972
|
let requirement;
|
|
140326
140973
|
try {
|
|
140327
|
-
requirement = JSON.parse(await
|
|
140974
|
+
requirement = JSON.parse(await readFile47(requirementPath, "utf8"));
|
|
140328
140975
|
} catch (error) {
|
|
140329
140976
|
throw new ReleaseError(
|
|
140330
140977
|
GATE_FAILED,
|
|
@@ -140408,7 +141055,7 @@ var init_attest = __esm({
|
|
|
140408
141055
|
});
|
|
140409
141056
|
|
|
140410
141057
|
// src/artifacts/policy.mjs
|
|
140411
|
-
import { readFile as
|
|
141058
|
+
import { readFile as readFile48 } from "node:fs/promises";
|
|
140412
141059
|
import { join as join40 } from "node:path";
|
|
140413
141060
|
import { createHash as createHash19 } from "node:crypto";
|
|
140414
141061
|
function validateArtifactPolicy(policy) {
|
|
@@ -140508,7 +141155,7 @@ async function parseSafeYamlWithinRoot(root, policyPath) {
|
|
|
140508
141155
|
const fullPath = join40(root, policyPath);
|
|
140509
141156
|
let content;
|
|
140510
141157
|
try {
|
|
140511
|
-
content = await
|
|
141158
|
+
content = await readFile48(fullPath, "utf8");
|
|
140512
141159
|
} catch (err) {
|
|
140513
141160
|
throw new ReleaseError(
|
|
140514
141161
|
ARTIFACT_POLICY_INVALID,
|
|
@@ -140619,7 +141266,7 @@ var init_policy = __esm({
|
|
|
140619
141266
|
});
|
|
140620
141267
|
|
|
140621
141268
|
// src/artifacts/entry.mjs
|
|
140622
|
-
import { lstat as lstat46, readdir as readdir30, readFile as
|
|
141269
|
+
import { lstat as lstat46, readdir as readdir30, readFile as readFile49 } from "node:fs/promises";
|
|
140623
141270
|
import { join as join41 } from "node:path";
|
|
140624
141271
|
import { promisify as promisify21 } from "node:util";
|
|
140625
141272
|
import { execFile as execFile14 } from "node:child_process";
|
|
@@ -140664,7 +141311,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
140664
141311
|
const subEntries = await enumerateTreeEntries(root, absPath, relPath);
|
|
140665
141312
|
entries.push(...subEntries);
|
|
140666
141313
|
} else {
|
|
140667
|
-
const content = await
|
|
141314
|
+
const content = await readFile49(absPath);
|
|
140668
141315
|
entries.push(
|
|
140669
141316
|
Object.freeze({
|
|
140670
141317
|
path: relPath,
|
|
@@ -140727,7 +141374,7 @@ async function readEntry({ root, path: path40, source = "worktree" } = {}) {
|
|
|
140727
141374
|
{ path: path40, nlink: st.nlink }
|
|
140728
141375
|
);
|
|
140729
141376
|
}
|
|
140730
|
-
const content = await
|
|
141377
|
+
const content = await readFile49(absPath);
|
|
140731
141378
|
return Object.freeze({
|
|
140732
141379
|
kind: "regular",
|
|
140733
141380
|
path: path40,
|
|
@@ -140991,7 +141638,7 @@ var init_graph = __esm({
|
|
|
140991
141638
|
});
|
|
140992
141639
|
|
|
140993
141640
|
// src/artifacts/producer-registry.mjs
|
|
140994
|
-
import { readFile as
|
|
141641
|
+
import { readFile as readFile50, readdir as readdir31, stat as stat19, mkdir as mkdir32, writeFile as writeFile14, rm as rm18 } from "node:fs/promises";
|
|
140995
141642
|
import { join as join42 } from "node:path";
|
|
140996
141643
|
import { mkdtemp as mkdtemp13 } from "node:fs/promises";
|
|
140997
141644
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
@@ -141023,7 +141670,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
141023
141670
|
const lockfilePath = join42(new URL("../../..", import.meta.url).pathname, "pnpm-lock.yaml");
|
|
141024
141671
|
let lockfileBytes;
|
|
141025
141672
|
try {
|
|
141026
|
-
lockfileBytes = await
|
|
141673
|
+
lockfileBytes = await readFile50(lockfilePath);
|
|
141027
141674
|
} catch {
|
|
141028
141675
|
lockfileBytes = Buffer.from("");
|
|
141029
141676
|
}
|
|
@@ -141040,7 +141687,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
141040
141687
|
const allModuleBytes = await Promise.all(
|
|
141041
141688
|
allModulePaths.map(async (p) => {
|
|
141042
141689
|
try {
|
|
141043
|
-
return await
|
|
141690
|
+
return await readFile50(p);
|
|
141044
141691
|
} catch {
|
|
141045
141692
|
return Buffer.from("");
|
|
141046
141693
|
}
|
|
@@ -141066,7 +141713,7 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
141066
141713
|
if (st.isDirectory()) {
|
|
141067
141714
|
entries.push(...await readDirEntries(absPath, relPath));
|
|
141068
141715
|
} else {
|
|
141069
|
-
const content = await
|
|
141716
|
+
const content = await readFile50(absPath);
|
|
141070
141717
|
entries.push(Object.freeze({
|
|
141071
141718
|
path: relPath,
|
|
141072
141719
|
type: "blob",
|
|
@@ -141593,7 +142240,7 @@ var init_state = __esm({
|
|
|
141593
142240
|
});
|
|
141594
142241
|
|
|
141595
142242
|
// src/artifacts/artifact-plan.mjs
|
|
141596
|
-
import { writeFile as writeFile15, mkdir as mkdir33, readFile as
|
|
142243
|
+
import { writeFile as writeFile15, mkdir as mkdir33, readFile as readFile51, rename as rename5, open as open14 } from "node:fs/promises";
|
|
141597
142244
|
import { dirname as dirname23 } from "node:path";
|
|
141598
142245
|
function assemblePlan({
|
|
141599
142246
|
operation,
|
|
@@ -142282,7 +142929,7 @@ var init_adoption = __esm({
|
|
|
142282
142929
|
// src/artifacts/inspect.mjs
|
|
142283
142930
|
import { promisify as promisify24 } from "node:util";
|
|
142284
142931
|
import { execFile as execFile17 } from "node:child_process";
|
|
142285
|
-
import { readdir as readdir32, stat as stat20, readFile as
|
|
142932
|
+
import { readdir as readdir32, stat as stat20, readFile as readFile52 } from "node:fs/promises";
|
|
142286
142933
|
import { join as join43 } from "node:path";
|
|
142287
142934
|
async function hasNestedGitRoots(root) {
|
|
142288
142935
|
try {
|
|
@@ -142554,7 +143201,7 @@ var init_inspect = __esm({
|
|
|
142554
143201
|
});
|
|
142555
143202
|
|
|
142556
143203
|
// src/artifacts/resolution.mjs
|
|
142557
|
-
import { mkdir as mkdir34, open as open15, readFile as
|
|
143204
|
+
import { mkdir as mkdir34, open as open15, readFile as readFile53, stat as stat21, lstat as lstat47, chmod as chmod6 } from "node:fs/promises";
|
|
142558
143205
|
import { join as join44, resolve as resolve39, relative as relative31, isAbsolute as isAbsolute27, basename as basename15 } from "node:path";
|
|
142559
143206
|
function decodeBuffer(value, label) {
|
|
142560
143207
|
if (value == null) return null;
|
|
@@ -142886,7 +143533,7 @@ async function submitResolution({
|
|
|
142886
143533
|
async function readAndValidateResolvedFile(resolvedPath) {
|
|
142887
143534
|
let content;
|
|
142888
143535
|
try {
|
|
142889
|
-
content = await
|
|
143536
|
+
content = await readFile53(resolvedPath);
|
|
142890
143537
|
} catch (err) {
|
|
142891
143538
|
throw new ReleaseError(MISSING_PARAMETERS, `cannot read resolved file: ${err.message}`, { resolvedPath, cause: err.code });
|
|
142892
143539
|
}
|
|
@@ -143054,7 +143701,7 @@ var artifacts_exports = {};
|
|
|
143054
143701
|
__export(artifacts_exports, {
|
|
143055
143702
|
runArtifactsCommand: () => runArtifactsCommand
|
|
143056
143703
|
});
|
|
143057
|
-
import { readFile as
|
|
143704
|
+
import { readFile as readFile54 } from "node:fs/promises";
|
|
143058
143705
|
import { join as join45 } from "node:path";
|
|
143059
143706
|
async function runArtifactsCommand({ subcommand, args: args2, root } = {}) {
|
|
143060
143707
|
if (!VALID_SUBCOMMANDS.has(subcommand)) {
|
|
@@ -143183,7 +143830,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
143183
143830
|
{ subcommand: "adopt" }
|
|
143184
143831
|
);
|
|
143185
143832
|
}
|
|
143186
|
-
const planRaw = await
|
|
143833
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143187
143834
|
const plan = JSON.parse(planRaw);
|
|
143188
143835
|
if (expectedDigest && plan.planDigest !== expectedDigest) {
|
|
143189
143836
|
throw new ReleaseError(
|
|
@@ -143198,7 +143845,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
143198
143845
|
if (artifact.path) {
|
|
143199
143846
|
const entry = await readEntry({ root, path: artifact.path, source: "worktree" });
|
|
143200
143847
|
if (entry.kind === "regular") {
|
|
143201
|
-
const bytes = await
|
|
143848
|
+
const bytes = await readFile54(join45(root, artifact.path));
|
|
143202
143849
|
currentEntries.set(artifact.id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
143203
143850
|
} else {
|
|
143204
143851
|
currentEntries.set(artifact.id, entry);
|
|
@@ -143263,7 +143910,7 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
143263
143910
|
{ subcommand: "bootstrap" }
|
|
143264
143911
|
);
|
|
143265
143912
|
}
|
|
143266
|
-
const planRaw = await
|
|
143913
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143267
143914
|
const adoptionPlan = JSON.parse(planRaw);
|
|
143268
143915
|
const currentEntries = /* @__PURE__ */ new Map();
|
|
143269
143916
|
for (const id of new Set((adoptionPlan.protectedHunks ?? []).map((h) => h.artifactId))) {
|
|
@@ -143275,12 +143922,12 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
143275
143922
|
if (entry.kind !== "regular") {
|
|
143276
143923
|
throw new ReleaseError("PLAN_STALE", `artifact is no longer a regular file: ${id}`, { id });
|
|
143277
143924
|
}
|
|
143278
|
-
const bytes = await
|
|
143925
|
+
const bytes = await readFile54(join45(root, artifactPath));
|
|
143279
143926
|
currentEntries.set(id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
143280
143927
|
}
|
|
143281
143928
|
let replacementBytes;
|
|
143282
143929
|
if (action === "replace" && replacementPath) {
|
|
143283
|
-
replacementBytes = await
|
|
143930
|
+
replacementBytes = await readFile54(replacementPath);
|
|
143284
143931
|
}
|
|
143285
143932
|
const updated = await discardBootstrapHunk({
|
|
143286
143933
|
adoptionPlan,
|
|
@@ -143318,7 +143965,7 @@ async function handleResolve({ args: args2, root }) {
|
|
|
143318
143965
|
{ subcommand: "resolve" }
|
|
143319
143966
|
);
|
|
143320
143967
|
}
|
|
143321
|
-
const planRaw = await
|
|
143968
|
+
const planRaw = await readFile54(planPath, "utf8");
|
|
143322
143969
|
const plan = JSON.parse(planRaw);
|
|
143323
143970
|
if (plan.planDigest !== expectedDigest) {
|
|
143324
143971
|
throw new ReleaseError(
|
|
@@ -144136,7 +144783,7 @@ __export(route_exports, {
|
|
|
144136
144783
|
resolvePreviousReleaseCommit: () => resolvePreviousReleaseCommit
|
|
144137
144784
|
});
|
|
144138
144785
|
import { execFileSync } from "node:child_process";
|
|
144139
|
-
import { lstat as lstat48, readdir as readdir33, readFile as
|
|
144786
|
+
import { lstat as lstat48, readdir as readdir33, readFile as readFile55 } from "node:fs/promises";
|
|
144140
144787
|
import { relative as relative32, resolve as resolve40, basename as basename16, dirname as dirname24, join as join46 } from "node:path";
|
|
144141
144788
|
function classifyPath(path40) {
|
|
144142
144789
|
if (typeof path40 !== "string" || path40.length === 0) return "ignore";
|
|
@@ -144223,7 +144870,7 @@ async function resolvePreviousReleaseCommit(root) {
|
|
|
144223
144870
|
if (!file.endsWith(".json")) continue;
|
|
144224
144871
|
let plan;
|
|
144225
144872
|
try {
|
|
144226
|
-
plan = JSON.parse(await
|
|
144873
|
+
plan = JSON.parse(await readFile55(resolve40(plansDir, file), "utf8"));
|
|
144227
144874
|
} catch {
|
|
144228
144875
|
continue;
|
|
144229
144876
|
}
|
|
@@ -144349,7 +144996,7 @@ async function readRunRouting(root, options = {}) {
|
|
|
144349
144996
|
let authorityMissing = false;
|
|
144350
144997
|
let markerlessRunDebris = false;
|
|
144351
144998
|
try {
|
|
144352
|
-
await
|
|
144999
|
+
await readFile55(runPath);
|
|
144353
145000
|
authorityExists = true;
|
|
144354
145001
|
} catch (error) {
|
|
144355
145002
|
if (error.code === "ENOENT") {
|
|
@@ -144504,7 +145151,7 @@ async function isMarkerlessRunDebris(runDirectory) {
|
|
|
144504
145151
|
const evidenceFiles = await readDirectory(join46(runDirectory, "evidence", evidenceEntry.name));
|
|
144505
145152
|
if (!evidenceFiles || evidenceFiles.length !== 1 || evidenceFiles[0].name !== "release-skill-install-evidence.json" || !evidenceFiles[0].isFile() || evidenceFiles[0].isSymbolicLink()) return false;
|
|
144506
145153
|
try {
|
|
144507
|
-
const evidenceRecord = JSON.parse(await
|
|
145154
|
+
const evidenceRecord = JSON.parse(await readFile55(
|
|
144508
145155
|
join46(runDirectory, "evidence", evidenceEntry.name, evidenceFiles[0].name),
|
|
144509
145156
|
"utf8"
|
|
144510
145157
|
));
|
|
@@ -144589,8 +145236,8 @@ async function isProvenPreAuthorityFailure(runDir, runName) {
|
|
|
144589
145236
|
let summary;
|
|
144590
145237
|
let events;
|
|
144591
145238
|
try {
|
|
144592
|
-
summary = JSON.parse(await
|
|
144593
|
-
events = (await
|
|
145239
|
+
summary = JSON.parse(await readFile55(summaryPath, "utf8"));
|
|
145240
|
+
events = (await readFile55(evidencePath, "utf8")).trim().split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
144594
145241
|
} catch {
|
|
144595
145242
|
return false;
|
|
144596
145243
|
}
|
|
@@ -144675,7 +145322,7 @@ async function readLegacyPostverifyRecovery(runPath) {
|
|
|
144675
145322
|
if (run6.command !== "postverify" || run6.status !== "DISTRIBUTED") {
|
|
144676
145323
|
throw new ReleaseError(GATE_FAILED, "legacy postverify status is not terminal DISTRIBUTED");
|
|
144677
145324
|
}
|
|
144678
|
-
const planRaw = await
|
|
145325
|
+
const planRaw = await readFile55(run6.planPath, "utf8");
|
|
144679
145326
|
const plan = JSON.parse(planRaw);
|
|
144680
145327
|
validatePlan(plan);
|
|
144681
145328
|
if (!plan.digest || plan.digest !== computePlanDigest(plan)) {
|
|
@@ -144706,7 +145353,7 @@ async function readLegacyPostverifyRecovery(runPath) {
|
|
|
144706
145353
|
runPath: run6.sourceRunPath,
|
|
144707
145354
|
production
|
|
144708
145355
|
});
|
|
144709
|
-
const summary = JSON.parse(await
|
|
145356
|
+
const summary = JSON.parse(await readFile55(join46(resolve40(runPath, ".."), "summary.json"), "utf8"));
|
|
144710
145357
|
if (!summary || summary.status !== run6.status) {
|
|
144711
145358
|
throw new ReleaseError(GATE_FAILED, "legacy postverify summary status does not match its sealed run status");
|
|
144712
145359
|
}
|
|
@@ -145080,7 +145727,7 @@ Workflow Profiles:
|
|
|
145080
145727
|
});
|
|
145081
145728
|
|
|
145082
145729
|
// bin/release-skill-cli.mjs
|
|
145083
|
-
import { readFile as
|
|
145730
|
+
import { readFile as readFile56 } from "node:fs/promises";
|
|
145084
145731
|
import { basename as basename17, dirname as dirname25, join as join47, resolve as resolve41 } from "node:path";
|
|
145085
145732
|
import { execFile as execFileCb22 } from "node:child_process";
|
|
145086
145733
|
import { promisify as promisify26 } from "node:util";
|
|
@@ -145163,6 +145810,27 @@ async function exitAfterFlush(exitCode) {
|
|
|
145163
145810
|
process.exit(exitCode);
|
|
145164
145811
|
}
|
|
145165
145812
|
__name(exitAfterFlush, "exitAfterFlush");
|
|
145813
|
+
function publicErrorDetails(error) {
|
|
145814
|
+
const details = error?.details;
|
|
145815
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return {};
|
|
145816
|
+
const output = {};
|
|
145817
|
+
if (details.cause && typeof details.cause === "object" && !Array.isArray(details.cause)) {
|
|
145818
|
+
const cause = {};
|
|
145819
|
+
if (typeof details.cause.code === "string") cause.code = details.cause.code;
|
|
145820
|
+
if (typeof details.cause.message === "string") cause.message = details.cause.message;
|
|
145821
|
+
if (Object.keys(cause).length > 0) output.cause = cause;
|
|
145822
|
+
}
|
|
145823
|
+
if (Array.isArray(details.nextSteps)) {
|
|
145824
|
+
const nextSteps = details.nextSteps.filter((step) => step && typeof step === "object" && !Array.isArray(step)).map((step) => ({
|
|
145825
|
+
...typeof step.code === "string" ? { code: step.code } : {},
|
|
145826
|
+
...typeof step.message === "string" ? { message: step.message } : {},
|
|
145827
|
+
...Array.isArray(step.argv) && step.argv.every((arg) => typeof arg === "string") ? { argv: [...step.argv] } : {}
|
|
145828
|
+
})).filter((step) => Object.keys(step).length > 0);
|
|
145829
|
+
if (nextSteps.length > 0) output.nextSteps = nextSteps;
|
|
145830
|
+
}
|
|
145831
|
+
return output;
|
|
145832
|
+
}
|
|
145833
|
+
__name(publicErrorDetails, "publicErrorDetails");
|
|
145166
145834
|
async function checkDependency(command2, versionArgs = ["--version"]) {
|
|
145167
145835
|
try {
|
|
145168
145836
|
const { stdout } = await execFile19(command2, versionArgs, {
|
|
@@ -145871,9 +146539,15 @@ if (command === "ship") {
|
|
|
145871
146539
|
} else {
|
|
145872
146540
|
console.log("Post-release: branch advancement was already included; skip the merge question.");
|
|
145873
146541
|
}
|
|
145874
|
-
|
|
146542
|
+
const localHostUpdate = result2.postRelease.localHostUpdate;
|
|
146543
|
+
if (localHostUpdate?.available === true && typeof localHostUpdate.runPath === "string") {
|
|
145875
146544
|
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 ${
|
|
146545
|
+
console.log(`Post-release command: release-skill post-release --plan ${result2.planPath} --run ${localHostUpdate.runPath}`);
|
|
146546
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
146547
|
+
} else {
|
|
146548
|
+
for (const step of localHostUpdate?.nextSteps ?? []) {
|
|
146549
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
146550
|
+
}
|
|
145877
146551
|
}
|
|
145878
146552
|
}
|
|
145879
146553
|
for (const followUp of result2.manualFollowUps ?? []) {
|
|
@@ -146217,55 +146891,68 @@ if (command === "post-release") {
|
|
|
146217
146891
|
const planPath = value("--plan") ? resolve41(value("--plan")) : void 0;
|
|
146218
146892
|
const runPath = value("--run") ? resolve41(value("--run")) : void 0;
|
|
146219
146893
|
if (!planPath || !runPath) {
|
|
146220
|
-
const message = "post-release requires --plan <path> and --run <
|
|
146894
|
+
const message = "post-release requires --plan <path> and --run <verify-or-postverify-run-path>";
|
|
146221
146895
|
if (hasJson) console.log(JSON.stringify({ error: "MISSING_PARAMETERS", message, exitCode: 1 }));
|
|
146222
146896
|
else console.error(`Error: ${message}`);
|
|
146223
146897
|
await exitAfterFlush(1);
|
|
146224
146898
|
}
|
|
146225
146899
|
try {
|
|
146226
146900
|
const {
|
|
146227
|
-
assertVerifiedReleaseRun: assertVerifiedReleaseRun2,
|
|
146228
146901
|
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
146229
146902
|
updateLocalHostPlugins: updateLocalHostPlugins2
|
|
146230
146903
|
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
146231
146904
|
const { validatePlan: validatePlan2 } = await init_plan().then(() => plan_exports);
|
|
146232
146905
|
const {
|
|
146233
146906
|
loadRun: loadRun2,
|
|
146234
|
-
resolveRunPath: resolveRunPath2
|
|
146235
|
-
validateRunLineage: validateRunLineage2
|
|
146907
|
+
resolveRunPath: resolveRunPath2
|
|
146236
146908
|
} = await init_run().then(() => run_exports);
|
|
146237
|
-
const plan = JSON.parse(await
|
|
146909
|
+
const plan = JSON.parse(await readFile56(planPath, "utf8"));
|
|
146238
146910
|
validatePlan2(plan);
|
|
146911
|
+
const updateRequested = args.includes("--update-local-hosts");
|
|
146239
146912
|
const resolvedRunPath = await resolveRunPath2(runPath);
|
|
146240
146913
|
const runRecord = await loadRun2(resolvedRunPath, {
|
|
146241
146914
|
requireDigest: true,
|
|
146242
146915
|
authorityPlanPath: planPath
|
|
146243
146916
|
});
|
|
146244
|
-
|
|
146245
|
-
|
|
146246
|
-
|
|
146247
|
-
|
|
146248
|
-
|
|
146249
|
-
|
|
146250
|
-
|
|
146251
|
-
|
|
146917
|
+
if (!updateRequested) {
|
|
146918
|
+
const { assertLocalFinishRun: assertLocalFinishRun2 } = await init_post_release_local().then(() => post_release_local_exports);
|
|
146919
|
+
await assertLocalFinishRun2({
|
|
146920
|
+
plan,
|
|
146921
|
+
planPath,
|
|
146922
|
+
runPath: resolvedRunPath,
|
|
146923
|
+
runRecord,
|
|
146924
|
+
production: Boolean(plan.production),
|
|
146925
|
+
root: resolve41(value("--root") ?? process.cwd())
|
|
146926
|
+
});
|
|
146927
|
+
}
|
|
146252
146928
|
const hostsIndex = args.indexOf("--hosts");
|
|
146253
146929
|
const rawHosts = hostsIndex !== -1 && args[hostsIndex + 1] && !args[hostsIndex + 1].startsWith("--") ? args[hostsIndex + 1] : "";
|
|
146254
146930
|
const selectedHosts = rawHosts.split(",").map((host) => host.trim()).filter(Boolean);
|
|
146255
146931
|
const result2 = updateRequested ? await updateLocalHostPlugins2({
|
|
146256
|
-
|
|
146932
|
+
planPath,
|
|
146933
|
+
runPath: resolvedRunPath,
|
|
146257
146934
|
root: resolve41(value("--root") ?? process.cwd()),
|
|
146258
146935
|
confirmPlanDigest: value("--confirm-plan"),
|
|
146259
146936
|
selectedHosts
|
|
146260
|
-
}) : derivePostReleaseChecklist2(plan
|
|
146937
|
+
}) : derivePostReleaseChecklist2(plan, {
|
|
146938
|
+
runPath: runRecord.command === "postverify" && runRecord.status === "DISTRIBUTED" ? resolvedRunPath : runRecord.command === "verify" ? resolvedRunPath : void 0,
|
|
146939
|
+
root: resolve41(value("--root") ?? process.cwd()),
|
|
146940
|
+
postVerifyComplete: runRecord.command === "postverify" && runRecord.status === "DISTRIBUTED"
|
|
146941
|
+
});
|
|
146261
146942
|
if (hasJson) {
|
|
146262
146943
|
console.log(JSON.stringify(result2, null, 2));
|
|
146263
146944
|
} else if (!updateRequested) {
|
|
146264
146945
|
console.log(`Post-release status: ${result2.status}`);
|
|
146265
146946
|
if (result2.merge.promptRequired) console.log("Ask whether the user wants to merge the remaining branch.");
|
|
146266
146947
|
else console.log("Branch advancement was already included in the release workflow; skip the merge question.");
|
|
146267
|
-
if (result2.localHostUpdate.
|
|
146948
|
+
if (result2.localHostUpdate.available === true && typeof result2.localHostUpdate.runPath === "string") {
|
|
146268
146949
|
console.log(`Ask whether to update local host plugins: ${result2.localHostUpdate.hosts.join(", ")}`);
|
|
146950
|
+
console.log(`Post-release command: release-skill post-release --plan ${planPath} --run ${result2.localHostUpdate.runPath}`);
|
|
146951
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
146952
|
+
} else {
|
|
146953
|
+
for (const step of result2.localHostUpdate.nextSteps ?? []) {
|
|
146954
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
146955
|
+
}
|
|
146269
146956
|
}
|
|
146270
146957
|
} else {
|
|
146271
146958
|
console.log(`Local host update: ${result2.status}`);
|
|
@@ -146281,9 +146968,15 @@ if (command === "post-release") {
|
|
|
146281
146968
|
console.log(JSON.stringify({
|
|
146282
146969
|
error: err.code ?? "POST_RELEASE_FAILED",
|
|
146283
146970
|
message: err.message,
|
|
146971
|
+
details: publicErrorDetails(err),
|
|
146284
146972
|
exitCode: err.exitCode ?? 1
|
|
146285
146973
|
}));
|
|
146286
|
-
} else
|
|
146974
|
+
} else {
|
|
146975
|
+
console.error(`Error: ${err.message}`);
|
|
146976
|
+
for (const step of err.details?.nextSteps ?? []) {
|
|
146977
|
+
console.error(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
146978
|
+
}
|
|
146979
|
+
}
|
|
146287
146980
|
await exitAfterFlush(err.exitCode ?? 1);
|
|
146288
146981
|
}
|
|
146289
146982
|
}
|
|
@@ -146330,9 +147023,9 @@ if (command === "verify") {
|
|
|
146330
147023
|
derivePostReleaseChecklist: derivePostReleaseChecklist2,
|
|
146331
147024
|
unavailablePostReleaseChecklist: unavailablePostReleaseChecklist2
|
|
146332
147025
|
} = await init_post_release_local().then(() => post_release_local_exports);
|
|
146333
|
-
const plan = JSON.parse(await
|
|
147026
|
+
const plan = JSON.parse(await readFile56(planPath, "utf8"));
|
|
146334
147027
|
try {
|
|
146335
|
-
result2.postRelease = derivePostReleaseChecklist2(plan);
|
|
147028
|
+
result2.postRelease = derivePostReleaseChecklist2(plan, { root, runPath: result2.runPath });
|
|
146336
147029
|
} catch (error) {
|
|
146337
147030
|
result2.postRelease = unavailablePostReleaseChecklist2(plan, error);
|
|
146338
147031
|
}
|
|
@@ -146357,8 +147050,14 @@ if (command === "verify") {
|
|
|
146357
147050
|
} else if (result2.postRelease?.merge.promptRequired) {
|
|
146358
147051
|
console.log("Post-release: ask whether to merge the remaining branch.");
|
|
146359
147052
|
}
|
|
146360
|
-
if (result2.postRelease?.localHostUpdate.
|
|
147053
|
+
if (result2.postRelease?.localHostUpdate?.available === true && typeof result2.postRelease.localHostUpdate.runPath === "string") {
|
|
146361
147054
|
console.log(`Post-release: ask whether to update local host plugins (${result2.postRelease.localHostUpdate.hosts.join(", ")}).`);
|
|
147055
|
+
console.log(`Post-release command: release-skill post-release --plan ${planPath} --run ${result2.postRelease.localHostUpdate.runPath}`);
|
|
147056
|
+
console.log("Choose --hosts before adding --update-local-hosts to perform a local update.");
|
|
147057
|
+
} else {
|
|
147058
|
+
for (const step of result2.postRelease?.localHostUpdate?.nextSteps ?? []) {
|
|
147059
|
+
console.log(`Next [${step.code}] ${step.message} (${step.argv.join(" ")})`);
|
|
147060
|
+
}
|
|
146362
147061
|
}
|
|
146363
147062
|
}
|
|
146364
147063
|
await exitAfterFlush(result2.status === "VERIFIED" ? 0 : 1);
|
|
@@ -146367,6 +147066,7 @@ if (command === "verify") {
|
|
|
146367
147066
|
const errOutput = {
|
|
146368
147067
|
error: err.code ?? "UNKNOWN_ERROR",
|
|
146369
147068
|
message: err.message,
|
|
147069
|
+
details: err.details ?? {},
|
|
146370
147070
|
exitCode: err.exitCode ?? 1
|
|
146371
147071
|
};
|
|
146372
147072
|
console.log(JSON.stringify(errOutput));
|