release-skill 0.6.0 → 0.6.2
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 +31 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +12 -8
- package/README.zh-CN.md +12 -8
- 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 +1028 -423
- package/adapters/claude/schemas/release-plan.schema.json +9 -0
- package/adapters/claude/schemas/release-project.schema.json +8 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1028 -423
- package/adapters/codex/schemas/release-plan.schema.json +9 -0
- package/adapters/codex/schemas/release-project.schema.json +8 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +1028 -423
- package/adapters/kimi/schemas/release-plan.schema.json +9 -0
- package/adapters/kimi/schemas/release-project.schema.json +8 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +1028 -423
- package/adapters/workbuddy/schemas/release-plan.schema.json +9 -0
- package/adapters/workbuddy/schemas/release-project.schema.json +8 -0
- package/bin/release-skill-cli.mjs +11 -0
- package/bin/release-skill.bundle.mjs +1028 -423
- package/package.json +1 -1
- package/references/05-evidence-and-errors.md +1 -0
- package/schemas/release-plan.schema.json +9 -0
- package/schemas/release-project.schema.json +8 -0
- package/scripts/build-bundle.mjs +11 -2
- package/scripts/sync-public-files.mjs +4 -0
- package/src/commands/lineage.mjs +101 -32
- package/src/commands/prepare.mjs +273 -9
- package/src/commands/publish.mjs +10 -1
- package/src/commands/verify.mjs +22 -0
- package/src/core/bundle-freshness.mjs +236 -0
- package/src/core/errors.mjs +2 -0
- package/src/core/frozen-marker.mjs +97 -0
- package/src/core/hooks.mjs +12 -1
- package/src/core/skill-resource-closure.mjs +240 -10
- package/src/platforms/registry.mjs +12 -0
|
@@ -9,7 +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.6.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.6.2"});
|
|
13
|
+
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
+
const __bundleSourceDigest = "12dcb7942e6587f1321c3f81625b0bc3f1dd64afe978ddf8084bf1a5824de23a";
|
|
13
15
|
|
|
14
16
|
var __create = Object.create;
|
|
15
17
|
var __defProp = Object.defineProperty;
|
|
@@ -175,6 +177,7 @@ __export(errors_exports, {
|
|
|
175
177
|
AUTH_MISSING: () => AUTH_MISSING,
|
|
176
178
|
BASELINE_CHANGED: () => BASELINE_CHANGED,
|
|
177
179
|
BASE_UNAVAILABLE: () => BASE_UNAVAILABLE,
|
|
180
|
+
BUNDLE_STALE: () => BUNDLE_STALE,
|
|
178
181
|
CONFIG_EXISTS: () => CONFIG_EXISTS,
|
|
179
182
|
CONFIG_INVALID: () => CONFIG_INVALID,
|
|
180
183
|
CONFIG_MISSING: () => CONFIG_MISSING,
|
|
@@ -221,7 +224,7 @@ __export(errors_exports, {
|
|
|
221
224
|
function registerPathRedactor(fn) {
|
|
222
225
|
if (typeof fn === "function") redactSensitivePaths2 = fn;
|
|
223
226
|
}
|
|
224
|
-
var redactSensitivePaths2, EXIT_CODE_MAP, CONFIG_INVALID, BASELINE_CHANGED, DIRTY_SCOPE_CONFLICT, GATE_FAILED, AUTH_MISSING, REMOTE_CONFLICT, HOOK_TIMEOUT, PARTIAL_RELEASE, POST_PUBLISH_VERIFY_FAILED, INVALID_STATE_TRANSITION, PLAN_DIGEST_MISMATCH, SECRET_DETECTED, PUBLIC_PATH_FORBIDDEN, STALE_BUILD_ARTIFACT, MISSING_PARAMETERS, PUBLIC_FILE_MISSING, SNAPSHOT_FIDELITY_FAILED, FORBIDDEN_CONTENT_DETECTED, PATH_UNSAFE, STRUCTURE_INVALID, LOCK_MIGRATION_REQUIRED, ARTIFACT_POLICY_INVALID, BASE_UNAVAILABLE, PRODUCER_NONDETERMINISTIC, PRODUCER_SCOPE_VIOLATION, ADOPTION_AMBIGUOUS, PLAN_STALE, SENSITIVE_CONFLICT, TRANSACTION_INCOMPLETE, SAFE_WRITE_UNAVAILABLE, SETUP_DIGEST_MISMATCH, CONFIG_EXISTS, RELEASE_DOCS_INVALID, RELEASE_DOCS_TRANSLATION_MISSING, RELEASE_DOCS_CONFLICT, RELEASE_DOCS_REFRESH_STALE, RELEASE_DOCS_STALE, CONSUMER_VERIFICATION_DEFERRED, CONFIG_MISSING, REMOTE_UNAVAILABLE, REF_MISSING, NOT_DEFAULT, CONTENT_MISMATCH, DIRTY_SOURCE_INPUT, ReleaseError, ALL_ERROR_CODES;
|
|
227
|
+
var redactSensitivePaths2, EXIT_CODE_MAP, CONFIG_INVALID, BASELINE_CHANGED, DIRTY_SCOPE_CONFLICT, GATE_FAILED, AUTH_MISSING, REMOTE_CONFLICT, HOOK_TIMEOUT, PARTIAL_RELEASE, POST_PUBLISH_VERIFY_FAILED, INVALID_STATE_TRANSITION, PLAN_DIGEST_MISMATCH, SECRET_DETECTED, PUBLIC_PATH_FORBIDDEN, STALE_BUILD_ARTIFACT, MISSING_PARAMETERS, PUBLIC_FILE_MISSING, SNAPSHOT_FIDELITY_FAILED, FORBIDDEN_CONTENT_DETECTED, PATH_UNSAFE, STRUCTURE_INVALID, LOCK_MIGRATION_REQUIRED, ARTIFACT_POLICY_INVALID, BASE_UNAVAILABLE, PRODUCER_NONDETERMINISTIC, PRODUCER_SCOPE_VIOLATION, ADOPTION_AMBIGUOUS, PLAN_STALE, SENSITIVE_CONFLICT, TRANSACTION_INCOMPLETE, SAFE_WRITE_UNAVAILABLE, SETUP_DIGEST_MISMATCH, CONFIG_EXISTS, RELEASE_DOCS_INVALID, RELEASE_DOCS_TRANSLATION_MISSING, RELEASE_DOCS_CONFLICT, RELEASE_DOCS_REFRESH_STALE, RELEASE_DOCS_STALE, CONSUMER_VERIFICATION_DEFERRED, CONFIG_MISSING, REMOTE_UNAVAILABLE, REF_MISSING, NOT_DEFAULT, CONTENT_MISMATCH, DIRTY_SOURCE_INPUT, BUNDLE_STALE, ReleaseError, ALL_ERROR_CODES;
|
|
225
228
|
var init_errors = __esm({
|
|
226
229
|
"src/core/errors.mjs"() {
|
|
227
230
|
redactSensitivePaths2 = /* @__PURE__ */ __name((value) => value, "redactSensitivePaths");
|
|
@@ -275,7 +278,8 @@ var init_errors = __esm({
|
|
|
275
278
|
REF_MISSING: 50,
|
|
276
279
|
NOT_DEFAULT: 51,
|
|
277
280
|
CONTENT_MISMATCH: 52,
|
|
278
|
-
DIRTY_SOURCE_INPUT: 53
|
|
281
|
+
DIRTY_SOURCE_INPUT: 53,
|
|
282
|
+
BUNDLE_STALE: 54
|
|
279
283
|
});
|
|
280
284
|
CONFIG_INVALID = "CONFIG_INVALID";
|
|
281
285
|
BASELINE_CHANGED = "BASELINE_CHANGED";
|
|
@@ -321,6 +325,7 @@ var init_errors = __esm({
|
|
|
321
325
|
NOT_DEFAULT = "NOT_DEFAULT";
|
|
322
326
|
CONTENT_MISMATCH = "CONTENT_MISMATCH";
|
|
323
327
|
DIRTY_SOURCE_INPUT = "DIRTY_SOURCE_INPUT";
|
|
328
|
+
BUNDLE_STALE = "BUNDLE_STALE";
|
|
324
329
|
ReleaseError = class _ReleaseError extends Error {
|
|
325
330
|
static {
|
|
326
331
|
__name(this, "ReleaseError");
|
|
@@ -21718,7 +21723,7 @@ var require_cjs = __commonJS({
|
|
|
21718
21723
|
var require_lib2 = __commonJS({
|
|
21719
21724
|
"../../node_modules/.pnpm/write-file-atomic@5.0.1/node_modules/write-file-atomic/lib/index.js"(exports, module) {
|
|
21720
21725
|
"use strict";
|
|
21721
|
-
module.exports =
|
|
21726
|
+
module.exports = writeFile14;
|
|
21722
21727
|
module.exports.sync = writeFileSync2;
|
|
21723
21728
|
module.exports._getTmpname = getTmpname;
|
|
21724
21729
|
module.exports._cleanupOnExit = cleanupOnExit;
|
|
@@ -21848,7 +21853,7 @@ var require_lib2 = __commonJS({
|
|
|
21848
21853
|
}
|
|
21849
21854
|
}
|
|
21850
21855
|
__name(writeFileAsync, "writeFileAsync");
|
|
21851
|
-
async function
|
|
21856
|
+
async function writeFile14(filename, data, options, callback) {
|
|
21852
21857
|
if (options instanceof Function) {
|
|
21853
21858
|
callback = options;
|
|
21854
21859
|
options = {};
|
|
@@ -21864,7 +21869,7 @@ var require_lib2 = __commonJS({
|
|
|
21864
21869
|
}
|
|
21865
21870
|
return promise;
|
|
21866
21871
|
}
|
|
21867
|
-
__name(
|
|
21872
|
+
__name(writeFile14, "writeFile");
|
|
21868
21873
|
function writeFileSync2(filename, data, options) {
|
|
21869
21874
|
if (typeof options === "string") {
|
|
21870
21875
|
options = { encoding: options };
|
|
@@ -22977,16 +22982,16 @@ var require_windows = __commonJS({
|
|
|
22977
22982
|
return false;
|
|
22978
22983
|
}
|
|
22979
22984
|
__name(checkPathExt, "checkPathExt");
|
|
22980
|
-
function checkStat(
|
|
22981
|
-
if (!
|
|
22985
|
+
function checkStat(stat10, path15, options) {
|
|
22986
|
+
if (!stat10.isSymbolicLink() && !stat10.isFile()) {
|
|
22982
22987
|
return false;
|
|
22983
22988
|
}
|
|
22984
22989
|
return checkPathExt(path15, options);
|
|
22985
22990
|
}
|
|
22986
22991
|
__name(checkStat, "checkStat");
|
|
22987
22992
|
function isexe(path15, options, cb) {
|
|
22988
|
-
fs.stat(path15, function(er,
|
|
22989
|
-
cb(er, er ? false : checkStat(
|
|
22993
|
+
fs.stat(path15, function(er, stat10) {
|
|
22994
|
+
cb(er, er ? false : checkStat(stat10, path15, options));
|
|
22990
22995
|
});
|
|
22991
22996
|
}
|
|
22992
22997
|
__name(isexe, "isexe");
|
|
@@ -23004,8 +23009,8 @@ var require_mode = __commonJS({
|
|
|
23004
23009
|
isexe.sync = sync;
|
|
23005
23010
|
var fs = __require("fs");
|
|
23006
23011
|
function isexe(path15, options, cb) {
|
|
23007
|
-
fs.stat(path15, function(er,
|
|
23008
|
-
cb(er, er ? false : checkStat(
|
|
23012
|
+
fs.stat(path15, function(er, stat10) {
|
|
23013
|
+
cb(er, er ? false : checkStat(stat10, options));
|
|
23009
23014
|
});
|
|
23010
23015
|
}
|
|
23011
23016
|
__name(isexe, "isexe");
|
|
@@ -23013,14 +23018,14 @@ var require_mode = __commonJS({
|
|
|
23013
23018
|
return checkStat(fs.statSync(path15), options);
|
|
23014
23019
|
}
|
|
23015
23020
|
__name(sync, "sync");
|
|
23016
|
-
function checkStat(
|
|
23017
|
-
return
|
|
23021
|
+
function checkStat(stat10, options) {
|
|
23022
|
+
return stat10.isFile() && checkMode(stat10, options);
|
|
23018
23023
|
}
|
|
23019
23024
|
__name(checkStat, "checkStat");
|
|
23020
|
-
function checkMode(
|
|
23021
|
-
var mod =
|
|
23022
|
-
var uid =
|
|
23023
|
-
var gid =
|
|
23025
|
+
function checkMode(stat10, options) {
|
|
23026
|
+
var mod = stat10.mode;
|
|
23027
|
+
var uid = stat10.uid;
|
|
23028
|
+
var gid = stat10.gid;
|
|
23024
23029
|
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
23025
23030
|
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
23026
23031
|
var u = parseInt("100", 8);
|
|
@@ -23544,13 +23549,13 @@ var require_cross_spawn = __commonJS({
|
|
|
23544
23549
|
var cp2 = __require("child_process");
|
|
23545
23550
|
var parse2 = require_parse();
|
|
23546
23551
|
var enoent = require_enoent();
|
|
23547
|
-
function
|
|
23552
|
+
function spawn5(command2, args2, options) {
|
|
23548
23553
|
const parsed = parse2(command2, args2, options);
|
|
23549
23554
|
const spawned = cp2.spawn(parsed.command, parsed.args, parsed.options);
|
|
23550
23555
|
enoent.hookChildProcess(spawned, parsed);
|
|
23551
23556
|
return spawned;
|
|
23552
23557
|
}
|
|
23553
|
-
__name(
|
|
23558
|
+
__name(spawn5, "spawn");
|
|
23554
23559
|
function spawnSync2(command2, args2, options) {
|
|
23555
23560
|
const parsed = parse2(command2, args2, options);
|
|
23556
23561
|
const result = cp2.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
@@ -23558,8 +23563,8 @@ var require_cross_spawn = __commonJS({
|
|
|
23558
23563
|
return result;
|
|
23559
23564
|
}
|
|
23560
23565
|
__name(spawnSync2, "spawnSync");
|
|
23561
|
-
module.exports =
|
|
23562
|
-
module.exports.spawn =
|
|
23566
|
+
module.exports = spawn5;
|
|
23567
|
+
module.exports.spawn = spawn5;
|
|
23563
23568
|
module.exports.sync = spawnSync2;
|
|
23564
23569
|
module.exports._parse = parse2;
|
|
23565
23570
|
module.exports._enoent = enoent;
|
|
@@ -25725,8 +25730,8 @@ var require_graceful_fs = __commonJS({
|
|
|
25725
25730
|
fs2.createReadStream = createReadStream2;
|
|
25726
25731
|
fs2.createWriteStream = createWriteStream;
|
|
25727
25732
|
var fs$readFile = fs2.readFile;
|
|
25728
|
-
fs2.readFile =
|
|
25729
|
-
function
|
|
25733
|
+
fs2.readFile = readFile42;
|
|
25734
|
+
function readFile42(path15, options, cb) {
|
|
25730
25735
|
if (typeof options === "function")
|
|
25731
25736
|
cb = options, options = null;
|
|
25732
25737
|
return go$readFile(path15, options, cb);
|
|
@@ -25742,10 +25747,10 @@ var require_graceful_fs = __commonJS({
|
|
|
25742
25747
|
}
|
|
25743
25748
|
__name(go$readFile, "go$readFile");
|
|
25744
25749
|
}
|
|
25745
|
-
__name(
|
|
25750
|
+
__name(readFile42, "readFile");
|
|
25746
25751
|
var fs$writeFile = fs2.writeFile;
|
|
25747
|
-
fs2.writeFile =
|
|
25748
|
-
function
|
|
25752
|
+
fs2.writeFile = writeFile14;
|
|
25753
|
+
function writeFile14(path15, data, options, cb) {
|
|
25749
25754
|
if (typeof options === "function")
|
|
25750
25755
|
cb = options, options = null;
|
|
25751
25756
|
return go$writeFile(path15, data, options, cb);
|
|
@@ -25761,7 +25766,7 @@ var require_graceful_fs = __commonJS({
|
|
|
25761
25766
|
}
|
|
25762
25767
|
__name(go$writeFile, "go$writeFile");
|
|
25763
25768
|
}
|
|
25764
|
-
__name(
|
|
25769
|
+
__name(writeFile14, "writeFile");
|
|
25765
25770
|
var fs$appendFile = fs2.appendFile;
|
|
25766
25771
|
if (fs$appendFile)
|
|
25767
25772
|
fs2.appendFile = appendFile;
|
|
@@ -25805,9 +25810,9 @@ var require_graceful_fs = __commonJS({
|
|
|
25805
25810
|
}
|
|
25806
25811
|
__name(copyFile, "copyFile");
|
|
25807
25812
|
var fs$readdir = fs2.readdir;
|
|
25808
|
-
fs2.readdir =
|
|
25813
|
+
fs2.readdir = readdir21;
|
|
25809
25814
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
25810
|
-
function
|
|
25815
|
+
function readdir21(path15, options, cb) {
|
|
25811
25816
|
if (typeof options === "function")
|
|
25812
25817
|
cb = options, options = null;
|
|
25813
25818
|
var go$readdir = noReaddirOptionVersions.test(process.version) ? /* @__PURE__ */ __name(function go$readdir2(path16, options2, cb2, startTime) {
|
|
@@ -25846,7 +25851,7 @@ var require_graceful_fs = __commonJS({
|
|
|
25846
25851
|
}
|
|
25847
25852
|
__name(fs$readdirCallback, "fs$readdirCallback");
|
|
25848
25853
|
}
|
|
25849
|
-
__name(
|
|
25854
|
+
__name(readdir21, "readdir");
|
|
25850
25855
|
if (process.version.substr(0, 4) === "v0.8") {
|
|
25851
25856
|
var legStreams = legacy(fs2);
|
|
25852
25857
|
ReadStream = legStreams.ReadStream;
|
|
@@ -27559,7 +27564,7 @@ var require_lib10 = __commonJS({
|
|
|
27559
27564
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27560
27565
|
exports.createShortHash = createShortHash;
|
|
27561
27566
|
exports.createHexHash = createHexHash;
|
|
27562
|
-
exports.createHash =
|
|
27567
|
+
exports.createHash = createHash18;
|
|
27563
27568
|
exports.createHashFromMultipleFiles = createHashFromMultipleFiles;
|
|
27564
27569
|
exports.createHashFromFile = createHashFromFile;
|
|
27565
27570
|
exports.createHexHashFromFile = createHexHashFromFile;
|
|
@@ -27576,20 +27581,20 @@ var require_lib10 = __commonJS({
|
|
|
27576
27581
|
return crypto.hash("sha256", input, "hex");
|
|
27577
27582
|
}
|
|
27578
27583
|
__name(createHexHash, "createHexHash");
|
|
27579
|
-
function
|
|
27584
|
+
function createHash18(input) {
|
|
27580
27585
|
return `sha256-${crypto.hash("sha256", input, "base64")}`;
|
|
27581
27586
|
}
|
|
27582
|
-
__name(
|
|
27587
|
+
__name(createHash18, "createHash");
|
|
27583
27588
|
async function createHashFromMultipleFiles(files) {
|
|
27584
27589
|
if (files.length === 1) {
|
|
27585
27590
|
return createHashFromFile(files[0]);
|
|
27586
27591
|
}
|
|
27587
27592
|
const hashes = await Promise.all(files.map(createHashFromFile));
|
|
27588
|
-
return
|
|
27593
|
+
return createHash18(hashes.join(","));
|
|
27589
27594
|
}
|
|
27590
27595
|
__name(createHashFromMultipleFiles, "createHashFromMultipleFiles");
|
|
27591
27596
|
async function createHashFromFile(file) {
|
|
27592
|
-
return
|
|
27597
|
+
return createHash18(await readNormalizedFile(file));
|
|
27593
27598
|
}
|
|
27594
27599
|
__name(createHashFromFile, "createHashFromFile");
|
|
27595
27600
|
async function createHexHashFromFile(file) {
|
|
@@ -32213,7 +32218,7 @@ var init_report = __esm({
|
|
|
32213
32218
|
init_closure();
|
|
32214
32219
|
init_errors3();
|
|
32215
32220
|
init_validation();
|
|
32216
|
-
PACKAGE_META = Object.freeze({ "name": "release-skill", "version": "0.6.
|
|
32221
|
+
PACKAGE_META = Object.freeze({ "name": "release-skill", "version": "0.6.2" });
|
|
32217
32222
|
REPORT_RENDERER_VERSION = PACKAGE_META.version;
|
|
32218
32223
|
SUPPORTED_REPORT_LOCALES = Object.freeze(["zh-CN", "en-US"]);
|
|
32219
32224
|
EXECUTION_STATUSES = Object.freeze([
|
|
@@ -33153,10 +33158,10 @@ function lexicalPath(resource, code) {
|
|
|
33153
33158
|
}
|
|
33154
33159
|
return path15;
|
|
33155
33160
|
}
|
|
33156
|
-
function assertStat(
|
|
33157
|
-
if (
|
|
33158
|
-
if (!
|
|
33159
|
-
if (
|
|
33161
|
+
function assertStat(stat10, resource, code) {
|
|
33162
|
+
if (stat10.isSymbolicLink()) fail(code, resource, "SYMLINK");
|
|
33163
|
+
if (!stat10.isFile()) fail(code, resource, "NOT_REGULAR_FILE");
|
|
33164
|
+
if (stat10.nlink !== 1) fail(code, resource, "UNEXPECTED_HARDLINK_COUNT");
|
|
33160
33165
|
}
|
|
33161
33166
|
function assertPhysicalContainment(physicalRoot, physicalPath, resource, code) {
|
|
33162
33167
|
const rel = relative(physicalRoot, physicalPath);
|
|
@@ -33190,13 +33195,13 @@ function readTrustedPackageResourceSync(resource, { code = CONFIG_INVALID } = {}
|
|
|
33190
33195
|
const classification = classifyPathInput(resource, process.platform);
|
|
33191
33196
|
if (!classification.ok) fail(code, String(resource), "INVALID_RESOURCE_PATH");
|
|
33192
33197
|
const path15 = lexicalPath(resource, code);
|
|
33193
|
-
let
|
|
33198
|
+
let stat10;
|
|
33194
33199
|
try {
|
|
33195
|
-
|
|
33200
|
+
stat10 = lstatSync2(path15);
|
|
33196
33201
|
} catch {
|
|
33197
33202
|
fail(code, resource, "MISSING");
|
|
33198
33203
|
}
|
|
33199
|
-
assertStat(
|
|
33204
|
+
assertStat(stat10, resource, code);
|
|
33200
33205
|
let physicalRoot;
|
|
33201
33206
|
let physicalPath;
|
|
33202
33207
|
try {
|
|
@@ -33219,13 +33224,13 @@ async function readTrustedPackageResource(resource, { code = CONFIG_INVALID } =
|
|
|
33219
33224
|
} catch (cause) {
|
|
33220
33225
|
mapHarnessError(cause, resource, code);
|
|
33221
33226
|
}
|
|
33222
|
-
let
|
|
33227
|
+
let stat10;
|
|
33223
33228
|
try {
|
|
33224
|
-
|
|
33229
|
+
stat10 = await lstat8(target);
|
|
33225
33230
|
} catch {
|
|
33226
33231
|
fail(code, resource, "MISSING");
|
|
33227
33232
|
}
|
|
33228
|
-
assertStat(
|
|
33233
|
+
assertStat(stat10, resource, code);
|
|
33229
33234
|
try {
|
|
33230
33235
|
return await readFileContained(PKG_ROOT, resource);
|
|
33231
33236
|
} catch (cause) {
|
|
@@ -33465,14 +33470,14 @@ async function assertNoSymlinkAncestors(directory) {
|
|
|
33465
33470
|
let current = join2(parsed.root, ...segments.slice(0, firstChecked));
|
|
33466
33471
|
for (const segment of segments.slice(firstChecked)) {
|
|
33467
33472
|
current = join2(current, segment);
|
|
33468
|
-
let
|
|
33473
|
+
let stat10;
|
|
33469
33474
|
try {
|
|
33470
|
-
|
|
33475
|
+
stat10 = await lstat9(current);
|
|
33471
33476
|
} catch (error) {
|
|
33472
33477
|
if (error.code === "ENOENT") continue;
|
|
33473
33478
|
throw error;
|
|
33474
33479
|
}
|
|
33475
|
-
if (
|
|
33480
|
+
if (stat10.isSymbolicLink() || !stat10.isDirectory()) {
|
|
33476
33481
|
throw new ReleaseError(
|
|
33477
33482
|
GATE_FAILED,
|
|
33478
33483
|
"release authority path contains a symlink or non-directory ancestor",
|
|
@@ -33492,8 +33497,8 @@ async function assertAuthorityFileTarget(filePath) {
|
|
|
33492
33497
|
const absolute = resolve3(filePath);
|
|
33493
33498
|
await prepareAuthorityDirectory(dirname3(absolute));
|
|
33494
33499
|
try {
|
|
33495
|
-
const
|
|
33496
|
-
if (
|
|
33500
|
+
const stat10 = await lstat9(absolute);
|
|
33501
|
+
if (stat10.isSymbolicLink() || !stat10.isFile()) {
|
|
33497
33502
|
throw new ReleaseError(
|
|
33498
33503
|
GATE_FAILED,
|
|
33499
33504
|
"release authority target must be a regular file, never a symlink or special file",
|
|
@@ -35538,6 +35543,9 @@ function assertRegistry(registry = PLATFORMS) {
|
|
|
35538
35543
|
if (!platform.buildAdapter || typeof platform.buildAdapter !== "object") {
|
|
35539
35544
|
throw new Error(`platform registry: ${label} buildAdapter must be an object`);
|
|
35540
35545
|
}
|
|
35546
|
+
if (typeof platform.buildAdapter.name !== "string" || platform.buildAdapter.name.length === 0) {
|
|
35547
|
+
throw new Error(`platform registry: ${label} buildAdapter needs a non-empty name (its adapter directory name)`);
|
|
35548
|
+
}
|
|
35541
35549
|
if (!VALID_LIST_OUTPUTS.has(platform.jsonProtocol?.listOutput)) {
|
|
35542
35550
|
throw new Error(`platform registry: ${label} has illegal jsonProtocol.listOutput "${platform.jsonProtocol?.listOutput}"`);
|
|
35543
35551
|
}
|
|
@@ -35725,6 +35733,9 @@ var init_registry2 = __esm({
|
|
|
35725
35733
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
35726
35734
|
skillRendering: Object.freeze({ mode: "verbatim", preamble: null, placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35727
35735
|
buildAdapter: Object.freeze({
|
|
35736
|
+
// D6: explicit adapter directory name (adapters/claude/); assertRegistry
|
|
35737
|
+
// requires this on every platform.
|
|
35738
|
+
name: "claude",
|
|
35728
35739
|
pluginDirName: ".claude-plugin",
|
|
35729
35740
|
templateFileName: "plugin.json",
|
|
35730
35741
|
marketplaceFileName: "marketplace.json",
|
|
@@ -35782,6 +35793,8 @@ var init_registry2 = __esm({
|
|
|
35782
35793
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
35783
35794
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "codex", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35784
35795
|
buildAdapter: Object.freeze({
|
|
35796
|
+
// D6: explicit adapter directory name (adapters/codex/).
|
|
35797
|
+
name: "codex",
|
|
35785
35798
|
pluginDirName: ".codex-plugin",
|
|
35786
35799
|
templateFileName: "plugin.json",
|
|
35787
35800
|
marketplaceFileName: null,
|
|
@@ -35838,6 +35851,8 @@ var init_registry2 = __esm({
|
|
|
35838
35851
|
schemaRequiredFields: Object.freeze(["plugin", "entrySkill"]),
|
|
35839
35852
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "kimi", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35840
35853
|
buildAdapter: Object.freeze({
|
|
35854
|
+
// D6: explicit adapter directory name (adapters/kimi/).
|
|
35855
|
+
name: "kimi",
|
|
35841
35856
|
pluginDirName: ".kimi-plugin",
|
|
35842
35857
|
templateFileName: "plugin.json",
|
|
35843
35858
|
marketplaceFileName: null,
|
|
@@ -37362,8 +37377,8 @@ function safeRelative(root, path15) {
|
|
|
37362
37377
|
return rel || ".";
|
|
37363
37378
|
}
|
|
37364
37379
|
async function readJsonBounded(path15, label) {
|
|
37365
|
-
const
|
|
37366
|
-
if (!
|
|
37380
|
+
const stat10 = await lstat11(path15);
|
|
37381
|
+
if (!stat10.isFile() || stat10.isSymbolicLink() || stat10.size > MAX_JSON_BYTES) {
|
|
37367
37382
|
throw setupError(CONFIG_INVALID, `${label} must be a regular JSON file no larger than 1 MiB`, { path: path15 });
|
|
37368
37383
|
}
|
|
37369
37384
|
try {
|
|
@@ -37625,14 +37640,14 @@ async function pathIsGitIgnored(unitAbsDir, target) {
|
|
|
37625
37640
|
async function classifyNpmEntryCandidate(unitAbsDir, target, trackedFiles) {
|
|
37626
37641
|
const tracked = trackedFiles.includes(target);
|
|
37627
37642
|
const ignored = await pathIsGitIgnored(unitAbsDir, target);
|
|
37628
|
-
let
|
|
37643
|
+
let stat10 = null;
|
|
37629
37644
|
try {
|
|
37630
|
-
|
|
37645
|
+
stat10 = await lstat11(join8(unitAbsDir, target));
|
|
37631
37646
|
} catch (error) {
|
|
37632
37647
|
if (error.code !== "ENOENT") throw error;
|
|
37633
37648
|
}
|
|
37634
|
-
const exists =
|
|
37635
|
-
const regular =
|
|
37649
|
+
const exists = stat10 !== null;
|
|
37650
|
+
const regular = stat10?.isFile() === true && stat10?.isSymbolicLink() !== true;
|
|
37636
37651
|
const state = exists && !regular ? "NON_REGULAR" : exists && tracked ? "TRACKED_PRESENT" : exists && ignored ? "IGNORED_PRESENT" : exists ? "UNTRACKED_PRESENT" : ignored ? "IGNORED_MISSING" : "MISSING";
|
|
37637
37652
|
return { path: target, state, exists, tracked, ignored };
|
|
37638
37653
|
}
|
|
@@ -38524,9 +38539,9 @@ async function setupProject({ root, answersPath, write = false, confirmSetup, fa
|
|
|
38524
38539
|
const configPath = join8(rootReal, ".release-skill", "project.yaml");
|
|
38525
38540
|
let configExists = false;
|
|
38526
38541
|
try {
|
|
38527
|
-
const
|
|
38542
|
+
const stat10 = await lstat11(configPath);
|
|
38528
38543
|
configExists = true;
|
|
38529
|
-
if (!
|
|
38544
|
+
if (!stat10.isFile() || stat10.isSymbolicLink()) {
|
|
38530
38545
|
throw setupError(CONFIG_INVALID, "existing project.yaml must be a regular file");
|
|
38531
38546
|
}
|
|
38532
38547
|
} catch (error) {
|
|
@@ -39064,9 +39079,9 @@ async function assertSafeDirectoryPath({
|
|
|
39064
39079
|
let cursor = workspaceRoot;
|
|
39065
39080
|
for (const segment of rel.split(sep3).filter(Boolean)) {
|
|
39066
39081
|
cursor = join9(cursor, segment);
|
|
39067
|
-
let
|
|
39082
|
+
let stat10;
|
|
39068
39083
|
try {
|
|
39069
|
-
|
|
39084
|
+
stat10 = await lstat12(cursor);
|
|
39070
39085
|
} catch (error) {
|
|
39071
39086
|
failConfig(`cannot inspect public surface scan root "${configuredRoot}"`, {
|
|
39072
39087
|
reason: "PUBLIC_SURFACE_SCAN_ROOT_UNSAFE",
|
|
@@ -39075,7 +39090,7 @@ async function assertSafeDirectoryPath({
|
|
|
39075
39090
|
cause: error.code ?? "UNKNOWN"
|
|
39076
39091
|
});
|
|
39077
39092
|
}
|
|
39078
|
-
if (
|
|
39093
|
+
if (stat10.isSymbolicLink() || !stat10.isDirectory()) {
|
|
39079
39094
|
failConfig(`public surface scan root or ancestor is not a physical directory: "${configuredRoot}"`, {
|
|
39080
39095
|
reason: "PUBLIC_SURFACE_SCAN_ROOT_UNSAFE",
|
|
39081
39096
|
unitId,
|
|
@@ -39462,24 +39477,24 @@ async function computeWorkspaceDigest(root) {
|
|
|
39462
39477
|
`Refusing to read path outside repository root: ${relPath} resolves to ${absPath}`
|
|
39463
39478
|
);
|
|
39464
39479
|
}
|
|
39465
|
-
const
|
|
39480
|
+
const stat10 = await lstat13(absPath);
|
|
39466
39481
|
let type;
|
|
39467
|
-
if (
|
|
39482
|
+
if (stat10.isSymbolicLink()) {
|
|
39468
39483
|
type = "symlink";
|
|
39469
|
-
} else if (
|
|
39484
|
+
} else if (stat10.isDirectory()) {
|
|
39470
39485
|
type = "dir";
|
|
39471
|
-
} else if (
|
|
39486
|
+
} else if (stat10.isFile()) {
|
|
39472
39487
|
type = "file";
|
|
39473
39488
|
} else {
|
|
39474
39489
|
type = "other";
|
|
39475
39490
|
}
|
|
39476
39491
|
const typeMarker = `TYPE:${type}`;
|
|
39477
39492
|
let content;
|
|
39478
|
-
if (
|
|
39493
|
+
if (stat10.isFile()) {
|
|
39479
39494
|
const handle = await open6(absPath, fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW);
|
|
39480
39495
|
try {
|
|
39481
39496
|
const fdStat = await handle.stat();
|
|
39482
|
-
if (fdStat.ino !==
|
|
39497
|
+
if (fdStat.ino !== stat10.ino) {
|
|
39483
39498
|
throw new Error(
|
|
39484
39499
|
`Race detected: inode changed for ${relPath} between lstat and read`
|
|
39485
39500
|
);
|
|
@@ -39494,7 +39509,7 @@ async function computeWorkspaceDigest(root) {
|
|
|
39494
39509
|
} finally {
|
|
39495
39510
|
await handle.close();
|
|
39496
39511
|
}
|
|
39497
|
-
} else if (
|
|
39512
|
+
} else if (stat10.isSymbolicLink()) {
|
|
39498
39513
|
content = Buffer.from(await readlink(absPath), "utf8");
|
|
39499
39514
|
} else {
|
|
39500
39515
|
content = Buffer.alloc(0);
|
|
@@ -40908,7 +40923,7 @@ function validateHook(hook) {
|
|
|
40908
40923
|
if (!hook || typeof hook !== "object" || Array.isArray(hook)) {
|
|
40909
40924
|
throw new ReleaseError("INVALID_HOOK", "hook must be a non-null object");
|
|
40910
40925
|
}
|
|
40911
|
-
const { command: command2, cwd, timeoutMs, envAllowlist, cacheable, cacheInputs } = hook;
|
|
40926
|
+
const { command: command2, cwd, timeoutMs, envAllowlist, cacheable, cacheInputs, testSelection } = hook;
|
|
40912
40927
|
if (!Array.isArray(command2) || command2.length === 0) {
|
|
40913
40928
|
throw new ReleaseError("INVALID_HOOK", "hook.command must be a non-empty array");
|
|
40914
40929
|
}
|
|
@@ -40963,6 +40978,12 @@ function validateHook(hook) {
|
|
|
40963
40978
|
"hook.cacheable=true requires a non-empty hook.cacheInputs"
|
|
40964
40979
|
);
|
|
40965
40980
|
}
|
|
40981
|
+
if (testSelection !== void 0 && testSelection !== "full" && testSelection !== "incremental") {
|
|
40982
|
+
throw new ReleaseError(
|
|
40983
|
+
"INVALID_HOOK",
|
|
40984
|
+
'hook.testSelection must be "full" or "incremental" when provided'
|
|
40985
|
+
);
|
|
40986
|
+
}
|
|
40966
40987
|
}
|
|
40967
40988
|
function buildFilteredEnv(envAllowlist, contextEnv) {
|
|
40968
40989
|
const env = {};
|
|
@@ -41279,10 +41300,10 @@ async function resolveSafeCwd(executionRoot, cwd, gate) {
|
|
|
41279
41300
|
let current = rootReal;
|
|
41280
41301
|
for (const segment of rel.split(/[\\/]/).filter(Boolean)) {
|
|
41281
41302
|
current = join11(current, segment);
|
|
41282
|
-
const
|
|
41303
|
+
const stat10 = await lstat14(current).catch((error) => {
|
|
41283
41304
|
throw gateError(gate, "cwd does not exist", { cause: error.code });
|
|
41284
41305
|
});
|
|
41285
|
-
if (
|
|
41306
|
+
if (stat10.isSymbolicLink()) throw gateError(gate, "cwd contains a symlink");
|
|
41286
41307
|
}
|
|
41287
41308
|
const physical = await realpath12(lexical);
|
|
41288
41309
|
if (!isInside2(rootReal, physical)) throw gateError(gate, "cwd resolves outside the execution root");
|
|
@@ -41523,9 +41544,9 @@ async function runVerificationGate({
|
|
|
41523
41544
|
return result;
|
|
41524
41545
|
}
|
|
41525
41546
|
async function makeTreeWritable(root) {
|
|
41526
|
-
const
|
|
41527
|
-
if (!
|
|
41528
|
-
await chmod2(root,
|
|
41547
|
+
const stat10 = await lstat14(root);
|
|
41548
|
+
if (!stat10.isDirectory() || stat10.isSymbolicLink()) throw new Error("gate copy root must be a real directory");
|
|
41549
|
+
await chmod2(root, stat10.mode | 448);
|
|
41529
41550
|
for (const child of await readdir7(root, { withFileTypes: true })) {
|
|
41530
41551
|
const absolute = join11(root, child.name);
|
|
41531
41552
|
const childStat = await lstat14(absolute);
|
|
@@ -41696,7 +41717,7 @@ function trimCandidate(value) {
|
|
|
41696
41717
|
function isPathToken(value) {
|
|
41697
41718
|
const token = trimCandidate(value);
|
|
41698
41719
|
if (!token || GLOB_PATTERN.test(token)) return false;
|
|
41699
|
-
return BARE_PREFIXES.some((prefix) => token.startsWith(prefix)) || EXPLICIT_PREFIXES.some((prefix) => token.startsWith(prefix)) || SOURCE_TREE_PATTERN.test(token) || MACHINE_ABSOLUTE_PATTERN.test(token);
|
|
41720
|
+
return BARE_PREFIXES.some((prefix) => token.startsWith(prefix)) || EXPLICIT_PREFIXES.some((prefix) => token.startsWith(prefix)) || HOME_DIRECTORY_PATTERN.test(token) || SOURCE_TREE_PATTERN.test(token) || MACHINE_ABSOLUTE_PATTERN.test(token);
|
|
41700
41721
|
}
|
|
41701
41722
|
function scanSnippet(snippet, line, sourceOnly, results, seen) {
|
|
41702
41723
|
const candidates = snippet.match(/(?:"[^"\n]+"|'[^'\n]+'|[^\s"'`()\[\],;]+)/gu) ?? [];
|
|
@@ -41721,15 +41742,14 @@ function extractPathTokens(content) {
|
|
|
41721
41742
|
inFence = !inFence;
|
|
41722
41743
|
continue;
|
|
41723
41744
|
}
|
|
41724
|
-
|
|
41725
|
-
if (inFence) scanSnippet(line, lineNumber, sourceOnly, results, seen);
|
|
41745
|
+
if (inFence) scanSnippet(line, lineNumber, SOURCE_ONLY_MARKER.test(line), results, seen);
|
|
41726
41746
|
for (const match of line.matchAll(/`([^`]+)`/gu)) {
|
|
41727
|
-
scanSnippet(match[1], lineNumber,
|
|
41747
|
+
scanSnippet(match[1], lineNumber, SOURCE_ONLY_MARKER.test(match[1]), results, seen);
|
|
41728
41748
|
}
|
|
41729
41749
|
for (const match of line.matchAll(/\]\(([^)]+)\)/gu)) {
|
|
41730
41750
|
const target = match[1].trim().split(/[?#]/u)[0];
|
|
41731
41751
|
if (!/^(?:https?:|#)/iu.test(target)) {
|
|
41732
|
-
scanSnippet(target, lineNumber,
|
|
41752
|
+
scanSnippet(target, lineNumber, SOURCE_ONLY_MARKER.test(match[1]), results, seen);
|
|
41733
41753
|
}
|
|
41734
41754
|
}
|
|
41735
41755
|
}
|
|
@@ -41750,6 +41770,14 @@ function classifyReference(token, skillRoot, pluginRoot, scanRoot2) {
|
|
|
41750
41770
|
absoluteTarget: token
|
|
41751
41771
|
};
|
|
41752
41772
|
}
|
|
41773
|
+
if (HOME_DIRECTORY_PATTERN.test(token)) {
|
|
41774
|
+
return {
|
|
41775
|
+
classification: CLASSIFICATION.HOME_DIRECTORY,
|
|
41776
|
+
resolutionRoot: "(home)",
|
|
41777
|
+
resolvedTarget: token,
|
|
41778
|
+
absoluteTarget: token
|
|
41779
|
+
};
|
|
41780
|
+
}
|
|
41753
41781
|
if (SOURCE_TREE_PATTERN.test(token)) {
|
|
41754
41782
|
return {
|
|
41755
41783
|
classification: CLASSIFICATION.SOURCE_BACKJUMP,
|
|
@@ -41780,14 +41808,14 @@ async function inspectRegularFile(root, target) {
|
|
|
41780
41808
|
}
|
|
41781
41809
|
for (const part of parts) {
|
|
41782
41810
|
current = join12(current, part);
|
|
41783
|
-
let
|
|
41811
|
+
let stat10;
|
|
41784
41812
|
try {
|
|
41785
|
-
|
|
41813
|
+
stat10 = await lstat15(current);
|
|
41786
41814
|
} catch (error) {
|
|
41787
41815
|
if (error.code === "ENOENT") return { code: FINDING_CODE.RESOURCE_MISSING };
|
|
41788
41816
|
throw error;
|
|
41789
41817
|
}
|
|
41790
|
-
if (
|
|
41818
|
+
if (stat10.isSymbolicLink()) return { code: FINDING_CODE.SYMLINK_NOT_ALLOWED };
|
|
41791
41819
|
}
|
|
41792
41820
|
const targetStat = await lstat15(target);
|
|
41793
41821
|
if (!targetStat.isFile() || targetStat.nlink !== 1) {
|
|
@@ -41795,8 +41823,26 @@ async function inspectRegularFile(root, target) {
|
|
|
41795
41823
|
}
|
|
41796
41824
|
return { code: null };
|
|
41797
41825
|
}
|
|
41826
|
+
async function collectRegularFiles(dir, results) {
|
|
41827
|
+
let entries;
|
|
41828
|
+
try {
|
|
41829
|
+
entries = await readdir8(dir, { withFileTypes: true });
|
|
41830
|
+
} catch (error) {
|
|
41831
|
+
if (error.code === "ENOENT") return;
|
|
41832
|
+
throw error;
|
|
41833
|
+
}
|
|
41834
|
+
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
41835
|
+
if (entry.isSymbolicLink()) continue;
|
|
41836
|
+
const absolute = join12(dir, entry.name);
|
|
41837
|
+
if (entry.isDirectory()) {
|
|
41838
|
+
await collectRegularFiles(absolute, results);
|
|
41839
|
+
} else if (entry.isFile()) {
|
|
41840
|
+
results.push(absolute);
|
|
41841
|
+
}
|
|
41842
|
+
}
|
|
41843
|
+
}
|
|
41798
41844
|
function inferSurfaceHost(surfaceId, defaultHost) {
|
|
41799
|
-
const match =
|
|
41845
|
+
const match = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
|
|
41800
41846
|
return match?.[1] ?? defaultHost;
|
|
41801
41847
|
}
|
|
41802
41848
|
function receiptProjection(result) {
|
|
@@ -41807,6 +41853,7 @@ function receiptProjection(result) {
|
|
|
41807
41853
|
skillCount: result.skillCount,
|
|
41808
41854
|
referenceCount: result.referenceCount,
|
|
41809
41855
|
sourceOnlyCount: result.sourceOnlyCount,
|
|
41856
|
+
sourceOnlyReferences: result.sourceOnlyReferences,
|
|
41810
41857
|
findingCount: result.findings.length
|
|
41811
41858
|
};
|
|
41812
41859
|
}
|
|
@@ -41883,8 +41930,23 @@ async function checkSkillResourceClosure({
|
|
|
41883
41930
|
const skillPaths = await discoverSkills(scanRoot2);
|
|
41884
41931
|
const findings = [];
|
|
41885
41932
|
const surfaceMap = /* @__PURE__ */ new Map();
|
|
41933
|
+
const skillsBySurface = /* @__PURE__ */ new Map();
|
|
41934
|
+
const resolvedResourcesBySurface = /* @__PURE__ */ new Map();
|
|
41935
|
+
const referencedTargetsBySurface = /* @__PURE__ */ new Map();
|
|
41936
|
+
const resourceReferencesBySurface = /* @__PURE__ */ new Map();
|
|
41937
|
+
const sourceOnlyReferences = [];
|
|
41886
41938
|
let referenceCount = 0;
|
|
41887
41939
|
let sourceOnlyCount = 0;
|
|
41940
|
+
const recordSourceOnlyExemption = /* @__PURE__ */ __name((surface, skill, pathToken) => {
|
|
41941
|
+
sourceOnlyCount += 1;
|
|
41942
|
+
surface.sourceOnlyCount += 1;
|
|
41943
|
+
sourceOnlyReferences.push({
|
|
41944
|
+
skill,
|
|
41945
|
+
line: pathToken.line,
|
|
41946
|
+
reference: pathToken.token,
|
|
41947
|
+
surface: surface.id
|
|
41948
|
+
});
|
|
41949
|
+
}, "recordSourceOnlyExemption");
|
|
41888
41950
|
for (const skill of skillPaths) {
|
|
41889
41951
|
const skillRoot = resolveSkillRoot(skill, scanRoot2);
|
|
41890
41952
|
const pluginRoot = resolvePluginRoot(skill, scanRoot2);
|
|
@@ -41899,6 +41961,8 @@ async function checkSkillResourceClosure({
|
|
|
41899
41961
|
};
|
|
41900
41962
|
surface.skillCount += 1;
|
|
41901
41963
|
surfaceMap.set(surfaceId, surface);
|
|
41964
|
+
if (!skillsBySurface.has(surfaceId)) skillsBySurface.set(surfaceId, []);
|
|
41965
|
+
skillsBySurface.get(surfaceId).push(skill);
|
|
41902
41966
|
const content = await readFile12(resolve16(scanRoot2, skill), "utf8");
|
|
41903
41967
|
for (const pathToken of extractPathTokens(content)) {
|
|
41904
41968
|
referenceCount += 1;
|
|
@@ -41921,8 +41985,7 @@ async function checkSkillResourceClosure({
|
|
|
41921
41985
|
};
|
|
41922
41986
|
if (classification.classification === CLASSIFICATION.SOURCE_BACKJUMP) {
|
|
41923
41987
|
if (pathToken.sourceOnly) {
|
|
41924
|
-
|
|
41925
|
-
surface.sourceOnlyCount += 1;
|
|
41988
|
+
recordSourceOnlyExemption(surface, skill, pathToken);
|
|
41926
41989
|
} else {
|
|
41927
41990
|
findings.push({ ...findingBase, code: FINDING_CODE.SOURCE_BACKJUMP });
|
|
41928
41991
|
}
|
|
@@ -41932,6 +41995,10 @@ async function checkSkillResourceClosure({
|
|
|
41932
41995
|
findings.push({ ...findingBase, code: FINDING_CODE.MACHINE_ABSOLUTE_PATH });
|
|
41933
41996
|
continue;
|
|
41934
41997
|
}
|
|
41998
|
+
if (classification.classification === CLASSIFICATION.HOME_DIRECTORY) {
|
|
41999
|
+
findings.push({ ...findingBase, code: FINDING_CODE.HOME_DIRECTORY_SEARCH });
|
|
42000
|
+
continue;
|
|
42001
|
+
}
|
|
41935
42002
|
if (classification.classification === CLASSIFICATION.OUT_OF_BOUNDS) {
|
|
41936
42003
|
findings.push({ ...findingBase, code: FINDING_CODE.OUT_OF_BOUNDS });
|
|
41937
42004
|
continue;
|
|
@@ -41943,14 +42010,112 @@ async function checkSkillResourceClosure({
|
|
|
41943
42010
|
);
|
|
41944
42011
|
if (inspection.code) {
|
|
41945
42012
|
if (pathToken.sourceOnly && inspection.code === FINDING_CODE.RESOURCE_MISSING) {
|
|
41946
|
-
|
|
41947
|
-
surface.sourceOnlyCount += 1;
|
|
42013
|
+
recordSourceOnlyExemption(surface, skill, pathToken);
|
|
41948
42014
|
} else {
|
|
41949
42015
|
findings.push({ ...findingBase, code: inspection.code });
|
|
41950
42016
|
}
|
|
42017
|
+
continue;
|
|
42018
|
+
}
|
|
42019
|
+
const relativeResource = relativeStable(pluginRoot, classification.absoluteTarget);
|
|
42020
|
+
if (!resolvedResourcesBySurface.has(surfaceId)) {
|
|
42021
|
+
resolvedResourcesBySurface.set(surfaceId, /* @__PURE__ */ new Map());
|
|
42022
|
+
referencedTargetsBySurface.set(surfaceId, /* @__PURE__ */ new Set());
|
|
42023
|
+
resourceReferencesBySurface.set(surfaceId, /* @__PURE__ */ new Map());
|
|
42024
|
+
}
|
|
42025
|
+
resolvedResourcesBySurface.get(surfaceId).set(relativeResource, classification.absoluteTarget);
|
|
42026
|
+
referencedTargetsBySurface.get(surfaceId).add(classification.absoluteTarget);
|
|
42027
|
+
const resourceReferences = resourceReferencesBySurface.get(surfaceId);
|
|
42028
|
+
if (!resourceReferences.has(relativeResource)) resourceReferences.set(relativeResource, []);
|
|
42029
|
+
resourceReferences.get(relativeResource).push({
|
|
42030
|
+
surface: surfaceId,
|
|
42031
|
+
skill,
|
|
42032
|
+
line: pathToken.line
|
|
42033
|
+
});
|
|
42034
|
+
}
|
|
42035
|
+
}
|
|
42036
|
+
const contentDigestCache = /* @__PURE__ */ new Map();
|
|
42037
|
+
const digestOfTarget = /* @__PURE__ */ __name(async (absoluteTarget) => {
|
|
42038
|
+
if (!contentDigestCache.has(absoluteTarget)) {
|
|
42039
|
+
contentDigestCache.set(
|
|
42040
|
+
absoluteTarget,
|
|
42041
|
+
digestDocument({ content: await readFile12(absoluteTarget, "utf8") })
|
|
42042
|
+
);
|
|
42043
|
+
}
|
|
42044
|
+
return contentDigestCache.get(absoluteTarget);
|
|
42045
|
+
}, "digestOfTarget");
|
|
42046
|
+
const surfaceIds = [...resolvedResourcesBySurface.keys()].sort((a, b) => a.localeCompare(b));
|
|
42047
|
+
for (let i = 0; i < surfaceIds.length; i += 1) {
|
|
42048
|
+
for (let j = i + 1; j < surfaceIds.length; j += 1) {
|
|
42049
|
+
const [leftId, rightId] = [surfaceIds[i], surfaceIds[j]];
|
|
42050
|
+
const left = resolvedResourcesBySurface.get(leftId);
|
|
42051
|
+
const right = resolvedResourcesBySurface.get(rightId);
|
|
42052
|
+
const commonPaths = [...left.keys()].filter((path15) => right.has(path15)).sort((a, b) => a.localeCompare(b));
|
|
42053
|
+
for (const resourcePath of commonPaths) {
|
|
42054
|
+
const [leftDigest, rightDigest] = await Promise.all([
|
|
42055
|
+
digestOfTarget(left.get(resourcePath)),
|
|
42056
|
+
digestOfTarget(right.get(resourcePath))
|
|
42057
|
+
]);
|
|
42058
|
+
if (leftDigest === rightDigest) continue;
|
|
42059
|
+
const rightSurface = surfaceMap.get(rightId);
|
|
42060
|
+
const driftReferences = [];
|
|
42061
|
+
const seenReference = /* @__PURE__ */ new Set();
|
|
42062
|
+
for (const surfaceId of [leftId, rightId]) {
|
|
42063
|
+
for (const ref of resourceReferencesBySurface.get(surfaceId)?.get(resourcePath) ?? []) {
|
|
42064
|
+
const key = `${ref.surface}\0${ref.skill}\0${ref.line}`;
|
|
42065
|
+
if (seenReference.has(key)) continue;
|
|
42066
|
+
seenReference.add(key);
|
|
42067
|
+
driftReferences.push({ surface: ref.surface, skill: ref.skill, line: ref.line });
|
|
42068
|
+
}
|
|
42069
|
+
}
|
|
42070
|
+
driftReferences.sort((a, b) => a.surface.localeCompare(b.surface) || a.skill.localeCompare(b.skill) || a.line - b.line);
|
|
42071
|
+
findings.push({
|
|
42072
|
+
host: rightSurface.host,
|
|
42073
|
+
surface: rightId,
|
|
42074
|
+
skill: null,
|
|
42075
|
+
line: null,
|
|
42076
|
+
reference: resourcePath,
|
|
42077
|
+
classification: CLASSIFICATION.RESOURCE_DRIFT,
|
|
42078
|
+
resolutionRoot: rightId,
|
|
42079
|
+
resolvedTarget: resourcePath,
|
|
42080
|
+
surfaces: [leftId, rightId],
|
|
42081
|
+
references: driftReferences,
|
|
42082
|
+
code: FINDING_CODE.RESOURCE_DRIFT
|
|
42083
|
+
});
|
|
42084
|
+
}
|
|
42085
|
+
}
|
|
42086
|
+
}
|
|
42087
|
+
for (const surfaceId of [...skillsBySurface.keys()].sort((a, b) => a.localeCompare(b))) {
|
|
42088
|
+
if (!ADAPTER_SURFACE_PATTERN.test(surfaceId)) continue;
|
|
42089
|
+
const surface = surfaceMap.get(surfaceId);
|
|
42090
|
+
const surfaceRootAbsolute = resolve16(scanRoot2, surfaceId);
|
|
42091
|
+
const referencedTargets = referencedTargetsBySurface.get(surfaceId) ?? /* @__PURE__ */ new Set();
|
|
42092
|
+
const stale = [];
|
|
42093
|
+
for (const skill of skillsBySurface.get(surfaceId)) {
|
|
42094
|
+
const skillDir = resolve16(scanRoot2, dirname7(skill));
|
|
42095
|
+
for (const closureDir of CLOSURE_RESOURCE_DIRS) {
|
|
42096
|
+
const files = [];
|
|
42097
|
+
await collectRegularFiles(join12(skillDir, closureDir), files);
|
|
42098
|
+
for (const absolute of files) {
|
|
42099
|
+
if (referencedTargets.has(absolute)) continue;
|
|
42100
|
+
const relativeResource = relativeStable(surfaceRootAbsolute, absolute);
|
|
42101
|
+
stale.push({
|
|
42102
|
+
host: surface.host,
|
|
42103
|
+
surface: surfaceId,
|
|
42104
|
+
skill,
|
|
42105
|
+
line: null,
|
|
42106
|
+
reference: relativeResource,
|
|
42107
|
+
classification: CLASSIFICATION.STALE_RESOURCE,
|
|
42108
|
+
resolutionRoot: surfaceId,
|
|
42109
|
+
resolvedTarget: relativeResource,
|
|
42110
|
+
code: FINDING_CODE.STALE_RESOURCE
|
|
42111
|
+
});
|
|
42112
|
+
}
|
|
41951
42113
|
}
|
|
41952
42114
|
}
|
|
42115
|
+
stale.sort((a, b) => a.skill.localeCompare(b.skill) || a.resolvedTarget.localeCompare(b.resolvedTarget));
|
|
42116
|
+
findings.push(...stale);
|
|
41953
42117
|
}
|
|
42118
|
+
sourceOnlyReferences.sort((a, b) => a.skill.localeCompare(b.skill) || a.line - b.line || a.reference.localeCompare(b.reference));
|
|
41954
42119
|
if (snapshotError) {
|
|
41955
42120
|
findings.push({
|
|
41956
42121
|
host,
|
|
@@ -41973,18 +42138,29 @@ async function checkSkillResourceClosure({
|
|
|
41973
42138
|
skillCount: skillPaths.length,
|
|
41974
42139
|
referenceCount,
|
|
41975
42140
|
sourceOnlyCount,
|
|
42141
|
+
sourceOnlyReferences,
|
|
41976
42142
|
findings
|
|
41977
42143
|
};
|
|
41978
42144
|
result.receiptDigest = digestDocument(receiptProjection(result));
|
|
41979
42145
|
return result;
|
|
41980
42146
|
}
|
|
41981
|
-
|
|
42147
|
+
function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
|
|
42148
|
+
const missing = [];
|
|
42149
|
+
for (const expectedHost of [...new Set(expectedHosts ?? [])].sort((a, b) => a.localeCompare(b))) {
|
|
42150
|
+
const surface = (surfaces ?? []).find((item) => item.host === expectedHost);
|
|
42151
|
+
if (!surface || !(surface.skillCount >= 1)) {
|
|
42152
|
+
missing.push({ host: expectedHost, skillCount: surface?.skillCount ?? 0 });
|
|
42153
|
+
}
|
|
42154
|
+
}
|
|
42155
|
+
return { passed: missing.length === 0, missing };
|
|
42156
|
+
}
|
|
42157
|
+
var CHECKER_VERSION, BARE_PREFIXES, EXPLICIT_PREFIXES, SOURCE_TREE_PATTERN, MACHINE_ABSOLUTE_PATTERN, HOME_DIRECTORY_PATTERN, ADAPTER_SURFACE_PATTERN, CLOSURE_RESOURCE_DIRS, GLOB_PATTERN, SOURCE_ONLY_MARKER, TRANSPORT_EXCLUSIONS, CLASSIFICATION, FINDING_CODE;
|
|
41982
42158
|
var init_skill_resource_closure = __esm({
|
|
41983
42159
|
"src/core/skill-resource-closure.mjs"() {
|
|
41984
42160
|
init_src();
|
|
41985
42161
|
init_errors();
|
|
41986
42162
|
init_frozen();
|
|
41987
|
-
CHECKER_VERSION = "skill-resource-closure-
|
|
42163
|
+
CHECKER_VERSION = "skill-resource-closure-v2";
|
|
41988
42164
|
BARE_PREFIXES = ["references/", "assets/", "schemas/", "examples/", "scripts/"];
|
|
41989
42165
|
EXPLICIT_PREFIXES = [
|
|
41990
42166
|
"<plugin-root>/",
|
|
@@ -41996,6 +42172,9 @@ var init_skill_resource_closure = __esm({
|
|
|
41996
42172
|
];
|
|
41997
42173
|
SOURCE_TREE_PATTERN = /(?:^|\/)packages\/[A-Za-z0-9._-]+(?:\/|$)/u;
|
|
41998
42174
|
MACHINE_ABSOLUTE_PATTERN = /^(?:\/(?:Users|home|root|tmp|var|etc|opt)(?:\/|$)|[A-Za-z]:[\\/])/u;
|
|
42175
|
+
HOME_DIRECTORY_PATTERN = /^(?:~|\$HOME|\$\{HOME\})\/.+/u;
|
|
42176
|
+
ADAPTER_SURFACE_PATTERN = /^adapters\/([^/]+)$/u;
|
|
42177
|
+
CLOSURE_RESOURCE_DIRS = Object.freeze(["references", "assets", "schemas", "examples", "scripts"]);
|
|
41999
42178
|
GLOB_PATTERN = /[*?\[]/u;
|
|
42000
42179
|
SOURCE_ONLY_MARKER = /(?:\bsource-only\b|仅源码包)/iu;
|
|
42001
42180
|
TRANSPORT_EXCLUSIONS = Object.freeze([
|
|
@@ -42009,7 +42188,10 @@ var init_skill_resource_closure = __esm({
|
|
|
42009
42188
|
PLUGIN_ROOT: "plugin_root",
|
|
42010
42189
|
SOURCE_BACKJUMP: "source_backjump",
|
|
42011
42190
|
MACHINE_ABSOLUTE: "machine_absolute",
|
|
42012
|
-
|
|
42191
|
+
HOME_DIRECTORY: "home_directory",
|
|
42192
|
+
OUT_OF_BOUNDS: "out_of_bounds",
|
|
42193
|
+
RESOURCE_DRIFT: "resource_drift",
|
|
42194
|
+
STALE_RESOURCE: "stale_resource"
|
|
42013
42195
|
});
|
|
42014
42196
|
FINDING_CODE = Object.freeze({
|
|
42015
42197
|
SNAPSHOT_UNSAFE: "SNAPSHOT_UNSAFE",
|
|
@@ -42017,8 +42199,11 @@ var init_skill_resource_closure = __esm({
|
|
|
42017
42199
|
RESOURCE_NOT_REGULAR_FILE: "RESOURCE_NOT_REGULAR_FILE",
|
|
42018
42200
|
SOURCE_BACKJUMP: "SOURCE_BACKJUMP",
|
|
42019
42201
|
MACHINE_ABSOLUTE_PATH: "MACHINE_ABSOLUTE_PATH",
|
|
42202
|
+
HOME_DIRECTORY_SEARCH: "HOME_DIRECTORY_SEARCH",
|
|
42020
42203
|
OUT_OF_BOUNDS: "OUT_OF_BOUNDS",
|
|
42021
|
-
SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED"
|
|
42204
|
+
SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED",
|
|
42205
|
+
RESOURCE_DRIFT: "RESOURCE_DRIFT",
|
|
42206
|
+
STALE_RESOURCE: "STALE_RESOURCE"
|
|
42022
42207
|
});
|
|
42023
42208
|
__name(toPosix, "toPosix");
|
|
42024
42209
|
__name(relativeStable, "relativeStable");
|
|
@@ -42033,12 +42218,14 @@ var init_skill_resource_closure = __esm({
|
|
|
42033
42218
|
__name(stripExplicitPrefix, "stripExplicitPrefix");
|
|
42034
42219
|
__name(classifyReference, "classifyReference");
|
|
42035
42220
|
__name(inspectRegularFile, "inspectRegularFile");
|
|
42221
|
+
__name(collectRegularFiles, "collectRegularFiles");
|
|
42036
42222
|
__name(inferSurfaceHost, "inferSurfaceHost");
|
|
42037
42223
|
__name(receiptProjection, "receiptProjection");
|
|
42038
42224
|
__name(createSkillResourceClosureReceipt, "createSkillResourceClosureReceipt");
|
|
42039
42225
|
__name(assertSkillResourceClosureReceipt, "assertSkillResourceClosureReceipt");
|
|
42040
42226
|
__name(evaluateConsumerSkillResourceClosureReceipts, "evaluateConsumerSkillResourceClosureReceipts");
|
|
42041
42227
|
__name(checkSkillResourceClosure, "checkSkillResourceClosure");
|
|
42228
|
+
__name(evaluateDeclaredHostSurfaceCoverage, "evaluateDeclaredHostSurfaceCoverage");
|
|
42042
42229
|
}
|
|
42043
42230
|
});
|
|
42044
42231
|
|
|
@@ -43575,11 +43762,182 @@ var init_contract2 = __esm({
|
|
|
43575
43762
|
}
|
|
43576
43763
|
});
|
|
43577
43764
|
|
|
43765
|
+
// src/core/bundle-freshness.mjs
|
|
43766
|
+
import { readFile as readFile16, readdir as readdir11, stat as stat4 } from "node:fs/promises";
|
|
43767
|
+
import { join as join14 } from "node:path";
|
|
43768
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
43769
|
+
function bundlePathFor(pkgRoot) {
|
|
43770
|
+
return join14(pkgRoot, BUNDLE_RELPATH);
|
|
43771
|
+
}
|
|
43772
|
+
async function listFilesSorted(dir, prefix = "") {
|
|
43773
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
43774
|
+
const files = [];
|
|
43775
|
+
for (const entry of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
43776
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
43777
|
+
if (entry.isDirectory()) {
|
|
43778
|
+
files.push(...await listFilesSorted(join14(dir, entry.name), rel));
|
|
43779
|
+
} else if (entry.isFile()) {
|
|
43780
|
+
files.push(rel);
|
|
43781
|
+
}
|
|
43782
|
+
}
|
|
43783
|
+
return files;
|
|
43784
|
+
}
|
|
43785
|
+
async function listBundleSourceInputs(pkgRoot) {
|
|
43786
|
+
const inputs = [];
|
|
43787
|
+
for (const dir of SOURCE_DIRS) {
|
|
43788
|
+
const abs = join14(pkgRoot, dir);
|
|
43789
|
+
const st = await stat4(abs).catch(() => null);
|
|
43790
|
+
if (st?.isDirectory()) {
|
|
43791
|
+
for (const rel of await listFilesSorted(abs)) {
|
|
43792
|
+
inputs.push(`${dir}/${rel}`);
|
|
43793
|
+
}
|
|
43794
|
+
}
|
|
43795
|
+
}
|
|
43796
|
+
for (const rel of SOURCE_FILES) {
|
|
43797
|
+
const st = await stat4(join14(pkgRoot, rel)).catch(() => null);
|
|
43798
|
+
if (st?.isFile()) {
|
|
43799
|
+
inputs.push(rel.split(/[\\/]/).join("/"));
|
|
43800
|
+
}
|
|
43801
|
+
}
|
|
43802
|
+
return inputs.sort();
|
|
43803
|
+
}
|
|
43804
|
+
async function computeBundleSourceDigest(pkgRoot) {
|
|
43805
|
+
const inputs = await listBundleSourceInputs(pkgRoot);
|
|
43806
|
+
const hash = createHash13("sha256");
|
|
43807
|
+
hash.update(BUNDLE_SOURCE_DIGEST_ALGORITHM);
|
|
43808
|
+
hash.update("\n");
|
|
43809
|
+
for (const rel of inputs) {
|
|
43810
|
+
const content = await readFile16(join14(pkgRoot, rel));
|
|
43811
|
+
hash.update(rel);
|
|
43812
|
+
hash.update("\0");
|
|
43813
|
+
hash.update(createHash13("sha256").update(content).digest("hex"));
|
|
43814
|
+
hash.update("\n");
|
|
43815
|
+
}
|
|
43816
|
+
return hash.digest("hex");
|
|
43817
|
+
}
|
|
43818
|
+
async function readEmbeddedBundleDigest(bundlePath) {
|
|
43819
|
+
let content;
|
|
43820
|
+
try {
|
|
43821
|
+
content = await readFile16(bundlePath, "utf8");
|
|
43822
|
+
} catch {
|
|
43823
|
+
return null;
|
|
43824
|
+
}
|
|
43825
|
+
const match = content.match(EMBEDDED_DIGEST_PATTERN);
|
|
43826
|
+
return match ? match[1] : null;
|
|
43827
|
+
}
|
|
43828
|
+
async function checkBundleFreshness(pkgRoot) {
|
|
43829
|
+
const base = {
|
|
43830
|
+
applicable: true,
|
|
43831
|
+
fresh: false,
|
|
43832
|
+
embeddedDigest: null,
|
|
43833
|
+
sourceDigest: null,
|
|
43834
|
+
algorithm: BUNDLE_SOURCE_DIGEST_ALGORITHM
|
|
43835
|
+
};
|
|
43836
|
+
const srcStat = await stat4(join14(pkgRoot, "src")).catch(() => null);
|
|
43837
|
+
if (!srcStat?.isDirectory()) {
|
|
43838
|
+
return { ...base, applicable: false, reason: "installed-layout" };
|
|
43839
|
+
}
|
|
43840
|
+
const bundleStat = await stat4(bundlePathFor(pkgRoot)).catch(() => null);
|
|
43841
|
+
if (!bundleStat?.isFile()) {
|
|
43842
|
+
return { ...base, reason: "bundle-missing" };
|
|
43843
|
+
}
|
|
43844
|
+
const [embeddedDigest, sourceDigest] = await Promise.all([
|
|
43845
|
+
readEmbeddedBundleDigest(bundlePathFor(pkgRoot)),
|
|
43846
|
+
computeBundleSourceDigest(pkgRoot)
|
|
43847
|
+
]);
|
|
43848
|
+
if (!embeddedDigest) {
|
|
43849
|
+
return { ...base, sourceDigest, reason: "digest-missing" };
|
|
43850
|
+
}
|
|
43851
|
+
if (embeddedDigest !== sourceDigest) {
|
|
43852
|
+
return { ...base, embeddedDigest, sourceDigest, reason: "digest-mismatch" };
|
|
43853
|
+
}
|
|
43854
|
+
return { ...base, fresh: true, embeddedDigest, sourceDigest, reason: "fresh" };
|
|
43855
|
+
}
|
|
43856
|
+
async function assertBundleFreshness(pkgRoot) {
|
|
43857
|
+
const result = await checkBundleFreshness(pkgRoot);
|
|
43858
|
+
if (!result.applicable) {
|
|
43859
|
+
return result;
|
|
43860
|
+
}
|
|
43861
|
+
if (result.fresh) {
|
|
43862
|
+
return result;
|
|
43863
|
+
}
|
|
43864
|
+
const reasonText = {
|
|
43865
|
+
"bundle-missing": "the bundle file is missing",
|
|
43866
|
+
"digest-missing": "the bundle carries no embedded source digest",
|
|
43867
|
+
"digest-mismatch": "the bundle is out of sync with src/"
|
|
43868
|
+
}[result.reason] ?? result.reason;
|
|
43869
|
+
throw new ReleaseError(
|
|
43870
|
+
BUNDLE_STALE,
|
|
43871
|
+
`bin/release-skill.bundle.mjs is stale: ${reasonText}. Rebuild it from the release-skill package root with: ${BUNDLE_REBUILD_COMMAND} (or pnpm build)`,
|
|
43872
|
+
{
|
|
43873
|
+
reason: result.reason,
|
|
43874
|
+
algorithm: result.algorithm,
|
|
43875
|
+
embeddedDigest: result.embeddedDigest,
|
|
43876
|
+
sourceDigest: result.sourceDigest,
|
|
43877
|
+
rebuildCommand: BUNDLE_REBUILD_COMMAND
|
|
43878
|
+
}
|
|
43879
|
+
);
|
|
43880
|
+
}
|
|
43881
|
+
var BUNDLE_SOURCE_DIGEST_ALGORITHM, BUNDLE_RELPATH, SOURCE_DIRS, SOURCE_FILES, EMBEDDED_DIGEST_PATTERN, BUNDLE_REBUILD_COMMAND;
|
|
43882
|
+
var init_bundle_freshness = __esm({
|
|
43883
|
+
"src/core/bundle-freshness.mjs"() {
|
|
43884
|
+
init_errors();
|
|
43885
|
+
BUNDLE_SOURCE_DIGEST_ALGORITHM = "bundle-source-digest-v1";
|
|
43886
|
+
BUNDLE_RELPATH = join14("bin", "release-skill.bundle.mjs");
|
|
43887
|
+
SOURCE_DIRS = ["src", "skills-src"];
|
|
43888
|
+
SOURCE_FILES = [join14("bin", "release-skill-cli.mjs"), "package.json"];
|
|
43889
|
+
EMBEDDED_DIGEST_PATTERN = /const __bundleSourceDigest = "([a-f0-9]{64})";/;
|
|
43890
|
+
__name(bundlePathFor, "bundlePathFor");
|
|
43891
|
+
__name(listFilesSorted, "listFilesSorted");
|
|
43892
|
+
__name(listBundleSourceInputs, "listBundleSourceInputs");
|
|
43893
|
+
__name(computeBundleSourceDigest, "computeBundleSourceDigest");
|
|
43894
|
+
__name(readEmbeddedBundleDigest, "readEmbeddedBundleDigest");
|
|
43895
|
+
__name(checkBundleFreshness, "checkBundleFreshness");
|
|
43896
|
+
BUNDLE_REBUILD_COMMAND = "node scripts/build-bundle.mjs";
|
|
43897
|
+
__name(assertBundleFreshness, "assertBundleFreshness");
|
|
43898
|
+
}
|
|
43899
|
+
});
|
|
43900
|
+
|
|
43901
|
+
// src/core/frozen-marker.mjs
|
|
43902
|
+
import { readFile as readFile17, writeFile as writeFile6, unlink as unlink5 } from "node:fs/promises";
|
|
43903
|
+
import { join as join15 } from "node:path";
|
|
43904
|
+
function frozenMarkerPath(releaseDir) {
|
|
43905
|
+
return join15(releaseDir, FROZEN_MARKER_FILENAME);
|
|
43906
|
+
}
|
|
43907
|
+
async function writeFrozenMarker(releaseDir, marker) {
|
|
43908
|
+
const payload = {
|
|
43909
|
+
planDigest: marker.planDigest,
|
|
43910
|
+
targetVersions: marker.targetVersions,
|
|
43911
|
+
createdAt: marker.createdAt,
|
|
43912
|
+
runId: marker.runId
|
|
43913
|
+
};
|
|
43914
|
+
const markerPath = frozenMarkerPath(releaseDir);
|
|
43915
|
+
await writeFile6(markerPath, JSON.stringify(payload, null, 2) + "\n", "utf8");
|
|
43916
|
+
return markerPath;
|
|
43917
|
+
}
|
|
43918
|
+
async function clearFrozenMarker(releaseDir) {
|
|
43919
|
+
try {
|
|
43920
|
+
await unlink5(frozenMarkerPath(releaseDir));
|
|
43921
|
+
return true;
|
|
43922
|
+
} catch {
|
|
43923
|
+
return false;
|
|
43924
|
+
}
|
|
43925
|
+
}
|
|
43926
|
+
var FROZEN_MARKER_FILENAME;
|
|
43927
|
+
var init_frozen_marker = __esm({
|
|
43928
|
+
"src/core/frozen-marker.mjs"() {
|
|
43929
|
+
FROZEN_MARKER_FILENAME = "FROZEN";
|
|
43930
|
+
__name(frozenMarkerPath, "frozenMarkerPath");
|
|
43931
|
+
__name(writeFrozenMarker, "writeFrozenMarker");
|
|
43932
|
+
__name(clearFrozenMarker, "clearFrozenMarker");
|
|
43933
|
+
}
|
|
43934
|
+
});
|
|
43935
|
+
|
|
43578
43936
|
// src/core/source-authority.mjs
|
|
43579
43937
|
import { execFile as execFileCb6 } from "node:child_process";
|
|
43580
43938
|
import { promisify as promisify6 } from "node:util";
|
|
43581
|
-
import { lstat as lstat17, mkdtemp as mkdtemp5, readFile as
|
|
43582
|
-
import { join as
|
|
43939
|
+
import { lstat as lstat17, mkdtemp as mkdtemp5, readFile as readFile18, readdir as readdir12, realpath as realpath14, rm as rm7 } from "node:fs/promises";
|
|
43940
|
+
import { join as join16, relative as relative16, resolve as resolve18, sep as sep5 } from "node:path";
|
|
43583
43941
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
43584
43942
|
async function computeSourceInputClosure({ units, root }) {
|
|
43585
43943
|
const realRoot = await realpath14(resolve18(root));
|
|
@@ -43619,9 +43977,9 @@ function computeEntriesDigest(entries) {
|
|
|
43619
43977
|
}))));
|
|
43620
43978
|
}
|
|
43621
43979
|
async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
43622
|
-
let
|
|
43980
|
+
let stat10;
|
|
43623
43981
|
try {
|
|
43624
|
-
|
|
43982
|
+
stat10 = await lstat17(absolutePath);
|
|
43625
43983
|
} catch (error) {
|
|
43626
43984
|
throw new ReleaseError(
|
|
43627
43985
|
CONFIG_INVALID,
|
|
@@ -43630,7 +43988,7 @@ async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
|
43630
43988
|
);
|
|
43631
43989
|
}
|
|
43632
43990
|
const rel = toRelative(root, absolutePath);
|
|
43633
|
-
if (
|
|
43991
|
+
if (stat10.isSymbolicLink()) {
|
|
43634
43992
|
throw new ReleaseError(
|
|
43635
43993
|
CONFIG_INVALID,
|
|
43636
43994
|
`source-input closure rejects symlink "${rel}"`,
|
|
@@ -43645,30 +44003,30 @@ async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
|
43645
44003
|
{ path: rel }
|
|
43646
44004
|
);
|
|
43647
44005
|
}
|
|
43648
|
-
if (
|
|
43649
|
-
const children = await
|
|
44006
|
+
if (stat10.isDirectory()) {
|
|
44007
|
+
const children = await readdir12(absolutePath, { withFileTypes: true });
|
|
43650
44008
|
children.sort((left, right) => left.name.localeCompare(right.name));
|
|
43651
44009
|
for (const child of children) {
|
|
43652
44010
|
await collectPath({
|
|
43653
|
-
absolutePath:
|
|
44011
|
+
absolutePath: join16(absolutePath, child.name),
|
|
43654
44012
|
root,
|
|
43655
44013
|
entriesByPath
|
|
43656
44014
|
});
|
|
43657
44015
|
}
|
|
43658
44016
|
return;
|
|
43659
44017
|
}
|
|
43660
|
-
if (!
|
|
44018
|
+
if (!stat10.isFile()) {
|
|
43661
44019
|
throw new ReleaseError(
|
|
43662
44020
|
CONFIG_INVALID,
|
|
43663
44021
|
`source-input closure rejects non-regular file "${rel}"`,
|
|
43664
44022
|
{ path: rel }
|
|
43665
44023
|
);
|
|
43666
44024
|
}
|
|
43667
|
-
const content = await
|
|
44025
|
+
const content = await readFile18(absolutePath);
|
|
43668
44026
|
entriesByPath.set(rel, {
|
|
43669
44027
|
path: rel,
|
|
43670
44028
|
digest: sha256Hex(content),
|
|
43671
|
-
mode: normalizeLocalGitMode(
|
|
44029
|
+
mode: normalizeLocalGitMode(stat10.mode)
|
|
43672
44030
|
});
|
|
43673
44031
|
}
|
|
43674
44032
|
function resolveInside(base, candidate, containmentRoot = base) {
|
|
@@ -43894,7 +44252,7 @@ async function verifyWithTemporaryGit({
|
|
|
43894
44252
|
if (!branchLine) {
|
|
43895
44253
|
return failure(REF_MISSING, `remote ref "refs/heads/${defaultBranch}" does not exist`);
|
|
43896
44254
|
}
|
|
43897
|
-
const tempRoot = await mkdtemp5(
|
|
44255
|
+
const tempRoot = await mkdtemp5(join16(tmpdir3(), "release-skill-source-authority-"));
|
|
43898
44256
|
try {
|
|
43899
44257
|
await execFn("git", ["init", "--bare", tempRoot], {
|
|
43900
44258
|
encoding: "utf8",
|
|
@@ -55969,17 +56327,17 @@ var require_polyfill = __commonJS({
|
|
|
55969
56327
|
copyFile,
|
|
55970
56328
|
lstat: lstat27,
|
|
55971
56329
|
mkdir: mkdir24,
|
|
55972
|
-
readdir:
|
|
56330
|
+
readdir: readdir21,
|
|
55973
56331
|
readlink: readlink2,
|
|
55974
|
-
stat:
|
|
56332
|
+
stat: stat10,
|
|
55975
56333
|
symlink,
|
|
55976
|
-
unlink:
|
|
56334
|
+
unlink: unlink6,
|
|
55977
56335
|
utimes
|
|
55978
56336
|
} = __require("fs/promises");
|
|
55979
56337
|
var {
|
|
55980
56338
|
dirname: dirname18,
|
|
55981
56339
|
isAbsolute: isAbsolute23,
|
|
55982
|
-
join:
|
|
56340
|
+
join: join34,
|
|
55983
56341
|
parse: parse2,
|
|
55984
56342
|
resolve: resolve35,
|
|
55985
56343
|
sep: sep7,
|
|
@@ -56068,7 +56426,7 @@ var require_polyfill = __commonJS({
|
|
|
56068
56426
|
}
|
|
56069
56427
|
__name(areIdentical, "areIdentical");
|
|
56070
56428
|
function getStats(src, dest, opts) {
|
|
56071
|
-
const statFunc = opts.dereference ? (file) =>
|
|
56429
|
+
const statFunc = opts.dereference ? (file) => stat10(file, { bigint: true }) : (file) => lstat27(file, { bigint: true });
|
|
56072
56430
|
return Promise.all([
|
|
56073
56431
|
statFunc(src),
|
|
56074
56432
|
statFunc(dest).catch((err) => {
|
|
@@ -56091,7 +56449,7 @@ var require_polyfill = __commonJS({
|
|
|
56091
56449
|
}
|
|
56092
56450
|
__name(checkParentDir, "checkParentDir");
|
|
56093
56451
|
function pathExists2(dest) {
|
|
56094
|
-
return
|
|
56452
|
+
return stat10(dest).then(
|
|
56095
56453
|
() => true,
|
|
56096
56454
|
// istanbul ignore next: not sure when this would occur
|
|
56097
56455
|
(err) => err.code === "ENOENT" ? false : Promise.reject(err)
|
|
@@ -56106,7 +56464,7 @@ var require_polyfill = __commonJS({
|
|
|
56106
56464
|
}
|
|
56107
56465
|
let destStat;
|
|
56108
56466
|
try {
|
|
56109
|
-
destStat = await
|
|
56467
|
+
destStat = await stat10(destParent, { bigint: true });
|
|
56110
56468
|
} catch (err) {
|
|
56111
56469
|
if (err.code === "ENOENT") {
|
|
56112
56470
|
return;
|
|
@@ -56146,7 +56504,7 @@ var require_polyfill = __commonJS({
|
|
|
56146
56504
|
}
|
|
56147
56505
|
__name(startCopy, "startCopy");
|
|
56148
56506
|
async function getStatsForCopy(destStat, src, dest, opts) {
|
|
56149
|
-
const statFn = opts.dereference ?
|
|
56507
|
+
const statFn = opts.dereference ? stat10 : lstat27;
|
|
56150
56508
|
const srcStat = await statFn(src);
|
|
56151
56509
|
if (srcStat.isDirectory() && opts.recursive) {
|
|
56152
56510
|
return onDir(srcStat, destStat, src, dest, opts);
|
|
@@ -56193,7 +56551,7 @@ var require_polyfill = __commonJS({
|
|
|
56193
56551
|
__name(onFile, "onFile");
|
|
56194
56552
|
async function mayCopyFile(srcStat, src, dest, opts) {
|
|
56195
56553
|
if (opts.force) {
|
|
56196
|
-
await
|
|
56554
|
+
await unlink6(dest);
|
|
56197
56555
|
return _copyFile(srcStat, src, dest, opts);
|
|
56198
56556
|
} else if (opts.errorOnExist) {
|
|
56199
56557
|
throw new ERR_FS_CP_EEXIST({
|
|
@@ -56239,7 +56597,7 @@ var require_polyfill = __commonJS({
|
|
|
56239
56597
|
}
|
|
56240
56598
|
__name(setDestMode, "setDestMode");
|
|
56241
56599
|
async function setDestTimestamps(src, dest) {
|
|
56242
|
-
const updatedSrcStat = await
|
|
56600
|
+
const updatedSrcStat = await stat10(src);
|
|
56243
56601
|
return utimes(dest, updatedSrcStat.atime, updatedSrcStat.mtime);
|
|
56244
56602
|
}
|
|
56245
56603
|
__name(setDestTimestamps, "setDestTimestamps");
|
|
@@ -56257,11 +56615,11 @@ var require_polyfill = __commonJS({
|
|
|
56257
56615
|
}
|
|
56258
56616
|
__name(mkDirAndCopy, "mkDirAndCopy");
|
|
56259
56617
|
async function copyDir(src, dest, opts) {
|
|
56260
|
-
const dir = await
|
|
56618
|
+
const dir = await readdir21(src);
|
|
56261
56619
|
for (let i = 0; i < dir.length; i++) {
|
|
56262
56620
|
const item = dir[i];
|
|
56263
|
-
const srcItem =
|
|
56264
|
-
const destItem =
|
|
56621
|
+
const srcItem = join34(src, item);
|
|
56622
|
+
const destItem = join34(dest, item);
|
|
56265
56623
|
const { destStat } = await checkPaths(srcItem, destItem, opts);
|
|
56266
56624
|
await startCopy(destStat, srcItem, destItem, opts);
|
|
56267
56625
|
}
|
|
@@ -56295,7 +56653,7 @@ var require_polyfill = __commonJS({
|
|
|
56295
56653
|
errno: EINVAL
|
|
56296
56654
|
});
|
|
56297
56655
|
}
|
|
56298
|
-
const srcStat = await
|
|
56656
|
+
const srcStat = await stat10(src);
|
|
56299
56657
|
if (srcStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
|
|
56300
56658
|
throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({
|
|
56301
56659
|
message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
|
|
@@ -56308,7 +56666,7 @@ var require_polyfill = __commonJS({
|
|
|
56308
56666
|
}
|
|
56309
56667
|
__name(onLink, "onLink");
|
|
56310
56668
|
async function copyLink(resolvedSrc, dest) {
|
|
56311
|
-
await
|
|
56669
|
+
await unlink6(dest);
|
|
56312
56670
|
return symlink(resolvedSrc, dest);
|
|
56313
56671
|
}
|
|
56314
56672
|
__name(copyLink, "copyLink");
|
|
@@ -56337,7 +56695,7 @@ var require_cp = __commonJS({
|
|
|
56337
56695
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js
|
|
56338
56696
|
var require_with_temp_dir = __commonJS({
|
|
56339
56697
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js"(exports, module) {
|
|
56340
|
-
var { join:
|
|
56698
|
+
var { join: join34, sep: sep7 } = __require("path");
|
|
56341
56699
|
var getOptions = require_get_options();
|
|
56342
56700
|
var { mkdir: mkdir24, mkdtemp: mkdtemp10, rm: rm15 } = __require("fs/promises");
|
|
56343
56701
|
var withTempDir = /* @__PURE__ */ __name(async (root, fn, opts) => {
|
|
@@ -56345,7 +56703,7 @@ var require_with_temp_dir = __commonJS({
|
|
|
56345
56703
|
copy: ["tmpPrefix"]
|
|
56346
56704
|
});
|
|
56347
56705
|
await mkdir24(root, { recursive: true });
|
|
56348
|
-
const target = await mkdtemp10(
|
|
56706
|
+
const target = await mkdtemp10(join34(`${root}${sep7}`, options.tmpPrefix || ""));
|
|
56349
56707
|
let err;
|
|
56350
56708
|
let result;
|
|
56351
56709
|
try {
|
|
@@ -56369,14 +56727,14 @@ var require_with_temp_dir = __commonJS({
|
|
|
56369
56727
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/readdir-scoped.js
|
|
56370
56728
|
var require_readdir_scoped = __commonJS({
|
|
56371
56729
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/readdir-scoped.js"(exports, module) {
|
|
56372
|
-
var { readdir:
|
|
56373
|
-
var { join:
|
|
56730
|
+
var { readdir: readdir21 } = __require("fs/promises");
|
|
56731
|
+
var { join: join34 } = __require("path");
|
|
56374
56732
|
var readdirScoped = /* @__PURE__ */ __name(async (dir) => {
|
|
56375
56733
|
const results = [];
|
|
56376
|
-
for (const item of await
|
|
56734
|
+
for (const item of await readdir21(dir)) {
|
|
56377
56735
|
if (item.startsWith("@")) {
|
|
56378
|
-
for (const scopedItem of await
|
|
56379
|
-
results.push(
|
|
56736
|
+
for (const scopedItem of await readdir21(join34(dir, item))) {
|
|
56737
|
+
results.push(join34(item, scopedItem));
|
|
56380
56738
|
}
|
|
56381
56739
|
} else {
|
|
56382
56740
|
results.push(item);
|
|
@@ -56391,7 +56749,7 @@ var require_readdir_scoped = __commonJS({
|
|
|
56391
56749
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js
|
|
56392
56750
|
var require_move_file = __commonJS({
|
|
56393
56751
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js"(exports, module) {
|
|
56394
|
-
var { dirname: dirname18, join:
|
|
56752
|
+
var { dirname: dirname18, join: join34, resolve: resolve35, relative: relative27, isAbsolute: isAbsolute23 } = __require("path");
|
|
56395
56753
|
var fs = __require("fs/promises");
|
|
56396
56754
|
var pathExists2 = /* @__PURE__ */ __name(async (path15) => {
|
|
56397
56755
|
try {
|
|
@@ -56421,7 +56779,7 @@ var require_move_file = __commonJS({
|
|
|
56421
56779
|
if (sourceStat.isDirectory()) {
|
|
56422
56780
|
const files = await fs.readdir(source);
|
|
56423
56781
|
await Promise.all(files.map(
|
|
56424
|
-
(file) => moveFile(
|
|
56782
|
+
(file) => moveFile(join34(source, file), join34(destination, file), options, false, symlinks)
|
|
56425
56783
|
));
|
|
56426
56784
|
} else if (sourceStat.isSymbolicLink()) {
|
|
56427
56785
|
symlinks.push({ source, destination });
|
|
@@ -56695,10 +57053,10 @@ var require_entry_index = __commonJS({
|
|
|
56695
57053
|
var {
|
|
56696
57054
|
appendFile,
|
|
56697
57055
|
mkdir: mkdir24,
|
|
56698
|
-
readFile:
|
|
56699
|
-
readdir:
|
|
57056
|
+
readFile: readFile42,
|
|
57057
|
+
readdir: readdir21,
|
|
56700
57058
|
rm: rm15,
|
|
56701
|
-
writeFile:
|
|
57059
|
+
writeFile: writeFile14
|
|
56702
57060
|
} = __require("fs/promises");
|
|
56703
57061
|
var { Minipass } = require_commonjs();
|
|
56704
57062
|
var path15 = __require("path");
|
|
@@ -56753,7 +57111,7 @@ var require_entry_index = __commonJS({
|
|
|
56753
57111
|
}
|
|
56754
57112
|
}, "teardown");
|
|
56755
57113
|
const write = /* @__PURE__ */ __name(async (tmp2) => {
|
|
56756
|
-
await
|
|
57114
|
+
await writeFile14(tmp2.target, newIndex, { flag: "wx" });
|
|
56757
57115
|
await mkdir24(path15.dirname(bucket), { recursive: true });
|
|
56758
57116
|
await moveFile(tmp2.target, bucket);
|
|
56759
57117
|
tmp2.moved = true;
|
|
@@ -56887,7 +57245,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
56887
57245
|
__name(ls, "ls");
|
|
56888
57246
|
module.exports.bucketEntries = bucketEntries;
|
|
56889
57247
|
async function bucketEntries(bucket, filter) {
|
|
56890
|
-
const data = await
|
|
57248
|
+
const data = await readFile42(bucket, "utf8");
|
|
56891
57249
|
return _bucketEntries(data, filter);
|
|
56892
57250
|
}
|
|
56893
57251
|
__name(bucketEntries, "bucketEntries");
|
|
@@ -56956,7 +57314,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
56956
57314
|
}
|
|
56957
57315
|
__name(formatEntry, "formatEntry");
|
|
56958
57316
|
function readdirOrEmpty(dir) {
|
|
56959
|
-
return
|
|
57317
|
+
return readdir21(dir).catch((err) => {
|
|
56960
57318
|
if (err.code === "ENOENT" || err.code === "ENOTDIR") {
|
|
56961
57319
|
return [];
|
|
56962
57320
|
}
|
|
@@ -57452,16 +57810,16 @@ var require_read2 = __commonJS({
|
|
|
57452
57810
|
var MAX_SINGLE_READ_SIZE = 64 * 1024 * 1024;
|
|
57453
57811
|
async function read(cache, integrity, opts = {}) {
|
|
57454
57812
|
const { size } = opts;
|
|
57455
|
-
const { stat:
|
|
57456
|
-
const
|
|
57457
|
-
return { stat:
|
|
57813
|
+
const { stat: stat10, cpath, sri } = await withContentSri(cache, integrity, async (cpath2, sri2) => {
|
|
57814
|
+
const stat11 = size ? { size } : await fs.stat(cpath2);
|
|
57815
|
+
return { stat: stat11, cpath: cpath2, sri: sri2 };
|
|
57458
57816
|
});
|
|
57459
|
-
if (
|
|
57460
|
-
return readPipeline(cpath,
|
|
57817
|
+
if (stat10.size > MAX_SINGLE_READ_SIZE) {
|
|
57818
|
+
return readPipeline(cpath, stat10.size, sri, new Pipeline()).concat();
|
|
57461
57819
|
}
|
|
57462
57820
|
const data = await fs.readFile(cpath, { encoding: null });
|
|
57463
|
-
if (
|
|
57464
|
-
throw sizeError(
|
|
57821
|
+
if (stat10.size !== data.length) {
|
|
57822
|
+
throw sizeError(stat10.size, data.length);
|
|
57465
57823
|
}
|
|
57466
57824
|
if (!ssri.checkData(data, sri)) {
|
|
57467
57825
|
throw integrityError(sri, cpath);
|
|
@@ -57488,11 +57846,11 @@ var require_read2 = __commonJS({
|
|
|
57488
57846
|
const { size } = opts;
|
|
57489
57847
|
const stream = new Pipeline();
|
|
57490
57848
|
Promise.resolve().then(async () => {
|
|
57491
|
-
const { stat:
|
|
57492
|
-
const
|
|
57493
|
-
return { stat:
|
|
57849
|
+
const { stat: stat10, cpath, sri } = await withContentSri(cache, integrity, async (cpath2, sri2) => {
|
|
57850
|
+
const stat11 = size ? { size } : await fs.stat(cpath2);
|
|
57851
|
+
return { stat: stat11, cpath: cpath2, sri: sri2 };
|
|
57494
57852
|
});
|
|
57495
|
-
return readPipeline(cpath,
|
|
57853
|
+
return readPipeline(cpath, stat10.size, sri, stream);
|
|
57496
57854
|
}).catch((err) => stream.emit("error", err));
|
|
57497
57855
|
return stream;
|
|
57498
57856
|
}
|
|
@@ -57511,8 +57869,8 @@ var require_read2 = __commonJS({
|
|
|
57511
57869
|
}
|
|
57512
57870
|
try {
|
|
57513
57871
|
return await withContentSri(cache, integrity, async (cpath, sri) => {
|
|
57514
|
-
const
|
|
57515
|
-
return { size:
|
|
57872
|
+
const stat10 = await fs.stat(cpath);
|
|
57873
|
+
return { size: stat10.size, sri, stat: stat10 };
|
|
57516
57874
|
});
|
|
57517
57875
|
} catch (err) {
|
|
57518
57876
|
if (err.code === "ENOENT") {
|
|
@@ -62907,11 +63265,11 @@ var require_verify = __commonJS({
|
|
|
62907
63265
|
"use strict";
|
|
62908
63266
|
var {
|
|
62909
63267
|
mkdir: mkdir24,
|
|
62910
|
-
readFile:
|
|
63268
|
+
readFile: readFile42,
|
|
62911
63269
|
rm: rm15,
|
|
62912
|
-
stat:
|
|
63270
|
+
stat: stat10,
|
|
62913
63271
|
truncate,
|
|
62914
|
-
writeFile:
|
|
63272
|
+
writeFile: writeFile14
|
|
62915
63273
|
} = __require("fs/promises");
|
|
62916
63274
|
var contentPath = require_path();
|
|
62917
63275
|
var fsm = require_lib29();
|
|
@@ -63029,7 +63387,7 @@ var require_verify = __commonJS({
|
|
|
63029
63387
|
}
|
|
63030
63388
|
} else {
|
|
63031
63389
|
stats.reclaimedCount++;
|
|
63032
|
-
const s = await
|
|
63390
|
+
const s = await stat10(f);
|
|
63033
63391
|
await rm15(f, { recursive: true, force: true });
|
|
63034
63392
|
stats.reclaimedSize += s.size;
|
|
63035
63393
|
}
|
|
@@ -63043,7 +63401,7 @@ var require_verify = __commonJS({
|
|
|
63043
63401
|
async function verifyContent(filepath, sri) {
|
|
63044
63402
|
const contentInfo = {};
|
|
63045
63403
|
try {
|
|
63046
|
-
const { size } = await
|
|
63404
|
+
const { size } = await stat10(filepath);
|
|
63047
63405
|
contentInfo.size = size;
|
|
63048
63406
|
contentInfo.valid = true;
|
|
63049
63407
|
await ssri.checkStream(new fsm.ReadStream(filepath), sri);
|
|
@@ -63103,7 +63461,7 @@ var require_verify = __commonJS({
|
|
|
63103
63461
|
for (const entry of bucket) {
|
|
63104
63462
|
const content = contentPath(cache, entry.integrity);
|
|
63105
63463
|
try {
|
|
63106
|
-
await
|
|
63464
|
+
await stat10(content);
|
|
63107
63465
|
await index.insert(cache, entry.key, entry.integrity, {
|
|
63108
63466
|
metadata: entry.metadata,
|
|
63109
63467
|
size: entry.size,
|
|
@@ -63129,12 +63487,12 @@ var require_verify = __commonJS({
|
|
|
63129
63487
|
async function writeVerifile(cache, opts) {
|
|
63130
63488
|
const verifile = path15.join(cache, "_lastverified");
|
|
63131
63489
|
opts.log.silly("verify", "writing verifile to " + verifile);
|
|
63132
|
-
return
|
|
63490
|
+
return writeFile14(verifile, `${Date.now()}`);
|
|
63133
63491
|
}
|
|
63134
63492
|
__name(writeVerifile, "writeVerifile");
|
|
63135
63493
|
module.exports.lastRun = lastRun;
|
|
63136
63494
|
async function lastRun(cache) {
|
|
63137
|
-
const data = await
|
|
63495
|
+
const data = await readFile42(path15.join(cache, "_lastverified"), { encoding: "utf8" });
|
|
63138
63496
|
return /* @__PURE__ */ new Date(+data);
|
|
63139
63497
|
}
|
|
63140
63498
|
__name(lastRun, "lastRun");
|
|
@@ -71674,7 +72032,7 @@ var require_index_min = __commonJS({
|
|
|
71674
72032
|
var require_lib35 = __commonJS({
|
|
71675
72033
|
"../../node_modules/.pnpm/which@5.0.0/node_modules/which/lib/index.js"(exports, module) {
|
|
71676
72034
|
var { isexe, sync: isexeSync } = require_index_min();
|
|
71677
|
-
var { join:
|
|
72035
|
+
var { join: join34, delimiter, sep: sep7, posix: posix3 } = __require("path");
|
|
71678
72036
|
var isWindows = process.platform === "win32";
|
|
71679
72037
|
var rSlash = new RegExp(`[${posix3.sep}${sep7 === posix3.sep ? "" : sep7}]`.replace(/(\\)/g, "\\$1"));
|
|
71680
72038
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -71703,7 +72061,7 @@ var require_lib35 = __commonJS({
|
|
|
71703
72061
|
var getPathPart = /* @__PURE__ */ __name((raw, cmd) => {
|
|
71704
72062
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
71705
72063
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
71706
|
-
return prefix +
|
|
72064
|
+
return prefix + join34(pathPart, cmd);
|
|
71707
72065
|
}, "getPathPart");
|
|
71708
72066
|
var which = /* @__PURE__ */ __name(async (cmd, opt = {}) => {
|
|
71709
72067
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -71818,7 +72176,7 @@ var require_escape3 = __commonJS({
|
|
|
71818
72176
|
var require_lib36 = __commonJS({
|
|
71819
72177
|
"../../node_modules/.pnpm/@npmcli+promise-spawn@8.0.3/node_modules/@npmcli/promise-spawn/lib/index.js"(exports, module) {
|
|
71820
72178
|
"use strict";
|
|
71821
|
-
var { spawn:
|
|
72179
|
+
var { spawn: spawn5 } = __require("child_process");
|
|
71822
72180
|
var os4 = __require("os");
|
|
71823
72181
|
var which = require_lib35();
|
|
71824
72182
|
var escape2 = require_escape3();
|
|
@@ -71845,7 +72203,7 @@ var require_lib36 = __commonJS({
|
|
|
71845
72203
|
const resultError = getResult(erOpts);
|
|
71846
72204
|
reject(Object.assign(er, resultError));
|
|
71847
72205
|
}, "rejectWithOpts");
|
|
71848
|
-
const proc =
|
|
72206
|
+
const proc = spawn5(cmd, args2, opts);
|
|
71849
72207
|
promise.stdin = proc.stdin;
|
|
71850
72208
|
promise.process = proc;
|
|
71851
72209
|
proc.on("error", rejectWithOpts);
|
|
@@ -72351,7 +72709,7 @@ var require_which3 = __commonJS({
|
|
|
72351
72709
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/spawn.js
|
|
72352
72710
|
var require_spawn = __commonJS({
|
|
72353
72711
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/spawn.js"(exports, module) {
|
|
72354
|
-
var
|
|
72712
|
+
var spawn5 = require_lib36();
|
|
72355
72713
|
var promiseRetry = require_promise_retry();
|
|
72356
72714
|
var { log } = require_lib21();
|
|
72357
72715
|
var makeError = require_make_error();
|
|
@@ -72376,7 +72734,7 @@ var require_spawn = __commonJS({
|
|
|
72376
72734
|
if (number !== 1) {
|
|
72377
72735
|
log.silly("git", `Retrying git command: ${args2.join(" ")} attempt # ${number}`);
|
|
72378
72736
|
}
|
|
72379
|
-
return
|
|
72737
|
+
return spawn5(gitPath, args2, makeOpts(opts)).catch((er) => {
|
|
72380
72738
|
const gitError = makeError(er);
|
|
72381
72739
|
if (!gitError.shouldRetry(number)) {
|
|
72382
72740
|
throw gitError;
|
|
@@ -72500,7 +72858,7 @@ var require_lines_to_revs = __commonJS({
|
|
|
72500
72858
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/revs.js
|
|
72501
72859
|
var require_revs = __commonJS({
|
|
72502
72860
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/revs.js"(exports, module) {
|
|
72503
|
-
var
|
|
72861
|
+
var spawn5 = require_spawn();
|
|
72504
72862
|
var { LRUCache } = require_commonjs3();
|
|
72505
72863
|
var linesToRevs = require_lines_to_revs();
|
|
72506
72864
|
var revsCache = new LRUCache({
|
|
@@ -72514,7 +72872,7 @@ var require_revs = __commonJS({
|
|
|
72514
72872
|
return cached;
|
|
72515
72873
|
}
|
|
72516
72874
|
}
|
|
72517
|
-
const { stdout } = await
|
|
72875
|
+
const { stdout } = await spawn5(["ls-remote", repo], opts);
|
|
72518
72876
|
const revs = linesToRevs(stdout.trim().split("\n"));
|
|
72519
72877
|
revsCache.set(repo, revs);
|
|
72520
72878
|
return revs;
|
|
@@ -72842,7 +73200,7 @@ var require_lib37 = __commonJS({
|
|
|
72842
73200
|
// ../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js
|
|
72843
73201
|
var require_lib38 = __commonJS({
|
|
72844
73202
|
"../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js"(exports, module) {
|
|
72845
|
-
var { join:
|
|
73203
|
+
var { join: join34, basename: basename13 } = __require("path");
|
|
72846
73204
|
var normalize4 = /* @__PURE__ */ __name((pkg) => !pkg.bin ? removeBin(pkg) : typeof pkg.bin === "string" ? normalizeString(pkg) : Array.isArray(pkg.bin) ? normalizeArray(pkg) : typeof pkg.bin === "object" ? normalizeObject(pkg) : removeBin(pkg), "normalize");
|
|
72847
73205
|
var normalizeString = /* @__PURE__ */ __name((pkg) => {
|
|
72848
73206
|
if (!pkg.name) {
|
|
@@ -72853,7 +73211,7 @@ var require_lib38 = __commonJS({
|
|
|
72853
73211
|
}, "normalizeString");
|
|
72854
73212
|
var normalizeArray = /* @__PURE__ */ __name((pkg) => {
|
|
72855
73213
|
pkg.bin = pkg.bin.reduce((acc, k) => {
|
|
72856
|
-
acc[
|
|
73214
|
+
acc[basename13(k)] = k;
|
|
72857
73215
|
return acc;
|
|
72858
73216
|
}, {});
|
|
72859
73217
|
return normalizeObject(pkg);
|
|
@@ -72867,11 +73225,11 @@ var require_lib38 = __commonJS({
|
|
|
72867
73225
|
const clean = {};
|
|
72868
73226
|
let hasBins = false;
|
|
72869
73227
|
Object.keys(orig).forEach((binKey) => {
|
|
72870
|
-
const base =
|
|
73228
|
+
const base = join34("/", basename13(binKey.replace(/\\|:/g, "/"))).slice(1);
|
|
72871
73229
|
if (typeof orig[binKey] !== "string" || !base) {
|
|
72872
73230
|
return;
|
|
72873
73231
|
}
|
|
72874
|
-
const binTarget =
|
|
73232
|
+
const binTarget = join34("/", orig[binKey].replace(/\\/g, "/")).replace(/\\/g, "/").slice(1);
|
|
72875
73233
|
if (!binTarget) {
|
|
72876
73234
|
return;
|
|
72877
73235
|
}
|
|
@@ -73058,7 +73416,7 @@ var require_clone2 = __commonJS({
|
|
|
73058
73416
|
var { parse: parse2 } = __require("url");
|
|
73059
73417
|
var path15 = __require("path");
|
|
73060
73418
|
var getRevs = require_revs();
|
|
73061
|
-
var
|
|
73419
|
+
var spawn5 = require_spawn();
|
|
73062
73420
|
var { isWindows } = require_utils4();
|
|
73063
73421
|
var pickManifest = require_lib39();
|
|
73064
73422
|
var fs = __require("fs/promises");
|
|
@@ -73112,7 +73470,7 @@ var require_clone2 = __commonJS({
|
|
|
73112
73470
|
var other = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
73113
73471
|
const shallow = maybeShallow(repo, opts);
|
|
73114
73472
|
const fetchOrigin = ["fetch", "origin", revDoc.rawRef].concat(shallow ? ["--depth=1"] : []);
|
|
73115
|
-
const git3 = /* @__PURE__ */ __name((args2) =>
|
|
73473
|
+
const git3 = /* @__PURE__ */ __name((args2) => spawn5(args2, { ...opts, cwd: target }), "git");
|
|
73116
73474
|
return fs.mkdir(target, { recursive: true }).then(() => git3(["init"])).then(() => isWindows(opts) ? git3(["config", "--local", "--add", "core.longpaths", "true"]) : null).then(() => git3(["remote", "add", "origin", repo])).then(() => git3(fetchOrigin)).then(() => git3(["checkout", revDoc.sha])).then(() => updateSubmodules(target, opts)).then(() => revDoc.sha);
|
|
73117
73475
|
}, "other");
|
|
73118
73476
|
var branch = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
@@ -73130,7 +73488,7 @@ var require_clone2 = __commonJS({
|
|
|
73130
73488
|
if (isWindows(opts)) {
|
|
73131
73489
|
args2.push("--config", "core.longpaths=true");
|
|
73132
73490
|
}
|
|
73133
|
-
return
|
|
73491
|
+
return spawn5(args2, opts).then(() => revDoc.sha);
|
|
73134
73492
|
}, "branch");
|
|
73135
73493
|
var plain = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
73136
73494
|
const args2 = [
|
|
@@ -73145,14 +73503,14 @@ var require_clone2 = __commonJS({
|
|
|
73145
73503
|
if (isWindows(opts)) {
|
|
73146
73504
|
args2.push("--config", "core.longpaths=true");
|
|
73147
73505
|
}
|
|
73148
|
-
return
|
|
73506
|
+
return spawn5(args2, opts).then(() => revDoc.sha);
|
|
73149
73507
|
}, "plain");
|
|
73150
73508
|
var updateSubmodules = /* @__PURE__ */ __name(async (target, opts) => {
|
|
73151
73509
|
const hasSubmodules = await fs.stat(`${target}/.gitmodules`).then(() => true).catch(() => false);
|
|
73152
73510
|
if (!hasSubmodules) {
|
|
73153
73511
|
return null;
|
|
73154
73512
|
}
|
|
73155
|
-
return
|
|
73513
|
+
return spawn5([
|
|
73156
73514
|
"submodule",
|
|
73157
73515
|
"update",
|
|
73158
73516
|
"-q",
|
|
@@ -73163,7 +73521,7 @@ var require_clone2 = __commonJS({
|
|
|
73163
73521
|
var unresolved = /* @__PURE__ */ __name((repo, ref, target, opts) => {
|
|
73164
73522
|
const lp = isWindows(opts) ? ["--config", "core.longpaths=true"] : [];
|
|
73165
73523
|
const cloneArgs = ["clone", "--mirror", "-q", repo, target + "/.git"];
|
|
73166
|
-
const git3 = /* @__PURE__ */ __name((args2) =>
|
|
73524
|
+
const git3 = /* @__PURE__ */ __name((args2) => spawn5(args2, { ...opts, cwd: target }), "git");
|
|
73167
73525
|
return fs.mkdir(target, { recursive: true }).then(() => git3(cloneArgs.concat(lp))).then(() => git3(["init"])).then(() => git3(["checkout", ref])).then(() => updateSubmodules(target, opts)).then(() => git3(["rev-parse", "--revs-only", "HEAD"])).then(({ stdout }) => stdout.trim());
|
|
73168
73526
|
}, "unresolved");
|
|
73169
73527
|
}
|
|
@@ -73172,8 +73530,8 @@ var require_clone2 = __commonJS({
|
|
|
73172
73530
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is.js
|
|
73173
73531
|
var require_is = __commonJS({
|
|
73174
73532
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is.js"(exports, module) {
|
|
73175
|
-
var { stat:
|
|
73176
|
-
module.exports = ({ cwd = process.cwd() } = {}) =>
|
|
73533
|
+
var { stat: stat10 } = __require("fs/promises");
|
|
73534
|
+
module.exports = ({ cwd = process.cwd() } = {}) => stat10(cwd + "/.git").then(() => true, () => false);
|
|
73177
73535
|
}
|
|
73178
73536
|
});
|
|
73179
73537
|
|
|
@@ -73200,8 +73558,8 @@ var require_find = __commonJS({
|
|
|
73200
73558
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is-clean.js
|
|
73201
73559
|
var require_is_clean = __commonJS({
|
|
73202
73560
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is-clean.js"(exports, module) {
|
|
73203
|
-
var
|
|
73204
|
-
module.exports = (opts = {}) =>
|
|
73561
|
+
var spawn5 = require_spawn();
|
|
73562
|
+
module.exports = (opts = {}) => spawn5(["status", "--porcelain=v1", "-uno"], opts).then((res) => !res.stdout.trim().split(/\r?\n+/).map((l) => l.trim()).filter((l) => l).length);
|
|
73205
73563
|
}
|
|
73206
73564
|
});
|
|
73207
73565
|
|
|
@@ -75412,11 +75770,11 @@ var require_normalize = __commonJS({
|
|
|
75412
75770
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js
|
|
75413
75771
|
var require_read_package = __commonJS({
|
|
75414
75772
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js"(exports, module) {
|
|
75415
|
-
var { readFile:
|
|
75773
|
+
var { readFile: readFile42 } = __require("fs/promises");
|
|
75416
75774
|
var parseJSON = require_lib34();
|
|
75417
75775
|
async function read(filename) {
|
|
75418
75776
|
try {
|
|
75419
|
-
const data = await
|
|
75777
|
+
const data = await readFile42(filename, "utf8");
|
|
75420
75778
|
return data;
|
|
75421
75779
|
} catch (err) {
|
|
75422
75780
|
err.message = `Could not read package.json: ${err}`;
|
|
@@ -75549,7 +75907,7 @@ var require_sort2 = __commonJS({
|
|
|
75549
75907
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js
|
|
75550
75908
|
var require_lib41 = __commonJS({
|
|
75551
75909
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js"(exports, module) {
|
|
75552
|
-
var { readFile:
|
|
75910
|
+
var { readFile: readFile42, writeFile: writeFile14 } = __require("node:fs/promises");
|
|
75553
75911
|
var { resolve: resolve35 } = __require("node:path");
|
|
75554
75912
|
var parseJSON = require_lib34();
|
|
75555
75913
|
var updateDeps = require_update_dependencies();
|
|
@@ -75676,7 +76034,7 @@ var require_lib41 = __commonJS({
|
|
|
75676
76034
|
const indexFile = resolve35(this.path, "index.js");
|
|
75677
76035
|
let indexFileContent;
|
|
75678
76036
|
try {
|
|
75679
|
-
indexFileContent = await
|
|
76037
|
+
indexFileContent = await readFile42(indexFile, "utf8");
|
|
75680
76038
|
} catch (err) {
|
|
75681
76039
|
throw parseErr;
|
|
75682
76040
|
}
|
|
@@ -75764,7 +76122,7 @@ var require_lib41 = __commonJS({
|
|
|
75764
76122
|
const fileContent = `${JSON.stringify(content, null, format)}
|
|
75765
76123
|
`.replace(/\n/g, eol);
|
|
75766
76124
|
if (fileContent.trim() !== this.#readFileContent.trim()) {
|
|
75767
|
-
const written = await
|
|
76125
|
+
const written = await writeFile14(this.filename, fileContent);
|
|
75768
76126
|
this.#readFileContent = fileContent;
|
|
75769
76127
|
return written;
|
|
75770
76128
|
}
|
|
@@ -82875,12 +83233,12 @@ var require_url = __commonJS({
|
|
|
82875
83233
|
"../../node_modules/.pnpm/tuf-js@3.1.0/node_modules/tuf-js/dist/utils/url.js"(exports) {
|
|
82876
83234
|
"use strict";
|
|
82877
83235
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82878
|
-
exports.join =
|
|
83236
|
+
exports.join = join34;
|
|
82879
83237
|
var url_1 = __require("url");
|
|
82880
|
-
function
|
|
83238
|
+
function join34(base, path15) {
|
|
82881
83239
|
return new url_1.URL(ensureTrailingSlash(base) + removeLeadingSlash(path15)).toString();
|
|
82882
83240
|
}
|
|
82883
|
-
__name(
|
|
83241
|
+
__name(join34, "join");
|
|
82884
83242
|
function ensureTrailingSlash(path15) {
|
|
82885
83243
|
return path15.endsWith("/") ? path15 : path15 + "/";
|
|
82886
83244
|
}
|
|
@@ -84985,7 +85343,7 @@ var require_dist16 = __commonJS({
|
|
|
84985
85343
|
var require_provenance = __commonJS({
|
|
84986
85344
|
"../../node_modules/.pnpm/libnpmpublish@11.1.0/node_modules/libnpmpublish/lib/provenance.js"(exports, module) {
|
|
84987
85345
|
var sigstore = require_dist16();
|
|
84988
|
-
var { readFile:
|
|
85346
|
+
var { readFile: readFile42 } = __require("node:fs/promises");
|
|
84989
85347
|
var ci = require_ci_info();
|
|
84990
85348
|
var { env } = process;
|
|
84991
85349
|
var INTOTO_PAYLOAD_TYPE = "application/vnd.in-toto+json";
|
|
@@ -85177,7 +85535,7 @@ var require_provenance = __commonJS({
|
|
|
85177
85535
|
var verifyProvenance = /* @__PURE__ */ __name(async (subject, provenancePath) => {
|
|
85178
85536
|
let provenanceBundle;
|
|
85179
85537
|
try {
|
|
85180
|
-
provenanceBundle = JSON.parse(await
|
|
85538
|
+
provenanceBundle = JSON.parse(await readFile42(provenancePath));
|
|
85181
85539
|
} catch (err) {
|
|
85182
85540
|
err.message = `Invalid provenance provided: ${err.message}`;
|
|
85183
85541
|
throw err;
|
|
@@ -85513,13 +85871,13 @@ __export(npm_exports, {
|
|
|
85513
85871
|
verifyFrozenNpmTarballContract: () => verifyFrozenNpmTarballContract,
|
|
85514
85872
|
verifyFrozenNpmTarballIdentity: () => verifyFrozenNpmTarballIdentity
|
|
85515
85873
|
});
|
|
85516
|
-
import { createHash as
|
|
85874
|
+
import { createHash as createHash14, randomUUID } from "node:crypto";
|
|
85517
85875
|
import { execFile as execFileCb7, spawn as spawn3 } from "node:child_process";
|
|
85518
85876
|
import { gunzipSync } from "node:zlib";
|
|
85519
85877
|
import { promisify as promisify7 } from "node:util";
|
|
85520
|
-
import { dirname as dirname9, isAbsolute as isAbsolute14, join as
|
|
85878
|
+
import { dirname as dirname9, isAbsolute as isAbsolute14, join as join17, relative as relative17, resolve as resolve19 } from "node:path";
|
|
85521
85879
|
import { constants as fsConstants4 } from "node:fs";
|
|
85522
|
-
import { chmod as chmod3, lstat as lstat18, mkdtemp as mkdtemp6, open as open8, readFile as
|
|
85880
|
+
import { chmod as chmod3, lstat as lstat18, mkdtemp as mkdtemp6, open as open8, readFile as readFile19, realpath as realpath15, rm as rm8 } from "node:fs/promises";
|
|
85523
85881
|
function validatePackageName(value) {
|
|
85524
85882
|
if (typeof value !== "string" || value.length > 214 || !SAFE_PACKAGE_NAME.test(value)) {
|
|
85525
85883
|
throw new Error("npm package must be a safe lowercase package name or @scope/name");
|
|
@@ -85573,7 +85931,7 @@ function expandNpmrcValue(raw, env) {
|
|
|
85573
85931
|
async function tokensFromNpmrc(path15, key, env) {
|
|
85574
85932
|
let contents;
|
|
85575
85933
|
try {
|
|
85576
|
-
contents = await
|
|
85934
|
+
contents = await readFile19(path15, "utf8");
|
|
85577
85935
|
} catch (err) {
|
|
85578
85936
|
if (err?.code === "ENOENT") return [];
|
|
85579
85937
|
throw new Error("cannot read npm authentication config");
|
|
@@ -85596,7 +85954,7 @@ async function defaultResolveAuthToken({ registry, cwd, exec, env = process.env
|
|
|
85596
85954
|
if (env[name]) candidates.push(env[name]);
|
|
85597
85955
|
}
|
|
85598
85956
|
const key = registryTokenKey(registry);
|
|
85599
|
-
candidates.push(...await tokensFromNpmrc(
|
|
85957
|
+
candidates.push(...await tokensFromNpmrc(join17(cwd, ".npmrc"), key, env));
|
|
85600
85958
|
const npmUserConfigKey = ["npm", "config", "userconfig"].join("_");
|
|
85601
85959
|
const userConfig = env[npmUserConfigKey] ?? (await exec("npm", ["config", "get", "userconfig"], { cwd, shell: false })).stdout.trim();
|
|
85602
85960
|
if (userConfig) candidates.push(...await tokensFromNpmrc(userConfig, key, env));
|
|
@@ -85674,12 +86032,12 @@ async function readVerifiedTarballBytes(action, root) {
|
|
|
85674
86032
|
} finally {
|
|
85675
86033
|
await source.close();
|
|
85676
86034
|
}
|
|
85677
|
-
const digest2 =
|
|
86035
|
+
const digest2 = createHash14("sha256").update(bytes).digest("hex");
|
|
85678
86036
|
if (digest2 !== action.tarballSha256) throw new Error("frozen npm tarball SHA-256 mismatch");
|
|
85679
86037
|
if (typeof action.integrity !== "string" || !/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(action.integrity)) {
|
|
85680
86038
|
throw new Error("frozen npm tarball integrity must be an sha512 SRI value");
|
|
85681
86039
|
}
|
|
85682
|
-
const integrity = `sha512-${
|
|
86040
|
+
const integrity = `sha512-${createHash14("sha512").update(bytes).digest("base64")}`;
|
|
85683
86041
|
if (integrity !== action.integrity) throw new Error("frozen npm tarball SHA-512 integrity mismatch");
|
|
85684
86042
|
return bytes;
|
|
85685
86043
|
}
|
|
@@ -86127,9 +86485,9 @@ var init_npm = __esm({
|
|
|
86127
86485
|
});
|
|
86128
86486
|
|
|
86129
86487
|
// src/core/run.mjs
|
|
86130
|
-
import { lstat as lstat19, mkdir as mkdir12, readFile as
|
|
86488
|
+
import { lstat as lstat19, mkdir as mkdir12, readFile as readFile20 } from "node:fs/promises";
|
|
86131
86489
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
86132
|
-
import { dirname as dirname10, join as
|
|
86490
|
+
import { dirname as dirname10, join as join18, resolve as resolve20, basename as basename5, relative as relative18, isAbsolute as isAbsolute15 } from "node:path";
|
|
86133
86491
|
function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.now()}`) {
|
|
86134
86492
|
const absolute = resolve20(planPath);
|
|
86135
86493
|
const fileName = basename5(absolute);
|
|
@@ -86139,7 +86497,7 @@ function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.no
|
|
|
86139
86497
|
}
|
|
86140
86498
|
if (basename5(parentDir) === "plans") {
|
|
86141
86499
|
const releaseDir = dirname10(parentDir);
|
|
86142
|
-
return
|
|
86500
|
+
return join18(releaseDir, "runs", runId);
|
|
86143
86501
|
}
|
|
86144
86502
|
return `${parentDir}/runs/${runId}`;
|
|
86145
86503
|
}
|
|
@@ -86179,7 +86537,7 @@ function validateRun(run5, options = {}) {
|
|
|
86179
86537
|
async function loadRun(runPath, options = {}) {
|
|
86180
86538
|
let raw;
|
|
86181
86539
|
try {
|
|
86182
|
-
raw = await
|
|
86540
|
+
raw = await readFile20(runPath, "utf8");
|
|
86183
86541
|
} catch (err) {
|
|
86184
86542
|
throw new ReleaseError(
|
|
86185
86543
|
GATE_FAILED,
|
|
@@ -86218,7 +86576,7 @@ function assertImmutableRunAuthority(runPath, planPath, run5) {
|
|
|
86218
86576
|
}
|
|
86219
86577
|
cursor = dirname10(cursor);
|
|
86220
86578
|
}
|
|
86221
|
-
const runsDir =
|
|
86579
|
+
const runsDir = join18(authorityRoot, "runs");
|
|
86222
86580
|
const absoluteRun = realpathSync3(resolve20(runPath));
|
|
86223
86581
|
const rel = relative18(runsDir, absoluteRun);
|
|
86224
86582
|
if (isAbsolute15(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
@@ -86273,7 +86631,7 @@ async function createProductionPrepareRunDir(runDir, releaseDir) {
|
|
|
86273
86631
|
return createProductionRunDirWithinAuthority(runDir, physicalAuthorityRoot);
|
|
86274
86632
|
}
|
|
86275
86633
|
async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
86276
|
-
const runsDir =
|
|
86634
|
+
const runsDir = join18(authorityRoot, "runs");
|
|
86277
86635
|
let runsStat;
|
|
86278
86636
|
try {
|
|
86279
86637
|
runsStat = await lstat19(runsDir);
|
|
@@ -86383,7 +86741,7 @@ async function validateStatePredecessorChain(run5, runPath, options = {}) {
|
|
|
86383
86741
|
if (traversed > 1e5) {
|
|
86384
86742
|
throw new ReleaseError(GATE_FAILED, "run state predecessor chain exceeds maximum depth");
|
|
86385
86743
|
}
|
|
86386
|
-
const previousPath =
|
|
86744
|
+
const previousPath = join18(dirname10(currentPath), `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
86387
86745
|
const previous = await loadRun(previousPath, {
|
|
86388
86746
|
requireDigest: true,
|
|
86389
86747
|
...options.production ? { authorityPlanPath: options.planPath } : {}
|
|
@@ -86556,7 +86914,7 @@ async function writeRunAtomic(runPath, run5) {
|
|
|
86556
86914
|
await publishFileExclusive(dir, basename5(runPath), json, { mode: 384 });
|
|
86557
86915
|
} catch (cause) {
|
|
86558
86916
|
if (cause?.details?.kind === HARNESS_ERROR_KINDS.EXCLUSIVE_PUBLISH_CONFLICT) {
|
|
86559
|
-
const existing = await
|
|
86917
|
+
const existing = await readFile20(runPath, "utf8").catch(() => null);
|
|
86560
86918
|
if (existing === json) return Object.freeze(sealed);
|
|
86561
86919
|
throw new ReleaseError(
|
|
86562
86920
|
GATE_FAILED,
|
|
@@ -86576,10 +86934,10 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
86576
86934
|
if (!Number.isSafeInteger(sequence) || sequence < 0) {
|
|
86577
86935
|
throw new ReleaseError(GATE_FAILED, "run state sequence must be a non-negative integer");
|
|
86578
86936
|
}
|
|
86579
|
-
const statesDir =
|
|
86937
|
+
const statesDir = join18(runDir, "states");
|
|
86580
86938
|
let previousStateDigest;
|
|
86581
86939
|
if (sequence > 0) {
|
|
86582
|
-
const previousPath =
|
|
86940
|
+
const previousPath = join18(statesDir, `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
86583
86941
|
const previous = await loadRun(previousPath, { requireDigest: true });
|
|
86584
86942
|
if (previous.stateSequence !== sequence - 1 || previous.runId !== run5.runId || previous.command !== run5.command || previous.planDigest !== run5.planDigest) {
|
|
86585
86943
|
throw new ReleaseError(
|
|
@@ -86596,7 +86954,7 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
86596
86954
|
stateSequence: sequence,
|
|
86597
86955
|
...previousStateDigest ? { previousStateDigest } : {}
|
|
86598
86956
|
});
|
|
86599
|
-
const statePath =
|
|
86957
|
+
const statePath = join18(statesDir, `${String(sequence).padStart(6, "0")}.json`);
|
|
86600
86958
|
await writeRunAtomic(statePath, state);
|
|
86601
86959
|
return Object.freeze({ state, statePath });
|
|
86602
86960
|
}
|
|
@@ -86649,9 +87007,9 @@ __export(plugin_marketplace_exports, {
|
|
|
86649
87007
|
});
|
|
86650
87008
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
86651
87009
|
import { promisify as promisify8 } from "node:util";
|
|
86652
|
-
import { readFile as
|
|
86653
|
-
import { join as
|
|
86654
|
-
import { createHash as
|
|
87010
|
+
import { readFile as readFile21, stat as stat5, mkdir as mkdir13, readdir as readdir13, realpath as realpath16, lstat as lstat20 } from "node:fs/promises";
|
|
87011
|
+
import { join as join19, resolve as resolve21, relative as relative19, isAbsolute as isAbsolute16, basename as basename6 } from "node:path";
|
|
87012
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
86655
87013
|
function transportPayload(entries) {
|
|
86656
87014
|
return entries.map(({ path: path15, type, mode, size, contentDigest }) => ({
|
|
86657
87015
|
path: path15,
|
|
@@ -86736,7 +87094,7 @@ async function resolvePluginManifestFromMarketplaceEntrySource(marketIndex, plug
|
|
|
86736
87094
|
const fullManifestRelative = pluginRootRelToSnapshot === "" ? manifestRelative : `${pluginRootRelToSnapshot}/${manifestRelative}`;
|
|
86737
87095
|
let raw;
|
|
86738
87096
|
try {
|
|
86739
|
-
raw = await
|
|
87097
|
+
raw = await readFile21(manifestAbs, "utf8");
|
|
86740
87098
|
} catch (err) {
|
|
86741
87099
|
throw new Error(
|
|
86742
87100
|
`plugin manifest not found at "${fullManifestRelative}": ${err.message}`
|
|
@@ -87185,7 +87543,7 @@ async function run2(cmd, args2, options = {}) {
|
|
|
87185
87543
|
}
|
|
87186
87544
|
async function validateManifestFile(manifestPath, requiredFields) {
|
|
87187
87545
|
try {
|
|
87188
|
-
const content = await
|
|
87546
|
+
const content = await readFile21(manifestPath, "utf8");
|
|
87189
87547
|
const manifest = JSON.parse(content);
|
|
87190
87548
|
const missing = requiredFields.filter((f) => !(f in manifest));
|
|
87191
87549
|
return {
|
|
@@ -87207,7 +87565,7 @@ async function checkRequiredFiles(dir, requiredFiles) {
|
|
|
87207
87565
|
const missing = [];
|
|
87208
87566
|
for (const file of requiredFiles) {
|
|
87209
87567
|
try {
|
|
87210
|
-
await
|
|
87568
|
+
await stat5(resolve21(dir, file));
|
|
87211
87569
|
} catch {
|
|
87212
87570
|
missing.push(file);
|
|
87213
87571
|
}
|
|
@@ -87303,7 +87661,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
87303
87661
|
});
|
|
87304
87662
|
}
|
|
87305
87663
|
try {
|
|
87306
|
-
const s = await
|
|
87664
|
+
const s = await stat5(pluginDir);
|
|
87307
87665
|
if (!s.isDirectory()) {
|
|
87308
87666
|
return createResult({
|
|
87309
87667
|
actionType,
|
|
@@ -88089,7 +88447,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88089
88447
|
let entrySkillFile = resolve21(pluginRootForSkill, "skills", action.entrySkill, "SKILL.md");
|
|
88090
88448
|
let entrySkillExists = false;
|
|
88091
88449
|
try {
|
|
88092
|
-
await
|
|
88450
|
+
await stat5(entrySkillFile);
|
|
88093
88451
|
entrySkillExists = true;
|
|
88094
88452
|
} catch {
|
|
88095
88453
|
if (action.plugin) {
|
|
@@ -88100,7 +88458,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88100
88458
|
"SKILL.md"
|
|
88101
88459
|
);
|
|
88102
88460
|
try {
|
|
88103
|
-
await
|
|
88461
|
+
await stat5(prefixed);
|
|
88104
88462
|
entrySkillFile = prefixed;
|
|
88105
88463
|
entrySkillExists = true;
|
|
88106
88464
|
} catch {
|
|
@@ -88517,7 +88875,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88517
88875
|
if (actionType === ActionType.PLUGIN_MANIFEST_VALIDATE) {
|
|
88518
88876
|
const manifestPath = action.manifestPath;
|
|
88519
88877
|
try {
|
|
88520
|
-
const content = await
|
|
88878
|
+
const content = await readFile21(manifestPath, "utf8");
|
|
88521
88879
|
const manifest = JSON.parse(content);
|
|
88522
88880
|
return createResult({
|
|
88523
88881
|
actionType,
|
|
@@ -88612,7 +88970,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88612
88970
|
}
|
|
88613
88971
|
let requirement = null;
|
|
88614
88972
|
try {
|
|
88615
|
-
requirement = JSON.parse(await
|
|
88973
|
+
requirement = JSON.parse(await readFile21(resolve21(attestationDir, KIMI_REQUIREMENT_FILE), "utf8"));
|
|
88616
88974
|
} catch {
|
|
88617
88975
|
return createResult({
|
|
88618
88976
|
actionType,
|
|
@@ -88636,7 +88994,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88636
88994
|
}
|
|
88637
88995
|
let attestation = null;
|
|
88638
88996
|
try {
|
|
88639
|
-
attestation = JSON.parse(await
|
|
88997
|
+
attestation = JSON.parse(await readFile21(resolve21(attestationDir, KIMI_ATTESTATION_FILE), "utf8"));
|
|
88640
88998
|
} catch {
|
|
88641
88999
|
return createResult({
|
|
88642
89000
|
actionType,
|
|
@@ -88803,7 +89161,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88803
89161
|
}
|
|
88804
89162
|
let requirement = null;
|
|
88805
89163
|
try {
|
|
88806
|
-
requirement = JSON.parse(await
|
|
89164
|
+
requirement = JSON.parse(await readFile21(resolve21(attestationDir, CODEBUDDY_REQUIREMENT_FILE), "utf8"));
|
|
88807
89165
|
} catch {
|
|
88808
89166
|
return createResult({
|
|
88809
89167
|
actionType,
|
|
@@ -88827,7 +89185,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88827
89185
|
}
|
|
88828
89186
|
let attestation = null;
|
|
88829
89187
|
try {
|
|
88830
|
-
attestation = JSON.parse(await
|
|
89188
|
+
attestation = JSON.parse(await readFile21(resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE), "utf8"));
|
|
88831
89189
|
} catch {
|
|
88832
89190
|
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
88833
89191
|
return createResult({
|
|
@@ -88976,13 +89334,13 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88976
89334
|
if (codexAttestationDir) {
|
|
88977
89335
|
let codexRequirement = null;
|
|
88978
89336
|
try {
|
|
88979
|
-
codexRequirement = JSON.parse(await
|
|
89337
|
+
codexRequirement = JSON.parse(await readFile21(resolve21(codexAttestationDir, CODEX_REQUIREMENT_FILE), "utf8"));
|
|
88980
89338
|
} catch {
|
|
88981
89339
|
}
|
|
88982
89340
|
if (codexRequirement && codexRequirement.planDigest === codexBoundPlanDigest && codexRequirement.plugin === action.plugin && codexRequirement.version === action.version && codexRequirement.repo === action.repo && codexRequirement.ref === (action.ref ?? `v${action.version}`) && (!action.entrySkill || codexRequirement.entrySkill === action.entrySkill)) {
|
|
88983
89341
|
let codexAttestation = null;
|
|
88984
89342
|
try {
|
|
88985
|
-
codexAttestation = JSON.parse(await
|
|
89343
|
+
codexAttestation = JSON.parse(await readFile21(resolve21(codexAttestationDir, CODEX_ATTESTATION_FILE), "utf8"));
|
|
88986
89344
|
} catch {
|
|
88987
89345
|
}
|
|
88988
89346
|
if (codexAttestation) {
|
|
@@ -89037,7 +89395,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
89037
89395
|
}
|
|
89038
89396
|
let evidence = null;
|
|
89039
89397
|
try {
|
|
89040
|
-
const evidenceRaw = await
|
|
89398
|
+
const evidenceRaw = await readFile21(resolve21(runDir, "evidence", `${consumer}-${action.plugin}`, "release-skill-install-evidence.json"), "utf8");
|
|
89041
89399
|
evidence = JSON.parse(evidenceRaw);
|
|
89042
89400
|
} catch {
|
|
89043
89401
|
return createResult({
|
|
@@ -89220,7 +89578,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
89220
89578
|
}
|
|
89221
89579
|
try {
|
|
89222
89580
|
const installedManifestPath = resolve21(installPath, platform.manifestPaths.plugin);
|
|
89223
|
-
const installedManifestContent = await
|
|
89581
|
+
const installedManifestContent = await readFile21(installedManifestPath, "utf8");
|
|
89224
89582
|
const installedManifest = JSON.parse(installedManifestContent);
|
|
89225
89583
|
const expectedName = observation.plugin;
|
|
89226
89584
|
if (expectedName && installedManifest.name !== expectedName) {
|
|
@@ -89651,8 +90009,8 @@ var init_postpublish = __esm({
|
|
|
89651
90009
|
});
|
|
89652
90010
|
|
|
89653
90011
|
// src/artifacts/transaction-journal.mjs
|
|
89654
|
-
import { readdir as
|
|
89655
|
-
import { join as
|
|
90012
|
+
import { readdir as readdir14, readFile as readFile22, rm as rm9, stat as stat6 } from "node:fs/promises";
|
|
90013
|
+
import { join as join20 } from "node:path";
|
|
89656
90014
|
function failSchema(message, details) {
|
|
89657
90015
|
throw new ReleaseError(TRANSACTION_INCOMPLETE, message, details);
|
|
89658
90016
|
}
|
|
@@ -90649,7 +91007,7 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90649
91007
|
if (!Number.isInteger(retentionMax) || retentionMax < 0) return summary;
|
|
90650
91008
|
let entries;
|
|
90651
91009
|
try {
|
|
90652
|
-
entries = await
|
|
91010
|
+
entries = await readdir14(transactionsRoot, { withFileTypes: true });
|
|
90653
91011
|
} catch (scanErr) {
|
|
90654
91012
|
summary.errors.push(`scan: ${scanErr?.code || scanErr?.message || "readdir-failed"}`);
|
|
90655
91013
|
return summary;
|
|
@@ -90659,11 +91017,11 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90659
91017
|
if (txnDirs.length <= retentionMax) return summary;
|
|
90660
91018
|
const terminal = [];
|
|
90661
91019
|
for (const entry of txnDirs) {
|
|
90662
|
-
const recordDir =
|
|
91020
|
+
const recordDir = join20(transactionsRoot, entry.name);
|
|
90663
91021
|
let state = null;
|
|
90664
91022
|
let createdAt = null;
|
|
90665
91023
|
try {
|
|
90666
|
-
const raw = await
|
|
91024
|
+
const raw = await readFile22(join20(recordDir, "journal.json"), "utf8");
|
|
90667
91025
|
const journal = JSON.parse(raw);
|
|
90668
91026
|
if (journal && typeof journal === "object") {
|
|
90669
91027
|
state = typeof journal.state === "string" ? journal.state : null;
|
|
@@ -90676,7 +91034,7 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90676
91034
|
let sortTime = Date.parse(createdAt);
|
|
90677
91035
|
if (!Number.isFinite(sortTime)) {
|
|
90678
91036
|
try {
|
|
90679
|
-
const dirStat = await
|
|
91037
|
+
const dirStat = await stat6(recordDir);
|
|
90680
91038
|
sortTime = dirStat.mtimeMs;
|
|
90681
91039
|
} catch {
|
|
90682
91040
|
sortTime = Number.MAX_SAFE_INTEGER;
|
|
@@ -90727,7 +91085,7 @@ async function createTransactionJournal({
|
|
|
90727
91085
|
);
|
|
90728
91086
|
if (typeof root === "string" && root.length > 0) {
|
|
90729
91087
|
await pruneTerminalTransactionRecords(
|
|
90730
|
-
|
|
91088
|
+
join20(root, ".release-skill", "transactions"),
|
|
90731
91089
|
{ retentionMax }
|
|
90732
91090
|
);
|
|
90733
91091
|
}
|
|
@@ -94862,6 +95220,7 @@ var init_refresh_service = __esm({
|
|
|
94862
95220
|
// src/commands/prepare.mjs
|
|
94863
95221
|
var prepare_exports = {};
|
|
94864
95222
|
__export(prepare_exports, {
|
|
95223
|
+
boundedOutputTail: () => boundedOutputTail,
|
|
94865
95224
|
buildExternalActions: () => buildExternalActions,
|
|
94866
95225
|
decodeExternalMarketplaceIndex: () => decodeExternalMarketplaceIndex,
|
|
94867
95226
|
parseExternalMarketplaceLsRemote: () => parseExternalMarketplaceLsRemote,
|
|
@@ -94873,8 +95232,8 @@ __export(prepare_exports, {
|
|
|
94873
95232
|
resolveUnitVersion: () => resolveUnitVersion,
|
|
94874
95233
|
runDeclaredHooks: () => runDeclaredHooks
|
|
94875
95234
|
});
|
|
94876
|
-
import { resolve as resolve23, relative as relative22, isAbsolute as isAbsolute18, normalize as normalize3, dirname as dirname11 } from "node:path";
|
|
94877
|
-
import { readFile as
|
|
95235
|
+
import { resolve as resolve23, relative as relative22, isAbsolute as isAbsolute18, normalize as normalize3, dirname as dirname11, basename as basename7 } from "node:path";
|
|
95236
|
+
import { readFile as readFile23, mkdir as mkdir14, readdir as readdir15, realpath as realpath17 } from "node:fs/promises";
|
|
94878
95237
|
import { execFile as execFileCb9 } from "node:child_process";
|
|
94879
95238
|
import { promisify as promisify9 } from "node:util";
|
|
94880
95239
|
async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
@@ -94906,7 +95265,7 @@ async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
|
94906
95265
|
}
|
|
94907
95266
|
let content;
|
|
94908
95267
|
try {
|
|
94909
|
-
content = await
|
|
95268
|
+
content = await readFile23(normalizedPath, "utf8");
|
|
94910
95269
|
} catch (err) {
|
|
94911
95270
|
throw new ReleaseError(
|
|
94912
95271
|
CONFIG_INVALID,
|
|
@@ -94968,17 +95327,38 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
94968
95327
|
});
|
|
94969
95328
|
return resolvedVersions;
|
|
94970
95329
|
}
|
|
95330
|
+
function boundedOutputTail(text) {
|
|
95331
|
+
if (typeof text !== "string" || text.length === 0) return "";
|
|
95332
|
+
let lines = text.split("\n");
|
|
95333
|
+
if (lines.length > 1 && lines[lines.length - 1] === "") {
|
|
95334
|
+
lines = lines.slice(0, -1);
|
|
95335
|
+
}
|
|
95336
|
+
let tail2 = lines.slice(-HOOK_OUTPUT_TAIL_MAX_LINES);
|
|
95337
|
+
let joined = tail2.join("\n");
|
|
95338
|
+
while (tail2.length > 1 && Buffer.byteLength(joined, "utf8") > HOOK_OUTPUT_TAIL_MAX_BYTES) {
|
|
95339
|
+
tail2 = tail2.slice(1);
|
|
95340
|
+
joined = tail2.join("\n");
|
|
95341
|
+
}
|
|
95342
|
+
if (Buffer.byteLength(joined, "utf8") > HOOK_OUTPUT_TAIL_MAX_BYTES) {
|
|
95343
|
+
const buf = Buffer.from(joined, "utf8");
|
|
95344
|
+
joined = buf.subarray(buf.length - HOOK_OUTPUT_TAIL_MAX_BYTES).toString("utf8");
|
|
95345
|
+
}
|
|
95346
|
+
return joined;
|
|
95347
|
+
}
|
|
94971
95348
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
94972
95349
|
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
94973
95350
|
const hooks = config.hooks ?? {};
|
|
94974
95351
|
const cacheEnabled = options.hookCache !== false;
|
|
95352
|
+
const records = [];
|
|
94975
95353
|
for (const name of hookOrder) {
|
|
94976
95354
|
const hook = hooks[name];
|
|
94977
95355
|
if (!hook) continue;
|
|
95356
|
+
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
94978
95357
|
await evidence.append({
|
|
94979
95358
|
phase: "hooks",
|
|
94980
95359
|
status: "started",
|
|
94981
|
-
hookName: name
|
|
95360
|
+
hookName: name,
|
|
95361
|
+
...selectionField
|
|
94982
95362
|
});
|
|
94983
95363
|
let cacheKey;
|
|
94984
95364
|
if (cacheEnabled && hook.cacheable === true) {
|
|
@@ -95000,8 +95380,10 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95000
95380
|
status: "completed",
|
|
95001
95381
|
hookName: name,
|
|
95002
95382
|
cached: true,
|
|
95003
|
-
cacheKey
|
|
95383
|
+
cacheKey,
|
|
95384
|
+
...selectionField
|
|
95004
95385
|
});
|
|
95386
|
+
records.push({ name, completed: true, cached: true, testSelection: selectionField.testSelection });
|
|
95005
95387
|
continue;
|
|
95006
95388
|
}
|
|
95007
95389
|
}
|
|
@@ -95016,7 +95398,8 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95016
95398
|
phase: "hooks",
|
|
95017
95399
|
status: "failed",
|
|
95018
95400
|
hookName: name,
|
|
95019
|
-
error: { code: err.code, message: err.message }
|
|
95401
|
+
error: { code: err.code, message: err.message },
|
|
95402
|
+
...selectionField
|
|
95020
95403
|
});
|
|
95021
95404
|
throw new ReleaseError(
|
|
95022
95405
|
GATE_FAILED,
|
|
@@ -95025,16 +95408,31 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95025
95408
|
);
|
|
95026
95409
|
}
|
|
95027
95410
|
if (result.exitCode !== 0) {
|
|
95411
|
+
const stdoutTail = boundedOutputTail(result.stdout);
|
|
95412
|
+
const stderrTail = boundedOutputTail(result.stderr);
|
|
95413
|
+
process.stderr.write(`[release-skill] hook "${name}" failed with exit code ${result.exitCode}
|
|
95414
|
+
`);
|
|
95415
|
+
if (stdoutTail) {
|
|
95416
|
+
process.stderr.write(`[release-skill] hook "${name}" stdout tail:
|
|
95417
|
+
${stdoutTail}
|
|
95418
|
+
`);
|
|
95419
|
+
}
|
|
95420
|
+
if (stderrTail) {
|
|
95421
|
+
process.stderr.write(`[release-skill] hook "${name}" stderr tail:
|
|
95422
|
+
${stderrTail}
|
|
95423
|
+
`);
|
|
95424
|
+
}
|
|
95028
95425
|
await evidence.append({
|
|
95029
95426
|
phase: "hooks",
|
|
95030
95427
|
status: "failed",
|
|
95031
95428
|
hookName: name,
|
|
95032
95429
|
exitCode: result.exitCode,
|
|
95033
95430
|
// Test runners usually emit the actionable failure summary at the
|
|
95034
|
-
// end. Preserve bounded tails
|
|
95035
|
-
// compiler prelude at the beginning.
|
|
95036
|
-
stdoutTail
|
|
95037
|
-
stderrTail
|
|
95431
|
+
// end. Preserve bounded tails (last 50 lines, capped at 8 KB) of both
|
|
95432
|
+
// streams instead of the noisy compiler prelude at the beginning.
|
|
95433
|
+
stdoutTail,
|
|
95434
|
+
stderrTail,
|
|
95435
|
+
...selectionField
|
|
95038
95436
|
});
|
|
95039
95437
|
throw new ReleaseError(
|
|
95040
95438
|
GATE_FAILED,
|
|
@@ -95062,9 +95460,12 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95062
95460
|
phase: "hooks",
|
|
95063
95461
|
status: "completed",
|
|
95064
95462
|
hookName: name,
|
|
95065
|
-
exitCode: 0
|
|
95463
|
+
exitCode: 0,
|
|
95464
|
+
...selectionField
|
|
95066
95465
|
});
|
|
95466
|
+
records.push({ name, completed: true, cached: false, testSelection: selectionField.testSelection });
|
|
95067
95467
|
}
|
|
95468
|
+
return records;
|
|
95068
95469
|
}
|
|
95069
95470
|
async function resolveReleaseDocsPlanFn(injected) {
|
|
95070
95471
|
if (typeof injected === "function") return injected;
|
|
@@ -96021,7 +96422,7 @@ async function readLatestFrozenPlan(root) {
|
|
|
96021
96422
|
const plansDir = resolve23(root, ".release-skill", "plans");
|
|
96022
96423
|
let files;
|
|
96023
96424
|
try {
|
|
96024
|
-
files = await
|
|
96425
|
+
files = await readdir15(plansDir);
|
|
96025
96426
|
} catch {
|
|
96026
96427
|
return null;
|
|
96027
96428
|
}
|
|
@@ -96030,7 +96431,7 @@ async function readLatestFrozenPlan(root) {
|
|
|
96030
96431
|
if (!file.endsWith(".json")) continue;
|
|
96031
96432
|
let plan;
|
|
96032
96433
|
try {
|
|
96033
|
-
plan = JSON.parse(await
|
|
96434
|
+
plan = JSON.parse(await readFile23(resolve23(plansDir, file), "utf8"));
|
|
96034
96435
|
} catch {
|
|
96035
96436
|
continue;
|
|
96036
96437
|
}
|
|
@@ -96055,7 +96456,8 @@ async function prepareRelease(options) {
|
|
|
96055
96456
|
verificationGatesAuthorized,
|
|
96056
96457
|
production = false,
|
|
96057
96458
|
workflow = "full",
|
|
96058
|
-
observePreviousPublicBaselineFn
|
|
96459
|
+
observePreviousPublicBaselineFn,
|
|
96460
|
+
testSelection = "full"
|
|
96059
96461
|
} = options ?? {};
|
|
96060
96462
|
const WORKFLOW_KINDS2 = /* @__PURE__ */ new Set(["full", "docs", "config", "marketplace"]);
|
|
96061
96463
|
if (!WORKFLOW_KINDS2.has(workflow)) {
|
|
@@ -96065,6 +96467,20 @@ async function prepareRelease(options) {
|
|
|
96065
96467
|
{ workflow }
|
|
96066
96468
|
);
|
|
96067
96469
|
}
|
|
96470
|
+
if (testSelection === "incremental") {
|
|
96471
|
+
throw new ReleaseError(
|
|
96472
|
+
GATE_FAILED,
|
|
96473
|
+
"incremental selection is not allowed at freeze time",
|
|
96474
|
+
{ testSelection, reservedFor: "preflight mode" }
|
|
96475
|
+
);
|
|
96476
|
+
}
|
|
96477
|
+
if (testSelection !== "full") {
|
|
96478
|
+
throw new ReleaseError(
|
|
96479
|
+
CONFIG_INVALID,
|
|
96480
|
+
`unknown testSelection "${testSelection}"; expected "full" or "incremental"`,
|
|
96481
|
+
{ testSelection }
|
|
96482
|
+
);
|
|
96483
|
+
}
|
|
96068
96484
|
const trimmedWorkflow = workflow !== "full";
|
|
96069
96485
|
const skipDeclaredHooks = trimmedWorkflow;
|
|
96070
96486
|
const skipSnapshotVerifyGates = trimmedWorkflow;
|
|
@@ -96128,6 +96544,34 @@ async function prepareRelease(options) {
|
|
|
96128
96544
|
...warning
|
|
96129
96545
|
});
|
|
96130
96546
|
}
|
|
96547
|
+
await evidence.append({ phase: "bundle-freshness", status: "started" });
|
|
96548
|
+
const bundleFreshnessFn = options.bundleFreshnessFn ?? assertBundleFreshness;
|
|
96549
|
+
let bundleFreshness;
|
|
96550
|
+
try {
|
|
96551
|
+
bundleFreshness = await bundleFreshnessFn(PKG_ROOT);
|
|
96552
|
+
} catch (err) {
|
|
96553
|
+
await evidence.append({
|
|
96554
|
+
phase: "bundle-freshness",
|
|
96555
|
+
status: "blocking",
|
|
96556
|
+
reason: err.details?.reason ?? null,
|
|
96557
|
+
error: { code: err.code, message: err.message }
|
|
96558
|
+
});
|
|
96559
|
+
throw err;
|
|
96560
|
+
}
|
|
96561
|
+
if (bundleFreshness?.applicable === false) {
|
|
96562
|
+
await evidence.append({
|
|
96563
|
+
phase: "bundle-freshness",
|
|
96564
|
+
status: "not-applicable",
|
|
96565
|
+
reason: bundleFreshness.reason
|
|
96566
|
+
});
|
|
96567
|
+
} else {
|
|
96568
|
+
await evidence.append({
|
|
96569
|
+
phase: "bundle-freshness",
|
|
96570
|
+
status: "completed",
|
|
96571
|
+
algorithm: bundleFreshness?.algorithm ?? null,
|
|
96572
|
+
sourceDigest: bundleFreshness?.sourceDigest ?? null
|
|
96573
|
+
});
|
|
96574
|
+
}
|
|
96131
96575
|
await evidence.append({
|
|
96132
96576
|
phase: "workflow",
|
|
96133
96577
|
status: "configured",
|
|
@@ -96210,6 +96654,7 @@ async function prepareRelease(options) {
|
|
|
96210
96654
|
}))
|
|
96211
96655
|
});
|
|
96212
96656
|
}
|
|
96657
|
+
let hookRecords = [];
|
|
96213
96658
|
if (skipDeclaredHooks) {
|
|
96214
96659
|
await evidence.append({
|
|
96215
96660
|
phase: "hooks",
|
|
@@ -96218,7 +96663,7 @@ async function prepareRelease(options) {
|
|
|
96218
96663
|
});
|
|
96219
96664
|
} else {
|
|
96220
96665
|
await evidence.append({ phase: "hooks", status: "started" });
|
|
96221
|
-
await runDeclaredHooks(config, realRoot, evidence, options.runHookFn ?? runHook, {
|
|
96666
|
+
hookRecords = await runDeclaredHooks(config, realRoot, evidence, options.runHookFn ?? runHook, {
|
|
96222
96667
|
hookCache: options.hookCache,
|
|
96223
96668
|
// Explicit env delivery (0.5.1 hook-env-delivery fix): the hook runner
|
|
96224
96669
|
// reads envAllowlist keys exclusively from context.env, so the invoking
|
|
@@ -96734,6 +97179,47 @@ async function prepareRelease(options) {
|
|
|
96734
97179
|
await evidence.append({ phase: "remote-check", status: "skipped", reason: "offline mode" });
|
|
96735
97180
|
}
|
|
96736
97181
|
await evidence.append({ phase: "plan-assembly", status: "started" });
|
|
97182
|
+
if (skipDeclaredHooks) {
|
|
97183
|
+
await evidence.append({
|
|
97184
|
+
phase: "full-test-gate",
|
|
97185
|
+
status: "skipped",
|
|
97186
|
+
reason: `workflow "${workflow}" trims declared hooks`
|
|
97187
|
+
});
|
|
97188
|
+
} else if (!config.hooks?.test) {
|
|
97189
|
+
await evidence.append({
|
|
97190
|
+
phase: "full-test-gate",
|
|
97191
|
+
status: "not-declared",
|
|
97192
|
+
reason: "no test hook declared; nothing can run incrementally"
|
|
97193
|
+
});
|
|
97194
|
+
} else {
|
|
97195
|
+
const testRecord = hookRecords.find((record) => record.name === "test");
|
|
97196
|
+
const satisfied = Boolean(
|
|
97197
|
+
testRecord && testRecord.completed && testRecord.testSelection === "full"
|
|
97198
|
+
);
|
|
97199
|
+
if (!satisfied) {
|
|
97200
|
+
await evidence.append({
|
|
97201
|
+
phase: "full-test-gate",
|
|
97202
|
+
status: "blocking",
|
|
97203
|
+
testSelection: testRecord?.testSelection ?? null,
|
|
97204
|
+
cached: Boolean(testRecord?.cached)
|
|
97205
|
+
});
|
|
97206
|
+
throw new ReleaseError(
|
|
97207
|
+
GATE_FAILED,
|
|
97208
|
+
testRecord?.testSelection === "incremental" ? "full-test freeze gate failed: incremental test selection cannot satisfy the freeze-time requirement of a completed full test run in this prepare run" : "full-test freeze gate failed: prepare requires a completed full-mode test hook in this run before the plan digest is computed",
|
|
97209
|
+
{
|
|
97210
|
+
gate: "full-test-freeze",
|
|
97211
|
+
testSelection: testRecord?.testSelection ?? null,
|
|
97212
|
+
cached: Boolean(testRecord?.cached)
|
|
97213
|
+
}
|
|
97214
|
+
);
|
|
97215
|
+
}
|
|
97216
|
+
await evidence.append({
|
|
97217
|
+
phase: "full-test-gate",
|
|
97218
|
+
status: "completed",
|
|
97219
|
+
testSelection: "full",
|
|
97220
|
+
cached: Boolean(testRecord.cached)
|
|
97221
|
+
});
|
|
97222
|
+
}
|
|
96737
97223
|
const createdAtTimestamp = production ? normalizeGitTimestamp(clock ? clock() : (/* @__PURE__ */ new Date()).toISOString(), "plan createdAt timestamp") : null;
|
|
96738
97224
|
const freezeTimestamp = production ? await readHeadCommitTimestamp(realRoot, baseline.gitHead) : null;
|
|
96739
97225
|
const productionAssets = production ? await buildProductionAssets(
|
|
@@ -96764,7 +97250,11 @@ async function prepareRelease(options) {
|
|
|
96764
97250
|
snapshotDir: manifest.outputDir,
|
|
96765
97251
|
host: "root"
|
|
96766
97252
|
});
|
|
96767
|
-
const receipt = createSkillResourceClosureReceipt(closureResult, {
|
|
97253
|
+
const receipt = createSkillResourceClosureReceipt(closureResult, {
|
|
97254
|
+
unitId: unit.id,
|
|
97255
|
+
preparedAt: freezeTimestamp ?? null,
|
|
97256
|
+
exitCode: 0
|
|
97257
|
+
});
|
|
96768
97258
|
skillResourceClosureResults.push(receipt);
|
|
96769
97259
|
if (closureResult.findings.length > 0) {
|
|
96770
97260
|
await evidence.append({
|
|
@@ -96777,7 +97267,10 @@ async function prepareRelease(options) {
|
|
|
96777
97267
|
line: f.line,
|
|
96778
97268
|
reference: f.reference,
|
|
96779
97269
|
classification: f.classification,
|
|
96780
|
-
code: f.code
|
|
97270
|
+
code: f.code,
|
|
97271
|
+
// D4: RESOURCE_DRIFT findings localize via references (the
|
|
97272
|
+
// finding's own skill/line stay null for a cross-surface drift).
|
|
97273
|
+
...f.references ? { references: f.references } : {}
|
|
96781
97274
|
}))
|
|
96782
97275
|
});
|
|
96783
97276
|
throw new ReleaseError(
|
|
@@ -96790,6 +97283,33 @@ async function prepareRelease(options) {
|
|
|
96790
97283
|
}
|
|
96791
97284
|
);
|
|
96792
97285
|
}
|
|
97286
|
+
const expectedHosts = (unit.distributions ?? []).map((distribution) => PLATFORMS.find((platform) => platform.distributionType === distribution.type)).filter(Boolean).map((platform) => platform.buildAdapter.name);
|
|
97287
|
+
const hostCoverage = evaluateDeclaredHostSurfaceCoverage(
|
|
97288
|
+
expectedHosts,
|
|
97289
|
+
closureResult.surfaces
|
|
97290
|
+
);
|
|
97291
|
+
if (!hostCoverage.passed) {
|
|
97292
|
+
await evidence.append({
|
|
97293
|
+
phase: "skill-resource-closure",
|
|
97294
|
+
status: "blocking",
|
|
97295
|
+
unitId: unit.id,
|
|
97296
|
+
reason: "declared-host-surface-missing",
|
|
97297
|
+
missingHosts: hostCoverage.missing
|
|
97298
|
+
});
|
|
97299
|
+
throw new ReleaseError(
|
|
97300
|
+
GATE_FAILED,
|
|
97301
|
+
`skill resource closure gate failed for unit "${unit.id}": declared host surface(s) missing or empty: ${hostCoverage.missing.map((item) => item.host).join(", ")}`,
|
|
97302
|
+
{
|
|
97303
|
+
unitId: unit.id,
|
|
97304
|
+
missingHosts: hostCoverage.missing,
|
|
97305
|
+
observedSurfaces: closureResult.surfaces.map((surface) => ({
|
|
97306
|
+
id: surface.id,
|
|
97307
|
+
host: surface.host,
|
|
97308
|
+
skillCount: surface.skillCount
|
|
97309
|
+
}))
|
|
97310
|
+
}
|
|
97311
|
+
);
|
|
97312
|
+
}
|
|
96793
97313
|
await evidence.append({
|
|
96794
97314
|
phase: "skill-resource-closure",
|
|
96795
97315
|
status: "completed",
|
|
@@ -96799,6 +97319,10 @@ async function prepareRelease(options) {
|
|
|
96799
97319
|
skillCount: receipt.skillCount,
|
|
96800
97320
|
referenceCount: closureResult.referenceCount,
|
|
96801
97321
|
sourceOnlyCount: closureResult.sourceOnlyCount,
|
|
97322
|
+
// D2: per-reference exemption detail for approval/audit review —
|
|
97323
|
+
// evidence-layer only; the receipt object (and its digest binding)
|
|
97324
|
+
// is intentionally left unchanged.
|
|
97325
|
+
sourceOnlyReferences: closureResult.sourceOnlyReferences,
|
|
96802
97326
|
findingCount: 0,
|
|
96803
97327
|
receiptDigest: closureResult.receiptDigest
|
|
96804
97328
|
});
|
|
@@ -96890,7 +97414,7 @@ async function prepareRelease(options) {
|
|
|
96890
97414
|
const marketplaceIndexPath = resolve23(snapshotDir, marketplaceIndexRelative);
|
|
96891
97415
|
let marketplaceIndexRaw;
|
|
96892
97416
|
try {
|
|
96893
|
-
marketplaceIndexRaw = await
|
|
97417
|
+
marketplaceIndexRaw = await readFile23(marketplaceIndexPath, "utf8");
|
|
96894
97418
|
} catch (err) {
|
|
96895
97419
|
throw new ReleaseError(
|
|
96896
97420
|
GATE_FAILED,
|
|
@@ -96959,7 +97483,7 @@ async function prepareRelease(options) {
|
|
|
96959
97483
|
const pluginManifestPath = resolve23(snapshotDir, pluginManifestRelative);
|
|
96960
97484
|
let raw;
|
|
96961
97485
|
try {
|
|
96962
|
-
raw = await
|
|
97486
|
+
raw = await readFile23(pluginManifestPath, "utf8");
|
|
96963
97487
|
} catch (err) {
|
|
96964
97488
|
throw new ReleaseError(
|
|
96965
97489
|
GATE_FAILED,
|
|
@@ -97196,6 +97720,19 @@ async function prepareRelease(options) {
|
|
|
97196
97720
|
planPath: writtenPath,
|
|
97197
97721
|
planDigest
|
|
97198
97722
|
});
|
|
97723
|
+
await writeFrozenMarker(releaseDir, {
|
|
97724
|
+
planDigest,
|
|
97725
|
+
targetVersions: Object.fromEntries(
|
|
97726
|
+
configUnits.map((unit, index) => [unit.id, resolvedVersions[index]])
|
|
97727
|
+
),
|
|
97728
|
+
createdAt: plan.createdAt,
|
|
97729
|
+
runId: basename7(runDir)
|
|
97730
|
+
});
|
|
97731
|
+
await evidence.append({
|
|
97732
|
+
phase: "frozen-marker",
|
|
97733
|
+
status: "written",
|
|
97734
|
+
markerPath: `.release-skill/${FROZEN_MARKER_FILENAME}`
|
|
97735
|
+
});
|
|
97199
97736
|
await evidence.finish({
|
|
97200
97737
|
status: "PREPARED",
|
|
97201
97738
|
planPath: writtenPath,
|
|
@@ -97231,7 +97768,7 @@ async function prepareRelease(options) {
|
|
|
97231
97768
|
await lock.release();
|
|
97232
97769
|
}
|
|
97233
97770
|
}
|
|
97234
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
97771
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_OUTPUT_TAIL_MAX_LINES, HOOK_OUTPUT_TAIL_MAX_BYTES, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
97235
97772
|
var init_prepare = __esm({
|
|
97236
97773
|
async "src/commands/prepare.mjs"() {
|
|
97237
97774
|
await init_config();
|
|
@@ -97250,6 +97787,9 @@ var init_prepare = __esm({
|
|
|
97250
97787
|
init_contract2();
|
|
97251
97788
|
init_frozen();
|
|
97252
97789
|
init_errors();
|
|
97790
|
+
init_bundle_freshness();
|
|
97791
|
+
init_pkg_root();
|
|
97792
|
+
init_frozen_marker();
|
|
97253
97793
|
init_source_authority();
|
|
97254
97794
|
init_project_lock();
|
|
97255
97795
|
init_previous_public_baseline();
|
|
@@ -97263,6 +97803,9 @@ var init_prepare = __esm({
|
|
|
97263
97803
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
97264
97804
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
97265
97805
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
97806
|
+
HOOK_OUTPUT_TAIL_MAX_LINES = 50;
|
|
97807
|
+
HOOK_OUTPUT_TAIL_MAX_BYTES = 8 * 1024;
|
|
97808
|
+
__name(boundedOutputTail, "boundedOutputTail");
|
|
97266
97809
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
97267
97810
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
97268
97811
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -97332,8 +97875,8 @@ var init_hooks2 = __esm({
|
|
|
97332
97875
|
});
|
|
97333
97876
|
|
|
97334
97877
|
// src/core/approval.mjs
|
|
97335
|
-
import { readFile as
|
|
97336
|
-
import { basename as
|
|
97878
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
97879
|
+
import { basename as basename8, dirname as dirname12, join as join21, resolve as resolve25 } from "node:path";
|
|
97337
97880
|
function validateApprovalRecordSchema(approval) {
|
|
97338
97881
|
if (validateApprovalSchema(approval)) return;
|
|
97339
97882
|
const errors = validateApprovalSchema.errors ?? [];
|
|
@@ -97352,7 +97895,7 @@ function assertImmutableApprovalAuthority(approvalPath, plan, rawApproval) {
|
|
|
97352
97895
|
const approvalDigest = computeApprovalDigest(rawApproval);
|
|
97353
97896
|
const absolute = resolve25(approvalPath);
|
|
97354
97897
|
const planDirectory = dirname12(absolute);
|
|
97355
|
-
if (
|
|
97898
|
+
if (basename8(absolute) !== `${approvalDigest}.json` || basename8(planDirectory) !== planDigest || basename8(dirname12(planDirectory)) !== "approvals") {
|
|
97356
97899
|
throw new ReleaseError(
|
|
97357
97900
|
GATE_FAILED,
|
|
97358
97901
|
"production commands require approvals/<planDigest>/<approvalDigest>.json immutable authority",
|
|
@@ -97619,8 +98162,8 @@ var approve_exports = {};
|
|
|
97619
98162
|
__export(approve_exports, {
|
|
97620
98163
|
approvePlan: () => approvePlan
|
|
97621
98164
|
});
|
|
97622
|
-
import { readFile as
|
|
97623
|
-
import { resolve as resolve26, dirname as dirname13, basename as
|
|
98165
|
+
import { readFile as readFile25, writeFile as writeFile7 } from "node:fs/promises";
|
|
98166
|
+
import { resolve as resolve26, dirname as dirname13, basename as basename9 } from "node:path";
|
|
97624
98167
|
function defaultClock() {
|
|
97625
98168
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
97626
98169
|
}
|
|
@@ -97643,7 +98186,7 @@ async function approvePlan(options) {
|
|
|
97643
98186
|
}
|
|
97644
98187
|
let planRaw;
|
|
97645
98188
|
try {
|
|
97646
|
-
planRaw = await
|
|
98189
|
+
planRaw = await readFile25(planPath, "utf8");
|
|
97647
98190
|
} catch (err) {
|
|
97648
98191
|
throw new ReleaseError(
|
|
97649
98192
|
GATE_FAILED,
|
|
@@ -97749,7 +98292,7 @@ async function approvePlan(options) {
|
|
|
97749
98292
|
};
|
|
97750
98293
|
validateApprovalRecordSchema(approvalRecord);
|
|
97751
98294
|
const planDir = dirname13(resolve26(planPath));
|
|
97752
|
-
const releaseDir =
|
|
98295
|
+
const releaseDir = basename9(planDir) === "plans" && basename9(planPath) === `${actualDigest}.json` ? dirname13(planDir) : planDir;
|
|
97753
98296
|
if (plan.production?.mode === "github-npm-v1" && outputPath && resolve26(outputPath) !== resolve26(releaseDir, "approval-record.json")) {
|
|
97754
98297
|
throw new ReleaseError(
|
|
97755
98298
|
GATE_FAILED,
|
|
@@ -97768,10 +98311,10 @@ async function approvePlan(options) {
|
|
|
97768
98311
|
await prepareAuthorityDirectory(dirname13(immutableApprovalPath));
|
|
97769
98312
|
await assertAuthorityFileTarget(immutableApprovalPath);
|
|
97770
98313
|
try {
|
|
97771
|
-
await
|
|
98314
|
+
await writeFile7(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
97772
98315
|
} catch (error) {
|
|
97773
98316
|
if (error.code !== "EEXIST") throw error;
|
|
97774
|
-
const existing = await
|
|
98317
|
+
const existing = await readFile25(immutableApprovalPath, "utf8");
|
|
97775
98318
|
if (existing !== json) {
|
|
97776
98319
|
throw new ReleaseError(
|
|
97777
98320
|
GATE_FAILED,
|
|
@@ -97783,7 +98326,7 @@ async function approvePlan(options) {
|
|
|
97783
98326
|
const writePath = outputPath ?? resolve26(releaseDir, "approval-record.json");
|
|
97784
98327
|
await prepareAuthorityDirectory(dirname13(writePath));
|
|
97785
98328
|
await assertAuthorityFileTarget(writePath);
|
|
97786
|
-
await
|
|
98329
|
+
await writeFile7(writePath, json, "utf8");
|
|
97787
98330
|
return Object.freeze({
|
|
97788
98331
|
...approvalRecord,
|
|
97789
98332
|
approvalDigest,
|
|
@@ -98073,8 +98616,8 @@ __export(publish_exports, {
|
|
|
98073
98616
|
classifyPreObservation: () => classifyPreObservation,
|
|
98074
98617
|
publishRelease: () => publishRelease
|
|
98075
98618
|
});
|
|
98076
|
-
import { readFile as
|
|
98077
|
-
import { isAbsolute as isAbsolute19, join as
|
|
98619
|
+
import { readFile as readFile26, mkdir as mkdir16 } from "node:fs/promises";
|
|
98620
|
+
import { isAbsolute as isAbsolute19, join as join22, relative as relative23 } from "node:path";
|
|
98078
98621
|
function assertInsideAssetRoot(assetRoot, candidate, label) {
|
|
98079
98622
|
const rel = relative23(assetRoot, candidate);
|
|
98080
98623
|
if (rel === "" || isAbsolute19(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
@@ -98306,7 +98849,7 @@ async function publishRelease(options) {
|
|
|
98306
98849
|
const captureBaselineActual = typeof captureBaselineFn === "function" ? captureBaselineFn : captureBaseline;
|
|
98307
98850
|
let planRaw;
|
|
98308
98851
|
try {
|
|
98309
|
-
planRaw = await
|
|
98852
|
+
planRaw = await readFile26(planPath, "utf8");
|
|
98310
98853
|
} catch (err) {
|
|
98311
98854
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
98312
98855
|
}
|
|
@@ -98450,7 +98993,11 @@ async function publishRelease(options) {
|
|
|
98450
98993
|
{ unitId, findings: closureResult.findings }
|
|
98451
98994
|
);
|
|
98452
98995
|
}
|
|
98453
|
-
const observed = createSkillResourceClosureReceipt(closureResult, {
|
|
98996
|
+
const observed = createSkillResourceClosureReceipt(closureResult, {
|
|
98997
|
+
unitId,
|
|
98998
|
+
preparedAt: expected.preparedAt ?? null,
|
|
98999
|
+
exitCode: expected.exitCode ?? 0
|
|
99000
|
+
});
|
|
98454
99001
|
assertSkillResourceClosureReceipt(expected, observed, `unit "${unitId}"`);
|
|
98455
99002
|
}
|
|
98456
99003
|
await evidence.append({
|
|
@@ -98464,7 +99011,7 @@ async function publishRelease(options) {
|
|
|
98464
99011
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
98465
99012
|
let approvalRaw;
|
|
98466
99013
|
try {
|
|
98467
|
-
approvalRaw = await
|
|
99014
|
+
approvalRaw = await readFile26(approvalPath, "utf8");
|
|
98468
99015
|
} catch (err) {
|
|
98469
99016
|
throw new ReleaseError(
|
|
98470
99017
|
GATE_FAILED,
|
|
@@ -98778,7 +99325,7 @@ async function publishRelease(options) {
|
|
|
98778
99325
|
}
|
|
98779
99326
|
}
|
|
98780
99327
|
await evidence.append({ phase: "safety-gate", gate: "global-preflight", status: "passed" });
|
|
98781
|
-
const runPath =
|
|
99328
|
+
const runPath = join22(runDir, "release-run.json");
|
|
98782
99329
|
const checkpoints = orderedActions.map((action) => {
|
|
98783
99330
|
if (isMarketplaceAction(action.type)) {
|
|
98784
99331
|
return {
|
|
@@ -99051,8 +99598,8 @@ var reconcile_exports = {};
|
|
|
99051
99598
|
__export(reconcile_exports, {
|
|
99052
99599
|
reconcileRelease: () => reconcileRelease
|
|
99053
99600
|
});
|
|
99054
|
-
import { readFile as
|
|
99055
|
-
import { join as
|
|
99601
|
+
import { readFile as readFile27, mkdir as mkdir17 } from "node:fs/promises";
|
|
99602
|
+
import { join as join23 } from "node:path";
|
|
99056
99603
|
function defaultClock4() {
|
|
99057
99604
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
99058
99605
|
}
|
|
@@ -99080,7 +99627,7 @@ async function reconcileRelease(options) {
|
|
|
99080
99627
|
}
|
|
99081
99628
|
let planRaw;
|
|
99082
99629
|
try {
|
|
99083
|
-
planRaw = await
|
|
99630
|
+
planRaw = await readFile27(planPath, "utf8");
|
|
99084
99631
|
} catch (err) {
|
|
99085
99632
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
99086
99633
|
}
|
|
@@ -99202,7 +99749,7 @@ async function reconcileRelease(options) {
|
|
|
99202
99749
|
{ sourceRunId: sourceRun.runId }
|
|
99203
99750
|
);
|
|
99204
99751
|
}
|
|
99205
|
-
const sourceApprovalRaw = await
|
|
99752
|
+
const sourceApprovalRaw = await readFile27(consumedApprovalPath, "utf8").catch((error) => {
|
|
99206
99753
|
throw new ReleaseError(GATE_FAILED, "source run approval authority is unavailable", {
|
|
99207
99754
|
sourceRunId: sourceRun.runId,
|
|
99208
99755
|
cause: error.code
|
|
@@ -99364,7 +99911,7 @@ async function reconcileRelease(options) {
|
|
|
99364
99911
|
if (approvalPath) {
|
|
99365
99912
|
let approvalRaw;
|
|
99366
99913
|
try {
|
|
99367
|
-
approvalRaw = await
|
|
99914
|
+
approvalRaw = await readFile27(approvalPath, "utf8");
|
|
99368
99915
|
} catch (err) {
|
|
99369
99916
|
throw new ReleaseError(
|
|
99370
99917
|
GATE_FAILED,
|
|
@@ -99977,7 +100524,7 @@ async function reconcileRelease(options) {
|
|
|
99977
100524
|
...normalized === "deferred" ? { reason: CONSUMER_VERIFICATION_DEFERRED, phase: "post-publish-verification" } : {}
|
|
99978
100525
|
};
|
|
99979
100526
|
});
|
|
99980
|
-
const runPath =
|
|
100527
|
+
const runPath = join23(runDir, "release-run.json");
|
|
99981
100528
|
const sourceRunDigest = sourceAuthorityDigest;
|
|
99982
100529
|
const runState = {
|
|
99983
100530
|
runId,
|
|
@@ -100057,7 +100604,7 @@ var init_reconcile = __esm({
|
|
|
100057
100604
|
});
|
|
100058
100605
|
|
|
100059
100606
|
// src/core/baseline-advance.mjs
|
|
100060
|
-
import { readFile as
|
|
100607
|
+
import { readFile as readFile28, writeFile as writeFile8 } from "node:fs/promises";
|
|
100061
100608
|
import { execFile as execFileCb10 } from "node:child_process";
|
|
100062
100609
|
import { promisify as promisify10 } from "node:util";
|
|
100063
100610
|
function defaultExec(command2, args2, options = {}) {
|
|
@@ -100091,7 +100638,7 @@ async function applyBaselineAdvances({ configPath, advances, validateFn }) {
|
|
|
100091
100638
|
}
|
|
100092
100639
|
let content;
|
|
100093
100640
|
try {
|
|
100094
|
-
content = await
|
|
100641
|
+
content = await readFile28(configPath, "utf8");
|
|
100095
100642
|
} catch (err) {
|
|
100096
100643
|
throw new ReleaseError(
|
|
100097
100644
|
GATE_FAILED,
|
|
@@ -100133,12 +100680,12 @@ async function applyBaselineAdvances({ configPath, advances, validateFn }) {
|
|
|
100133
100680
|
return { changed: false, updatedUnits: [] };
|
|
100134
100681
|
}
|
|
100135
100682
|
const next = doc.toString();
|
|
100136
|
-
await
|
|
100683
|
+
await writeFile8(configPath, next, "utf8");
|
|
100137
100684
|
if (typeof validateFn === "function") {
|
|
100138
100685
|
try {
|
|
100139
100686
|
await validateFn(configPath);
|
|
100140
100687
|
} catch (err) {
|
|
100141
|
-
await
|
|
100688
|
+
await writeFile8(configPath, content, "utf8");
|
|
100142
100689
|
throw new ReleaseError(
|
|
100143
100690
|
GATE_FAILED,
|
|
100144
100691
|
`baseline advance reverted: rewritten config failed validation: ${err.message}`,
|
|
@@ -100185,9 +100732,9 @@ __export(verify_exports, {
|
|
|
100185
100732
|
runSmokeTest: () => runSmokeTest,
|
|
100186
100733
|
verifyRelease: () => verifyRelease
|
|
100187
100734
|
});
|
|
100188
|
-
import { readFile as
|
|
100735
|
+
import { readFile as readFile29, writeFile as writeFile9, mkdtemp as mkdtemp7, rm as rm10, mkdir as mkdir18, lstat as lstat21, realpath as realpath18, readdir as readdir16 } from "node:fs/promises";
|
|
100189
100736
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
100190
|
-
import { dirname as dirname14, join as
|
|
100737
|
+
import { dirname as dirname14, join as join24, relative as relative24, isAbsolute as isAbsolute20, resolve as resolve27, basename as basename10 } from "node:path";
|
|
100191
100738
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
100192
100739
|
import { execFile as execFileCb11 } from "node:child_process";
|
|
100193
100740
|
import { promisify as promisify11 } from "node:util";
|
|
@@ -100240,18 +100787,18 @@ async function collectMissingManualAttestations({
|
|
|
100240
100787
|
const isKimi = action.type === "kimi-marketplace-install";
|
|
100241
100788
|
const planDigest = isKimi ? resolveBoundPlanDigest(context) : await resolveCodeBuddyBoundPlanDigest(context);
|
|
100242
100789
|
const authorityDir = isKimi ? kimiAuthorityDir(context, planDigest, action.parameters.plugin) : codebuddyAuthorityDir(context, planDigest, action.parameters.plugin);
|
|
100243
|
-
const requirementPath =
|
|
100790
|
+
const requirementPath = join24(
|
|
100244
100791
|
authorityDir,
|
|
100245
100792
|
isKimi ? KIMI_REQUIREMENT_FILE : CODEBUDDY_REQUIREMENT_FILE
|
|
100246
100793
|
);
|
|
100247
|
-
const attestationPath =
|
|
100794
|
+
const attestationPath = join24(
|
|
100248
100795
|
authorityDir,
|
|
100249
100796
|
isKimi ? KIMI_ATTESTATION_FILE : CODEBUDDY_ATTESTATION_FILE
|
|
100250
100797
|
);
|
|
100251
100798
|
let valid = false;
|
|
100252
100799
|
let reason = "attestation file is missing";
|
|
100253
100800
|
try {
|
|
100254
|
-
const attestation = JSON.parse(await
|
|
100801
|
+
const attestation = JSON.parse(await readFile29(attestationPath, "utf8"));
|
|
100255
100802
|
const validation = isKimi ? validateKimiAttestation(attestation, action.parameters, clockFn(), planDigest) : validateCodeBuddyAttestation(attestation, action.parameters, clockFn(), planDigest);
|
|
100256
100803
|
valid = validation.valid;
|
|
100257
100804
|
reason = validation.error;
|
|
@@ -100293,7 +100840,7 @@ function matchesSubset2(actual, expected) {
|
|
|
100293
100840
|
async function runSmokeTest(plan, root, options = {}) {
|
|
100294
100841
|
const baseDir = options.baseDir ?? tmpdir4();
|
|
100295
100842
|
await mkdir18(baseDir, { recursive: true });
|
|
100296
|
-
const tmpDir = await mkdtemp7(
|
|
100843
|
+
const tmpDir = await mkdtemp7(join24(baseDir, "verify-smoke-"));
|
|
100297
100844
|
const npmExec = options.npmExecutor ?? defaultNpmExecutor;
|
|
100298
100845
|
const installFlags = [
|
|
100299
100846
|
"--ignore-scripts",
|
|
@@ -100341,7 +100888,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100341
100888
|
for (const { package: pkgName, registry, targetVersion, unitId, smokeBin, smokeArgs, smokeExpectedJson } of npmDistributions) {
|
|
100342
100889
|
const packageAtVersion = `${pkgName}@${targetVersion}`;
|
|
100343
100890
|
const installDir = resolveUnitScopedPath(tmpDir, unitId);
|
|
100344
|
-
await mkdir18(
|
|
100891
|
+
await mkdir18(join24(installDir, "node_modules"), { recursive: true });
|
|
100345
100892
|
const registryFlags = [...installFlags, "--registry", registry];
|
|
100346
100893
|
const installResult = await npmExec.install(
|
|
100347
100894
|
packageAtVersion,
|
|
@@ -100359,10 +100906,10 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100359
100906
|
}
|
|
100360
100907
|
};
|
|
100361
100908
|
}
|
|
100362
|
-
const installedPkgPath =
|
|
100909
|
+
const installedPkgPath = join24(installDir, "node_modules", pkgName, "package.json");
|
|
100363
100910
|
let installedPkg;
|
|
100364
100911
|
try {
|
|
100365
|
-
installedPkg = JSON.parse(await
|
|
100912
|
+
installedPkg = JSON.parse(await readFile29(installedPkgPath, "utf8"));
|
|
100366
100913
|
} catch {
|
|
100367
100914
|
return {
|
|
100368
100915
|
passed: false,
|
|
@@ -100393,7 +100940,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100393
100940
|
}
|
|
100394
100941
|
};
|
|
100395
100942
|
}
|
|
100396
|
-
const pkgRoot =
|
|
100943
|
+
const pkgRoot = join24(installDir, "node_modules", pkgName);
|
|
100397
100944
|
{
|
|
100398
100945
|
const dirIndex = await buildDirectoryFileIndex(pkgRoot);
|
|
100399
100946
|
const closureResult = checkNpmEntryClosure(installedPkg, dirIndex);
|
|
@@ -100622,7 +101169,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100622
101169
|
}
|
|
100623
101170
|
async function discoverDistributeRuns({ planPath, plan }) {
|
|
100624
101171
|
const planDir = dirname14(planPath);
|
|
100625
|
-
const releaseDir =
|
|
101172
|
+
const releaseDir = basename10(planDir) === "plans" ? dirname14(planDir) : planDir;
|
|
100626
101173
|
const runsDir = resolve27(releaseDir, "runs");
|
|
100627
101174
|
try {
|
|
100628
101175
|
const runsDirStat = await lstat21(runsDir);
|
|
@@ -100654,7 +101201,7 @@ async function discoverDistributeRuns({ planPath, plan }) {
|
|
|
100654
101201
|
return null;
|
|
100655
101202
|
}
|
|
100656
101203
|
const candidates = [];
|
|
100657
|
-
const entries = await
|
|
101204
|
+
const entries = await readdir16(runsDir, { withFileTypes: true });
|
|
100658
101205
|
for (const entry of entries) {
|
|
100659
101206
|
if (!entry.name.startsWith("distribute-")) continue;
|
|
100660
101207
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
@@ -100719,7 +101266,7 @@ async function verifyRelease(options) {
|
|
|
100719
101266
|
}
|
|
100720
101267
|
let planRaw;
|
|
100721
101268
|
try {
|
|
100722
|
-
planRaw = await
|
|
101269
|
+
planRaw = await readFile29(planPath, "utf8");
|
|
100723
101270
|
} catch (err) {
|
|
100724
101271
|
throw new ReleaseError(
|
|
100725
101272
|
GATE_FAILED,
|
|
@@ -100808,7 +101355,7 @@ async function verifyRelease(options) {
|
|
|
100808
101355
|
}
|
|
100809
101356
|
let approvalRaw;
|
|
100810
101357
|
try {
|
|
100811
|
-
approvalRaw = await
|
|
101358
|
+
approvalRaw = await readFile29(sourceRun.approvalPath, "utf8");
|
|
100812
101359
|
} catch (error) {
|
|
100813
101360
|
throw new ReleaseError(
|
|
100814
101361
|
GATE_FAILED,
|
|
@@ -100884,7 +101431,7 @@ async function verifyRelease(options) {
|
|
|
100884
101431
|
const actions = plan.externalActions ?? [];
|
|
100885
101432
|
const trustedVerifyRuns = [];
|
|
100886
101433
|
const planDir = dirname14(planPath);
|
|
100887
|
-
const releaseDir =
|
|
101434
|
+
const releaseDir = basename10(planDir) === "plans" ? dirname14(planDir) : planDir;
|
|
100888
101435
|
const runsDir = resolve27(releaseDir, "runs");
|
|
100889
101436
|
let runsDirReal = null;
|
|
100890
101437
|
let authorityDirReal = null;
|
|
@@ -100927,7 +101474,7 @@ async function verifyRelease(options) {
|
|
|
100927
101474
|
runsDirReal = null;
|
|
100928
101475
|
}
|
|
100929
101476
|
if (runsDirReal) {
|
|
100930
|
-
const entries = await
|
|
101477
|
+
const entries = await readdir16(runsDirReal, { withFileTypes: true });
|
|
100931
101478
|
for (const entry of entries) {
|
|
100932
101479
|
if (!entry.name.startsWith("verify-")) continue;
|
|
100933
101480
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
@@ -101379,7 +101926,7 @@ async function verifyRelease(options) {
|
|
|
101379
101926
|
assertTransition(PUBLISHED, VERIFIED);
|
|
101380
101927
|
await evidence.append({ phase: "verify", status: "completed", overallStatus: VERIFIED });
|
|
101381
101928
|
const sourceRunDigest = sourceRun.runDigest ?? computeRunDigest(sourceRun);
|
|
101382
|
-
const verifyRunPath =
|
|
101929
|
+
const verifyRunPath = join24(runDir, "release-run.json");
|
|
101383
101930
|
const verifyRunState = {
|
|
101384
101931
|
runId,
|
|
101385
101932
|
command: "verify",
|
|
@@ -101421,11 +101968,24 @@ async function verifyRelease(options) {
|
|
|
101421
101968
|
finishedAt: clockFn()
|
|
101422
101969
|
};
|
|
101423
101970
|
const persistedVerifyRun = await writeRunAtomic(verifyRunPath, verifyRunState);
|
|
101971
|
+
try {
|
|
101972
|
+
const removed = await clearFrozenMarker(join24(root, ".release-skill"));
|
|
101973
|
+
await evidence.append({
|
|
101974
|
+
phase: "frozen-marker",
|
|
101975
|
+
status: removed ? "cleared" : "absent"
|
|
101976
|
+
});
|
|
101977
|
+
} catch (err) {
|
|
101978
|
+
await evidence.append({
|
|
101979
|
+
phase: "frozen-marker",
|
|
101980
|
+
status: "clear-failed",
|
|
101981
|
+
error: { code: err.code, message: err.message }
|
|
101982
|
+
});
|
|
101983
|
+
}
|
|
101424
101984
|
let baselineAdvance = null;
|
|
101425
101985
|
const baselineAdvances = deriveBaselineAdvances(plan);
|
|
101426
101986
|
if (baselineAdvances.length > 0) {
|
|
101427
101987
|
try {
|
|
101428
|
-
const configAbs = configPathOpt ? isAbsolute20(configPathOpt) ? configPathOpt :
|
|
101988
|
+
const configAbs = configPathOpt ? isAbsolute20(configPathOpt) ? configPathOpt : join24(root, configPathOpt) : join24(root, ".release-skill/project.yaml");
|
|
101429
101989
|
const cleanBefore = await isWorktreeFileClean({ root, filePath: configAbs, execFn });
|
|
101430
101990
|
const applyResult = await applyBaselineAdvances({
|
|
101431
101991
|
configPath: configAbs,
|
|
@@ -101508,6 +102068,7 @@ var init_verify = __esm({
|
|
|
101508
102068
|
init_baseline_advance();
|
|
101509
102069
|
await init_config();
|
|
101510
102070
|
init_state_machine();
|
|
102071
|
+
init_frozen_marker();
|
|
101511
102072
|
init_public_path();
|
|
101512
102073
|
init_npm();
|
|
101513
102074
|
init_verification_gates();
|
|
@@ -101549,8 +102110,8 @@ var init_verify = __esm({
|
|
|
101549
102110
|
exec: execFile9,
|
|
101550
102111
|
env: process.env
|
|
101551
102112
|
});
|
|
101552
|
-
const userConfig =
|
|
101553
|
-
await
|
|
102113
|
+
const userConfig = join24(cwd, ".release-skill-npmrc");
|
|
102114
|
+
await writeFile9(
|
|
101554
102115
|
userConfig,
|
|
101555
102116
|
`registry=${normalizedRegistry}/
|
|
101556
102117
|
${registryTokenKey(normalizedRegistry)}=${token}
|
|
@@ -101612,10 +102173,10 @@ __export(distribute_exports, {
|
|
|
101612
102173
|
});
|
|
101613
102174
|
import { execFile as execFileCb12 } from "node:child_process";
|
|
101614
102175
|
import { promisify as promisify12 } from "node:util";
|
|
101615
|
-
import { realpath as realpath19, lstat as lstat22, mkdir as mkdir19, readFile as
|
|
102176
|
+
import { realpath as realpath19, lstat as lstat22, mkdir as mkdir19, readFile as readFile30, rm as rm11 } from "node:fs/promises";
|
|
101616
102177
|
import { mkdtemp as mkdtemp8 } from "node:fs/promises";
|
|
101617
102178
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
101618
|
-
import { isAbsolute as isAbsolute21, join as
|
|
102179
|
+
import { isAbsolute as isAbsolute21, join as join25, relative as relative25, resolve as resolve28 } from "node:path";
|
|
101619
102180
|
function defaultClock6() {
|
|
101620
102181
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
101621
102182
|
}
|
|
@@ -101712,7 +102273,7 @@ async function distributeRelease(options) {
|
|
|
101712
102273
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
101713
102274
|
let planRaw;
|
|
101714
102275
|
try {
|
|
101715
|
-
planRaw = await
|
|
102276
|
+
planRaw = await readFile30(planPath, "utf8");
|
|
101716
102277
|
} catch (err) {
|
|
101717
102278
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
101718
102279
|
}
|
|
@@ -101746,7 +102307,7 @@ async function distributeRelease(options) {
|
|
|
101746
102307
|
} else {
|
|
101747
102308
|
await mkdir19(runDir, { recursive: true });
|
|
101748
102309
|
}
|
|
101749
|
-
const runPath =
|
|
102310
|
+
const runPath = join25(runDir, "release-run.json");
|
|
101750
102311
|
const evidence = createEvidenceWriter({ runDir, command: "distribute", clock: clockFn });
|
|
101751
102312
|
let lineageKnown = false;
|
|
101752
102313
|
let sourceRunId = null;
|
|
@@ -101821,7 +102382,7 @@ async function distributeRelease(options) {
|
|
|
101821
102382
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
101822
102383
|
let approvalRaw;
|
|
101823
102384
|
try {
|
|
101824
|
-
approvalRaw = await
|
|
102385
|
+
approvalRaw = await readFile30(approvalPath, "utf8");
|
|
101825
102386
|
} catch (err) {
|
|
101826
102387
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
101827
102388
|
}
|
|
@@ -102041,8 +102602,8 @@ async function distributeRelease(options) {
|
|
|
102041
102602
|
}
|
|
102042
102603
|
await evidence.append({ phase: "worktree", status: "started", tagCommit: postPublish.tagCommit });
|
|
102043
102604
|
try {
|
|
102044
|
-
tmpBase = await mkdtemp8(
|
|
102045
|
-
worktreePath =
|
|
102605
|
+
tmpBase = await mkdtemp8(join25(tmpdir5(), "release-skill-distribute-"));
|
|
102606
|
+
worktreePath = join25(tmpBase, "worktree");
|
|
102046
102607
|
await exec("git", ["-C", root, "worktree", "add", "--detach", worktreePath, postPublish.tagCommit]);
|
|
102047
102608
|
} catch (err) {
|
|
102048
102609
|
await evidence.append({ phase: "worktree", status: "failed", error: tail(err?.stderr ?? err?.message) });
|
|
@@ -102545,7 +103106,7 @@ var release_metadata_exports = {};
|
|
|
102545
103106
|
__export(release_metadata_exports, {
|
|
102546
103107
|
updatePreviousPublicBaselines: () => updatePreviousPublicBaselines
|
|
102547
103108
|
});
|
|
102548
|
-
import { lstat as lstat23, readFile as
|
|
103109
|
+
import { lstat as lstat23, readFile as readFile31, rename as rename4, rm as rm12, writeFile as writeFile10 } from "node:fs/promises";
|
|
102549
103110
|
import { resolve as resolve29 } from "node:path";
|
|
102550
103111
|
function assertOid(value, label) {
|
|
102551
103112
|
if (typeof value !== "string" || !/^[a-f0-9]{40,64}$/.test(value)) {
|
|
@@ -102561,8 +103122,8 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
102561
103122
|
let configStat;
|
|
102562
103123
|
try {
|
|
102563
103124
|
[plan, configRaw, configStat] = await Promise.all([
|
|
102564
|
-
|
|
102565
|
-
|
|
103125
|
+
readFile31(planPath, "utf8").then(JSON.parse),
|
|
103126
|
+
readFile31(configPath, "utf8"),
|
|
102566
103127
|
lstat23(configPath)
|
|
102567
103128
|
]);
|
|
102568
103129
|
} catch (error) {
|
|
@@ -102624,7 +103185,7 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
102624
103185
|
}
|
|
102625
103186
|
const tempPath = `${configPath}.${process.pid}.${Date.now()}.tmp`;
|
|
102626
103187
|
try {
|
|
102627
|
-
await
|
|
103188
|
+
await writeFile10(tempPath, nextRaw, {
|
|
102628
103189
|
encoding: "utf8",
|
|
102629
103190
|
mode: configStat.mode & 511,
|
|
102630
103191
|
flag: "wx"
|
|
@@ -102652,7 +103213,7 @@ var ship_exports = {};
|
|
|
102652
103213
|
__export(ship_exports, {
|
|
102653
103214
|
advanceShip: () => advanceShip
|
|
102654
103215
|
});
|
|
102655
|
-
import { readFile as
|
|
103216
|
+
import { readFile as readFile32, lstat as lstat24, mkdir as mkdir20, rename as rename5, rm as rm13, writeFile as writeFile11 } from "node:fs/promises";
|
|
102656
103217
|
import { dirname as dirname15, resolve as resolve30 } from "node:path";
|
|
102657
103218
|
async function writeJsonAtomic(path15, value) {
|
|
102658
103219
|
await mkdir20(dirname15(path15), { recursive: true });
|
|
@@ -102663,7 +103224,7 @@ async function writeJsonAtomic(path15, value) {
|
|
|
102663
103224
|
stateDigest: sha256Hex(canonicalJson2(body))
|
|
102664
103225
|
};
|
|
102665
103226
|
try {
|
|
102666
|
-
await
|
|
103227
|
+
await writeFile11(temp, `${JSON.stringify(sealed, null, 2)}
|
|
102667
103228
|
`, {
|
|
102668
103229
|
encoding: "utf8",
|
|
102669
103230
|
mode: 384,
|
|
@@ -102678,11 +103239,11 @@ async function writeJsonAtomic(path15, value) {
|
|
|
102678
103239
|
}
|
|
102679
103240
|
async function readState(path15) {
|
|
102680
103241
|
try {
|
|
102681
|
-
const
|
|
102682
|
-
if (!
|
|
103242
|
+
const stat10 = await lstat24(path15);
|
|
103243
|
+
if (!stat10.isFile() || stat10.isSymbolicLink()) {
|
|
102683
103244
|
throw new Error("ship state must be a regular non-symlink file");
|
|
102684
103245
|
}
|
|
102685
|
-
const state = JSON.parse(await
|
|
103246
|
+
const state = JSON.parse(await readFile32(path15, "utf8"));
|
|
102686
103247
|
const { stateDigest, ...body } = state;
|
|
102687
103248
|
if (typeof stateDigest !== "string" || stateDigest !== sha256Hex(canonicalJson2(body)) || body.statePath !== path15) {
|
|
102688
103249
|
throw new Error("ship state digest or authority path does not match");
|
|
@@ -102755,7 +103316,7 @@ function publicState(state) {
|
|
|
102755
103316
|
}
|
|
102756
103317
|
async function buildApprovalSummary(planPath) {
|
|
102757
103318
|
try {
|
|
102758
|
-
const plan = JSON.parse(await
|
|
103319
|
+
const plan = JSON.parse(await readFile32(planPath, "utf8"));
|
|
102759
103320
|
const units = (plan.units ?? []).map((unit) => ({
|
|
102760
103321
|
id: unit.id,
|
|
102761
103322
|
targetVersion: unit.targetVersion ?? unit.version
|
|
@@ -102825,7 +103386,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
102825
103386
|
});
|
|
102826
103387
|
let transportPreflight = null;
|
|
102827
103388
|
if (deps.preflightGitTransports) {
|
|
102828
|
-
const frozenPlan = JSON.parse(await
|
|
103389
|
+
const frozenPlan = JSON.parse(await readFile32(prepared.planPath, "utf8"));
|
|
102829
103390
|
transportPreflight = await deps.preflightGitTransports(frozenPlan);
|
|
102830
103391
|
process.env.RELEASE_SKILL_GIT_TRANSPORT = transportPreflight.transport;
|
|
102831
103392
|
}
|
|
@@ -102909,7 +103470,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
102909
103470
|
await writeJsonAtomic(statePath, state);
|
|
102910
103471
|
}
|
|
102911
103472
|
if (state.status === "PUBLISHED" || state.status === "NEEDS_MANUAL_ATTESTATIONS") {
|
|
102912
|
-
const plan = JSON.parse(await
|
|
103473
|
+
const plan = JSON.parse(await readFile32(state.planPath, "utf8"));
|
|
102913
103474
|
const needsDistribution = plan.postPublish && plan.postPublish.targets && plan.postPublish.targets.length > 0;
|
|
102914
103475
|
if (needsDistribution && deps.distributeRelease) {
|
|
102915
103476
|
state.status = "DISTRIBUTING";
|
|
@@ -103571,8 +104132,8 @@ var attest_exports = {};
|
|
|
103571
104132
|
__export(attest_exports, {
|
|
103572
104133
|
recordManualAttestation: () => recordManualAttestation
|
|
103573
104134
|
});
|
|
103574
|
-
import { readFile as
|
|
103575
|
-
import { resolve as resolve31, join as
|
|
104135
|
+
import { readFile as readFile33 } from "node:fs/promises";
|
|
104136
|
+
import { resolve as resolve31, join as join26 } from "node:path";
|
|
103576
104137
|
async function validateInstalledConsumerClosure({
|
|
103577
104138
|
root,
|
|
103578
104139
|
platform,
|
|
@@ -103589,7 +104150,7 @@ async function validateInstalledConsumerClosure({
|
|
|
103589
104150
|
]);
|
|
103590
104151
|
let plan;
|
|
103591
104152
|
try {
|
|
103592
|
-
plan = JSON.parse(await
|
|
104153
|
+
plan = JSON.parse(await readFile33(planPath, "utf8"));
|
|
103593
104154
|
} catch (error) {
|
|
103594
104155
|
throw new ReleaseError(
|
|
103595
104156
|
GATE_FAILED,
|
|
@@ -103660,10 +104221,10 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
103660
104221
|
throw new ReleaseError(MISSING_PARAMETERS, "attest requires --result <passed|failed>");
|
|
103661
104222
|
}
|
|
103662
104223
|
const authorityDir = resolve31(root, ".release-skill", descriptor.directory, plugin);
|
|
103663
|
-
const requirementPath =
|
|
104224
|
+
const requirementPath = join26(authorityDir, descriptor.requirementFile);
|
|
103664
104225
|
let requirement;
|
|
103665
104226
|
try {
|
|
103666
|
-
requirement = JSON.parse(await
|
|
104227
|
+
requirement = JSON.parse(await readFile33(requirementPath, "utf8"));
|
|
103667
104228
|
} catch (error) {
|
|
103668
104229
|
throw new ReleaseError(
|
|
103669
104230
|
GATE_FAILED,
|
|
@@ -103713,7 +104274,7 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
103713
104274
|
extraInstalledPaths: installBinding.extraInstalledPaths
|
|
103714
104275
|
} : {}
|
|
103715
104276
|
};
|
|
103716
|
-
const attestationPath =
|
|
104277
|
+
const attestationPath = join26(authorityDir, requirement.attestationFile);
|
|
103717
104278
|
await writeEvidenceAtomic(attestationPath, receipt);
|
|
103718
104279
|
return {
|
|
103719
104280
|
command: "attest",
|
|
@@ -103747,9 +104308,9 @@ var init_attest = __esm({
|
|
|
103747
104308
|
});
|
|
103748
104309
|
|
|
103749
104310
|
// src/artifacts/policy.mjs
|
|
103750
|
-
import { readFile as
|
|
103751
|
-
import { join as
|
|
103752
|
-
import { createHash as
|
|
104311
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
104312
|
+
import { join as join27 } from "node:path";
|
|
104313
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
103753
104314
|
function validateArtifactPolicy(policy) {
|
|
103754
104315
|
const ok = _validate(policy);
|
|
103755
104316
|
if (!ok) {
|
|
@@ -103844,10 +104405,10 @@ async function parseSafeYamlWithinRoot(root, policyPath) {
|
|
|
103844
104405
|
}
|
|
103845
104406
|
throw err;
|
|
103846
104407
|
}
|
|
103847
|
-
const fullPath =
|
|
104408
|
+
const fullPath = join27(root, policyPath);
|
|
103848
104409
|
let content;
|
|
103849
104410
|
try {
|
|
103850
|
-
content = await
|
|
104411
|
+
content = await readFile34(fullPath, "utf8");
|
|
103851
104412
|
} catch (err) {
|
|
103852
104413
|
throw new ReleaseError(
|
|
103853
104414
|
ARTIFACT_POLICY_INVALID,
|
|
@@ -103898,7 +104459,7 @@ function canonicalJson3(obj) {
|
|
|
103898
104459
|
return JSON.stringify(obj, Object.keys(obj ?? {}).sort());
|
|
103899
104460
|
}
|
|
103900
104461
|
function sha256Hex2(data) {
|
|
103901
|
-
return
|
|
104462
|
+
return createHash16("sha256").update(data).digest("hex");
|
|
103902
104463
|
}
|
|
103903
104464
|
function compareProtection(previousLock, policy) {
|
|
103904
104465
|
if (!previousLock || !Array.isArray(previousLock.artifactIds)) {
|
|
@@ -103958,14 +104519,14 @@ var init_policy = __esm({
|
|
|
103958
104519
|
});
|
|
103959
104520
|
|
|
103960
104521
|
// src/artifacts/entry.mjs
|
|
103961
|
-
import { lstat as lstat25, readdir as
|
|
103962
|
-
import { join as
|
|
104522
|
+
import { lstat as lstat25, readdir as readdir17, readFile as readFile35 } from "node:fs/promises";
|
|
104523
|
+
import { join as join28 } from "node:path";
|
|
103963
104524
|
import { promisify as promisify16 } from "node:util";
|
|
103964
104525
|
import { execFile as execFile13 } from "node:child_process";
|
|
103965
|
-
function statToGitMode(
|
|
103966
|
-
if (
|
|
103967
|
-
if (
|
|
103968
|
-
const mode =
|
|
104526
|
+
function statToGitMode(stat10) {
|
|
104527
|
+
if (stat10.isDirectory()) return "040000";
|
|
104528
|
+
if (stat10.isSymbolicLink()) return "120000";
|
|
104529
|
+
const mode = stat10.mode & 511;
|
|
103969
104530
|
const executable = (mode & 73) !== 0;
|
|
103970
104531
|
return executable ? "100755" : "100644";
|
|
103971
104532
|
}
|
|
@@ -103979,10 +104540,10 @@ async function gitHashObject(root, absPath) {
|
|
|
103979
104540
|
}
|
|
103980
104541
|
async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
103981
104542
|
const entries = [];
|
|
103982
|
-
const items = await
|
|
104543
|
+
const items = await readdir17(dirPath, { withFileTypes: true });
|
|
103983
104544
|
for (const item of items) {
|
|
103984
104545
|
if (SKIP_DIRS2.has(item.name)) continue;
|
|
103985
|
-
const absPath =
|
|
104546
|
+
const absPath = join28(dirPath, item.name);
|
|
103986
104547
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
103987
104548
|
const st = await lstat25(absPath);
|
|
103988
104549
|
if (st.isSymbolicLink()) {
|
|
@@ -104003,7 +104564,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
104003
104564
|
const subEntries = await enumerateTreeEntries(root, absPath, relPath);
|
|
104004
104565
|
entries.push(...subEntries);
|
|
104005
104566
|
} else {
|
|
104006
|
-
const content = await
|
|
104567
|
+
const content = await readFile35(absPath);
|
|
104007
104568
|
entries.push(
|
|
104008
104569
|
Object.freeze({
|
|
104009
104570
|
path: relPath,
|
|
@@ -104033,7 +104594,7 @@ async function readEntry({ root, path: path15, source = "worktree" } = {}) {
|
|
|
104033
104594
|
if (source !== "worktree") {
|
|
104034
104595
|
throw new ReleaseError(PATH_UNSAFE, `unsupported readEntry source: ${source}`, { source });
|
|
104035
104596
|
}
|
|
104036
|
-
const absPath =
|
|
104597
|
+
const absPath = join28(root, path15);
|
|
104037
104598
|
let st;
|
|
104038
104599
|
try {
|
|
104039
104600
|
st = await lstat25(absPath);
|
|
@@ -104066,7 +104627,7 @@ async function readEntry({ root, path: path15, source = "worktree" } = {}) {
|
|
|
104066
104627
|
{ path: path15, nlink: st.nlink }
|
|
104067
104628
|
);
|
|
104068
104629
|
}
|
|
104069
|
-
const content = await
|
|
104630
|
+
const content = await readFile35(absPath);
|
|
104070
104631
|
return Object.freeze({
|
|
104071
104632
|
kind: "regular",
|
|
104072
104633
|
path: path15,
|
|
@@ -104330,8 +104891,8 @@ var init_graph = __esm({
|
|
|
104330
104891
|
});
|
|
104331
104892
|
|
|
104332
104893
|
// src/artifacts/producer-registry.mjs
|
|
104333
|
-
import { readFile as
|
|
104334
|
-
import { join as
|
|
104894
|
+
import { readFile as readFile36, readdir as readdir18, stat as stat7, mkdir as mkdir21, writeFile as writeFile12, rm as rm14 } from "node:fs/promises";
|
|
104895
|
+
import { join as join29 } from "node:path";
|
|
104335
104896
|
import { mkdtemp as mkdtemp9 } from "node:fs/promises";
|
|
104336
104897
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
104337
104898
|
import { readFileSync as readFileSync13 } from "node:fs";
|
|
@@ -104351,7 +104912,7 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
104351
104912
|
const dir = abs.replace(/\/[^/]*$/, "");
|
|
104352
104913
|
while ((match = importRe.exec(source)) !== null) {
|
|
104353
104914
|
const spec = match[1];
|
|
104354
|
-
let resolved =
|
|
104915
|
+
let resolved = join29(dir, spec);
|
|
104355
104916
|
if (!resolved.endsWith(".mjs")) resolved += ".mjs";
|
|
104356
104917
|
results.push(...collectStaticImports(resolved, visited));
|
|
104357
104918
|
}
|
|
@@ -104359,10 +104920,10 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
104359
104920
|
}
|
|
104360
104921
|
async function createBuiltInProducerRegistry() {
|
|
104361
104922
|
const producers = /* @__PURE__ */ new Map();
|
|
104362
|
-
const lockfilePath =
|
|
104923
|
+
const lockfilePath = join29(new URL("../../..", import.meta.url).pathname, "pnpm-lock.yaml");
|
|
104363
104924
|
let lockfileBytes;
|
|
104364
104925
|
try {
|
|
104365
|
-
lockfileBytes = await
|
|
104926
|
+
lockfileBytes = await readFile36(lockfilePath);
|
|
104366
104927
|
} catch {
|
|
104367
104928
|
lockfileBytes = Buffer.from("");
|
|
104368
104929
|
}
|
|
@@ -104379,7 +104940,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
104379
104940
|
const allModuleBytes = await Promise.all(
|
|
104380
104941
|
allModulePaths.map(async (p) => {
|
|
104381
104942
|
try {
|
|
104382
|
-
return await
|
|
104943
|
+
return await readFile36(p);
|
|
104383
104944
|
} catch {
|
|
104384
104945
|
return Buffer.from("");
|
|
104385
104946
|
}
|
|
@@ -104396,16 +104957,16 @@ async function createBuiltInProducerRegistry() {
|
|
|
104396
104957
|
}
|
|
104397
104958
|
async function readDirEntries(dirPath, relBase = "") {
|
|
104398
104959
|
const entries = [];
|
|
104399
|
-
const items = await
|
|
104960
|
+
const items = await readdir18(dirPath, { withFileTypes: true });
|
|
104400
104961
|
for (const item of items) {
|
|
104401
104962
|
if (item.name === ".git") continue;
|
|
104402
|
-
const absPath =
|
|
104963
|
+
const absPath = join29(dirPath, item.name);
|
|
104403
104964
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
104404
|
-
const st = await
|
|
104965
|
+
const st = await stat7(absPath);
|
|
104405
104966
|
if (st.isDirectory()) {
|
|
104406
104967
|
entries.push(...await readDirEntries(absPath, relPath));
|
|
104407
104968
|
} else {
|
|
104408
|
-
const content = await
|
|
104969
|
+
const content = await readFile36(absPath);
|
|
104409
104970
|
entries.push(Object.freeze({
|
|
104410
104971
|
path: relPath,
|
|
104411
104972
|
type: "blob",
|
|
@@ -104422,13 +104983,13 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
104422
104983
|
async function materializeEntries(entries, dirPath) {
|
|
104423
104984
|
for (const entry of entries) {
|
|
104424
104985
|
if (!entry.path) continue;
|
|
104425
|
-
const targetPath2 =
|
|
104986
|
+
const targetPath2 = join29(dirPath, entry.path);
|
|
104426
104987
|
if (entry.type === "tree" || entry.kind === "tree") {
|
|
104427
104988
|
await mkdir21(targetPath2, { recursive: true });
|
|
104428
104989
|
} else {
|
|
104429
|
-
await mkdir21(
|
|
104990
|
+
await mkdir21(join29(targetPath2, ".."), { recursive: true });
|
|
104430
104991
|
if (entry.content) {
|
|
104431
|
-
await
|
|
104992
|
+
await writeFile12(targetPath2, entry.content);
|
|
104432
104993
|
}
|
|
104433
104994
|
}
|
|
104434
104995
|
}
|
|
@@ -104470,7 +105031,7 @@ async function runProducerClosure({
|
|
|
104470
105031
|
graph,
|
|
104471
105032
|
inputSnapshot,
|
|
104472
105033
|
artifactIds,
|
|
104473
|
-
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp9(
|
|
105034
|
+
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp9(join29(tmpdir6(), "producer-")), "tempRootFactory")
|
|
104474
105035
|
} = {}) {
|
|
104475
105036
|
const generatedSet = new Set(graph.topologicalOrder);
|
|
104476
105037
|
for (const id of artifactIds) {
|
|
@@ -104507,9 +105068,9 @@ async function runProducerClosure({
|
|
|
104507
105068
|
if (inputEntries) {
|
|
104508
105069
|
const first = inputEntries[0];
|
|
104509
105070
|
if (first && first.path) {
|
|
104510
|
-
const absPath = first.path.startsWith("/") ? first.path :
|
|
105071
|
+
const absPath = first.path.startsWith("/") ? first.path : join29(process.cwd(), first.path);
|
|
104511
105072
|
try {
|
|
104512
|
-
const st = await
|
|
105073
|
+
const st = await stat7(absPath);
|
|
104513
105074
|
if (st.isDirectory()) {
|
|
104514
105075
|
inputPath = absPath;
|
|
104515
105076
|
} else {
|
|
@@ -104600,13 +105161,13 @@ var init_producer_registry = __esm({
|
|
|
104600
105161
|
// src/artifacts/git-authority.mjs
|
|
104601
105162
|
import { promisify as promisify18 } from "node:util";
|
|
104602
105163
|
import { execFile as execFile15 } from "node:child_process";
|
|
104603
|
-
import { createHash as
|
|
105164
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
104604
105165
|
async function git(cwd, ...args2) {
|
|
104605
105166
|
const { stdout } = await execFileAsync6("git", args2, { cwd, shell: false });
|
|
104606
105167
|
return stdout.trim();
|
|
104607
105168
|
}
|
|
104608
105169
|
function sha256Hex3(data) {
|
|
104609
|
-
return
|
|
105170
|
+
return createHash17("sha256").update(data).digest("hex");
|
|
104610
105171
|
}
|
|
104611
105172
|
async function readRepositoryIdentity(root) {
|
|
104612
105173
|
let gitDir;
|
|
@@ -104932,7 +105493,7 @@ var init_state = __esm({
|
|
|
104932
105493
|
});
|
|
104933
105494
|
|
|
104934
105495
|
// src/artifacts/artifact-plan.mjs
|
|
104935
|
-
import { writeFile as
|
|
105496
|
+
import { writeFile as writeFile13, mkdir as mkdir22, readFile as readFile37, rename as rename6, open as open9 } from "node:fs/promises";
|
|
104936
105497
|
import { dirname as dirname16 } from "node:path";
|
|
104937
105498
|
function assemblePlan({
|
|
104938
105499
|
operation,
|
|
@@ -104962,7 +105523,7 @@ async function writePlan(plan, outputPath) {
|
|
|
104962
105523
|
const content = JSON.stringify(plan, null, 2);
|
|
104963
105524
|
const fh = await open9(tmpPath, "w");
|
|
104964
105525
|
try {
|
|
104965
|
-
await
|
|
105526
|
+
await writeFile13(fh, content, "utf8");
|
|
104966
105527
|
await fh.sync();
|
|
104967
105528
|
} finally {
|
|
104968
105529
|
await fh.close();
|
|
@@ -105621,8 +106182,8 @@ var init_adoption = __esm({
|
|
|
105621
106182
|
// src/artifacts/inspect.mjs
|
|
105622
106183
|
import { promisify as promisify19 } from "node:util";
|
|
105623
106184
|
import { execFile as execFile16 } from "node:child_process";
|
|
105624
|
-
import { readdir as
|
|
105625
|
-
import { join as
|
|
106185
|
+
import { readdir as readdir19, stat as stat8, readFile as readFile38 } from "node:fs/promises";
|
|
106186
|
+
import { join as join30 } from "node:path";
|
|
105626
106187
|
async function hasNestedGitRoots(root) {
|
|
105627
106188
|
try {
|
|
105628
106189
|
const { stdout } = await execFileAsync7(
|
|
@@ -105632,10 +106193,10 @@ async function hasNestedGitRoots(root) {
|
|
|
105632
106193
|
);
|
|
105633
106194
|
const dirs = stdout.split("\n").filter((s) => s.length > 0);
|
|
105634
106195
|
for (const dir of dirs) {
|
|
105635
|
-
const absDir =
|
|
106196
|
+
const absDir = join30(root, dir);
|
|
105636
106197
|
try {
|
|
105637
|
-
const nestedGit =
|
|
105638
|
-
await
|
|
106198
|
+
const nestedGit = join30(absDir, ".git");
|
|
106199
|
+
await stat8(nestedGit);
|
|
105639
106200
|
return true;
|
|
105640
106201
|
} catch {
|
|
105641
106202
|
}
|
|
@@ -105893,8 +106454,8 @@ var init_inspect = __esm({
|
|
|
105893
106454
|
});
|
|
105894
106455
|
|
|
105895
106456
|
// src/artifacts/resolution.mjs
|
|
105896
|
-
import { mkdir as mkdir23, open as open10, readFile as
|
|
105897
|
-
import { join as
|
|
106457
|
+
import { mkdir as mkdir23, open as open10, readFile as readFile39, stat as stat9, lstat as lstat26, chmod as chmod4 } from "node:fs/promises";
|
|
106458
|
+
import { join as join31, resolve as resolve32, relative as relative26, isAbsolute as isAbsolute22, basename as basename11 } from "node:path";
|
|
105898
106459
|
function decodeBuffer(value, label) {
|
|
105899
106460
|
if (value == null) return null;
|
|
105900
106461
|
if (Buffer.isBuffer(value)) return value;
|
|
@@ -105996,9 +106557,9 @@ function assertSafeArtifactId(id) {
|
|
|
105996
106557
|
}
|
|
105997
106558
|
async function assertNoSymlinksInPath(root, artifactId) {
|
|
105998
106559
|
const levels = [
|
|
105999
|
-
|
|
106000
|
-
|
|
106001
|
-
|
|
106560
|
+
join31(root, ".release-skill"),
|
|
106561
|
+
join31(root, ".release-skill", "resolution"),
|
|
106562
|
+
join31(root, ".release-skill", "resolution", artifactId)
|
|
106002
106563
|
];
|
|
106003
106564
|
for (const dir of levels) {
|
|
106004
106565
|
try {
|
|
@@ -106025,7 +106586,7 @@ async function assertSafeResolvedPath(root, artifactId, resolvedPath) {
|
|
|
106025
106586
|
{ resolvedPath, resolutionDir }
|
|
106026
106587
|
);
|
|
106027
106588
|
}
|
|
106028
|
-
const filename =
|
|
106589
|
+
const filename = basename11(resolvedPath);
|
|
106029
106590
|
if (filename !== `${artifactId}.resolved`) {
|
|
106030
106591
|
throw new ReleaseError(
|
|
106031
106592
|
PATH_UNSAFE,
|
|
@@ -106177,13 +106738,13 @@ async function materializeResolution({
|
|
|
106177
106738
|
const template = buildConflictTemplate(artifact.conflict ?? {}, decodedBuffers);
|
|
106178
106739
|
const templateDigest = sha256Hex(template);
|
|
106179
106740
|
await assertNoSymlinksInPath(root, artifactId);
|
|
106180
|
-
const resolutionDir =
|
|
106741
|
+
const resolutionDir = join31(root, ".release-skill", "resolution", artifactId);
|
|
106181
106742
|
await mkdir23(resolutionDir, { recursive: true, mode: 448 });
|
|
106182
|
-
const dirStat = await
|
|
106743
|
+
const dirStat = await stat9(resolutionDir);
|
|
106183
106744
|
if ((dirStat.mode & 511) !== 448) {
|
|
106184
106745
|
await chmod4(resolutionDir, 448);
|
|
106185
106746
|
}
|
|
106186
|
-
const resolvedPath =
|
|
106747
|
+
const resolvedPath = join31(resolutionDir, `${artifactId}.resolved`);
|
|
106187
106748
|
const fh = await open10(resolvedPath, "wx", 384);
|
|
106188
106749
|
try {
|
|
106189
106750
|
await fh.write(template, 0, template.length);
|
|
@@ -106225,7 +106786,7 @@ async function submitResolution({
|
|
|
106225
106786
|
async function readAndValidateResolvedFile(resolvedPath) {
|
|
106226
106787
|
let content;
|
|
106227
106788
|
try {
|
|
106228
|
-
content = await
|
|
106789
|
+
content = await readFile39(resolvedPath);
|
|
106229
106790
|
} catch (err) {
|
|
106230
106791
|
throw new ReleaseError(MISSING_PARAMETERS, `cannot read resolved file: ${err.message}`, { resolvedPath, cause: err.code });
|
|
106231
106792
|
}
|
|
@@ -106393,8 +106954,8 @@ var artifacts_exports = {};
|
|
|
106393
106954
|
__export(artifacts_exports, {
|
|
106394
106955
|
runArtifactsCommand: () => runArtifactsCommand
|
|
106395
106956
|
});
|
|
106396
|
-
import { readFile as
|
|
106397
|
-
import { join as
|
|
106957
|
+
import { readFile as readFile40 } from "node:fs/promises";
|
|
106958
|
+
import { join as join32 } from "node:path";
|
|
106398
106959
|
async function runArtifactsCommand({ subcommand, args: args2, root } = {}) {
|
|
106399
106960
|
if (!VALID_SUBCOMMANDS.has(subcommand)) {
|
|
106400
106961
|
throw new ReleaseError(
|
|
@@ -106522,7 +107083,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
106522
107083
|
{ subcommand: "adopt" }
|
|
106523
107084
|
);
|
|
106524
107085
|
}
|
|
106525
|
-
const planRaw = await
|
|
107086
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106526
107087
|
const plan = JSON.parse(planRaw);
|
|
106527
107088
|
if (expectedDigest && plan.planDigest !== expectedDigest) {
|
|
106528
107089
|
throw new ReleaseError(
|
|
@@ -106537,7 +107098,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
106537
107098
|
if (artifact.path) {
|
|
106538
107099
|
const entry = await readEntry({ root, path: artifact.path, source: "worktree" });
|
|
106539
107100
|
if (entry.kind === "regular") {
|
|
106540
|
-
const bytes = await
|
|
107101
|
+
const bytes = await readFile40(join32(root, artifact.path));
|
|
106541
107102
|
currentEntries.set(artifact.id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
106542
107103
|
} else {
|
|
106543
107104
|
currentEntries.set(artifact.id, entry);
|
|
@@ -106602,7 +107163,7 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
106602
107163
|
{ subcommand: "bootstrap" }
|
|
106603
107164
|
);
|
|
106604
107165
|
}
|
|
106605
|
-
const planRaw = await
|
|
107166
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106606
107167
|
const adoptionPlan = JSON.parse(planRaw);
|
|
106607
107168
|
const currentEntries = /* @__PURE__ */ new Map();
|
|
106608
107169
|
for (const id of new Set((adoptionPlan.protectedHunks ?? []).map((h) => h.artifactId))) {
|
|
@@ -106614,12 +107175,12 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
106614
107175
|
if (entry.kind !== "regular") {
|
|
106615
107176
|
throw new ReleaseError("PLAN_STALE", `artifact is no longer a regular file: ${id}`, { id });
|
|
106616
107177
|
}
|
|
106617
|
-
const bytes = await
|
|
107178
|
+
const bytes = await readFile40(join32(root, artifactPath));
|
|
106618
107179
|
currentEntries.set(id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
106619
107180
|
}
|
|
106620
107181
|
let replacementBytes;
|
|
106621
107182
|
if (action === "replace" && replacementPath) {
|
|
106622
|
-
replacementBytes = await
|
|
107183
|
+
replacementBytes = await readFile40(replacementPath);
|
|
106623
107184
|
}
|
|
106624
107185
|
const updated = await discardBootstrapHunk({
|
|
106625
107186
|
adoptionPlan,
|
|
@@ -106657,7 +107218,7 @@ async function handleResolve({ args: args2, root }) {
|
|
|
106657
107218
|
{ subcommand: "resolve" }
|
|
106658
107219
|
);
|
|
106659
107220
|
}
|
|
106660
|
-
const planRaw = await
|
|
107221
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106661
107222
|
const plan = JSON.parse(planRaw);
|
|
106662
107223
|
if (plan.planDigest !== expectedDigest) {
|
|
106663
107224
|
throw new ReleaseError(
|
|
@@ -107038,13 +107599,14 @@ __export(lineage_exports, {
|
|
|
107038
107599
|
listReleaseTags: () => listReleaseTags,
|
|
107039
107600
|
objectExists: () => objectExists,
|
|
107040
107601
|
parseArgs: () => parseArgs,
|
|
107602
|
+
parseCommitIdent: () => parseCommitIdent,
|
|
107041
107603
|
parseReleaseTag: () => parseReleaseTag,
|
|
107042
107604
|
parseSemverVersion: () => parseSemverVersion2,
|
|
107043
107605
|
readCommitMeta: () => readCommitMeta,
|
|
107044
107606
|
rebuildLineage: () => rebuildLineage,
|
|
107045
107607
|
runLineageCommand: () => runLineageCommand
|
|
107046
107608
|
});
|
|
107047
|
-
import { execFile as execFileCb16 } from "node:child_process";
|
|
107609
|
+
import { execFile as execFileCb16, spawn as spawn4 } from "node:child_process";
|
|
107048
107610
|
import { promisify as promisify20 } from "node:util";
|
|
107049
107611
|
function parseSemverVersion2(version) {
|
|
107050
107612
|
if (typeof version !== "string") {
|
|
@@ -107098,6 +107660,26 @@ async function git2(root, args2, options = {}) {
|
|
|
107098
107660
|
});
|
|
107099
107661
|
return stdout.trim();
|
|
107100
107662
|
}
|
|
107663
|
+
async function gitRaw(root, args2, options = {}) {
|
|
107664
|
+
const { stdout } = await execFile17("git", args2, {
|
|
107665
|
+
cwd: root,
|
|
107666
|
+
encoding: "utf8",
|
|
107667
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
107668
|
+
...options
|
|
107669
|
+
});
|
|
107670
|
+
return stdout;
|
|
107671
|
+
}
|
|
107672
|
+
function parseCommitIdent(line) {
|
|
107673
|
+
if (typeof line !== "string") {
|
|
107674
|
+
throw new Error(`commit ident line must be a string, got ${typeof line}`);
|
|
107675
|
+
}
|
|
107676
|
+
const match = line.match(/^(.*) <([^>]*)> (\d+) ([+-]\d{4})$/);
|
|
107677
|
+
if (!match) {
|
|
107678
|
+
throw new Error(`unparseable commit ident line (fail-closed): "${line}"`);
|
|
107679
|
+
}
|
|
107680
|
+
const [, name, email, ts, tz] = match;
|
|
107681
|
+
return { name, email, ts, tz };
|
|
107682
|
+
}
|
|
107101
107683
|
async function getLocalTags(root) {
|
|
107102
107684
|
const output = await git2(root, ["tag", "-l", "--format=%(refname:short) %(objectname)"]);
|
|
107103
107685
|
if (!output) return [];
|
|
@@ -107130,40 +107712,32 @@ async function objectExists(root, sha) {
|
|
|
107130
107712
|
}
|
|
107131
107713
|
}
|
|
107132
107714
|
async function readCommitMeta(root, commitSha) {
|
|
107133
|
-
const raw = await
|
|
107134
|
-
const
|
|
107135
|
-
|
|
107136
|
-
|
|
107137
|
-
let inBody = false;
|
|
107138
|
-
for (const line of lines) {
|
|
107139
|
-
if (inBody) {
|
|
107140
|
-
messageLines.push(line);
|
|
107141
|
-
continue;
|
|
107142
|
-
}
|
|
107143
|
-
if (line === "") {
|
|
107144
|
-
inBody = true;
|
|
107145
|
-
continue;
|
|
107146
|
-
}
|
|
107147
|
-
const colon = line.indexOf(" ");
|
|
107148
|
-
if (colon === -1) continue;
|
|
107149
|
-
const key = line.slice(0, colon);
|
|
107150
|
-
const value = line.slice(colon + 1);
|
|
107151
|
-
headers[key] = value;
|
|
107715
|
+
const raw = await gitRaw(root, ["cat-file", "commit", commitSha]);
|
|
107716
|
+
const separator = raw.indexOf("\n\n");
|
|
107717
|
+
if (separator === -1) {
|
|
107718
|
+
throw new Error(`malformed commit object ${commitSha}: missing header/message separator`);
|
|
107152
107719
|
}
|
|
107153
|
-
const message =
|
|
107154
|
-
const
|
|
107155
|
-
const
|
|
107720
|
+
const message = raw.slice(separator + 2);
|
|
107721
|
+
const headers = {};
|
|
107722
|
+
for (const line of raw.slice(0, separator).split("\n")) {
|
|
107723
|
+
if (line.startsWith(" ")) continue;
|
|
107724
|
+
const space = line.indexOf(" ");
|
|
107725
|
+
if (space === -1) continue;
|
|
107726
|
+
headers[line.slice(0, space)] = line.slice(space + 1);
|
|
107727
|
+
}
|
|
107728
|
+
const author = parseCommitIdent(headers.author ?? "");
|
|
107729
|
+
const committer = parseCommitIdent(headers.committer ?? "");
|
|
107156
107730
|
return {
|
|
107157
107731
|
message,
|
|
107158
107732
|
author: {
|
|
107159
|
-
name:
|
|
107160
|
-
email:
|
|
107161
|
-
date:
|
|
107733
|
+
name: author.name,
|
|
107734
|
+
email: author.email,
|
|
107735
|
+
date: `${author.ts} ${author.tz}`
|
|
107162
107736
|
},
|
|
107163
107737
|
committer: {
|
|
107164
|
-
name:
|
|
107165
|
-
email:
|
|
107166
|
-
date:
|
|
107738
|
+
name: committer.name,
|
|
107739
|
+
email: committer.email,
|
|
107740
|
+
date: `${committer.ts} ${committer.tz}`
|
|
107167
107741
|
}
|
|
107168
107742
|
};
|
|
107169
107743
|
}
|
|
@@ -107248,7 +107822,7 @@ async function analyzeLineage(root) {
|
|
|
107248
107822
|
async function createRebuiltCommit(root, treeSha, parentSha, message, identity2) {
|
|
107249
107823
|
const args2 = ["commit-tree", treeSha];
|
|
107250
107824
|
if (parentSha) args2.push("-p", parentSha);
|
|
107251
|
-
args2.push("-
|
|
107825
|
+
args2.push("-F", "-");
|
|
107252
107826
|
const env = {
|
|
107253
107827
|
...process.env,
|
|
107254
107828
|
GIT_AUTHOR_NAME: identity2.author.name,
|
|
@@ -107258,8 +107832,31 @@ async function createRebuiltCommit(root, treeSha, parentSha, message, identity2)
|
|
|
107258
107832
|
GIT_COMMITTER_EMAIL: identity2.committer.email,
|
|
107259
107833
|
GIT_COMMITTER_DATE: identity2.committer.date
|
|
107260
107834
|
};
|
|
107261
|
-
|
|
107262
|
-
|
|
107835
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
107836
|
+
const child = spawn4("git", args2, { cwd: root, env });
|
|
107837
|
+
let stdout = "";
|
|
107838
|
+
let stderr = "";
|
|
107839
|
+
child.stdout.setEncoding("utf8");
|
|
107840
|
+
child.stderr.setEncoding("utf8");
|
|
107841
|
+
child.stdout.on("data", (chunk) => {
|
|
107842
|
+
stdout += chunk;
|
|
107843
|
+
});
|
|
107844
|
+
child.stderr.on("data", (chunk) => {
|
|
107845
|
+
stderr += chunk;
|
|
107846
|
+
});
|
|
107847
|
+
child.on("error", rejectPromise);
|
|
107848
|
+
child.on("close", (code) => {
|
|
107849
|
+
if (code !== 0) {
|
|
107850
|
+
rejectPromise(new Error(`git commit-tree failed (exit ${code}): ${stderr.trim()}`));
|
|
107851
|
+
return;
|
|
107852
|
+
}
|
|
107853
|
+
resolvePromise(stdout.trim());
|
|
107854
|
+
});
|
|
107855
|
+
child.stdin.on("error", () => {
|
|
107856
|
+
});
|
|
107857
|
+
child.stdin.write(message);
|
|
107858
|
+
child.stdin.end();
|
|
107859
|
+
});
|
|
107263
107860
|
}
|
|
107264
107861
|
async function rebuildLineage(root, options = {}) {
|
|
107265
107862
|
const { dryRun = false } = options;
|
|
@@ -107386,6 +107983,8 @@ var init_lineage = __esm({
|
|
|
107386
107983
|
__name(compareSemverVersions2, "compareSemverVersions");
|
|
107387
107984
|
__name(parseReleaseTag, "parseReleaseTag");
|
|
107388
107985
|
__name(git2, "git");
|
|
107986
|
+
__name(gitRaw, "gitRaw");
|
|
107987
|
+
__name(parseCommitIdent, "parseCommitIdent");
|
|
107389
107988
|
__name(getLocalTags, "getLocalTags");
|
|
107390
107989
|
__name(listReleaseTags, "listReleaseTags");
|
|
107391
107990
|
__name(getCommitTreeHash, "getCommitTreeHash");
|
|
@@ -107436,7 +108035,7 @@ __export(route_exports, {
|
|
|
107436
108035
|
resolvePreviousReleaseCommit: () => resolvePreviousReleaseCommit
|
|
107437
108036
|
});
|
|
107438
108037
|
import { execFileSync } from "node:child_process";
|
|
107439
|
-
import { readdir as
|
|
108038
|
+
import { readdir as readdir20, readFile as readFile41 } from "node:fs/promises";
|
|
107440
108039
|
import { resolve as resolve33 } from "node:path";
|
|
107441
108040
|
function classifyPath(path15) {
|
|
107442
108041
|
if (typeof path15 !== "string" || path15.length === 0) return "ignore";
|
|
@@ -107517,13 +108116,13 @@ async function resolvePreviousReleaseCommit(root) {
|
|
|
107517
108116
|
const cwd = resolve33(root);
|
|
107518
108117
|
try {
|
|
107519
108118
|
const plansDir = resolve33(cwd, ".release-skill", "plans");
|
|
107520
|
-
const planFiles = await
|
|
108119
|
+
const planFiles = await readdir20(plansDir).catch(() => []);
|
|
107521
108120
|
let best = null;
|
|
107522
108121
|
for (const file of planFiles) {
|
|
107523
108122
|
if (!file.endsWith(".json")) continue;
|
|
107524
108123
|
let plan;
|
|
107525
108124
|
try {
|
|
107526
|
-
plan = JSON.parse(await
|
|
108125
|
+
plan = JSON.parse(await readFile41(resolve33(plansDir, file), "utf8"));
|
|
107527
108126
|
} catch {
|
|
107528
108127
|
continue;
|
|
107529
108128
|
}
|
|
@@ -107607,14 +108206,14 @@ async function hasPartialRun(root) {
|
|
|
107607
108206
|
const runsDir = resolve33(cwd, ".release-skill", "runs");
|
|
107608
108207
|
let runDirs;
|
|
107609
108208
|
try {
|
|
107610
|
-
runDirs = await
|
|
108209
|
+
runDirs = await readdir20(runsDir);
|
|
107611
108210
|
} catch {
|
|
107612
108211
|
return false;
|
|
107613
108212
|
}
|
|
107614
108213
|
for (const runDir of runDirs) {
|
|
107615
108214
|
const summaryPath = resolve33(runsDir, runDir, "summary.json");
|
|
107616
108215
|
try {
|
|
107617
|
-
const summary = JSON.parse(await
|
|
108216
|
+
const summary = JSON.parse(await readFile41(summaryPath, "utf8"));
|
|
107618
108217
|
if (summary?.status === "PARTIAL") return true;
|
|
107619
108218
|
} catch {
|
|
107620
108219
|
}
|
|
@@ -107899,7 +108498,7 @@ Workflow Profiles:
|
|
|
107899
108498
|
});
|
|
107900
108499
|
|
|
107901
108500
|
// bin/release-skill-cli.mjs
|
|
107902
|
-
import { basename as
|
|
108501
|
+
import { basename as basename12, dirname as dirname17, join as join33, resolve as resolve34 } from "node:path";
|
|
107903
108502
|
import { execFile as execFileCb17 } from "node:child_process";
|
|
107904
108503
|
import { promisify as promisify21 } from "node:util";
|
|
107905
108504
|
|
|
@@ -108133,6 +108732,9 @@ Options:
|
|
|
108133
108732
|
deterministically trim code-class gates (declared hooks, snapshot-verify gates,
|
|
108134
108733
|
source-authority closure, skill-resource-closure) and record workflowDecision in the plan;
|
|
108135
108734
|
config also reports whether the public bytes are unchanged (no publish path)
|
|
108735
|
+
--test-selection <full|incremental> Test selection for the test hook (prepare). Only 'full' is accepted at
|
|
108736
|
+
freeze time; 'incremental' is reserved for a future preflight mode and is rejected
|
|
108737
|
+
('incremental selection is not allowed at freeze time')
|
|
108136
108738
|
--answers <path> Human-reviewed setup answers JSON
|
|
108137
108739
|
--write Create an absent project.yaml during setup; never overwrites
|
|
108138
108740
|
--confirm-setup <digest> Confirm exact setup facts and answers before create
|
|
@@ -108185,7 +108787,7 @@ if (!command && (args.includes("--version") || args.includes("-v"))) {
|
|
|
108185
108787
|
} else {
|
|
108186
108788
|
const { readFileSync: readFileSync14 } = await import("node:fs");
|
|
108187
108789
|
const { fileURLToPath: fileURLToPath3 } = await import("node:url");
|
|
108188
|
-
const pkgPath =
|
|
108790
|
+
const pkgPath = join33(dirname17(fileURLToPath3(import.meta.url)), "..", "package.json");
|
|
108189
108791
|
pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
|
|
108190
108792
|
}
|
|
108191
108793
|
if (hasJson) {
|
|
@@ -108525,6 +109127,8 @@ if (command === "prepare") {
|
|
|
108525
109127
|
const production = args.includes("--production");
|
|
108526
109128
|
const workflowIdx = args.indexOf("--workflow");
|
|
108527
109129
|
const workflow = workflowIdx !== -1 && args[workflowIdx + 1] ? args[workflowIdx + 1] : "full";
|
|
109130
|
+
const testSelectionIdx = args.indexOf("--test-selection");
|
|
109131
|
+
const testSelection = testSelectionIdx !== -1 && args[testSelectionIdx + 1] ? args[testSelectionIdx + 1] : void 0;
|
|
108528
109132
|
const outputIdx = args.indexOf("--output");
|
|
108529
109133
|
const output = outputIdx !== -1 && args[outputIdx + 1] ? resolve34(args[outputIdx + 1]) : void 0;
|
|
108530
109134
|
const runDirIdx = args.indexOf("--run-dir");
|
|
@@ -108541,6 +109145,7 @@ if (command === "prepare") {
|
|
|
108541
109145
|
hookCache,
|
|
108542
109146
|
production,
|
|
108543
109147
|
workflow,
|
|
109148
|
+
testSelection,
|
|
108544
109149
|
output,
|
|
108545
109150
|
runDir
|
|
108546
109151
|
});
|
|
@@ -108630,8 +109235,8 @@ if (command === "approve") {
|
|
|
108630
109235
|
}
|
|
108631
109236
|
const resolvedPlanPath = resolve34(planPath);
|
|
108632
109237
|
const planDir = dirname17(resolvedPlanPath);
|
|
108633
|
-
const releaseDir =
|
|
108634
|
-
const approvalPath = outputPath ??
|
|
109238
|
+
const releaseDir = basename12(planDir) === "plans" && basename12(resolvedPlanPath) === `${resolvedDigest}.json` ? dirname17(planDir) : planDir;
|
|
109239
|
+
const approvalPath = outputPath ?? join33(releaseDir, "approval-record.json");
|
|
108635
109240
|
const record = await approvePlan2({ planPath, expectedDigest: resolvedDigest, actor, outputPath: approvalPath });
|
|
108636
109241
|
if (hasJson) {
|
|
108637
109242
|
console.log(JSON.stringify(record, null, 2));
|