release-skill 0.6.0 → 0.6.1
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 +14 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +9 -8
- package/README.zh-CN.md +9 -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 +705 -356
- 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 +705 -356
- 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 +705 -356
- 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 +705 -356
- package/adapters/workbuddy/schemas/release-project.schema.json +8 -0
- package/bin/release-skill-cli.mjs +11 -0
- package/bin/release-skill.bundle.mjs +705 -356
- package/package.json +1 -1
- package/references/05-evidence-and-errors.md +1 -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/prepare.mjs +214 -8
- 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
|
@@ -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.1"});
|
|
13
|
+
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
+
const __bundleSourceDigest = "c51fa1df96e9ef06d5310a990e6ce2366e4878332d646b034842d0deaec549d4";
|
|
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);
|
|
@@ -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.1" });
|
|
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",
|
|
@@ -37362,8 +37367,8 @@ function safeRelative(root, path15) {
|
|
|
37362
37367
|
return rel || ".";
|
|
37363
37368
|
}
|
|
37364
37369
|
async function readJsonBounded(path15, label) {
|
|
37365
|
-
const
|
|
37366
|
-
if (!
|
|
37370
|
+
const stat10 = await lstat11(path15);
|
|
37371
|
+
if (!stat10.isFile() || stat10.isSymbolicLink() || stat10.size > MAX_JSON_BYTES) {
|
|
37367
37372
|
throw setupError(CONFIG_INVALID, `${label} must be a regular JSON file no larger than 1 MiB`, { path: path15 });
|
|
37368
37373
|
}
|
|
37369
37374
|
try {
|
|
@@ -37625,14 +37630,14 @@ async function pathIsGitIgnored(unitAbsDir, target) {
|
|
|
37625
37630
|
async function classifyNpmEntryCandidate(unitAbsDir, target, trackedFiles) {
|
|
37626
37631
|
const tracked = trackedFiles.includes(target);
|
|
37627
37632
|
const ignored = await pathIsGitIgnored(unitAbsDir, target);
|
|
37628
|
-
let
|
|
37633
|
+
let stat10 = null;
|
|
37629
37634
|
try {
|
|
37630
|
-
|
|
37635
|
+
stat10 = await lstat11(join8(unitAbsDir, target));
|
|
37631
37636
|
} catch (error) {
|
|
37632
37637
|
if (error.code !== "ENOENT") throw error;
|
|
37633
37638
|
}
|
|
37634
|
-
const exists =
|
|
37635
|
-
const regular =
|
|
37639
|
+
const exists = stat10 !== null;
|
|
37640
|
+
const regular = stat10?.isFile() === true && stat10?.isSymbolicLink() !== true;
|
|
37636
37641
|
const state = exists && !regular ? "NON_REGULAR" : exists && tracked ? "TRACKED_PRESENT" : exists && ignored ? "IGNORED_PRESENT" : exists ? "UNTRACKED_PRESENT" : ignored ? "IGNORED_MISSING" : "MISSING";
|
|
37637
37642
|
return { path: target, state, exists, tracked, ignored };
|
|
37638
37643
|
}
|
|
@@ -38524,9 +38529,9 @@ async function setupProject({ root, answersPath, write = false, confirmSetup, fa
|
|
|
38524
38529
|
const configPath = join8(rootReal, ".release-skill", "project.yaml");
|
|
38525
38530
|
let configExists = false;
|
|
38526
38531
|
try {
|
|
38527
|
-
const
|
|
38532
|
+
const stat10 = await lstat11(configPath);
|
|
38528
38533
|
configExists = true;
|
|
38529
|
-
if (!
|
|
38534
|
+
if (!stat10.isFile() || stat10.isSymbolicLink()) {
|
|
38530
38535
|
throw setupError(CONFIG_INVALID, "existing project.yaml must be a regular file");
|
|
38531
38536
|
}
|
|
38532
38537
|
} catch (error) {
|
|
@@ -39064,9 +39069,9 @@ async function assertSafeDirectoryPath({
|
|
|
39064
39069
|
let cursor = workspaceRoot;
|
|
39065
39070
|
for (const segment of rel.split(sep3).filter(Boolean)) {
|
|
39066
39071
|
cursor = join9(cursor, segment);
|
|
39067
|
-
let
|
|
39072
|
+
let stat10;
|
|
39068
39073
|
try {
|
|
39069
|
-
|
|
39074
|
+
stat10 = await lstat12(cursor);
|
|
39070
39075
|
} catch (error) {
|
|
39071
39076
|
failConfig(`cannot inspect public surface scan root "${configuredRoot}"`, {
|
|
39072
39077
|
reason: "PUBLIC_SURFACE_SCAN_ROOT_UNSAFE",
|
|
@@ -39075,7 +39080,7 @@ async function assertSafeDirectoryPath({
|
|
|
39075
39080
|
cause: error.code ?? "UNKNOWN"
|
|
39076
39081
|
});
|
|
39077
39082
|
}
|
|
39078
|
-
if (
|
|
39083
|
+
if (stat10.isSymbolicLink() || !stat10.isDirectory()) {
|
|
39079
39084
|
failConfig(`public surface scan root or ancestor is not a physical directory: "${configuredRoot}"`, {
|
|
39080
39085
|
reason: "PUBLIC_SURFACE_SCAN_ROOT_UNSAFE",
|
|
39081
39086
|
unitId,
|
|
@@ -39462,24 +39467,24 @@ async function computeWorkspaceDigest(root) {
|
|
|
39462
39467
|
`Refusing to read path outside repository root: ${relPath} resolves to ${absPath}`
|
|
39463
39468
|
);
|
|
39464
39469
|
}
|
|
39465
|
-
const
|
|
39470
|
+
const stat10 = await lstat13(absPath);
|
|
39466
39471
|
let type;
|
|
39467
|
-
if (
|
|
39472
|
+
if (stat10.isSymbolicLink()) {
|
|
39468
39473
|
type = "symlink";
|
|
39469
|
-
} else if (
|
|
39474
|
+
} else if (stat10.isDirectory()) {
|
|
39470
39475
|
type = "dir";
|
|
39471
|
-
} else if (
|
|
39476
|
+
} else if (stat10.isFile()) {
|
|
39472
39477
|
type = "file";
|
|
39473
39478
|
} else {
|
|
39474
39479
|
type = "other";
|
|
39475
39480
|
}
|
|
39476
39481
|
const typeMarker = `TYPE:${type}`;
|
|
39477
39482
|
let content;
|
|
39478
|
-
if (
|
|
39483
|
+
if (stat10.isFile()) {
|
|
39479
39484
|
const handle = await open6(absPath, fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW);
|
|
39480
39485
|
try {
|
|
39481
39486
|
const fdStat = await handle.stat();
|
|
39482
|
-
if (fdStat.ino !==
|
|
39487
|
+
if (fdStat.ino !== stat10.ino) {
|
|
39483
39488
|
throw new Error(
|
|
39484
39489
|
`Race detected: inode changed for ${relPath} between lstat and read`
|
|
39485
39490
|
);
|
|
@@ -39494,7 +39499,7 @@ async function computeWorkspaceDigest(root) {
|
|
|
39494
39499
|
} finally {
|
|
39495
39500
|
await handle.close();
|
|
39496
39501
|
}
|
|
39497
|
-
} else if (
|
|
39502
|
+
} else if (stat10.isSymbolicLink()) {
|
|
39498
39503
|
content = Buffer.from(await readlink(absPath), "utf8");
|
|
39499
39504
|
} else {
|
|
39500
39505
|
content = Buffer.alloc(0);
|
|
@@ -40908,7 +40913,7 @@ function validateHook(hook) {
|
|
|
40908
40913
|
if (!hook || typeof hook !== "object" || Array.isArray(hook)) {
|
|
40909
40914
|
throw new ReleaseError("INVALID_HOOK", "hook must be a non-null object");
|
|
40910
40915
|
}
|
|
40911
|
-
const { command: command2, cwd, timeoutMs, envAllowlist, cacheable, cacheInputs } = hook;
|
|
40916
|
+
const { command: command2, cwd, timeoutMs, envAllowlist, cacheable, cacheInputs, testSelection } = hook;
|
|
40912
40917
|
if (!Array.isArray(command2) || command2.length === 0) {
|
|
40913
40918
|
throw new ReleaseError("INVALID_HOOK", "hook.command must be a non-empty array");
|
|
40914
40919
|
}
|
|
@@ -40963,6 +40968,12 @@ function validateHook(hook) {
|
|
|
40963
40968
|
"hook.cacheable=true requires a non-empty hook.cacheInputs"
|
|
40964
40969
|
);
|
|
40965
40970
|
}
|
|
40971
|
+
if (testSelection !== void 0 && testSelection !== "full" && testSelection !== "incremental") {
|
|
40972
|
+
throw new ReleaseError(
|
|
40973
|
+
"INVALID_HOOK",
|
|
40974
|
+
'hook.testSelection must be "full" or "incremental" when provided'
|
|
40975
|
+
);
|
|
40976
|
+
}
|
|
40966
40977
|
}
|
|
40967
40978
|
function buildFilteredEnv(envAllowlist, contextEnv) {
|
|
40968
40979
|
const env = {};
|
|
@@ -41279,10 +41290,10 @@ async function resolveSafeCwd(executionRoot, cwd, gate) {
|
|
|
41279
41290
|
let current = rootReal;
|
|
41280
41291
|
for (const segment of rel.split(/[\\/]/).filter(Boolean)) {
|
|
41281
41292
|
current = join11(current, segment);
|
|
41282
|
-
const
|
|
41293
|
+
const stat10 = await lstat14(current).catch((error) => {
|
|
41283
41294
|
throw gateError(gate, "cwd does not exist", { cause: error.code });
|
|
41284
41295
|
});
|
|
41285
|
-
if (
|
|
41296
|
+
if (stat10.isSymbolicLink()) throw gateError(gate, "cwd contains a symlink");
|
|
41286
41297
|
}
|
|
41287
41298
|
const physical = await realpath12(lexical);
|
|
41288
41299
|
if (!isInside2(rootReal, physical)) throw gateError(gate, "cwd resolves outside the execution root");
|
|
@@ -41523,9 +41534,9 @@ async function runVerificationGate({
|
|
|
41523
41534
|
return result;
|
|
41524
41535
|
}
|
|
41525
41536
|
async function makeTreeWritable(root) {
|
|
41526
|
-
const
|
|
41527
|
-
if (!
|
|
41528
|
-
await chmod2(root,
|
|
41537
|
+
const stat10 = await lstat14(root);
|
|
41538
|
+
if (!stat10.isDirectory() || stat10.isSymbolicLink()) throw new Error("gate copy root must be a real directory");
|
|
41539
|
+
await chmod2(root, stat10.mode | 448);
|
|
41529
41540
|
for (const child of await readdir7(root, { withFileTypes: true })) {
|
|
41530
41541
|
const absolute = join11(root, child.name);
|
|
41531
41542
|
const childStat = await lstat14(absolute);
|
|
@@ -41780,14 +41791,14 @@ async function inspectRegularFile(root, target) {
|
|
|
41780
41791
|
}
|
|
41781
41792
|
for (const part of parts) {
|
|
41782
41793
|
current = join12(current, part);
|
|
41783
|
-
let
|
|
41794
|
+
let stat10;
|
|
41784
41795
|
try {
|
|
41785
|
-
|
|
41796
|
+
stat10 = await lstat15(current);
|
|
41786
41797
|
} catch (error) {
|
|
41787
41798
|
if (error.code === "ENOENT") return { code: FINDING_CODE.RESOURCE_MISSING };
|
|
41788
41799
|
throw error;
|
|
41789
41800
|
}
|
|
41790
|
-
if (
|
|
41801
|
+
if (stat10.isSymbolicLink()) return { code: FINDING_CODE.SYMLINK_NOT_ALLOWED };
|
|
41791
41802
|
}
|
|
41792
41803
|
const targetStat = await lstat15(target);
|
|
41793
41804
|
if (!targetStat.isFile() || targetStat.nlink !== 1) {
|
|
@@ -43575,11 +43586,182 @@ var init_contract2 = __esm({
|
|
|
43575
43586
|
}
|
|
43576
43587
|
});
|
|
43577
43588
|
|
|
43589
|
+
// src/core/bundle-freshness.mjs
|
|
43590
|
+
import { readFile as readFile16, readdir as readdir11, stat as stat4 } from "node:fs/promises";
|
|
43591
|
+
import { join as join14 } from "node:path";
|
|
43592
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
43593
|
+
function bundlePathFor(pkgRoot) {
|
|
43594
|
+
return join14(pkgRoot, BUNDLE_RELPATH);
|
|
43595
|
+
}
|
|
43596
|
+
async function listFilesSorted(dir, prefix = "") {
|
|
43597
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
43598
|
+
const files = [];
|
|
43599
|
+
for (const entry of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
43600
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
43601
|
+
if (entry.isDirectory()) {
|
|
43602
|
+
files.push(...await listFilesSorted(join14(dir, entry.name), rel));
|
|
43603
|
+
} else if (entry.isFile()) {
|
|
43604
|
+
files.push(rel);
|
|
43605
|
+
}
|
|
43606
|
+
}
|
|
43607
|
+
return files;
|
|
43608
|
+
}
|
|
43609
|
+
async function listBundleSourceInputs(pkgRoot) {
|
|
43610
|
+
const inputs = [];
|
|
43611
|
+
for (const dir of SOURCE_DIRS) {
|
|
43612
|
+
const abs = join14(pkgRoot, dir);
|
|
43613
|
+
const st = await stat4(abs).catch(() => null);
|
|
43614
|
+
if (st?.isDirectory()) {
|
|
43615
|
+
for (const rel of await listFilesSorted(abs)) {
|
|
43616
|
+
inputs.push(`${dir}/${rel}`);
|
|
43617
|
+
}
|
|
43618
|
+
}
|
|
43619
|
+
}
|
|
43620
|
+
for (const rel of SOURCE_FILES) {
|
|
43621
|
+
const st = await stat4(join14(pkgRoot, rel)).catch(() => null);
|
|
43622
|
+
if (st?.isFile()) {
|
|
43623
|
+
inputs.push(rel.split(/[\\/]/).join("/"));
|
|
43624
|
+
}
|
|
43625
|
+
}
|
|
43626
|
+
return inputs.sort();
|
|
43627
|
+
}
|
|
43628
|
+
async function computeBundleSourceDigest(pkgRoot) {
|
|
43629
|
+
const inputs = await listBundleSourceInputs(pkgRoot);
|
|
43630
|
+
const hash = createHash13("sha256");
|
|
43631
|
+
hash.update(BUNDLE_SOURCE_DIGEST_ALGORITHM);
|
|
43632
|
+
hash.update("\n");
|
|
43633
|
+
for (const rel of inputs) {
|
|
43634
|
+
const content = await readFile16(join14(pkgRoot, rel));
|
|
43635
|
+
hash.update(rel);
|
|
43636
|
+
hash.update("\0");
|
|
43637
|
+
hash.update(createHash13("sha256").update(content).digest("hex"));
|
|
43638
|
+
hash.update("\n");
|
|
43639
|
+
}
|
|
43640
|
+
return hash.digest("hex");
|
|
43641
|
+
}
|
|
43642
|
+
async function readEmbeddedBundleDigest(bundlePath) {
|
|
43643
|
+
let content;
|
|
43644
|
+
try {
|
|
43645
|
+
content = await readFile16(bundlePath, "utf8");
|
|
43646
|
+
} catch {
|
|
43647
|
+
return null;
|
|
43648
|
+
}
|
|
43649
|
+
const match = content.match(EMBEDDED_DIGEST_PATTERN);
|
|
43650
|
+
return match ? match[1] : null;
|
|
43651
|
+
}
|
|
43652
|
+
async function checkBundleFreshness(pkgRoot) {
|
|
43653
|
+
const base = {
|
|
43654
|
+
applicable: true,
|
|
43655
|
+
fresh: false,
|
|
43656
|
+
embeddedDigest: null,
|
|
43657
|
+
sourceDigest: null,
|
|
43658
|
+
algorithm: BUNDLE_SOURCE_DIGEST_ALGORITHM
|
|
43659
|
+
};
|
|
43660
|
+
const srcStat = await stat4(join14(pkgRoot, "src")).catch(() => null);
|
|
43661
|
+
if (!srcStat?.isDirectory()) {
|
|
43662
|
+
return { ...base, applicable: false, reason: "installed-layout" };
|
|
43663
|
+
}
|
|
43664
|
+
const bundleStat = await stat4(bundlePathFor(pkgRoot)).catch(() => null);
|
|
43665
|
+
if (!bundleStat?.isFile()) {
|
|
43666
|
+
return { ...base, reason: "bundle-missing" };
|
|
43667
|
+
}
|
|
43668
|
+
const [embeddedDigest, sourceDigest] = await Promise.all([
|
|
43669
|
+
readEmbeddedBundleDigest(bundlePathFor(pkgRoot)),
|
|
43670
|
+
computeBundleSourceDigest(pkgRoot)
|
|
43671
|
+
]);
|
|
43672
|
+
if (!embeddedDigest) {
|
|
43673
|
+
return { ...base, sourceDigest, reason: "digest-missing" };
|
|
43674
|
+
}
|
|
43675
|
+
if (embeddedDigest !== sourceDigest) {
|
|
43676
|
+
return { ...base, embeddedDigest, sourceDigest, reason: "digest-mismatch" };
|
|
43677
|
+
}
|
|
43678
|
+
return { ...base, fresh: true, embeddedDigest, sourceDigest, reason: "fresh" };
|
|
43679
|
+
}
|
|
43680
|
+
async function assertBundleFreshness(pkgRoot) {
|
|
43681
|
+
const result = await checkBundleFreshness(pkgRoot);
|
|
43682
|
+
if (!result.applicable) {
|
|
43683
|
+
return result;
|
|
43684
|
+
}
|
|
43685
|
+
if (result.fresh) {
|
|
43686
|
+
return result;
|
|
43687
|
+
}
|
|
43688
|
+
const reasonText = {
|
|
43689
|
+
"bundle-missing": "the bundle file is missing",
|
|
43690
|
+
"digest-missing": "the bundle carries no embedded source digest",
|
|
43691
|
+
"digest-mismatch": "the bundle is out of sync with src/"
|
|
43692
|
+
}[result.reason] ?? result.reason;
|
|
43693
|
+
throw new ReleaseError(
|
|
43694
|
+
BUNDLE_STALE,
|
|
43695
|
+
`bin/release-skill.bundle.mjs is stale: ${reasonText}. Rebuild it from the release-skill package root with: ${BUNDLE_REBUILD_COMMAND} (or pnpm build)`,
|
|
43696
|
+
{
|
|
43697
|
+
reason: result.reason,
|
|
43698
|
+
algorithm: result.algorithm,
|
|
43699
|
+
embeddedDigest: result.embeddedDigest,
|
|
43700
|
+
sourceDigest: result.sourceDigest,
|
|
43701
|
+
rebuildCommand: BUNDLE_REBUILD_COMMAND
|
|
43702
|
+
}
|
|
43703
|
+
);
|
|
43704
|
+
}
|
|
43705
|
+
var BUNDLE_SOURCE_DIGEST_ALGORITHM, BUNDLE_RELPATH, SOURCE_DIRS, SOURCE_FILES, EMBEDDED_DIGEST_PATTERN, BUNDLE_REBUILD_COMMAND;
|
|
43706
|
+
var init_bundle_freshness = __esm({
|
|
43707
|
+
"src/core/bundle-freshness.mjs"() {
|
|
43708
|
+
init_errors();
|
|
43709
|
+
BUNDLE_SOURCE_DIGEST_ALGORITHM = "bundle-source-digest-v1";
|
|
43710
|
+
BUNDLE_RELPATH = join14("bin", "release-skill.bundle.mjs");
|
|
43711
|
+
SOURCE_DIRS = ["src", "skills-src"];
|
|
43712
|
+
SOURCE_FILES = [join14("bin", "release-skill-cli.mjs"), "package.json"];
|
|
43713
|
+
EMBEDDED_DIGEST_PATTERN = /const __bundleSourceDigest = "([a-f0-9]{64})";/;
|
|
43714
|
+
__name(bundlePathFor, "bundlePathFor");
|
|
43715
|
+
__name(listFilesSorted, "listFilesSorted");
|
|
43716
|
+
__name(listBundleSourceInputs, "listBundleSourceInputs");
|
|
43717
|
+
__name(computeBundleSourceDigest, "computeBundleSourceDigest");
|
|
43718
|
+
__name(readEmbeddedBundleDigest, "readEmbeddedBundleDigest");
|
|
43719
|
+
__name(checkBundleFreshness, "checkBundleFreshness");
|
|
43720
|
+
BUNDLE_REBUILD_COMMAND = "node scripts/build-bundle.mjs";
|
|
43721
|
+
__name(assertBundleFreshness, "assertBundleFreshness");
|
|
43722
|
+
}
|
|
43723
|
+
});
|
|
43724
|
+
|
|
43725
|
+
// src/core/frozen-marker.mjs
|
|
43726
|
+
import { readFile as readFile17, writeFile as writeFile6, unlink as unlink5 } from "node:fs/promises";
|
|
43727
|
+
import { join as join15 } from "node:path";
|
|
43728
|
+
function frozenMarkerPath(releaseDir) {
|
|
43729
|
+
return join15(releaseDir, FROZEN_MARKER_FILENAME);
|
|
43730
|
+
}
|
|
43731
|
+
async function writeFrozenMarker(releaseDir, marker) {
|
|
43732
|
+
const payload = {
|
|
43733
|
+
planDigest: marker.planDigest,
|
|
43734
|
+
targetVersions: marker.targetVersions,
|
|
43735
|
+
createdAt: marker.createdAt,
|
|
43736
|
+
runId: marker.runId
|
|
43737
|
+
};
|
|
43738
|
+
const markerPath = frozenMarkerPath(releaseDir);
|
|
43739
|
+
await writeFile6(markerPath, JSON.stringify(payload, null, 2) + "\n", "utf8");
|
|
43740
|
+
return markerPath;
|
|
43741
|
+
}
|
|
43742
|
+
async function clearFrozenMarker(releaseDir) {
|
|
43743
|
+
try {
|
|
43744
|
+
await unlink5(frozenMarkerPath(releaseDir));
|
|
43745
|
+
return true;
|
|
43746
|
+
} catch {
|
|
43747
|
+
return false;
|
|
43748
|
+
}
|
|
43749
|
+
}
|
|
43750
|
+
var FROZEN_MARKER_FILENAME;
|
|
43751
|
+
var init_frozen_marker = __esm({
|
|
43752
|
+
"src/core/frozen-marker.mjs"() {
|
|
43753
|
+
FROZEN_MARKER_FILENAME = "FROZEN";
|
|
43754
|
+
__name(frozenMarkerPath, "frozenMarkerPath");
|
|
43755
|
+
__name(writeFrozenMarker, "writeFrozenMarker");
|
|
43756
|
+
__name(clearFrozenMarker, "clearFrozenMarker");
|
|
43757
|
+
}
|
|
43758
|
+
});
|
|
43759
|
+
|
|
43578
43760
|
// src/core/source-authority.mjs
|
|
43579
43761
|
import { execFile as execFileCb6 } from "node:child_process";
|
|
43580
43762
|
import { promisify as promisify6 } from "node:util";
|
|
43581
|
-
import { lstat as lstat17, mkdtemp as mkdtemp5, readFile as
|
|
43582
|
-
import { join as
|
|
43763
|
+
import { lstat as lstat17, mkdtemp as mkdtemp5, readFile as readFile18, readdir as readdir12, realpath as realpath14, rm as rm7 } from "node:fs/promises";
|
|
43764
|
+
import { join as join16, relative as relative16, resolve as resolve18, sep as sep5 } from "node:path";
|
|
43583
43765
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
43584
43766
|
async function computeSourceInputClosure({ units, root }) {
|
|
43585
43767
|
const realRoot = await realpath14(resolve18(root));
|
|
@@ -43619,9 +43801,9 @@ function computeEntriesDigest(entries) {
|
|
|
43619
43801
|
}))));
|
|
43620
43802
|
}
|
|
43621
43803
|
async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
43622
|
-
let
|
|
43804
|
+
let stat10;
|
|
43623
43805
|
try {
|
|
43624
|
-
|
|
43806
|
+
stat10 = await lstat17(absolutePath);
|
|
43625
43807
|
} catch (error) {
|
|
43626
43808
|
throw new ReleaseError(
|
|
43627
43809
|
CONFIG_INVALID,
|
|
@@ -43630,7 +43812,7 @@ async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
|
43630
43812
|
);
|
|
43631
43813
|
}
|
|
43632
43814
|
const rel = toRelative(root, absolutePath);
|
|
43633
|
-
if (
|
|
43815
|
+
if (stat10.isSymbolicLink()) {
|
|
43634
43816
|
throw new ReleaseError(
|
|
43635
43817
|
CONFIG_INVALID,
|
|
43636
43818
|
`source-input closure rejects symlink "${rel}"`,
|
|
@@ -43645,30 +43827,30 @@ async function collectPath({ absolutePath, root, entriesByPath }) {
|
|
|
43645
43827
|
{ path: rel }
|
|
43646
43828
|
);
|
|
43647
43829
|
}
|
|
43648
|
-
if (
|
|
43649
|
-
const children = await
|
|
43830
|
+
if (stat10.isDirectory()) {
|
|
43831
|
+
const children = await readdir12(absolutePath, { withFileTypes: true });
|
|
43650
43832
|
children.sort((left, right) => left.name.localeCompare(right.name));
|
|
43651
43833
|
for (const child of children) {
|
|
43652
43834
|
await collectPath({
|
|
43653
|
-
absolutePath:
|
|
43835
|
+
absolutePath: join16(absolutePath, child.name),
|
|
43654
43836
|
root,
|
|
43655
43837
|
entriesByPath
|
|
43656
43838
|
});
|
|
43657
43839
|
}
|
|
43658
43840
|
return;
|
|
43659
43841
|
}
|
|
43660
|
-
if (!
|
|
43842
|
+
if (!stat10.isFile()) {
|
|
43661
43843
|
throw new ReleaseError(
|
|
43662
43844
|
CONFIG_INVALID,
|
|
43663
43845
|
`source-input closure rejects non-regular file "${rel}"`,
|
|
43664
43846
|
{ path: rel }
|
|
43665
43847
|
);
|
|
43666
43848
|
}
|
|
43667
|
-
const content = await
|
|
43849
|
+
const content = await readFile18(absolutePath);
|
|
43668
43850
|
entriesByPath.set(rel, {
|
|
43669
43851
|
path: rel,
|
|
43670
43852
|
digest: sha256Hex(content),
|
|
43671
|
-
mode: normalizeLocalGitMode(
|
|
43853
|
+
mode: normalizeLocalGitMode(stat10.mode)
|
|
43672
43854
|
});
|
|
43673
43855
|
}
|
|
43674
43856
|
function resolveInside(base, candidate, containmentRoot = base) {
|
|
@@ -43894,7 +44076,7 @@ async function verifyWithTemporaryGit({
|
|
|
43894
44076
|
if (!branchLine) {
|
|
43895
44077
|
return failure(REF_MISSING, `remote ref "refs/heads/${defaultBranch}" does not exist`);
|
|
43896
44078
|
}
|
|
43897
|
-
const tempRoot = await mkdtemp5(
|
|
44079
|
+
const tempRoot = await mkdtemp5(join16(tmpdir3(), "release-skill-source-authority-"));
|
|
43898
44080
|
try {
|
|
43899
44081
|
await execFn("git", ["init", "--bare", tempRoot], {
|
|
43900
44082
|
encoding: "utf8",
|
|
@@ -55969,17 +56151,17 @@ var require_polyfill = __commonJS({
|
|
|
55969
56151
|
copyFile,
|
|
55970
56152
|
lstat: lstat27,
|
|
55971
56153
|
mkdir: mkdir24,
|
|
55972
|
-
readdir:
|
|
56154
|
+
readdir: readdir21,
|
|
55973
56155
|
readlink: readlink2,
|
|
55974
|
-
stat:
|
|
56156
|
+
stat: stat10,
|
|
55975
56157
|
symlink,
|
|
55976
|
-
unlink:
|
|
56158
|
+
unlink: unlink6,
|
|
55977
56159
|
utimes
|
|
55978
56160
|
} = __require("fs/promises");
|
|
55979
56161
|
var {
|
|
55980
56162
|
dirname: dirname18,
|
|
55981
56163
|
isAbsolute: isAbsolute23,
|
|
55982
|
-
join:
|
|
56164
|
+
join: join34,
|
|
55983
56165
|
parse: parse2,
|
|
55984
56166
|
resolve: resolve35,
|
|
55985
56167
|
sep: sep7,
|
|
@@ -56068,7 +56250,7 @@ var require_polyfill = __commonJS({
|
|
|
56068
56250
|
}
|
|
56069
56251
|
__name(areIdentical, "areIdentical");
|
|
56070
56252
|
function getStats(src, dest, opts) {
|
|
56071
|
-
const statFunc = opts.dereference ? (file) =>
|
|
56253
|
+
const statFunc = opts.dereference ? (file) => stat10(file, { bigint: true }) : (file) => lstat27(file, { bigint: true });
|
|
56072
56254
|
return Promise.all([
|
|
56073
56255
|
statFunc(src),
|
|
56074
56256
|
statFunc(dest).catch((err) => {
|
|
@@ -56091,7 +56273,7 @@ var require_polyfill = __commonJS({
|
|
|
56091
56273
|
}
|
|
56092
56274
|
__name(checkParentDir, "checkParentDir");
|
|
56093
56275
|
function pathExists2(dest) {
|
|
56094
|
-
return
|
|
56276
|
+
return stat10(dest).then(
|
|
56095
56277
|
() => true,
|
|
56096
56278
|
// istanbul ignore next: not sure when this would occur
|
|
56097
56279
|
(err) => err.code === "ENOENT" ? false : Promise.reject(err)
|
|
@@ -56106,7 +56288,7 @@ var require_polyfill = __commonJS({
|
|
|
56106
56288
|
}
|
|
56107
56289
|
let destStat;
|
|
56108
56290
|
try {
|
|
56109
|
-
destStat = await
|
|
56291
|
+
destStat = await stat10(destParent, { bigint: true });
|
|
56110
56292
|
} catch (err) {
|
|
56111
56293
|
if (err.code === "ENOENT") {
|
|
56112
56294
|
return;
|
|
@@ -56146,7 +56328,7 @@ var require_polyfill = __commonJS({
|
|
|
56146
56328
|
}
|
|
56147
56329
|
__name(startCopy, "startCopy");
|
|
56148
56330
|
async function getStatsForCopy(destStat, src, dest, opts) {
|
|
56149
|
-
const statFn = opts.dereference ?
|
|
56331
|
+
const statFn = opts.dereference ? stat10 : lstat27;
|
|
56150
56332
|
const srcStat = await statFn(src);
|
|
56151
56333
|
if (srcStat.isDirectory() && opts.recursive) {
|
|
56152
56334
|
return onDir(srcStat, destStat, src, dest, opts);
|
|
@@ -56193,7 +56375,7 @@ var require_polyfill = __commonJS({
|
|
|
56193
56375
|
__name(onFile, "onFile");
|
|
56194
56376
|
async function mayCopyFile(srcStat, src, dest, opts) {
|
|
56195
56377
|
if (opts.force) {
|
|
56196
|
-
await
|
|
56378
|
+
await unlink6(dest);
|
|
56197
56379
|
return _copyFile(srcStat, src, dest, opts);
|
|
56198
56380
|
} else if (opts.errorOnExist) {
|
|
56199
56381
|
throw new ERR_FS_CP_EEXIST({
|
|
@@ -56239,7 +56421,7 @@ var require_polyfill = __commonJS({
|
|
|
56239
56421
|
}
|
|
56240
56422
|
__name(setDestMode, "setDestMode");
|
|
56241
56423
|
async function setDestTimestamps(src, dest) {
|
|
56242
|
-
const updatedSrcStat = await
|
|
56424
|
+
const updatedSrcStat = await stat10(src);
|
|
56243
56425
|
return utimes(dest, updatedSrcStat.atime, updatedSrcStat.mtime);
|
|
56244
56426
|
}
|
|
56245
56427
|
__name(setDestTimestamps, "setDestTimestamps");
|
|
@@ -56257,11 +56439,11 @@ var require_polyfill = __commonJS({
|
|
|
56257
56439
|
}
|
|
56258
56440
|
__name(mkDirAndCopy, "mkDirAndCopy");
|
|
56259
56441
|
async function copyDir(src, dest, opts) {
|
|
56260
|
-
const dir = await
|
|
56442
|
+
const dir = await readdir21(src);
|
|
56261
56443
|
for (let i = 0; i < dir.length; i++) {
|
|
56262
56444
|
const item = dir[i];
|
|
56263
|
-
const srcItem =
|
|
56264
|
-
const destItem =
|
|
56445
|
+
const srcItem = join34(src, item);
|
|
56446
|
+
const destItem = join34(dest, item);
|
|
56265
56447
|
const { destStat } = await checkPaths(srcItem, destItem, opts);
|
|
56266
56448
|
await startCopy(destStat, srcItem, destItem, opts);
|
|
56267
56449
|
}
|
|
@@ -56295,7 +56477,7 @@ var require_polyfill = __commonJS({
|
|
|
56295
56477
|
errno: EINVAL
|
|
56296
56478
|
});
|
|
56297
56479
|
}
|
|
56298
|
-
const srcStat = await
|
|
56480
|
+
const srcStat = await stat10(src);
|
|
56299
56481
|
if (srcStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
|
|
56300
56482
|
throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({
|
|
56301
56483
|
message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
|
|
@@ -56308,7 +56490,7 @@ var require_polyfill = __commonJS({
|
|
|
56308
56490
|
}
|
|
56309
56491
|
__name(onLink, "onLink");
|
|
56310
56492
|
async function copyLink(resolvedSrc, dest) {
|
|
56311
|
-
await
|
|
56493
|
+
await unlink6(dest);
|
|
56312
56494
|
return symlink(resolvedSrc, dest);
|
|
56313
56495
|
}
|
|
56314
56496
|
__name(copyLink, "copyLink");
|
|
@@ -56337,7 +56519,7 @@ var require_cp = __commonJS({
|
|
|
56337
56519
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js
|
|
56338
56520
|
var require_with_temp_dir = __commonJS({
|
|
56339
56521
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js"(exports, module) {
|
|
56340
|
-
var { join:
|
|
56522
|
+
var { join: join34, sep: sep7 } = __require("path");
|
|
56341
56523
|
var getOptions = require_get_options();
|
|
56342
56524
|
var { mkdir: mkdir24, mkdtemp: mkdtemp10, rm: rm15 } = __require("fs/promises");
|
|
56343
56525
|
var withTempDir = /* @__PURE__ */ __name(async (root, fn, opts) => {
|
|
@@ -56345,7 +56527,7 @@ var require_with_temp_dir = __commonJS({
|
|
|
56345
56527
|
copy: ["tmpPrefix"]
|
|
56346
56528
|
});
|
|
56347
56529
|
await mkdir24(root, { recursive: true });
|
|
56348
|
-
const target = await mkdtemp10(
|
|
56530
|
+
const target = await mkdtemp10(join34(`${root}${sep7}`, options.tmpPrefix || ""));
|
|
56349
56531
|
let err;
|
|
56350
56532
|
let result;
|
|
56351
56533
|
try {
|
|
@@ -56369,14 +56551,14 @@ var require_with_temp_dir = __commonJS({
|
|
|
56369
56551
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/readdir-scoped.js
|
|
56370
56552
|
var require_readdir_scoped = __commonJS({
|
|
56371
56553
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/readdir-scoped.js"(exports, module) {
|
|
56372
|
-
var { readdir:
|
|
56373
|
-
var { join:
|
|
56554
|
+
var { readdir: readdir21 } = __require("fs/promises");
|
|
56555
|
+
var { join: join34 } = __require("path");
|
|
56374
56556
|
var readdirScoped = /* @__PURE__ */ __name(async (dir) => {
|
|
56375
56557
|
const results = [];
|
|
56376
|
-
for (const item of await
|
|
56558
|
+
for (const item of await readdir21(dir)) {
|
|
56377
56559
|
if (item.startsWith("@")) {
|
|
56378
|
-
for (const scopedItem of await
|
|
56379
|
-
results.push(
|
|
56560
|
+
for (const scopedItem of await readdir21(join34(dir, item))) {
|
|
56561
|
+
results.push(join34(item, scopedItem));
|
|
56380
56562
|
}
|
|
56381
56563
|
} else {
|
|
56382
56564
|
results.push(item);
|
|
@@ -56391,7 +56573,7 @@ var require_readdir_scoped = __commonJS({
|
|
|
56391
56573
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js
|
|
56392
56574
|
var require_move_file = __commonJS({
|
|
56393
56575
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js"(exports, module) {
|
|
56394
|
-
var { dirname: dirname18, join:
|
|
56576
|
+
var { dirname: dirname18, join: join34, resolve: resolve35, relative: relative27, isAbsolute: isAbsolute23 } = __require("path");
|
|
56395
56577
|
var fs = __require("fs/promises");
|
|
56396
56578
|
var pathExists2 = /* @__PURE__ */ __name(async (path15) => {
|
|
56397
56579
|
try {
|
|
@@ -56421,7 +56603,7 @@ var require_move_file = __commonJS({
|
|
|
56421
56603
|
if (sourceStat.isDirectory()) {
|
|
56422
56604
|
const files = await fs.readdir(source);
|
|
56423
56605
|
await Promise.all(files.map(
|
|
56424
|
-
(file) => moveFile(
|
|
56606
|
+
(file) => moveFile(join34(source, file), join34(destination, file), options, false, symlinks)
|
|
56425
56607
|
));
|
|
56426
56608
|
} else if (sourceStat.isSymbolicLink()) {
|
|
56427
56609
|
symlinks.push({ source, destination });
|
|
@@ -56695,10 +56877,10 @@ var require_entry_index = __commonJS({
|
|
|
56695
56877
|
var {
|
|
56696
56878
|
appendFile,
|
|
56697
56879
|
mkdir: mkdir24,
|
|
56698
|
-
readFile:
|
|
56699
|
-
readdir:
|
|
56880
|
+
readFile: readFile42,
|
|
56881
|
+
readdir: readdir21,
|
|
56700
56882
|
rm: rm15,
|
|
56701
|
-
writeFile:
|
|
56883
|
+
writeFile: writeFile14
|
|
56702
56884
|
} = __require("fs/promises");
|
|
56703
56885
|
var { Minipass } = require_commonjs();
|
|
56704
56886
|
var path15 = __require("path");
|
|
@@ -56753,7 +56935,7 @@ var require_entry_index = __commonJS({
|
|
|
56753
56935
|
}
|
|
56754
56936
|
}, "teardown");
|
|
56755
56937
|
const write = /* @__PURE__ */ __name(async (tmp2) => {
|
|
56756
|
-
await
|
|
56938
|
+
await writeFile14(tmp2.target, newIndex, { flag: "wx" });
|
|
56757
56939
|
await mkdir24(path15.dirname(bucket), { recursive: true });
|
|
56758
56940
|
await moveFile(tmp2.target, bucket);
|
|
56759
56941
|
tmp2.moved = true;
|
|
@@ -56887,7 +57069,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
56887
57069
|
__name(ls, "ls");
|
|
56888
57070
|
module.exports.bucketEntries = bucketEntries;
|
|
56889
57071
|
async function bucketEntries(bucket, filter) {
|
|
56890
|
-
const data = await
|
|
57072
|
+
const data = await readFile42(bucket, "utf8");
|
|
56891
57073
|
return _bucketEntries(data, filter);
|
|
56892
57074
|
}
|
|
56893
57075
|
__name(bucketEntries, "bucketEntries");
|
|
@@ -56956,7 +57138,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
56956
57138
|
}
|
|
56957
57139
|
__name(formatEntry, "formatEntry");
|
|
56958
57140
|
function readdirOrEmpty(dir) {
|
|
56959
|
-
return
|
|
57141
|
+
return readdir21(dir).catch((err) => {
|
|
56960
57142
|
if (err.code === "ENOENT" || err.code === "ENOTDIR") {
|
|
56961
57143
|
return [];
|
|
56962
57144
|
}
|
|
@@ -57452,16 +57634,16 @@ var require_read2 = __commonJS({
|
|
|
57452
57634
|
var MAX_SINGLE_READ_SIZE = 64 * 1024 * 1024;
|
|
57453
57635
|
async function read(cache, integrity, opts = {}) {
|
|
57454
57636
|
const { size } = opts;
|
|
57455
|
-
const { stat:
|
|
57456
|
-
const
|
|
57457
|
-
return { stat:
|
|
57637
|
+
const { stat: stat10, cpath, sri } = await withContentSri(cache, integrity, async (cpath2, sri2) => {
|
|
57638
|
+
const stat11 = size ? { size } : await fs.stat(cpath2);
|
|
57639
|
+
return { stat: stat11, cpath: cpath2, sri: sri2 };
|
|
57458
57640
|
});
|
|
57459
|
-
if (
|
|
57460
|
-
return readPipeline(cpath,
|
|
57641
|
+
if (stat10.size > MAX_SINGLE_READ_SIZE) {
|
|
57642
|
+
return readPipeline(cpath, stat10.size, sri, new Pipeline()).concat();
|
|
57461
57643
|
}
|
|
57462
57644
|
const data = await fs.readFile(cpath, { encoding: null });
|
|
57463
|
-
if (
|
|
57464
|
-
throw sizeError(
|
|
57645
|
+
if (stat10.size !== data.length) {
|
|
57646
|
+
throw sizeError(stat10.size, data.length);
|
|
57465
57647
|
}
|
|
57466
57648
|
if (!ssri.checkData(data, sri)) {
|
|
57467
57649
|
throw integrityError(sri, cpath);
|
|
@@ -57488,11 +57670,11 @@ var require_read2 = __commonJS({
|
|
|
57488
57670
|
const { size } = opts;
|
|
57489
57671
|
const stream = new Pipeline();
|
|
57490
57672
|
Promise.resolve().then(async () => {
|
|
57491
|
-
const { stat:
|
|
57492
|
-
const
|
|
57493
|
-
return { stat:
|
|
57673
|
+
const { stat: stat10, cpath, sri } = await withContentSri(cache, integrity, async (cpath2, sri2) => {
|
|
57674
|
+
const stat11 = size ? { size } : await fs.stat(cpath2);
|
|
57675
|
+
return { stat: stat11, cpath: cpath2, sri: sri2 };
|
|
57494
57676
|
});
|
|
57495
|
-
return readPipeline(cpath,
|
|
57677
|
+
return readPipeline(cpath, stat10.size, sri, stream);
|
|
57496
57678
|
}).catch((err) => stream.emit("error", err));
|
|
57497
57679
|
return stream;
|
|
57498
57680
|
}
|
|
@@ -57511,8 +57693,8 @@ var require_read2 = __commonJS({
|
|
|
57511
57693
|
}
|
|
57512
57694
|
try {
|
|
57513
57695
|
return await withContentSri(cache, integrity, async (cpath, sri) => {
|
|
57514
|
-
const
|
|
57515
|
-
return { size:
|
|
57696
|
+
const stat10 = await fs.stat(cpath);
|
|
57697
|
+
return { size: stat10.size, sri, stat: stat10 };
|
|
57516
57698
|
});
|
|
57517
57699
|
} catch (err) {
|
|
57518
57700
|
if (err.code === "ENOENT") {
|
|
@@ -62907,11 +63089,11 @@ var require_verify = __commonJS({
|
|
|
62907
63089
|
"use strict";
|
|
62908
63090
|
var {
|
|
62909
63091
|
mkdir: mkdir24,
|
|
62910
|
-
readFile:
|
|
63092
|
+
readFile: readFile42,
|
|
62911
63093
|
rm: rm15,
|
|
62912
|
-
stat:
|
|
63094
|
+
stat: stat10,
|
|
62913
63095
|
truncate,
|
|
62914
|
-
writeFile:
|
|
63096
|
+
writeFile: writeFile14
|
|
62915
63097
|
} = __require("fs/promises");
|
|
62916
63098
|
var contentPath = require_path();
|
|
62917
63099
|
var fsm = require_lib29();
|
|
@@ -63029,7 +63211,7 @@ var require_verify = __commonJS({
|
|
|
63029
63211
|
}
|
|
63030
63212
|
} else {
|
|
63031
63213
|
stats.reclaimedCount++;
|
|
63032
|
-
const s = await
|
|
63214
|
+
const s = await stat10(f);
|
|
63033
63215
|
await rm15(f, { recursive: true, force: true });
|
|
63034
63216
|
stats.reclaimedSize += s.size;
|
|
63035
63217
|
}
|
|
@@ -63043,7 +63225,7 @@ var require_verify = __commonJS({
|
|
|
63043
63225
|
async function verifyContent(filepath, sri) {
|
|
63044
63226
|
const contentInfo = {};
|
|
63045
63227
|
try {
|
|
63046
|
-
const { size } = await
|
|
63228
|
+
const { size } = await stat10(filepath);
|
|
63047
63229
|
contentInfo.size = size;
|
|
63048
63230
|
contentInfo.valid = true;
|
|
63049
63231
|
await ssri.checkStream(new fsm.ReadStream(filepath), sri);
|
|
@@ -63103,7 +63285,7 @@ var require_verify = __commonJS({
|
|
|
63103
63285
|
for (const entry of bucket) {
|
|
63104
63286
|
const content = contentPath(cache, entry.integrity);
|
|
63105
63287
|
try {
|
|
63106
|
-
await
|
|
63288
|
+
await stat10(content);
|
|
63107
63289
|
await index.insert(cache, entry.key, entry.integrity, {
|
|
63108
63290
|
metadata: entry.metadata,
|
|
63109
63291
|
size: entry.size,
|
|
@@ -63129,12 +63311,12 @@ var require_verify = __commonJS({
|
|
|
63129
63311
|
async function writeVerifile(cache, opts) {
|
|
63130
63312
|
const verifile = path15.join(cache, "_lastverified");
|
|
63131
63313
|
opts.log.silly("verify", "writing verifile to " + verifile);
|
|
63132
|
-
return
|
|
63314
|
+
return writeFile14(verifile, `${Date.now()}`);
|
|
63133
63315
|
}
|
|
63134
63316
|
__name(writeVerifile, "writeVerifile");
|
|
63135
63317
|
module.exports.lastRun = lastRun;
|
|
63136
63318
|
async function lastRun(cache) {
|
|
63137
|
-
const data = await
|
|
63319
|
+
const data = await readFile42(path15.join(cache, "_lastverified"), { encoding: "utf8" });
|
|
63138
63320
|
return /* @__PURE__ */ new Date(+data);
|
|
63139
63321
|
}
|
|
63140
63322
|
__name(lastRun, "lastRun");
|
|
@@ -71674,7 +71856,7 @@ var require_index_min = __commonJS({
|
|
|
71674
71856
|
var require_lib35 = __commonJS({
|
|
71675
71857
|
"../../node_modules/.pnpm/which@5.0.0/node_modules/which/lib/index.js"(exports, module) {
|
|
71676
71858
|
var { isexe, sync: isexeSync } = require_index_min();
|
|
71677
|
-
var { join:
|
|
71859
|
+
var { join: join34, delimiter, sep: sep7, posix: posix3 } = __require("path");
|
|
71678
71860
|
var isWindows = process.platform === "win32";
|
|
71679
71861
|
var rSlash = new RegExp(`[${posix3.sep}${sep7 === posix3.sep ? "" : sep7}]`.replace(/(\\)/g, "\\$1"));
|
|
71680
71862
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -71703,7 +71885,7 @@ var require_lib35 = __commonJS({
|
|
|
71703
71885
|
var getPathPart = /* @__PURE__ */ __name((raw, cmd) => {
|
|
71704
71886
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
71705
71887
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
71706
|
-
return prefix +
|
|
71888
|
+
return prefix + join34(pathPart, cmd);
|
|
71707
71889
|
}, "getPathPart");
|
|
71708
71890
|
var which = /* @__PURE__ */ __name(async (cmd, opt = {}) => {
|
|
71709
71891
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -72842,7 +73024,7 @@ var require_lib37 = __commonJS({
|
|
|
72842
73024
|
// ../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js
|
|
72843
73025
|
var require_lib38 = __commonJS({
|
|
72844
73026
|
"../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js"(exports, module) {
|
|
72845
|
-
var { join:
|
|
73027
|
+
var { join: join34, basename: basename13 } = __require("path");
|
|
72846
73028
|
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
73029
|
var normalizeString = /* @__PURE__ */ __name((pkg) => {
|
|
72848
73030
|
if (!pkg.name) {
|
|
@@ -72853,7 +73035,7 @@ var require_lib38 = __commonJS({
|
|
|
72853
73035
|
}, "normalizeString");
|
|
72854
73036
|
var normalizeArray = /* @__PURE__ */ __name((pkg) => {
|
|
72855
73037
|
pkg.bin = pkg.bin.reduce((acc, k) => {
|
|
72856
|
-
acc[
|
|
73038
|
+
acc[basename13(k)] = k;
|
|
72857
73039
|
return acc;
|
|
72858
73040
|
}, {});
|
|
72859
73041
|
return normalizeObject(pkg);
|
|
@@ -72867,11 +73049,11 @@ var require_lib38 = __commonJS({
|
|
|
72867
73049
|
const clean = {};
|
|
72868
73050
|
let hasBins = false;
|
|
72869
73051
|
Object.keys(orig).forEach((binKey) => {
|
|
72870
|
-
const base =
|
|
73052
|
+
const base = join34("/", basename13(binKey.replace(/\\|:/g, "/"))).slice(1);
|
|
72871
73053
|
if (typeof orig[binKey] !== "string" || !base) {
|
|
72872
73054
|
return;
|
|
72873
73055
|
}
|
|
72874
|
-
const binTarget =
|
|
73056
|
+
const binTarget = join34("/", orig[binKey].replace(/\\/g, "/")).replace(/\\/g, "/").slice(1);
|
|
72875
73057
|
if (!binTarget) {
|
|
72876
73058
|
return;
|
|
72877
73059
|
}
|
|
@@ -73172,8 +73354,8 @@ var require_clone2 = __commonJS({
|
|
|
73172
73354
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is.js
|
|
73173
73355
|
var require_is = __commonJS({
|
|
73174
73356
|
"../../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() } = {}) =>
|
|
73357
|
+
var { stat: stat10 } = __require("fs/promises");
|
|
73358
|
+
module.exports = ({ cwd = process.cwd() } = {}) => stat10(cwd + "/.git").then(() => true, () => false);
|
|
73177
73359
|
}
|
|
73178
73360
|
});
|
|
73179
73361
|
|
|
@@ -75412,11 +75594,11 @@ var require_normalize = __commonJS({
|
|
|
75412
75594
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js
|
|
75413
75595
|
var require_read_package = __commonJS({
|
|
75414
75596
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js"(exports, module) {
|
|
75415
|
-
var { readFile:
|
|
75597
|
+
var { readFile: readFile42 } = __require("fs/promises");
|
|
75416
75598
|
var parseJSON = require_lib34();
|
|
75417
75599
|
async function read(filename) {
|
|
75418
75600
|
try {
|
|
75419
|
-
const data = await
|
|
75601
|
+
const data = await readFile42(filename, "utf8");
|
|
75420
75602
|
return data;
|
|
75421
75603
|
} catch (err) {
|
|
75422
75604
|
err.message = `Could not read package.json: ${err}`;
|
|
@@ -75549,7 +75731,7 @@ var require_sort2 = __commonJS({
|
|
|
75549
75731
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js
|
|
75550
75732
|
var require_lib41 = __commonJS({
|
|
75551
75733
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js"(exports, module) {
|
|
75552
|
-
var { readFile:
|
|
75734
|
+
var { readFile: readFile42, writeFile: writeFile14 } = __require("node:fs/promises");
|
|
75553
75735
|
var { resolve: resolve35 } = __require("node:path");
|
|
75554
75736
|
var parseJSON = require_lib34();
|
|
75555
75737
|
var updateDeps = require_update_dependencies();
|
|
@@ -75676,7 +75858,7 @@ var require_lib41 = __commonJS({
|
|
|
75676
75858
|
const indexFile = resolve35(this.path, "index.js");
|
|
75677
75859
|
let indexFileContent;
|
|
75678
75860
|
try {
|
|
75679
|
-
indexFileContent = await
|
|
75861
|
+
indexFileContent = await readFile42(indexFile, "utf8");
|
|
75680
75862
|
} catch (err) {
|
|
75681
75863
|
throw parseErr;
|
|
75682
75864
|
}
|
|
@@ -75764,7 +75946,7 @@ var require_lib41 = __commonJS({
|
|
|
75764
75946
|
const fileContent = `${JSON.stringify(content, null, format)}
|
|
75765
75947
|
`.replace(/\n/g, eol);
|
|
75766
75948
|
if (fileContent.trim() !== this.#readFileContent.trim()) {
|
|
75767
|
-
const written = await
|
|
75949
|
+
const written = await writeFile14(this.filename, fileContent);
|
|
75768
75950
|
this.#readFileContent = fileContent;
|
|
75769
75951
|
return written;
|
|
75770
75952
|
}
|
|
@@ -82875,12 +83057,12 @@ var require_url = __commonJS({
|
|
|
82875
83057
|
"../../node_modules/.pnpm/tuf-js@3.1.0/node_modules/tuf-js/dist/utils/url.js"(exports) {
|
|
82876
83058
|
"use strict";
|
|
82877
83059
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
82878
|
-
exports.join =
|
|
83060
|
+
exports.join = join34;
|
|
82879
83061
|
var url_1 = __require("url");
|
|
82880
|
-
function
|
|
83062
|
+
function join34(base, path15) {
|
|
82881
83063
|
return new url_1.URL(ensureTrailingSlash(base) + removeLeadingSlash(path15)).toString();
|
|
82882
83064
|
}
|
|
82883
|
-
__name(
|
|
83065
|
+
__name(join34, "join");
|
|
82884
83066
|
function ensureTrailingSlash(path15) {
|
|
82885
83067
|
return path15.endsWith("/") ? path15 : path15 + "/";
|
|
82886
83068
|
}
|
|
@@ -84985,7 +85167,7 @@ var require_dist16 = __commonJS({
|
|
|
84985
85167
|
var require_provenance = __commonJS({
|
|
84986
85168
|
"../../node_modules/.pnpm/libnpmpublish@11.1.0/node_modules/libnpmpublish/lib/provenance.js"(exports, module) {
|
|
84987
85169
|
var sigstore = require_dist16();
|
|
84988
|
-
var { readFile:
|
|
85170
|
+
var { readFile: readFile42 } = __require("node:fs/promises");
|
|
84989
85171
|
var ci = require_ci_info();
|
|
84990
85172
|
var { env } = process;
|
|
84991
85173
|
var INTOTO_PAYLOAD_TYPE = "application/vnd.in-toto+json";
|
|
@@ -85177,7 +85359,7 @@ var require_provenance = __commonJS({
|
|
|
85177
85359
|
var verifyProvenance = /* @__PURE__ */ __name(async (subject, provenancePath) => {
|
|
85178
85360
|
let provenanceBundle;
|
|
85179
85361
|
try {
|
|
85180
|
-
provenanceBundle = JSON.parse(await
|
|
85362
|
+
provenanceBundle = JSON.parse(await readFile42(provenancePath));
|
|
85181
85363
|
} catch (err) {
|
|
85182
85364
|
err.message = `Invalid provenance provided: ${err.message}`;
|
|
85183
85365
|
throw err;
|
|
@@ -85513,13 +85695,13 @@ __export(npm_exports, {
|
|
|
85513
85695
|
verifyFrozenNpmTarballContract: () => verifyFrozenNpmTarballContract,
|
|
85514
85696
|
verifyFrozenNpmTarballIdentity: () => verifyFrozenNpmTarballIdentity
|
|
85515
85697
|
});
|
|
85516
|
-
import { createHash as
|
|
85698
|
+
import { createHash as createHash14, randomUUID } from "node:crypto";
|
|
85517
85699
|
import { execFile as execFileCb7, spawn as spawn3 } from "node:child_process";
|
|
85518
85700
|
import { gunzipSync } from "node:zlib";
|
|
85519
85701
|
import { promisify as promisify7 } from "node:util";
|
|
85520
|
-
import { dirname as dirname9, isAbsolute as isAbsolute14, join as
|
|
85702
|
+
import { dirname as dirname9, isAbsolute as isAbsolute14, join as join17, relative as relative17, resolve as resolve19 } from "node:path";
|
|
85521
85703
|
import { constants as fsConstants4 } from "node:fs";
|
|
85522
|
-
import { chmod as chmod3, lstat as lstat18, mkdtemp as mkdtemp6, open as open8, readFile as
|
|
85704
|
+
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
85705
|
function validatePackageName(value) {
|
|
85524
85706
|
if (typeof value !== "string" || value.length > 214 || !SAFE_PACKAGE_NAME.test(value)) {
|
|
85525
85707
|
throw new Error("npm package must be a safe lowercase package name or @scope/name");
|
|
@@ -85573,7 +85755,7 @@ function expandNpmrcValue(raw, env) {
|
|
|
85573
85755
|
async function tokensFromNpmrc(path15, key, env) {
|
|
85574
85756
|
let contents;
|
|
85575
85757
|
try {
|
|
85576
|
-
contents = await
|
|
85758
|
+
contents = await readFile19(path15, "utf8");
|
|
85577
85759
|
} catch (err) {
|
|
85578
85760
|
if (err?.code === "ENOENT") return [];
|
|
85579
85761
|
throw new Error("cannot read npm authentication config");
|
|
@@ -85596,7 +85778,7 @@ async function defaultResolveAuthToken({ registry, cwd, exec, env = process.env
|
|
|
85596
85778
|
if (env[name]) candidates.push(env[name]);
|
|
85597
85779
|
}
|
|
85598
85780
|
const key = registryTokenKey(registry);
|
|
85599
|
-
candidates.push(...await tokensFromNpmrc(
|
|
85781
|
+
candidates.push(...await tokensFromNpmrc(join17(cwd, ".npmrc"), key, env));
|
|
85600
85782
|
const npmUserConfigKey = ["npm", "config", "userconfig"].join("_");
|
|
85601
85783
|
const userConfig = env[npmUserConfigKey] ?? (await exec("npm", ["config", "get", "userconfig"], { cwd, shell: false })).stdout.trim();
|
|
85602
85784
|
if (userConfig) candidates.push(...await tokensFromNpmrc(userConfig, key, env));
|
|
@@ -85674,12 +85856,12 @@ async function readVerifiedTarballBytes(action, root) {
|
|
|
85674
85856
|
} finally {
|
|
85675
85857
|
await source.close();
|
|
85676
85858
|
}
|
|
85677
|
-
const digest2 =
|
|
85859
|
+
const digest2 = createHash14("sha256").update(bytes).digest("hex");
|
|
85678
85860
|
if (digest2 !== action.tarballSha256) throw new Error("frozen npm tarball SHA-256 mismatch");
|
|
85679
85861
|
if (typeof action.integrity !== "string" || !/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(action.integrity)) {
|
|
85680
85862
|
throw new Error("frozen npm tarball integrity must be an sha512 SRI value");
|
|
85681
85863
|
}
|
|
85682
|
-
const integrity = `sha512-${
|
|
85864
|
+
const integrity = `sha512-${createHash14("sha512").update(bytes).digest("base64")}`;
|
|
85683
85865
|
if (integrity !== action.integrity) throw new Error("frozen npm tarball SHA-512 integrity mismatch");
|
|
85684
85866
|
return bytes;
|
|
85685
85867
|
}
|
|
@@ -86127,9 +86309,9 @@ var init_npm = __esm({
|
|
|
86127
86309
|
});
|
|
86128
86310
|
|
|
86129
86311
|
// src/core/run.mjs
|
|
86130
|
-
import { lstat as lstat19, mkdir as mkdir12, readFile as
|
|
86312
|
+
import { lstat as lstat19, mkdir as mkdir12, readFile as readFile20 } from "node:fs/promises";
|
|
86131
86313
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
86132
|
-
import { dirname as dirname10, join as
|
|
86314
|
+
import { dirname as dirname10, join as join18, resolve as resolve20, basename as basename5, relative as relative18, isAbsolute as isAbsolute15 } from "node:path";
|
|
86133
86315
|
function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.now()}`) {
|
|
86134
86316
|
const absolute = resolve20(planPath);
|
|
86135
86317
|
const fileName = basename5(absolute);
|
|
@@ -86139,7 +86321,7 @@ function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.no
|
|
|
86139
86321
|
}
|
|
86140
86322
|
if (basename5(parentDir) === "plans") {
|
|
86141
86323
|
const releaseDir = dirname10(parentDir);
|
|
86142
|
-
return
|
|
86324
|
+
return join18(releaseDir, "runs", runId);
|
|
86143
86325
|
}
|
|
86144
86326
|
return `${parentDir}/runs/${runId}`;
|
|
86145
86327
|
}
|
|
@@ -86179,7 +86361,7 @@ function validateRun(run5, options = {}) {
|
|
|
86179
86361
|
async function loadRun(runPath, options = {}) {
|
|
86180
86362
|
let raw;
|
|
86181
86363
|
try {
|
|
86182
|
-
raw = await
|
|
86364
|
+
raw = await readFile20(runPath, "utf8");
|
|
86183
86365
|
} catch (err) {
|
|
86184
86366
|
throw new ReleaseError(
|
|
86185
86367
|
GATE_FAILED,
|
|
@@ -86218,7 +86400,7 @@ function assertImmutableRunAuthority(runPath, planPath, run5) {
|
|
|
86218
86400
|
}
|
|
86219
86401
|
cursor = dirname10(cursor);
|
|
86220
86402
|
}
|
|
86221
|
-
const runsDir =
|
|
86403
|
+
const runsDir = join18(authorityRoot, "runs");
|
|
86222
86404
|
const absoluteRun = realpathSync3(resolve20(runPath));
|
|
86223
86405
|
const rel = relative18(runsDir, absoluteRun);
|
|
86224
86406
|
if (isAbsolute15(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
@@ -86273,7 +86455,7 @@ async function createProductionPrepareRunDir(runDir, releaseDir) {
|
|
|
86273
86455
|
return createProductionRunDirWithinAuthority(runDir, physicalAuthorityRoot);
|
|
86274
86456
|
}
|
|
86275
86457
|
async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
86276
|
-
const runsDir =
|
|
86458
|
+
const runsDir = join18(authorityRoot, "runs");
|
|
86277
86459
|
let runsStat;
|
|
86278
86460
|
try {
|
|
86279
86461
|
runsStat = await lstat19(runsDir);
|
|
@@ -86383,7 +86565,7 @@ async function validateStatePredecessorChain(run5, runPath, options = {}) {
|
|
|
86383
86565
|
if (traversed > 1e5) {
|
|
86384
86566
|
throw new ReleaseError(GATE_FAILED, "run state predecessor chain exceeds maximum depth");
|
|
86385
86567
|
}
|
|
86386
|
-
const previousPath =
|
|
86568
|
+
const previousPath = join18(dirname10(currentPath), `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
86387
86569
|
const previous = await loadRun(previousPath, {
|
|
86388
86570
|
requireDigest: true,
|
|
86389
86571
|
...options.production ? { authorityPlanPath: options.planPath } : {}
|
|
@@ -86556,7 +86738,7 @@ async function writeRunAtomic(runPath, run5) {
|
|
|
86556
86738
|
await publishFileExclusive(dir, basename5(runPath), json, { mode: 384 });
|
|
86557
86739
|
} catch (cause) {
|
|
86558
86740
|
if (cause?.details?.kind === HARNESS_ERROR_KINDS.EXCLUSIVE_PUBLISH_CONFLICT) {
|
|
86559
|
-
const existing = await
|
|
86741
|
+
const existing = await readFile20(runPath, "utf8").catch(() => null);
|
|
86560
86742
|
if (existing === json) return Object.freeze(sealed);
|
|
86561
86743
|
throw new ReleaseError(
|
|
86562
86744
|
GATE_FAILED,
|
|
@@ -86576,10 +86758,10 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
86576
86758
|
if (!Number.isSafeInteger(sequence) || sequence < 0) {
|
|
86577
86759
|
throw new ReleaseError(GATE_FAILED, "run state sequence must be a non-negative integer");
|
|
86578
86760
|
}
|
|
86579
|
-
const statesDir =
|
|
86761
|
+
const statesDir = join18(runDir, "states");
|
|
86580
86762
|
let previousStateDigest;
|
|
86581
86763
|
if (sequence > 0) {
|
|
86582
|
-
const previousPath =
|
|
86764
|
+
const previousPath = join18(statesDir, `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
86583
86765
|
const previous = await loadRun(previousPath, { requireDigest: true });
|
|
86584
86766
|
if (previous.stateSequence !== sequence - 1 || previous.runId !== run5.runId || previous.command !== run5.command || previous.planDigest !== run5.planDigest) {
|
|
86585
86767
|
throw new ReleaseError(
|
|
@@ -86596,7 +86778,7 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
86596
86778
|
stateSequence: sequence,
|
|
86597
86779
|
...previousStateDigest ? { previousStateDigest } : {}
|
|
86598
86780
|
});
|
|
86599
|
-
const statePath =
|
|
86781
|
+
const statePath = join18(statesDir, `${String(sequence).padStart(6, "0")}.json`);
|
|
86600
86782
|
await writeRunAtomic(statePath, state);
|
|
86601
86783
|
return Object.freeze({ state, statePath });
|
|
86602
86784
|
}
|
|
@@ -86649,9 +86831,9 @@ __export(plugin_marketplace_exports, {
|
|
|
86649
86831
|
});
|
|
86650
86832
|
import { execFile as execFileCb8 } from "node:child_process";
|
|
86651
86833
|
import { promisify as promisify8 } from "node:util";
|
|
86652
|
-
import { readFile as
|
|
86653
|
-
import { join as
|
|
86654
|
-
import { createHash as
|
|
86834
|
+
import { readFile as readFile21, stat as stat5, mkdir as mkdir13, readdir as readdir13, realpath as realpath16, lstat as lstat20 } from "node:fs/promises";
|
|
86835
|
+
import { join as join19, resolve as resolve21, relative as relative19, isAbsolute as isAbsolute16, basename as basename6 } from "node:path";
|
|
86836
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
86655
86837
|
function transportPayload(entries) {
|
|
86656
86838
|
return entries.map(({ path: path15, type, mode, size, contentDigest }) => ({
|
|
86657
86839
|
path: path15,
|
|
@@ -86736,7 +86918,7 @@ async function resolvePluginManifestFromMarketplaceEntrySource(marketIndex, plug
|
|
|
86736
86918
|
const fullManifestRelative = pluginRootRelToSnapshot === "" ? manifestRelative : `${pluginRootRelToSnapshot}/${manifestRelative}`;
|
|
86737
86919
|
let raw;
|
|
86738
86920
|
try {
|
|
86739
|
-
raw = await
|
|
86921
|
+
raw = await readFile21(manifestAbs, "utf8");
|
|
86740
86922
|
} catch (err) {
|
|
86741
86923
|
throw new Error(
|
|
86742
86924
|
`plugin manifest not found at "${fullManifestRelative}": ${err.message}`
|
|
@@ -87185,7 +87367,7 @@ async function run2(cmd, args2, options = {}) {
|
|
|
87185
87367
|
}
|
|
87186
87368
|
async function validateManifestFile(manifestPath, requiredFields) {
|
|
87187
87369
|
try {
|
|
87188
|
-
const content = await
|
|
87370
|
+
const content = await readFile21(manifestPath, "utf8");
|
|
87189
87371
|
const manifest = JSON.parse(content);
|
|
87190
87372
|
const missing = requiredFields.filter((f) => !(f in manifest));
|
|
87191
87373
|
return {
|
|
@@ -87207,7 +87389,7 @@ async function checkRequiredFiles(dir, requiredFiles) {
|
|
|
87207
87389
|
const missing = [];
|
|
87208
87390
|
for (const file of requiredFiles) {
|
|
87209
87391
|
try {
|
|
87210
|
-
await
|
|
87392
|
+
await stat5(resolve21(dir, file));
|
|
87211
87393
|
} catch {
|
|
87212
87394
|
missing.push(file);
|
|
87213
87395
|
}
|
|
@@ -87303,7 +87485,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
87303
87485
|
});
|
|
87304
87486
|
}
|
|
87305
87487
|
try {
|
|
87306
|
-
const s = await
|
|
87488
|
+
const s = await stat5(pluginDir);
|
|
87307
87489
|
if (!s.isDirectory()) {
|
|
87308
87490
|
return createResult({
|
|
87309
87491
|
actionType,
|
|
@@ -88089,7 +88271,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88089
88271
|
let entrySkillFile = resolve21(pluginRootForSkill, "skills", action.entrySkill, "SKILL.md");
|
|
88090
88272
|
let entrySkillExists = false;
|
|
88091
88273
|
try {
|
|
88092
|
-
await
|
|
88274
|
+
await stat5(entrySkillFile);
|
|
88093
88275
|
entrySkillExists = true;
|
|
88094
88276
|
} catch {
|
|
88095
88277
|
if (action.plugin) {
|
|
@@ -88100,7 +88282,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88100
88282
|
"SKILL.md"
|
|
88101
88283
|
);
|
|
88102
88284
|
try {
|
|
88103
|
-
await
|
|
88285
|
+
await stat5(prefixed);
|
|
88104
88286
|
entrySkillFile = prefixed;
|
|
88105
88287
|
entrySkillExists = true;
|
|
88106
88288
|
} catch {
|
|
@@ -88517,7 +88699,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88517
88699
|
if (actionType === ActionType.PLUGIN_MANIFEST_VALIDATE) {
|
|
88518
88700
|
const manifestPath = action.manifestPath;
|
|
88519
88701
|
try {
|
|
88520
|
-
const content = await
|
|
88702
|
+
const content = await readFile21(manifestPath, "utf8");
|
|
88521
88703
|
const manifest = JSON.parse(content);
|
|
88522
88704
|
return createResult({
|
|
88523
88705
|
actionType,
|
|
@@ -88612,7 +88794,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88612
88794
|
}
|
|
88613
88795
|
let requirement = null;
|
|
88614
88796
|
try {
|
|
88615
|
-
requirement = JSON.parse(await
|
|
88797
|
+
requirement = JSON.parse(await readFile21(resolve21(attestationDir, KIMI_REQUIREMENT_FILE), "utf8"));
|
|
88616
88798
|
} catch {
|
|
88617
88799
|
return createResult({
|
|
88618
88800
|
actionType,
|
|
@@ -88636,7 +88818,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88636
88818
|
}
|
|
88637
88819
|
let attestation = null;
|
|
88638
88820
|
try {
|
|
88639
|
-
attestation = JSON.parse(await
|
|
88821
|
+
attestation = JSON.parse(await readFile21(resolve21(attestationDir, KIMI_ATTESTATION_FILE), "utf8"));
|
|
88640
88822
|
} catch {
|
|
88641
88823
|
return createResult({
|
|
88642
88824
|
actionType,
|
|
@@ -88803,7 +88985,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88803
88985
|
}
|
|
88804
88986
|
let requirement = null;
|
|
88805
88987
|
try {
|
|
88806
|
-
requirement = JSON.parse(await
|
|
88988
|
+
requirement = JSON.parse(await readFile21(resolve21(attestationDir, CODEBUDDY_REQUIREMENT_FILE), "utf8"));
|
|
88807
88989
|
} catch {
|
|
88808
88990
|
return createResult({
|
|
88809
88991
|
actionType,
|
|
@@ -88827,7 +89009,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88827
89009
|
}
|
|
88828
89010
|
let attestation = null;
|
|
88829
89011
|
try {
|
|
88830
|
-
attestation = JSON.parse(await
|
|
89012
|
+
attestation = JSON.parse(await readFile21(resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE), "utf8"));
|
|
88831
89013
|
} catch {
|
|
88832
89014
|
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
88833
89015
|
return createResult({
|
|
@@ -88976,13 +89158,13 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
88976
89158
|
if (codexAttestationDir) {
|
|
88977
89159
|
let codexRequirement = null;
|
|
88978
89160
|
try {
|
|
88979
|
-
codexRequirement = JSON.parse(await
|
|
89161
|
+
codexRequirement = JSON.parse(await readFile21(resolve21(codexAttestationDir, CODEX_REQUIREMENT_FILE), "utf8"));
|
|
88980
89162
|
} catch {
|
|
88981
89163
|
}
|
|
88982
89164
|
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
89165
|
let codexAttestation = null;
|
|
88984
89166
|
try {
|
|
88985
|
-
codexAttestation = JSON.parse(await
|
|
89167
|
+
codexAttestation = JSON.parse(await readFile21(resolve21(codexAttestationDir, CODEX_ATTESTATION_FILE), "utf8"));
|
|
88986
89168
|
} catch {
|
|
88987
89169
|
}
|
|
88988
89170
|
if (codexAttestation) {
|
|
@@ -89037,7 +89219,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
89037
89219
|
}
|
|
89038
89220
|
let evidence = null;
|
|
89039
89221
|
try {
|
|
89040
|
-
const evidenceRaw = await
|
|
89222
|
+
const evidenceRaw = await readFile21(resolve21(runDir, "evidence", `${consumer}-${action.plugin}`, "release-skill-install-evidence.json"), "utf8");
|
|
89041
89223
|
evidence = JSON.parse(evidenceRaw);
|
|
89042
89224
|
} catch {
|
|
89043
89225
|
return createResult({
|
|
@@ -89220,7 +89402,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
89220
89402
|
}
|
|
89221
89403
|
try {
|
|
89222
89404
|
const installedManifestPath = resolve21(installPath, platform.manifestPaths.plugin);
|
|
89223
|
-
const installedManifestContent = await
|
|
89405
|
+
const installedManifestContent = await readFile21(installedManifestPath, "utf8");
|
|
89224
89406
|
const installedManifest = JSON.parse(installedManifestContent);
|
|
89225
89407
|
const expectedName = observation.plugin;
|
|
89226
89408
|
if (expectedName && installedManifest.name !== expectedName) {
|
|
@@ -89651,8 +89833,8 @@ var init_postpublish = __esm({
|
|
|
89651
89833
|
});
|
|
89652
89834
|
|
|
89653
89835
|
// src/artifacts/transaction-journal.mjs
|
|
89654
|
-
import { readdir as
|
|
89655
|
-
import { join as
|
|
89836
|
+
import { readdir as readdir14, readFile as readFile22, rm as rm9, stat as stat6 } from "node:fs/promises";
|
|
89837
|
+
import { join as join20 } from "node:path";
|
|
89656
89838
|
function failSchema(message, details) {
|
|
89657
89839
|
throw new ReleaseError(TRANSACTION_INCOMPLETE, message, details);
|
|
89658
89840
|
}
|
|
@@ -90649,7 +90831,7 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90649
90831
|
if (!Number.isInteger(retentionMax) || retentionMax < 0) return summary;
|
|
90650
90832
|
let entries;
|
|
90651
90833
|
try {
|
|
90652
|
-
entries = await
|
|
90834
|
+
entries = await readdir14(transactionsRoot, { withFileTypes: true });
|
|
90653
90835
|
} catch (scanErr) {
|
|
90654
90836
|
summary.errors.push(`scan: ${scanErr?.code || scanErr?.message || "readdir-failed"}`);
|
|
90655
90837
|
return summary;
|
|
@@ -90659,11 +90841,11 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90659
90841
|
if (txnDirs.length <= retentionMax) return summary;
|
|
90660
90842
|
const terminal = [];
|
|
90661
90843
|
for (const entry of txnDirs) {
|
|
90662
|
-
const recordDir =
|
|
90844
|
+
const recordDir = join20(transactionsRoot, entry.name);
|
|
90663
90845
|
let state = null;
|
|
90664
90846
|
let createdAt = null;
|
|
90665
90847
|
try {
|
|
90666
|
-
const raw = await
|
|
90848
|
+
const raw = await readFile22(join20(recordDir, "journal.json"), "utf8");
|
|
90667
90849
|
const journal = JSON.parse(raw);
|
|
90668
90850
|
if (journal && typeof journal === "object") {
|
|
90669
90851
|
state = typeof journal.state === "string" ? journal.state : null;
|
|
@@ -90676,7 +90858,7 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
90676
90858
|
let sortTime = Date.parse(createdAt);
|
|
90677
90859
|
if (!Number.isFinite(sortTime)) {
|
|
90678
90860
|
try {
|
|
90679
|
-
const dirStat = await
|
|
90861
|
+
const dirStat = await stat6(recordDir);
|
|
90680
90862
|
sortTime = dirStat.mtimeMs;
|
|
90681
90863
|
} catch {
|
|
90682
90864
|
sortTime = Number.MAX_SAFE_INTEGER;
|
|
@@ -90727,7 +90909,7 @@ async function createTransactionJournal({
|
|
|
90727
90909
|
);
|
|
90728
90910
|
if (typeof root === "string" && root.length > 0) {
|
|
90729
90911
|
await pruneTerminalTransactionRecords(
|
|
90730
|
-
|
|
90912
|
+
join20(root, ".release-skill", "transactions"),
|
|
90731
90913
|
{ retentionMax }
|
|
90732
90914
|
);
|
|
90733
90915
|
}
|
|
@@ -94862,6 +95044,7 @@ var init_refresh_service = __esm({
|
|
|
94862
95044
|
// src/commands/prepare.mjs
|
|
94863
95045
|
var prepare_exports = {};
|
|
94864
95046
|
__export(prepare_exports, {
|
|
95047
|
+
boundedOutputTail: () => boundedOutputTail,
|
|
94865
95048
|
buildExternalActions: () => buildExternalActions,
|
|
94866
95049
|
decodeExternalMarketplaceIndex: () => decodeExternalMarketplaceIndex,
|
|
94867
95050
|
parseExternalMarketplaceLsRemote: () => parseExternalMarketplaceLsRemote,
|
|
@@ -94873,8 +95056,8 @@ __export(prepare_exports, {
|
|
|
94873
95056
|
resolveUnitVersion: () => resolveUnitVersion,
|
|
94874
95057
|
runDeclaredHooks: () => runDeclaredHooks
|
|
94875
95058
|
});
|
|
94876
|
-
import { resolve as resolve23, relative as relative22, isAbsolute as isAbsolute18, normalize as normalize3, dirname as dirname11 } from "node:path";
|
|
94877
|
-
import { readFile as
|
|
95059
|
+
import { resolve as resolve23, relative as relative22, isAbsolute as isAbsolute18, normalize as normalize3, dirname as dirname11, basename as basename7 } from "node:path";
|
|
95060
|
+
import { readFile as readFile23, mkdir as mkdir14, readdir as readdir15, realpath as realpath17 } from "node:fs/promises";
|
|
94878
95061
|
import { execFile as execFileCb9 } from "node:child_process";
|
|
94879
95062
|
import { promisify as promisify9 } from "node:util";
|
|
94880
95063
|
async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
@@ -94906,7 +95089,7 @@ async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
|
94906
95089
|
}
|
|
94907
95090
|
let content;
|
|
94908
95091
|
try {
|
|
94909
|
-
content = await
|
|
95092
|
+
content = await readFile23(normalizedPath, "utf8");
|
|
94910
95093
|
} catch (err) {
|
|
94911
95094
|
throw new ReleaseError(
|
|
94912
95095
|
CONFIG_INVALID,
|
|
@@ -94968,17 +95151,38 @@ async function resolveAllUnitVersions(units, root, explicitVersion, evidence) {
|
|
|
94968
95151
|
});
|
|
94969
95152
|
return resolvedVersions;
|
|
94970
95153
|
}
|
|
95154
|
+
function boundedOutputTail(text) {
|
|
95155
|
+
if (typeof text !== "string" || text.length === 0) return "";
|
|
95156
|
+
let lines = text.split("\n");
|
|
95157
|
+
if (lines.length > 1 && lines[lines.length - 1] === "") {
|
|
95158
|
+
lines = lines.slice(0, -1);
|
|
95159
|
+
}
|
|
95160
|
+
let tail2 = lines.slice(-HOOK_OUTPUT_TAIL_MAX_LINES);
|
|
95161
|
+
let joined = tail2.join("\n");
|
|
95162
|
+
while (tail2.length > 1 && Buffer.byteLength(joined, "utf8") > HOOK_OUTPUT_TAIL_MAX_BYTES) {
|
|
95163
|
+
tail2 = tail2.slice(1);
|
|
95164
|
+
joined = tail2.join("\n");
|
|
95165
|
+
}
|
|
95166
|
+
if (Buffer.byteLength(joined, "utf8") > HOOK_OUTPUT_TAIL_MAX_BYTES) {
|
|
95167
|
+
const buf = Buffer.from(joined, "utf8");
|
|
95168
|
+
joined = buf.subarray(buf.length - HOOK_OUTPUT_TAIL_MAX_BYTES).toString("utf8");
|
|
95169
|
+
}
|
|
95170
|
+
return joined;
|
|
95171
|
+
}
|
|
94971
95172
|
async function runDeclaredHooks(config, root, evidence, hookFn = runHook, options = {}) {
|
|
94972
95173
|
const hookOrder = ["docs", "build", "test", "typecheck"];
|
|
94973
95174
|
const hooks = config.hooks ?? {};
|
|
94974
95175
|
const cacheEnabled = options.hookCache !== false;
|
|
95176
|
+
const records = [];
|
|
94975
95177
|
for (const name of hookOrder) {
|
|
94976
95178
|
const hook = hooks[name];
|
|
94977
95179
|
if (!hook) continue;
|
|
95180
|
+
const selectionField = name === "test" ? { testSelection: hook.testSelection === "incremental" ? "incremental" : "full" } : {};
|
|
94978
95181
|
await evidence.append({
|
|
94979
95182
|
phase: "hooks",
|
|
94980
95183
|
status: "started",
|
|
94981
|
-
hookName: name
|
|
95184
|
+
hookName: name,
|
|
95185
|
+
...selectionField
|
|
94982
95186
|
});
|
|
94983
95187
|
let cacheKey;
|
|
94984
95188
|
if (cacheEnabled && hook.cacheable === true) {
|
|
@@ -95000,8 +95204,10 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95000
95204
|
status: "completed",
|
|
95001
95205
|
hookName: name,
|
|
95002
95206
|
cached: true,
|
|
95003
|
-
cacheKey
|
|
95207
|
+
cacheKey,
|
|
95208
|
+
...selectionField
|
|
95004
95209
|
});
|
|
95210
|
+
records.push({ name, completed: true, cached: true, testSelection: selectionField.testSelection });
|
|
95005
95211
|
continue;
|
|
95006
95212
|
}
|
|
95007
95213
|
}
|
|
@@ -95016,7 +95222,8 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95016
95222
|
phase: "hooks",
|
|
95017
95223
|
status: "failed",
|
|
95018
95224
|
hookName: name,
|
|
95019
|
-
error: { code: err.code, message: err.message }
|
|
95225
|
+
error: { code: err.code, message: err.message },
|
|
95226
|
+
...selectionField
|
|
95020
95227
|
});
|
|
95021
95228
|
throw new ReleaseError(
|
|
95022
95229
|
GATE_FAILED,
|
|
@@ -95025,16 +95232,31 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95025
95232
|
);
|
|
95026
95233
|
}
|
|
95027
95234
|
if (result.exitCode !== 0) {
|
|
95235
|
+
const stdoutTail = boundedOutputTail(result.stdout);
|
|
95236
|
+
const stderrTail = boundedOutputTail(result.stderr);
|
|
95237
|
+
process.stderr.write(`[release-skill] hook "${name}" failed with exit code ${result.exitCode}
|
|
95238
|
+
`);
|
|
95239
|
+
if (stdoutTail) {
|
|
95240
|
+
process.stderr.write(`[release-skill] hook "${name}" stdout tail:
|
|
95241
|
+
${stdoutTail}
|
|
95242
|
+
`);
|
|
95243
|
+
}
|
|
95244
|
+
if (stderrTail) {
|
|
95245
|
+
process.stderr.write(`[release-skill] hook "${name}" stderr tail:
|
|
95246
|
+
${stderrTail}
|
|
95247
|
+
`);
|
|
95248
|
+
}
|
|
95028
95249
|
await evidence.append({
|
|
95029
95250
|
phase: "hooks",
|
|
95030
95251
|
status: "failed",
|
|
95031
95252
|
hookName: name,
|
|
95032
95253
|
exitCode: result.exitCode,
|
|
95033
95254
|
// 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
|
|
95255
|
+
// end. Preserve bounded tails (last 50 lines, capped at 8 KB) of both
|
|
95256
|
+
// streams instead of the noisy compiler prelude at the beginning.
|
|
95257
|
+
stdoutTail,
|
|
95258
|
+
stderrTail,
|
|
95259
|
+
...selectionField
|
|
95038
95260
|
});
|
|
95039
95261
|
throw new ReleaseError(
|
|
95040
95262
|
GATE_FAILED,
|
|
@@ -95062,9 +95284,12 @@ async function runDeclaredHooks(config, root, evidence, hookFn = runHook, option
|
|
|
95062
95284
|
phase: "hooks",
|
|
95063
95285
|
status: "completed",
|
|
95064
95286
|
hookName: name,
|
|
95065
|
-
exitCode: 0
|
|
95287
|
+
exitCode: 0,
|
|
95288
|
+
...selectionField
|
|
95066
95289
|
});
|
|
95290
|
+
records.push({ name, completed: true, cached: false, testSelection: selectionField.testSelection });
|
|
95067
95291
|
}
|
|
95292
|
+
return records;
|
|
95068
95293
|
}
|
|
95069
95294
|
async function resolveReleaseDocsPlanFn(injected) {
|
|
95070
95295
|
if (typeof injected === "function") return injected;
|
|
@@ -96021,7 +96246,7 @@ async function readLatestFrozenPlan(root) {
|
|
|
96021
96246
|
const plansDir = resolve23(root, ".release-skill", "plans");
|
|
96022
96247
|
let files;
|
|
96023
96248
|
try {
|
|
96024
|
-
files = await
|
|
96249
|
+
files = await readdir15(plansDir);
|
|
96025
96250
|
} catch {
|
|
96026
96251
|
return null;
|
|
96027
96252
|
}
|
|
@@ -96030,7 +96255,7 @@ async function readLatestFrozenPlan(root) {
|
|
|
96030
96255
|
if (!file.endsWith(".json")) continue;
|
|
96031
96256
|
let plan;
|
|
96032
96257
|
try {
|
|
96033
|
-
plan = JSON.parse(await
|
|
96258
|
+
plan = JSON.parse(await readFile23(resolve23(plansDir, file), "utf8"));
|
|
96034
96259
|
} catch {
|
|
96035
96260
|
continue;
|
|
96036
96261
|
}
|
|
@@ -96055,7 +96280,8 @@ async function prepareRelease(options) {
|
|
|
96055
96280
|
verificationGatesAuthorized,
|
|
96056
96281
|
production = false,
|
|
96057
96282
|
workflow = "full",
|
|
96058
|
-
observePreviousPublicBaselineFn
|
|
96283
|
+
observePreviousPublicBaselineFn,
|
|
96284
|
+
testSelection = "full"
|
|
96059
96285
|
} = options ?? {};
|
|
96060
96286
|
const WORKFLOW_KINDS2 = /* @__PURE__ */ new Set(["full", "docs", "config", "marketplace"]);
|
|
96061
96287
|
if (!WORKFLOW_KINDS2.has(workflow)) {
|
|
@@ -96065,6 +96291,20 @@ async function prepareRelease(options) {
|
|
|
96065
96291
|
{ workflow }
|
|
96066
96292
|
);
|
|
96067
96293
|
}
|
|
96294
|
+
if (testSelection === "incremental") {
|
|
96295
|
+
throw new ReleaseError(
|
|
96296
|
+
GATE_FAILED,
|
|
96297
|
+
"incremental selection is not allowed at freeze time",
|
|
96298
|
+
{ testSelection, reservedFor: "preflight mode" }
|
|
96299
|
+
);
|
|
96300
|
+
}
|
|
96301
|
+
if (testSelection !== "full") {
|
|
96302
|
+
throw new ReleaseError(
|
|
96303
|
+
CONFIG_INVALID,
|
|
96304
|
+
`unknown testSelection "${testSelection}"; expected "full" or "incremental"`,
|
|
96305
|
+
{ testSelection }
|
|
96306
|
+
);
|
|
96307
|
+
}
|
|
96068
96308
|
const trimmedWorkflow = workflow !== "full";
|
|
96069
96309
|
const skipDeclaredHooks = trimmedWorkflow;
|
|
96070
96310
|
const skipSnapshotVerifyGates = trimmedWorkflow;
|
|
@@ -96128,6 +96368,34 @@ async function prepareRelease(options) {
|
|
|
96128
96368
|
...warning
|
|
96129
96369
|
});
|
|
96130
96370
|
}
|
|
96371
|
+
await evidence.append({ phase: "bundle-freshness", status: "started" });
|
|
96372
|
+
const bundleFreshnessFn = options.bundleFreshnessFn ?? assertBundleFreshness;
|
|
96373
|
+
let bundleFreshness;
|
|
96374
|
+
try {
|
|
96375
|
+
bundleFreshness = await bundleFreshnessFn(PKG_ROOT);
|
|
96376
|
+
} catch (err) {
|
|
96377
|
+
await evidence.append({
|
|
96378
|
+
phase: "bundle-freshness",
|
|
96379
|
+
status: "blocking",
|
|
96380
|
+
reason: err.details?.reason ?? null,
|
|
96381
|
+
error: { code: err.code, message: err.message }
|
|
96382
|
+
});
|
|
96383
|
+
throw err;
|
|
96384
|
+
}
|
|
96385
|
+
if (bundleFreshness?.applicable === false) {
|
|
96386
|
+
await evidence.append({
|
|
96387
|
+
phase: "bundle-freshness",
|
|
96388
|
+
status: "not-applicable",
|
|
96389
|
+
reason: bundleFreshness.reason
|
|
96390
|
+
});
|
|
96391
|
+
} else {
|
|
96392
|
+
await evidence.append({
|
|
96393
|
+
phase: "bundle-freshness",
|
|
96394
|
+
status: "completed",
|
|
96395
|
+
algorithm: bundleFreshness?.algorithm ?? null,
|
|
96396
|
+
sourceDigest: bundleFreshness?.sourceDigest ?? null
|
|
96397
|
+
});
|
|
96398
|
+
}
|
|
96131
96399
|
await evidence.append({
|
|
96132
96400
|
phase: "workflow",
|
|
96133
96401
|
status: "configured",
|
|
@@ -96210,6 +96478,7 @@ async function prepareRelease(options) {
|
|
|
96210
96478
|
}))
|
|
96211
96479
|
});
|
|
96212
96480
|
}
|
|
96481
|
+
let hookRecords = [];
|
|
96213
96482
|
if (skipDeclaredHooks) {
|
|
96214
96483
|
await evidence.append({
|
|
96215
96484
|
phase: "hooks",
|
|
@@ -96218,7 +96487,7 @@ async function prepareRelease(options) {
|
|
|
96218
96487
|
});
|
|
96219
96488
|
} else {
|
|
96220
96489
|
await evidence.append({ phase: "hooks", status: "started" });
|
|
96221
|
-
await runDeclaredHooks(config, realRoot, evidence, options.runHookFn ?? runHook, {
|
|
96490
|
+
hookRecords = await runDeclaredHooks(config, realRoot, evidence, options.runHookFn ?? runHook, {
|
|
96222
96491
|
hookCache: options.hookCache,
|
|
96223
96492
|
// Explicit env delivery (0.5.1 hook-env-delivery fix): the hook runner
|
|
96224
96493
|
// reads envAllowlist keys exclusively from context.env, so the invoking
|
|
@@ -96734,6 +97003,47 @@ async function prepareRelease(options) {
|
|
|
96734
97003
|
await evidence.append({ phase: "remote-check", status: "skipped", reason: "offline mode" });
|
|
96735
97004
|
}
|
|
96736
97005
|
await evidence.append({ phase: "plan-assembly", status: "started" });
|
|
97006
|
+
if (skipDeclaredHooks) {
|
|
97007
|
+
await evidence.append({
|
|
97008
|
+
phase: "full-test-gate",
|
|
97009
|
+
status: "skipped",
|
|
97010
|
+
reason: `workflow "${workflow}" trims declared hooks`
|
|
97011
|
+
});
|
|
97012
|
+
} else if (!config.hooks?.test) {
|
|
97013
|
+
await evidence.append({
|
|
97014
|
+
phase: "full-test-gate",
|
|
97015
|
+
status: "not-declared",
|
|
97016
|
+
reason: "no test hook declared; nothing can run incrementally"
|
|
97017
|
+
});
|
|
97018
|
+
} else {
|
|
97019
|
+
const testRecord = hookRecords.find((record) => record.name === "test");
|
|
97020
|
+
const satisfied = Boolean(
|
|
97021
|
+
testRecord && testRecord.completed && testRecord.testSelection === "full"
|
|
97022
|
+
);
|
|
97023
|
+
if (!satisfied) {
|
|
97024
|
+
await evidence.append({
|
|
97025
|
+
phase: "full-test-gate",
|
|
97026
|
+
status: "blocking",
|
|
97027
|
+
testSelection: testRecord?.testSelection ?? null,
|
|
97028
|
+
cached: Boolean(testRecord?.cached)
|
|
97029
|
+
});
|
|
97030
|
+
throw new ReleaseError(
|
|
97031
|
+
GATE_FAILED,
|
|
97032
|
+
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",
|
|
97033
|
+
{
|
|
97034
|
+
gate: "full-test-freeze",
|
|
97035
|
+
testSelection: testRecord?.testSelection ?? null,
|
|
97036
|
+
cached: Boolean(testRecord?.cached)
|
|
97037
|
+
}
|
|
97038
|
+
);
|
|
97039
|
+
}
|
|
97040
|
+
await evidence.append({
|
|
97041
|
+
phase: "full-test-gate",
|
|
97042
|
+
status: "completed",
|
|
97043
|
+
testSelection: "full",
|
|
97044
|
+
cached: Boolean(testRecord.cached)
|
|
97045
|
+
});
|
|
97046
|
+
}
|
|
96737
97047
|
const createdAtTimestamp = production ? normalizeGitTimestamp(clock ? clock() : (/* @__PURE__ */ new Date()).toISOString(), "plan createdAt timestamp") : null;
|
|
96738
97048
|
const freezeTimestamp = production ? await readHeadCommitTimestamp(realRoot, baseline.gitHead) : null;
|
|
96739
97049
|
const productionAssets = production ? await buildProductionAssets(
|
|
@@ -96890,7 +97200,7 @@ async function prepareRelease(options) {
|
|
|
96890
97200
|
const marketplaceIndexPath = resolve23(snapshotDir, marketplaceIndexRelative);
|
|
96891
97201
|
let marketplaceIndexRaw;
|
|
96892
97202
|
try {
|
|
96893
|
-
marketplaceIndexRaw = await
|
|
97203
|
+
marketplaceIndexRaw = await readFile23(marketplaceIndexPath, "utf8");
|
|
96894
97204
|
} catch (err) {
|
|
96895
97205
|
throw new ReleaseError(
|
|
96896
97206
|
GATE_FAILED,
|
|
@@ -96959,7 +97269,7 @@ async function prepareRelease(options) {
|
|
|
96959
97269
|
const pluginManifestPath = resolve23(snapshotDir, pluginManifestRelative);
|
|
96960
97270
|
let raw;
|
|
96961
97271
|
try {
|
|
96962
|
-
raw = await
|
|
97272
|
+
raw = await readFile23(pluginManifestPath, "utf8");
|
|
96963
97273
|
} catch (err) {
|
|
96964
97274
|
throw new ReleaseError(
|
|
96965
97275
|
GATE_FAILED,
|
|
@@ -97196,6 +97506,19 @@ async function prepareRelease(options) {
|
|
|
97196
97506
|
planPath: writtenPath,
|
|
97197
97507
|
planDigest
|
|
97198
97508
|
});
|
|
97509
|
+
await writeFrozenMarker(releaseDir, {
|
|
97510
|
+
planDigest,
|
|
97511
|
+
targetVersions: Object.fromEntries(
|
|
97512
|
+
configUnits.map((unit, index) => [unit.id, resolvedVersions[index]])
|
|
97513
|
+
),
|
|
97514
|
+
createdAt: plan.createdAt,
|
|
97515
|
+
runId: basename7(runDir)
|
|
97516
|
+
});
|
|
97517
|
+
await evidence.append({
|
|
97518
|
+
phase: "frozen-marker",
|
|
97519
|
+
status: "written",
|
|
97520
|
+
markerPath: `.release-skill/${FROZEN_MARKER_FILENAME}`
|
|
97521
|
+
});
|
|
97199
97522
|
await evidence.finish({
|
|
97200
97523
|
status: "PREPARED",
|
|
97201
97524
|
planPath: writtenPath,
|
|
@@ -97231,7 +97554,7 @@ async function prepareRelease(options) {
|
|
|
97231
97554
|
await lock.release();
|
|
97232
97555
|
}
|
|
97233
97556
|
}
|
|
97234
|
-
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
97557
|
+
var execFile8, CONSUMER_INSTALL_RECIPE_VERSION2, HOOK_OUTPUT_TAIL_MAX_LINES, HOOK_OUTPUT_TAIL_MAX_BYTES, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
97235
97558
|
var init_prepare = __esm({
|
|
97236
97559
|
async "src/commands/prepare.mjs"() {
|
|
97237
97560
|
await init_config();
|
|
@@ -97250,6 +97573,9 @@ var init_prepare = __esm({
|
|
|
97250
97573
|
init_contract2();
|
|
97251
97574
|
init_frozen();
|
|
97252
97575
|
init_errors();
|
|
97576
|
+
init_bundle_freshness();
|
|
97577
|
+
init_pkg_root();
|
|
97578
|
+
init_frozen_marker();
|
|
97253
97579
|
init_source_authority();
|
|
97254
97580
|
init_project_lock();
|
|
97255
97581
|
init_previous_public_baseline();
|
|
@@ -97263,6 +97589,9 @@ var init_prepare = __esm({
|
|
|
97263
97589
|
CONSUMER_INSTALL_RECIPE_VERSION2 = "consumer-install-v1";
|
|
97264
97590
|
__name(resolveUnitVersion, "resolveUnitVersion");
|
|
97265
97591
|
__name(resolveAllUnitVersions, "resolveAllUnitVersions");
|
|
97592
|
+
HOOK_OUTPUT_TAIL_MAX_LINES = 50;
|
|
97593
|
+
HOOK_OUTPUT_TAIL_MAX_BYTES = 8 * 1024;
|
|
97594
|
+
__name(boundedOutputTail, "boundedOutputTail");
|
|
97266
97595
|
__name(runDeclaredHooks, "runDeclaredHooks");
|
|
97267
97596
|
__name(resolveReleaseDocsPlanFn, "resolveReleaseDocsPlanFn");
|
|
97268
97597
|
__name(runReleaseDocsFreshnessGate, "runReleaseDocsFreshnessGate");
|
|
@@ -97332,8 +97661,8 @@ var init_hooks2 = __esm({
|
|
|
97332
97661
|
});
|
|
97333
97662
|
|
|
97334
97663
|
// src/core/approval.mjs
|
|
97335
|
-
import { readFile as
|
|
97336
|
-
import { basename as
|
|
97664
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
97665
|
+
import { basename as basename8, dirname as dirname12, join as join21, resolve as resolve25 } from "node:path";
|
|
97337
97666
|
function validateApprovalRecordSchema(approval) {
|
|
97338
97667
|
if (validateApprovalSchema(approval)) return;
|
|
97339
97668
|
const errors = validateApprovalSchema.errors ?? [];
|
|
@@ -97352,7 +97681,7 @@ function assertImmutableApprovalAuthority(approvalPath, plan, rawApproval) {
|
|
|
97352
97681
|
const approvalDigest = computeApprovalDigest(rawApproval);
|
|
97353
97682
|
const absolute = resolve25(approvalPath);
|
|
97354
97683
|
const planDirectory = dirname12(absolute);
|
|
97355
|
-
if (
|
|
97684
|
+
if (basename8(absolute) !== `${approvalDigest}.json` || basename8(planDirectory) !== planDigest || basename8(dirname12(planDirectory)) !== "approvals") {
|
|
97356
97685
|
throw new ReleaseError(
|
|
97357
97686
|
GATE_FAILED,
|
|
97358
97687
|
"production commands require approvals/<planDigest>/<approvalDigest>.json immutable authority",
|
|
@@ -97619,8 +97948,8 @@ var approve_exports = {};
|
|
|
97619
97948
|
__export(approve_exports, {
|
|
97620
97949
|
approvePlan: () => approvePlan
|
|
97621
97950
|
});
|
|
97622
|
-
import { readFile as
|
|
97623
|
-
import { resolve as resolve26, dirname as dirname13, basename as
|
|
97951
|
+
import { readFile as readFile25, writeFile as writeFile7 } from "node:fs/promises";
|
|
97952
|
+
import { resolve as resolve26, dirname as dirname13, basename as basename9 } from "node:path";
|
|
97624
97953
|
function defaultClock() {
|
|
97625
97954
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
97626
97955
|
}
|
|
@@ -97643,7 +97972,7 @@ async function approvePlan(options) {
|
|
|
97643
97972
|
}
|
|
97644
97973
|
let planRaw;
|
|
97645
97974
|
try {
|
|
97646
|
-
planRaw = await
|
|
97975
|
+
planRaw = await readFile25(planPath, "utf8");
|
|
97647
97976
|
} catch (err) {
|
|
97648
97977
|
throw new ReleaseError(
|
|
97649
97978
|
GATE_FAILED,
|
|
@@ -97749,7 +98078,7 @@ async function approvePlan(options) {
|
|
|
97749
98078
|
};
|
|
97750
98079
|
validateApprovalRecordSchema(approvalRecord);
|
|
97751
98080
|
const planDir = dirname13(resolve26(planPath));
|
|
97752
|
-
const releaseDir =
|
|
98081
|
+
const releaseDir = basename9(planDir) === "plans" && basename9(planPath) === `${actualDigest}.json` ? dirname13(planDir) : planDir;
|
|
97753
98082
|
if (plan.production?.mode === "github-npm-v1" && outputPath && resolve26(outputPath) !== resolve26(releaseDir, "approval-record.json")) {
|
|
97754
98083
|
throw new ReleaseError(
|
|
97755
98084
|
GATE_FAILED,
|
|
@@ -97768,10 +98097,10 @@ async function approvePlan(options) {
|
|
|
97768
98097
|
await prepareAuthorityDirectory(dirname13(immutableApprovalPath));
|
|
97769
98098
|
await assertAuthorityFileTarget(immutableApprovalPath);
|
|
97770
98099
|
try {
|
|
97771
|
-
await
|
|
98100
|
+
await writeFile7(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
97772
98101
|
} catch (error) {
|
|
97773
98102
|
if (error.code !== "EEXIST") throw error;
|
|
97774
|
-
const existing = await
|
|
98103
|
+
const existing = await readFile25(immutableApprovalPath, "utf8");
|
|
97775
98104
|
if (existing !== json) {
|
|
97776
98105
|
throw new ReleaseError(
|
|
97777
98106
|
GATE_FAILED,
|
|
@@ -97783,7 +98112,7 @@ async function approvePlan(options) {
|
|
|
97783
98112
|
const writePath = outputPath ?? resolve26(releaseDir, "approval-record.json");
|
|
97784
98113
|
await prepareAuthorityDirectory(dirname13(writePath));
|
|
97785
98114
|
await assertAuthorityFileTarget(writePath);
|
|
97786
|
-
await
|
|
98115
|
+
await writeFile7(writePath, json, "utf8");
|
|
97787
98116
|
return Object.freeze({
|
|
97788
98117
|
...approvalRecord,
|
|
97789
98118
|
approvalDigest,
|
|
@@ -98073,8 +98402,8 @@ __export(publish_exports, {
|
|
|
98073
98402
|
classifyPreObservation: () => classifyPreObservation,
|
|
98074
98403
|
publishRelease: () => publishRelease
|
|
98075
98404
|
});
|
|
98076
|
-
import { readFile as
|
|
98077
|
-
import { isAbsolute as isAbsolute19, join as
|
|
98405
|
+
import { readFile as readFile26, mkdir as mkdir16 } from "node:fs/promises";
|
|
98406
|
+
import { isAbsolute as isAbsolute19, join as join22, relative as relative23 } from "node:path";
|
|
98078
98407
|
function assertInsideAssetRoot(assetRoot, candidate, label) {
|
|
98079
98408
|
const rel = relative23(assetRoot, candidate);
|
|
98080
98409
|
if (rel === "" || isAbsolute19(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
@@ -98306,7 +98635,7 @@ async function publishRelease(options) {
|
|
|
98306
98635
|
const captureBaselineActual = typeof captureBaselineFn === "function" ? captureBaselineFn : captureBaseline;
|
|
98307
98636
|
let planRaw;
|
|
98308
98637
|
try {
|
|
98309
|
-
planRaw = await
|
|
98638
|
+
planRaw = await readFile26(planPath, "utf8");
|
|
98310
98639
|
} catch (err) {
|
|
98311
98640
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
98312
98641
|
}
|
|
@@ -98464,7 +98793,7 @@ async function publishRelease(options) {
|
|
|
98464
98793
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
98465
98794
|
let approvalRaw;
|
|
98466
98795
|
try {
|
|
98467
|
-
approvalRaw = await
|
|
98796
|
+
approvalRaw = await readFile26(approvalPath, "utf8");
|
|
98468
98797
|
} catch (err) {
|
|
98469
98798
|
throw new ReleaseError(
|
|
98470
98799
|
GATE_FAILED,
|
|
@@ -98778,7 +99107,7 @@ async function publishRelease(options) {
|
|
|
98778
99107
|
}
|
|
98779
99108
|
}
|
|
98780
99109
|
await evidence.append({ phase: "safety-gate", gate: "global-preflight", status: "passed" });
|
|
98781
|
-
const runPath =
|
|
99110
|
+
const runPath = join22(runDir, "release-run.json");
|
|
98782
99111
|
const checkpoints = orderedActions.map((action) => {
|
|
98783
99112
|
if (isMarketplaceAction(action.type)) {
|
|
98784
99113
|
return {
|
|
@@ -99051,8 +99380,8 @@ var reconcile_exports = {};
|
|
|
99051
99380
|
__export(reconcile_exports, {
|
|
99052
99381
|
reconcileRelease: () => reconcileRelease
|
|
99053
99382
|
});
|
|
99054
|
-
import { readFile as
|
|
99055
|
-
import { join as
|
|
99383
|
+
import { readFile as readFile27, mkdir as mkdir17 } from "node:fs/promises";
|
|
99384
|
+
import { join as join23 } from "node:path";
|
|
99056
99385
|
function defaultClock4() {
|
|
99057
99386
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
99058
99387
|
}
|
|
@@ -99080,7 +99409,7 @@ async function reconcileRelease(options) {
|
|
|
99080
99409
|
}
|
|
99081
99410
|
let planRaw;
|
|
99082
99411
|
try {
|
|
99083
|
-
planRaw = await
|
|
99412
|
+
planRaw = await readFile27(planPath, "utf8");
|
|
99084
99413
|
} catch (err) {
|
|
99085
99414
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
99086
99415
|
}
|
|
@@ -99202,7 +99531,7 @@ async function reconcileRelease(options) {
|
|
|
99202
99531
|
{ sourceRunId: sourceRun.runId }
|
|
99203
99532
|
);
|
|
99204
99533
|
}
|
|
99205
|
-
const sourceApprovalRaw = await
|
|
99534
|
+
const sourceApprovalRaw = await readFile27(consumedApprovalPath, "utf8").catch((error) => {
|
|
99206
99535
|
throw new ReleaseError(GATE_FAILED, "source run approval authority is unavailable", {
|
|
99207
99536
|
sourceRunId: sourceRun.runId,
|
|
99208
99537
|
cause: error.code
|
|
@@ -99364,7 +99693,7 @@ async function reconcileRelease(options) {
|
|
|
99364
99693
|
if (approvalPath) {
|
|
99365
99694
|
let approvalRaw;
|
|
99366
99695
|
try {
|
|
99367
|
-
approvalRaw = await
|
|
99696
|
+
approvalRaw = await readFile27(approvalPath, "utf8");
|
|
99368
99697
|
} catch (err) {
|
|
99369
99698
|
throw new ReleaseError(
|
|
99370
99699
|
GATE_FAILED,
|
|
@@ -99977,7 +100306,7 @@ async function reconcileRelease(options) {
|
|
|
99977
100306
|
...normalized === "deferred" ? { reason: CONSUMER_VERIFICATION_DEFERRED, phase: "post-publish-verification" } : {}
|
|
99978
100307
|
};
|
|
99979
100308
|
});
|
|
99980
|
-
const runPath =
|
|
100309
|
+
const runPath = join23(runDir, "release-run.json");
|
|
99981
100310
|
const sourceRunDigest = sourceAuthorityDigest;
|
|
99982
100311
|
const runState = {
|
|
99983
100312
|
runId,
|
|
@@ -100057,7 +100386,7 @@ var init_reconcile = __esm({
|
|
|
100057
100386
|
});
|
|
100058
100387
|
|
|
100059
100388
|
// src/core/baseline-advance.mjs
|
|
100060
|
-
import { readFile as
|
|
100389
|
+
import { readFile as readFile28, writeFile as writeFile8 } from "node:fs/promises";
|
|
100061
100390
|
import { execFile as execFileCb10 } from "node:child_process";
|
|
100062
100391
|
import { promisify as promisify10 } from "node:util";
|
|
100063
100392
|
function defaultExec(command2, args2, options = {}) {
|
|
@@ -100091,7 +100420,7 @@ async function applyBaselineAdvances({ configPath, advances, validateFn }) {
|
|
|
100091
100420
|
}
|
|
100092
100421
|
let content;
|
|
100093
100422
|
try {
|
|
100094
|
-
content = await
|
|
100423
|
+
content = await readFile28(configPath, "utf8");
|
|
100095
100424
|
} catch (err) {
|
|
100096
100425
|
throw new ReleaseError(
|
|
100097
100426
|
GATE_FAILED,
|
|
@@ -100133,12 +100462,12 @@ async function applyBaselineAdvances({ configPath, advances, validateFn }) {
|
|
|
100133
100462
|
return { changed: false, updatedUnits: [] };
|
|
100134
100463
|
}
|
|
100135
100464
|
const next = doc.toString();
|
|
100136
|
-
await
|
|
100465
|
+
await writeFile8(configPath, next, "utf8");
|
|
100137
100466
|
if (typeof validateFn === "function") {
|
|
100138
100467
|
try {
|
|
100139
100468
|
await validateFn(configPath);
|
|
100140
100469
|
} catch (err) {
|
|
100141
|
-
await
|
|
100470
|
+
await writeFile8(configPath, content, "utf8");
|
|
100142
100471
|
throw new ReleaseError(
|
|
100143
100472
|
GATE_FAILED,
|
|
100144
100473
|
`baseline advance reverted: rewritten config failed validation: ${err.message}`,
|
|
@@ -100185,9 +100514,9 @@ __export(verify_exports, {
|
|
|
100185
100514
|
runSmokeTest: () => runSmokeTest,
|
|
100186
100515
|
verifyRelease: () => verifyRelease
|
|
100187
100516
|
});
|
|
100188
|
-
import { readFile as
|
|
100517
|
+
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
100518
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
100190
|
-
import { dirname as dirname14, join as
|
|
100519
|
+
import { dirname as dirname14, join as join24, relative as relative24, isAbsolute as isAbsolute20, resolve as resolve27, basename as basename10 } from "node:path";
|
|
100191
100520
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
100192
100521
|
import { execFile as execFileCb11 } from "node:child_process";
|
|
100193
100522
|
import { promisify as promisify11 } from "node:util";
|
|
@@ -100240,18 +100569,18 @@ async function collectMissingManualAttestations({
|
|
|
100240
100569
|
const isKimi = action.type === "kimi-marketplace-install";
|
|
100241
100570
|
const planDigest = isKimi ? resolveBoundPlanDigest(context) : await resolveCodeBuddyBoundPlanDigest(context);
|
|
100242
100571
|
const authorityDir = isKimi ? kimiAuthorityDir(context, planDigest, action.parameters.plugin) : codebuddyAuthorityDir(context, planDigest, action.parameters.plugin);
|
|
100243
|
-
const requirementPath =
|
|
100572
|
+
const requirementPath = join24(
|
|
100244
100573
|
authorityDir,
|
|
100245
100574
|
isKimi ? KIMI_REQUIREMENT_FILE : CODEBUDDY_REQUIREMENT_FILE
|
|
100246
100575
|
);
|
|
100247
|
-
const attestationPath =
|
|
100576
|
+
const attestationPath = join24(
|
|
100248
100577
|
authorityDir,
|
|
100249
100578
|
isKimi ? KIMI_ATTESTATION_FILE : CODEBUDDY_ATTESTATION_FILE
|
|
100250
100579
|
);
|
|
100251
100580
|
let valid = false;
|
|
100252
100581
|
let reason = "attestation file is missing";
|
|
100253
100582
|
try {
|
|
100254
|
-
const attestation = JSON.parse(await
|
|
100583
|
+
const attestation = JSON.parse(await readFile29(attestationPath, "utf8"));
|
|
100255
100584
|
const validation = isKimi ? validateKimiAttestation(attestation, action.parameters, clockFn(), planDigest) : validateCodeBuddyAttestation(attestation, action.parameters, clockFn(), planDigest);
|
|
100256
100585
|
valid = validation.valid;
|
|
100257
100586
|
reason = validation.error;
|
|
@@ -100293,7 +100622,7 @@ function matchesSubset2(actual, expected) {
|
|
|
100293
100622
|
async function runSmokeTest(plan, root, options = {}) {
|
|
100294
100623
|
const baseDir = options.baseDir ?? tmpdir4();
|
|
100295
100624
|
await mkdir18(baseDir, { recursive: true });
|
|
100296
|
-
const tmpDir = await mkdtemp7(
|
|
100625
|
+
const tmpDir = await mkdtemp7(join24(baseDir, "verify-smoke-"));
|
|
100297
100626
|
const npmExec = options.npmExecutor ?? defaultNpmExecutor;
|
|
100298
100627
|
const installFlags = [
|
|
100299
100628
|
"--ignore-scripts",
|
|
@@ -100341,7 +100670,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100341
100670
|
for (const { package: pkgName, registry, targetVersion, unitId, smokeBin, smokeArgs, smokeExpectedJson } of npmDistributions) {
|
|
100342
100671
|
const packageAtVersion = `${pkgName}@${targetVersion}`;
|
|
100343
100672
|
const installDir = resolveUnitScopedPath(tmpDir, unitId);
|
|
100344
|
-
await mkdir18(
|
|
100673
|
+
await mkdir18(join24(installDir, "node_modules"), { recursive: true });
|
|
100345
100674
|
const registryFlags = [...installFlags, "--registry", registry];
|
|
100346
100675
|
const installResult = await npmExec.install(
|
|
100347
100676
|
packageAtVersion,
|
|
@@ -100359,10 +100688,10 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100359
100688
|
}
|
|
100360
100689
|
};
|
|
100361
100690
|
}
|
|
100362
|
-
const installedPkgPath =
|
|
100691
|
+
const installedPkgPath = join24(installDir, "node_modules", pkgName, "package.json");
|
|
100363
100692
|
let installedPkg;
|
|
100364
100693
|
try {
|
|
100365
|
-
installedPkg = JSON.parse(await
|
|
100694
|
+
installedPkg = JSON.parse(await readFile29(installedPkgPath, "utf8"));
|
|
100366
100695
|
} catch {
|
|
100367
100696
|
return {
|
|
100368
100697
|
passed: false,
|
|
@@ -100393,7 +100722,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100393
100722
|
}
|
|
100394
100723
|
};
|
|
100395
100724
|
}
|
|
100396
|
-
const pkgRoot =
|
|
100725
|
+
const pkgRoot = join24(installDir, "node_modules", pkgName);
|
|
100397
100726
|
{
|
|
100398
100727
|
const dirIndex = await buildDirectoryFileIndex(pkgRoot);
|
|
100399
100728
|
const closureResult = checkNpmEntryClosure(installedPkg, dirIndex);
|
|
@@ -100622,7 +100951,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
100622
100951
|
}
|
|
100623
100952
|
async function discoverDistributeRuns({ planPath, plan }) {
|
|
100624
100953
|
const planDir = dirname14(planPath);
|
|
100625
|
-
const releaseDir =
|
|
100954
|
+
const releaseDir = basename10(planDir) === "plans" ? dirname14(planDir) : planDir;
|
|
100626
100955
|
const runsDir = resolve27(releaseDir, "runs");
|
|
100627
100956
|
try {
|
|
100628
100957
|
const runsDirStat = await lstat21(runsDir);
|
|
@@ -100654,7 +100983,7 @@ async function discoverDistributeRuns({ planPath, plan }) {
|
|
|
100654
100983
|
return null;
|
|
100655
100984
|
}
|
|
100656
100985
|
const candidates = [];
|
|
100657
|
-
const entries = await
|
|
100986
|
+
const entries = await readdir16(runsDir, { withFileTypes: true });
|
|
100658
100987
|
for (const entry of entries) {
|
|
100659
100988
|
if (!entry.name.startsWith("distribute-")) continue;
|
|
100660
100989
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
@@ -100719,7 +101048,7 @@ async function verifyRelease(options) {
|
|
|
100719
101048
|
}
|
|
100720
101049
|
let planRaw;
|
|
100721
101050
|
try {
|
|
100722
|
-
planRaw = await
|
|
101051
|
+
planRaw = await readFile29(planPath, "utf8");
|
|
100723
101052
|
} catch (err) {
|
|
100724
101053
|
throw new ReleaseError(
|
|
100725
101054
|
GATE_FAILED,
|
|
@@ -100808,7 +101137,7 @@ async function verifyRelease(options) {
|
|
|
100808
101137
|
}
|
|
100809
101138
|
let approvalRaw;
|
|
100810
101139
|
try {
|
|
100811
|
-
approvalRaw = await
|
|
101140
|
+
approvalRaw = await readFile29(sourceRun.approvalPath, "utf8");
|
|
100812
101141
|
} catch (error) {
|
|
100813
101142
|
throw new ReleaseError(
|
|
100814
101143
|
GATE_FAILED,
|
|
@@ -100884,7 +101213,7 @@ async function verifyRelease(options) {
|
|
|
100884
101213
|
const actions = plan.externalActions ?? [];
|
|
100885
101214
|
const trustedVerifyRuns = [];
|
|
100886
101215
|
const planDir = dirname14(planPath);
|
|
100887
|
-
const releaseDir =
|
|
101216
|
+
const releaseDir = basename10(planDir) === "plans" ? dirname14(planDir) : planDir;
|
|
100888
101217
|
const runsDir = resolve27(releaseDir, "runs");
|
|
100889
101218
|
let runsDirReal = null;
|
|
100890
101219
|
let authorityDirReal = null;
|
|
@@ -100927,7 +101256,7 @@ async function verifyRelease(options) {
|
|
|
100927
101256
|
runsDirReal = null;
|
|
100928
101257
|
}
|
|
100929
101258
|
if (runsDirReal) {
|
|
100930
|
-
const entries = await
|
|
101259
|
+
const entries = await readdir16(runsDirReal, { withFileTypes: true });
|
|
100931
101260
|
for (const entry of entries) {
|
|
100932
101261
|
if (!entry.name.startsWith("verify-")) continue;
|
|
100933
101262
|
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
@@ -101379,7 +101708,7 @@ async function verifyRelease(options) {
|
|
|
101379
101708
|
assertTransition(PUBLISHED, VERIFIED);
|
|
101380
101709
|
await evidence.append({ phase: "verify", status: "completed", overallStatus: VERIFIED });
|
|
101381
101710
|
const sourceRunDigest = sourceRun.runDigest ?? computeRunDigest(sourceRun);
|
|
101382
|
-
const verifyRunPath =
|
|
101711
|
+
const verifyRunPath = join24(runDir, "release-run.json");
|
|
101383
101712
|
const verifyRunState = {
|
|
101384
101713
|
runId,
|
|
101385
101714
|
command: "verify",
|
|
@@ -101421,11 +101750,24 @@ async function verifyRelease(options) {
|
|
|
101421
101750
|
finishedAt: clockFn()
|
|
101422
101751
|
};
|
|
101423
101752
|
const persistedVerifyRun = await writeRunAtomic(verifyRunPath, verifyRunState);
|
|
101753
|
+
try {
|
|
101754
|
+
const removed = await clearFrozenMarker(join24(root, ".release-skill"));
|
|
101755
|
+
await evidence.append({
|
|
101756
|
+
phase: "frozen-marker",
|
|
101757
|
+
status: removed ? "cleared" : "absent"
|
|
101758
|
+
});
|
|
101759
|
+
} catch (err) {
|
|
101760
|
+
await evidence.append({
|
|
101761
|
+
phase: "frozen-marker",
|
|
101762
|
+
status: "clear-failed",
|
|
101763
|
+
error: { code: err.code, message: err.message }
|
|
101764
|
+
});
|
|
101765
|
+
}
|
|
101424
101766
|
let baselineAdvance = null;
|
|
101425
101767
|
const baselineAdvances = deriveBaselineAdvances(plan);
|
|
101426
101768
|
if (baselineAdvances.length > 0) {
|
|
101427
101769
|
try {
|
|
101428
|
-
const configAbs = configPathOpt ? isAbsolute20(configPathOpt) ? configPathOpt :
|
|
101770
|
+
const configAbs = configPathOpt ? isAbsolute20(configPathOpt) ? configPathOpt : join24(root, configPathOpt) : join24(root, ".release-skill/project.yaml");
|
|
101429
101771
|
const cleanBefore = await isWorktreeFileClean({ root, filePath: configAbs, execFn });
|
|
101430
101772
|
const applyResult = await applyBaselineAdvances({
|
|
101431
101773
|
configPath: configAbs,
|
|
@@ -101508,6 +101850,7 @@ var init_verify = __esm({
|
|
|
101508
101850
|
init_baseline_advance();
|
|
101509
101851
|
await init_config();
|
|
101510
101852
|
init_state_machine();
|
|
101853
|
+
init_frozen_marker();
|
|
101511
101854
|
init_public_path();
|
|
101512
101855
|
init_npm();
|
|
101513
101856
|
init_verification_gates();
|
|
@@ -101549,8 +101892,8 @@ var init_verify = __esm({
|
|
|
101549
101892
|
exec: execFile9,
|
|
101550
101893
|
env: process.env
|
|
101551
101894
|
});
|
|
101552
|
-
const userConfig =
|
|
101553
|
-
await
|
|
101895
|
+
const userConfig = join24(cwd, ".release-skill-npmrc");
|
|
101896
|
+
await writeFile9(
|
|
101554
101897
|
userConfig,
|
|
101555
101898
|
`registry=${normalizedRegistry}/
|
|
101556
101899
|
${registryTokenKey(normalizedRegistry)}=${token}
|
|
@@ -101612,10 +101955,10 @@ __export(distribute_exports, {
|
|
|
101612
101955
|
});
|
|
101613
101956
|
import { execFile as execFileCb12 } from "node:child_process";
|
|
101614
101957
|
import { promisify as promisify12 } from "node:util";
|
|
101615
|
-
import { realpath as realpath19, lstat as lstat22, mkdir as mkdir19, readFile as
|
|
101958
|
+
import { realpath as realpath19, lstat as lstat22, mkdir as mkdir19, readFile as readFile30, rm as rm11 } from "node:fs/promises";
|
|
101616
101959
|
import { mkdtemp as mkdtemp8 } from "node:fs/promises";
|
|
101617
101960
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
101618
|
-
import { isAbsolute as isAbsolute21, join as
|
|
101961
|
+
import { isAbsolute as isAbsolute21, join as join25, relative as relative25, resolve as resolve28 } from "node:path";
|
|
101619
101962
|
function defaultClock6() {
|
|
101620
101963
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
101621
101964
|
}
|
|
@@ -101712,7 +102055,7 @@ async function distributeRelease(options) {
|
|
|
101712
102055
|
const hookRunner = typeof runHookFn === "function" ? runHookFn : runHook;
|
|
101713
102056
|
let planRaw;
|
|
101714
102057
|
try {
|
|
101715
|
-
planRaw = await
|
|
102058
|
+
planRaw = await readFile30(planPath, "utf8");
|
|
101716
102059
|
} catch (err) {
|
|
101717
102060
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
101718
102061
|
}
|
|
@@ -101746,7 +102089,7 @@ async function distributeRelease(options) {
|
|
|
101746
102089
|
} else {
|
|
101747
102090
|
await mkdir19(runDir, { recursive: true });
|
|
101748
102091
|
}
|
|
101749
|
-
const runPath =
|
|
102092
|
+
const runPath = join25(runDir, "release-run.json");
|
|
101750
102093
|
const evidence = createEvidenceWriter({ runDir, command: "distribute", clock: clockFn });
|
|
101751
102094
|
let lineageKnown = false;
|
|
101752
102095
|
let sourceRunId = null;
|
|
@@ -101821,7 +102164,7 @@ async function distributeRelease(options) {
|
|
|
101821
102164
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
101822
102165
|
let approvalRaw;
|
|
101823
102166
|
try {
|
|
101824
|
-
approvalRaw = await
|
|
102167
|
+
approvalRaw = await readFile30(approvalPath, "utf8");
|
|
101825
102168
|
} catch (err) {
|
|
101826
102169
|
throw new ReleaseError(GATE_FAILED, `cannot read approval record: ${err.message}`, { approvalPath, cause: err.code });
|
|
101827
102170
|
}
|
|
@@ -102041,8 +102384,8 @@ async function distributeRelease(options) {
|
|
|
102041
102384
|
}
|
|
102042
102385
|
await evidence.append({ phase: "worktree", status: "started", tagCommit: postPublish.tagCommit });
|
|
102043
102386
|
try {
|
|
102044
|
-
tmpBase = await mkdtemp8(
|
|
102045
|
-
worktreePath =
|
|
102387
|
+
tmpBase = await mkdtemp8(join25(tmpdir5(), "release-skill-distribute-"));
|
|
102388
|
+
worktreePath = join25(tmpBase, "worktree");
|
|
102046
102389
|
await exec("git", ["-C", root, "worktree", "add", "--detach", worktreePath, postPublish.tagCommit]);
|
|
102047
102390
|
} catch (err) {
|
|
102048
102391
|
await evidence.append({ phase: "worktree", status: "failed", error: tail(err?.stderr ?? err?.message) });
|
|
@@ -102545,7 +102888,7 @@ var release_metadata_exports = {};
|
|
|
102545
102888
|
__export(release_metadata_exports, {
|
|
102546
102889
|
updatePreviousPublicBaselines: () => updatePreviousPublicBaselines
|
|
102547
102890
|
});
|
|
102548
|
-
import { lstat as lstat23, readFile as
|
|
102891
|
+
import { lstat as lstat23, readFile as readFile31, rename as rename4, rm as rm12, writeFile as writeFile10 } from "node:fs/promises";
|
|
102549
102892
|
import { resolve as resolve29 } from "node:path";
|
|
102550
102893
|
function assertOid(value, label) {
|
|
102551
102894
|
if (typeof value !== "string" || !/^[a-f0-9]{40,64}$/.test(value)) {
|
|
@@ -102561,8 +102904,8 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
102561
102904
|
let configStat;
|
|
102562
102905
|
try {
|
|
102563
102906
|
[plan, configRaw, configStat] = await Promise.all([
|
|
102564
|
-
|
|
102565
|
-
|
|
102907
|
+
readFile31(planPath, "utf8").then(JSON.parse),
|
|
102908
|
+
readFile31(configPath, "utf8"),
|
|
102566
102909
|
lstat23(configPath)
|
|
102567
102910
|
]);
|
|
102568
102911
|
} catch (error) {
|
|
@@ -102624,7 +102967,7 @@ async function updatePreviousPublicBaselines(options = {}) {
|
|
|
102624
102967
|
}
|
|
102625
102968
|
const tempPath = `${configPath}.${process.pid}.${Date.now()}.tmp`;
|
|
102626
102969
|
try {
|
|
102627
|
-
await
|
|
102970
|
+
await writeFile10(tempPath, nextRaw, {
|
|
102628
102971
|
encoding: "utf8",
|
|
102629
102972
|
mode: configStat.mode & 511,
|
|
102630
102973
|
flag: "wx"
|
|
@@ -102652,7 +102995,7 @@ var ship_exports = {};
|
|
|
102652
102995
|
__export(ship_exports, {
|
|
102653
102996
|
advanceShip: () => advanceShip
|
|
102654
102997
|
});
|
|
102655
|
-
import { readFile as
|
|
102998
|
+
import { readFile as readFile32, lstat as lstat24, mkdir as mkdir20, rename as rename5, rm as rm13, writeFile as writeFile11 } from "node:fs/promises";
|
|
102656
102999
|
import { dirname as dirname15, resolve as resolve30 } from "node:path";
|
|
102657
103000
|
async function writeJsonAtomic(path15, value) {
|
|
102658
103001
|
await mkdir20(dirname15(path15), { recursive: true });
|
|
@@ -102663,7 +103006,7 @@ async function writeJsonAtomic(path15, value) {
|
|
|
102663
103006
|
stateDigest: sha256Hex(canonicalJson2(body))
|
|
102664
103007
|
};
|
|
102665
103008
|
try {
|
|
102666
|
-
await
|
|
103009
|
+
await writeFile11(temp, `${JSON.stringify(sealed, null, 2)}
|
|
102667
103010
|
`, {
|
|
102668
103011
|
encoding: "utf8",
|
|
102669
103012
|
mode: 384,
|
|
@@ -102678,11 +103021,11 @@ async function writeJsonAtomic(path15, value) {
|
|
|
102678
103021
|
}
|
|
102679
103022
|
async function readState(path15) {
|
|
102680
103023
|
try {
|
|
102681
|
-
const
|
|
102682
|
-
if (!
|
|
103024
|
+
const stat10 = await lstat24(path15);
|
|
103025
|
+
if (!stat10.isFile() || stat10.isSymbolicLink()) {
|
|
102683
103026
|
throw new Error("ship state must be a regular non-symlink file");
|
|
102684
103027
|
}
|
|
102685
|
-
const state = JSON.parse(await
|
|
103028
|
+
const state = JSON.parse(await readFile32(path15, "utf8"));
|
|
102686
103029
|
const { stateDigest, ...body } = state;
|
|
102687
103030
|
if (typeof stateDigest !== "string" || stateDigest !== sha256Hex(canonicalJson2(body)) || body.statePath !== path15) {
|
|
102688
103031
|
throw new Error("ship state digest or authority path does not match");
|
|
@@ -102755,7 +103098,7 @@ function publicState(state) {
|
|
|
102755
103098
|
}
|
|
102756
103099
|
async function buildApprovalSummary(planPath) {
|
|
102757
103100
|
try {
|
|
102758
|
-
const plan = JSON.parse(await
|
|
103101
|
+
const plan = JSON.parse(await readFile32(planPath, "utf8"));
|
|
102759
103102
|
const units = (plan.units ?? []).map((unit) => ({
|
|
102760
103103
|
id: unit.id,
|
|
102761
103104
|
targetVersion: unit.targetVersion ?? unit.version
|
|
@@ -102825,7 +103168,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
102825
103168
|
});
|
|
102826
103169
|
let transportPreflight = null;
|
|
102827
103170
|
if (deps.preflightGitTransports) {
|
|
102828
|
-
const frozenPlan = JSON.parse(await
|
|
103171
|
+
const frozenPlan = JSON.parse(await readFile32(prepared.planPath, "utf8"));
|
|
102829
103172
|
transportPreflight = await deps.preflightGitTransports(frozenPlan);
|
|
102830
103173
|
process.env.RELEASE_SKILL_GIT_TRANSPORT = transportPreflight.transport;
|
|
102831
103174
|
}
|
|
@@ -102909,7 +103252,7 @@ async function advanceShip(options = {}, injected = {}) {
|
|
|
102909
103252
|
await writeJsonAtomic(statePath, state);
|
|
102910
103253
|
}
|
|
102911
103254
|
if (state.status === "PUBLISHED" || state.status === "NEEDS_MANUAL_ATTESTATIONS") {
|
|
102912
|
-
const plan = JSON.parse(await
|
|
103255
|
+
const plan = JSON.parse(await readFile32(state.planPath, "utf8"));
|
|
102913
103256
|
const needsDistribution = plan.postPublish && plan.postPublish.targets && plan.postPublish.targets.length > 0;
|
|
102914
103257
|
if (needsDistribution && deps.distributeRelease) {
|
|
102915
103258
|
state.status = "DISTRIBUTING";
|
|
@@ -103571,8 +103914,8 @@ var attest_exports = {};
|
|
|
103571
103914
|
__export(attest_exports, {
|
|
103572
103915
|
recordManualAttestation: () => recordManualAttestation
|
|
103573
103916
|
});
|
|
103574
|
-
import { readFile as
|
|
103575
|
-
import { resolve as resolve31, join as
|
|
103917
|
+
import { readFile as readFile33 } from "node:fs/promises";
|
|
103918
|
+
import { resolve as resolve31, join as join26 } from "node:path";
|
|
103576
103919
|
async function validateInstalledConsumerClosure({
|
|
103577
103920
|
root,
|
|
103578
103921
|
platform,
|
|
@@ -103589,7 +103932,7 @@ async function validateInstalledConsumerClosure({
|
|
|
103589
103932
|
]);
|
|
103590
103933
|
let plan;
|
|
103591
103934
|
try {
|
|
103592
|
-
plan = JSON.parse(await
|
|
103935
|
+
plan = JSON.parse(await readFile33(planPath, "utf8"));
|
|
103593
103936
|
} catch (error) {
|
|
103594
103937
|
throw new ReleaseError(
|
|
103595
103938
|
GATE_FAILED,
|
|
@@ -103660,10 +104003,10 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
103660
104003
|
throw new ReleaseError(MISSING_PARAMETERS, "attest requires --result <passed|failed>");
|
|
103661
104004
|
}
|
|
103662
104005
|
const authorityDir = resolve31(root, ".release-skill", descriptor.directory, plugin);
|
|
103663
|
-
const requirementPath =
|
|
104006
|
+
const requirementPath = join26(authorityDir, descriptor.requirementFile);
|
|
103664
104007
|
let requirement;
|
|
103665
104008
|
try {
|
|
103666
|
-
requirement = JSON.parse(await
|
|
104009
|
+
requirement = JSON.parse(await readFile33(requirementPath, "utf8"));
|
|
103667
104010
|
} catch (error) {
|
|
103668
104011
|
throw new ReleaseError(
|
|
103669
104012
|
GATE_FAILED,
|
|
@@ -103713,7 +104056,7 @@ async function recordManualAttestation(options = {}, injected = {}) {
|
|
|
103713
104056
|
extraInstalledPaths: installBinding.extraInstalledPaths
|
|
103714
104057
|
} : {}
|
|
103715
104058
|
};
|
|
103716
|
-
const attestationPath =
|
|
104059
|
+
const attestationPath = join26(authorityDir, requirement.attestationFile);
|
|
103717
104060
|
await writeEvidenceAtomic(attestationPath, receipt);
|
|
103718
104061
|
return {
|
|
103719
104062
|
command: "attest",
|
|
@@ -103747,9 +104090,9 @@ var init_attest = __esm({
|
|
|
103747
104090
|
});
|
|
103748
104091
|
|
|
103749
104092
|
// src/artifacts/policy.mjs
|
|
103750
|
-
import { readFile as
|
|
103751
|
-
import { join as
|
|
103752
|
-
import { createHash as
|
|
104093
|
+
import { readFile as readFile34 } from "node:fs/promises";
|
|
104094
|
+
import { join as join27 } from "node:path";
|
|
104095
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
103753
104096
|
function validateArtifactPolicy(policy) {
|
|
103754
104097
|
const ok = _validate(policy);
|
|
103755
104098
|
if (!ok) {
|
|
@@ -103844,10 +104187,10 @@ async function parseSafeYamlWithinRoot(root, policyPath) {
|
|
|
103844
104187
|
}
|
|
103845
104188
|
throw err;
|
|
103846
104189
|
}
|
|
103847
|
-
const fullPath =
|
|
104190
|
+
const fullPath = join27(root, policyPath);
|
|
103848
104191
|
let content;
|
|
103849
104192
|
try {
|
|
103850
|
-
content = await
|
|
104193
|
+
content = await readFile34(fullPath, "utf8");
|
|
103851
104194
|
} catch (err) {
|
|
103852
104195
|
throw new ReleaseError(
|
|
103853
104196
|
ARTIFACT_POLICY_INVALID,
|
|
@@ -103898,7 +104241,7 @@ function canonicalJson3(obj) {
|
|
|
103898
104241
|
return JSON.stringify(obj, Object.keys(obj ?? {}).sort());
|
|
103899
104242
|
}
|
|
103900
104243
|
function sha256Hex2(data) {
|
|
103901
|
-
return
|
|
104244
|
+
return createHash16("sha256").update(data).digest("hex");
|
|
103902
104245
|
}
|
|
103903
104246
|
function compareProtection(previousLock, policy) {
|
|
103904
104247
|
if (!previousLock || !Array.isArray(previousLock.artifactIds)) {
|
|
@@ -103958,14 +104301,14 @@ var init_policy = __esm({
|
|
|
103958
104301
|
});
|
|
103959
104302
|
|
|
103960
104303
|
// src/artifacts/entry.mjs
|
|
103961
|
-
import { lstat as lstat25, readdir as
|
|
103962
|
-
import { join as
|
|
104304
|
+
import { lstat as lstat25, readdir as readdir17, readFile as readFile35 } from "node:fs/promises";
|
|
104305
|
+
import { join as join28 } from "node:path";
|
|
103963
104306
|
import { promisify as promisify16 } from "node:util";
|
|
103964
104307
|
import { execFile as execFile13 } from "node:child_process";
|
|
103965
|
-
function statToGitMode(
|
|
103966
|
-
if (
|
|
103967
|
-
if (
|
|
103968
|
-
const mode =
|
|
104308
|
+
function statToGitMode(stat10) {
|
|
104309
|
+
if (stat10.isDirectory()) return "040000";
|
|
104310
|
+
if (stat10.isSymbolicLink()) return "120000";
|
|
104311
|
+
const mode = stat10.mode & 511;
|
|
103969
104312
|
const executable = (mode & 73) !== 0;
|
|
103970
104313
|
return executable ? "100755" : "100644";
|
|
103971
104314
|
}
|
|
@@ -103979,10 +104322,10 @@ async function gitHashObject(root, absPath) {
|
|
|
103979
104322
|
}
|
|
103980
104323
|
async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
103981
104324
|
const entries = [];
|
|
103982
|
-
const items = await
|
|
104325
|
+
const items = await readdir17(dirPath, { withFileTypes: true });
|
|
103983
104326
|
for (const item of items) {
|
|
103984
104327
|
if (SKIP_DIRS2.has(item.name)) continue;
|
|
103985
|
-
const absPath =
|
|
104328
|
+
const absPath = join28(dirPath, item.name);
|
|
103986
104329
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
103987
104330
|
const st = await lstat25(absPath);
|
|
103988
104331
|
if (st.isSymbolicLink()) {
|
|
@@ -104003,7 +104346,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
104003
104346
|
const subEntries = await enumerateTreeEntries(root, absPath, relPath);
|
|
104004
104347
|
entries.push(...subEntries);
|
|
104005
104348
|
} else {
|
|
104006
|
-
const content = await
|
|
104349
|
+
const content = await readFile35(absPath);
|
|
104007
104350
|
entries.push(
|
|
104008
104351
|
Object.freeze({
|
|
104009
104352
|
path: relPath,
|
|
@@ -104033,7 +104376,7 @@ async function readEntry({ root, path: path15, source = "worktree" } = {}) {
|
|
|
104033
104376
|
if (source !== "worktree") {
|
|
104034
104377
|
throw new ReleaseError(PATH_UNSAFE, `unsupported readEntry source: ${source}`, { source });
|
|
104035
104378
|
}
|
|
104036
|
-
const absPath =
|
|
104379
|
+
const absPath = join28(root, path15);
|
|
104037
104380
|
let st;
|
|
104038
104381
|
try {
|
|
104039
104382
|
st = await lstat25(absPath);
|
|
@@ -104066,7 +104409,7 @@ async function readEntry({ root, path: path15, source = "worktree" } = {}) {
|
|
|
104066
104409
|
{ path: path15, nlink: st.nlink }
|
|
104067
104410
|
);
|
|
104068
104411
|
}
|
|
104069
|
-
const content = await
|
|
104412
|
+
const content = await readFile35(absPath);
|
|
104070
104413
|
return Object.freeze({
|
|
104071
104414
|
kind: "regular",
|
|
104072
104415
|
path: path15,
|
|
@@ -104330,8 +104673,8 @@ var init_graph = __esm({
|
|
|
104330
104673
|
});
|
|
104331
104674
|
|
|
104332
104675
|
// src/artifacts/producer-registry.mjs
|
|
104333
|
-
import { readFile as
|
|
104334
|
-
import { join as
|
|
104676
|
+
import { readFile as readFile36, readdir as readdir18, stat as stat7, mkdir as mkdir21, writeFile as writeFile12, rm as rm14 } from "node:fs/promises";
|
|
104677
|
+
import { join as join29 } from "node:path";
|
|
104335
104678
|
import { mkdtemp as mkdtemp9 } from "node:fs/promises";
|
|
104336
104679
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
104337
104680
|
import { readFileSync as readFileSync13 } from "node:fs";
|
|
@@ -104351,7 +104694,7 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
104351
104694
|
const dir = abs.replace(/\/[^/]*$/, "");
|
|
104352
104695
|
while ((match = importRe.exec(source)) !== null) {
|
|
104353
104696
|
const spec = match[1];
|
|
104354
|
-
let resolved =
|
|
104697
|
+
let resolved = join29(dir, spec);
|
|
104355
104698
|
if (!resolved.endsWith(".mjs")) resolved += ".mjs";
|
|
104356
104699
|
results.push(...collectStaticImports(resolved, visited));
|
|
104357
104700
|
}
|
|
@@ -104359,10 +104702,10 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
104359
104702
|
}
|
|
104360
104703
|
async function createBuiltInProducerRegistry() {
|
|
104361
104704
|
const producers = /* @__PURE__ */ new Map();
|
|
104362
|
-
const lockfilePath =
|
|
104705
|
+
const lockfilePath = join29(new URL("../../..", import.meta.url).pathname, "pnpm-lock.yaml");
|
|
104363
104706
|
let lockfileBytes;
|
|
104364
104707
|
try {
|
|
104365
|
-
lockfileBytes = await
|
|
104708
|
+
lockfileBytes = await readFile36(lockfilePath);
|
|
104366
104709
|
} catch {
|
|
104367
104710
|
lockfileBytes = Buffer.from("");
|
|
104368
104711
|
}
|
|
@@ -104379,7 +104722,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
104379
104722
|
const allModuleBytes = await Promise.all(
|
|
104380
104723
|
allModulePaths.map(async (p) => {
|
|
104381
104724
|
try {
|
|
104382
|
-
return await
|
|
104725
|
+
return await readFile36(p);
|
|
104383
104726
|
} catch {
|
|
104384
104727
|
return Buffer.from("");
|
|
104385
104728
|
}
|
|
@@ -104396,16 +104739,16 @@ async function createBuiltInProducerRegistry() {
|
|
|
104396
104739
|
}
|
|
104397
104740
|
async function readDirEntries(dirPath, relBase = "") {
|
|
104398
104741
|
const entries = [];
|
|
104399
|
-
const items = await
|
|
104742
|
+
const items = await readdir18(dirPath, { withFileTypes: true });
|
|
104400
104743
|
for (const item of items) {
|
|
104401
104744
|
if (item.name === ".git") continue;
|
|
104402
|
-
const absPath =
|
|
104745
|
+
const absPath = join29(dirPath, item.name);
|
|
104403
104746
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
104404
|
-
const st = await
|
|
104747
|
+
const st = await stat7(absPath);
|
|
104405
104748
|
if (st.isDirectory()) {
|
|
104406
104749
|
entries.push(...await readDirEntries(absPath, relPath));
|
|
104407
104750
|
} else {
|
|
104408
|
-
const content = await
|
|
104751
|
+
const content = await readFile36(absPath);
|
|
104409
104752
|
entries.push(Object.freeze({
|
|
104410
104753
|
path: relPath,
|
|
104411
104754
|
type: "blob",
|
|
@@ -104422,13 +104765,13 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
104422
104765
|
async function materializeEntries(entries, dirPath) {
|
|
104423
104766
|
for (const entry of entries) {
|
|
104424
104767
|
if (!entry.path) continue;
|
|
104425
|
-
const targetPath2 =
|
|
104768
|
+
const targetPath2 = join29(dirPath, entry.path);
|
|
104426
104769
|
if (entry.type === "tree" || entry.kind === "tree") {
|
|
104427
104770
|
await mkdir21(targetPath2, { recursive: true });
|
|
104428
104771
|
} else {
|
|
104429
|
-
await mkdir21(
|
|
104772
|
+
await mkdir21(join29(targetPath2, ".."), { recursive: true });
|
|
104430
104773
|
if (entry.content) {
|
|
104431
|
-
await
|
|
104774
|
+
await writeFile12(targetPath2, entry.content);
|
|
104432
104775
|
}
|
|
104433
104776
|
}
|
|
104434
104777
|
}
|
|
@@ -104470,7 +104813,7 @@ async function runProducerClosure({
|
|
|
104470
104813
|
graph,
|
|
104471
104814
|
inputSnapshot,
|
|
104472
104815
|
artifactIds,
|
|
104473
|
-
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp9(
|
|
104816
|
+
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp9(join29(tmpdir6(), "producer-")), "tempRootFactory")
|
|
104474
104817
|
} = {}) {
|
|
104475
104818
|
const generatedSet = new Set(graph.topologicalOrder);
|
|
104476
104819
|
for (const id of artifactIds) {
|
|
@@ -104507,9 +104850,9 @@ async function runProducerClosure({
|
|
|
104507
104850
|
if (inputEntries) {
|
|
104508
104851
|
const first = inputEntries[0];
|
|
104509
104852
|
if (first && first.path) {
|
|
104510
|
-
const absPath = first.path.startsWith("/") ? first.path :
|
|
104853
|
+
const absPath = first.path.startsWith("/") ? first.path : join29(process.cwd(), first.path);
|
|
104511
104854
|
try {
|
|
104512
|
-
const st = await
|
|
104855
|
+
const st = await stat7(absPath);
|
|
104513
104856
|
if (st.isDirectory()) {
|
|
104514
104857
|
inputPath = absPath;
|
|
104515
104858
|
} else {
|
|
@@ -104600,13 +104943,13 @@ var init_producer_registry = __esm({
|
|
|
104600
104943
|
// src/artifacts/git-authority.mjs
|
|
104601
104944
|
import { promisify as promisify18 } from "node:util";
|
|
104602
104945
|
import { execFile as execFile15 } from "node:child_process";
|
|
104603
|
-
import { createHash as
|
|
104946
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
104604
104947
|
async function git(cwd, ...args2) {
|
|
104605
104948
|
const { stdout } = await execFileAsync6("git", args2, { cwd, shell: false });
|
|
104606
104949
|
return stdout.trim();
|
|
104607
104950
|
}
|
|
104608
104951
|
function sha256Hex3(data) {
|
|
104609
|
-
return
|
|
104952
|
+
return createHash17("sha256").update(data).digest("hex");
|
|
104610
104953
|
}
|
|
104611
104954
|
async function readRepositoryIdentity(root) {
|
|
104612
104955
|
let gitDir;
|
|
@@ -104932,7 +105275,7 @@ var init_state = __esm({
|
|
|
104932
105275
|
});
|
|
104933
105276
|
|
|
104934
105277
|
// src/artifacts/artifact-plan.mjs
|
|
104935
|
-
import { writeFile as
|
|
105278
|
+
import { writeFile as writeFile13, mkdir as mkdir22, readFile as readFile37, rename as rename6, open as open9 } from "node:fs/promises";
|
|
104936
105279
|
import { dirname as dirname16 } from "node:path";
|
|
104937
105280
|
function assemblePlan({
|
|
104938
105281
|
operation,
|
|
@@ -104962,7 +105305,7 @@ async function writePlan(plan, outputPath) {
|
|
|
104962
105305
|
const content = JSON.stringify(plan, null, 2);
|
|
104963
105306
|
const fh = await open9(tmpPath, "w");
|
|
104964
105307
|
try {
|
|
104965
|
-
await
|
|
105308
|
+
await writeFile13(fh, content, "utf8");
|
|
104966
105309
|
await fh.sync();
|
|
104967
105310
|
} finally {
|
|
104968
105311
|
await fh.close();
|
|
@@ -105621,8 +105964,8 @@ var init_adoption = __esm({
|
|
|
105621
105964
|
// src/artifacts/inspect.mjs
|
|
105622
105965
|
import { promisify as promisify19 } from "node:util";
|
|
105623
105966
|
import { execFile as execFile16 } from "node:child_process";
|
|
105624
|
-
import { readdir as
|
|
105625
|
-
import { join as
|
|
105967
|
+
import { readdir as readdir19, stat as stat8, readFile as readFile38 } from "node:fs/promises";
|
|
105968
|
+
import { join as join30 } from "node:path";
|
|
105626
105969
|
async function hasNestedGitRoots(root) {
|
|
105627
105970
|
try {
|
|
105628
105971
|
const { stdout } = await execFileAsync7(
|
|
@@ -105632,10 +105975,10 @@ async function hasNestedGitRoots(root) {
|
|
|
105632
105975
|
);
|
|
105633
105976
|
const dirs = stdout.split("\n").filter((s) => s.length > 0);
|
|
105634
105977
|
for (const dir of dirs) {
|
|
105635
|
-
const absDir =
|
|
105978
|
+
const absDir = join30(root, dir);
|
|
105636
105979
|
try {
|
|
105637
|
-
const nestedGit =
|
|
105638
|
-
await
|
|
105980
|
+
const nestedGit = join30(absDir, ".git");
|
|
105981
|
+
await stat8(nestedGit);
|
|
105639
105982
|
return true;
|
|
105640
105983
|
} catch {
|
|
105641
105984
|
}
|
|
@@ -105893,8 +106236,8 @@ var init_inspect = __esm({
|
|
|
105893
106236
|
});
|
|
105894
106237
|
|
|
105895
106238
|
// src/artifacts/resolution.mjs
|
|
105896
|
-
import { mkdir as mkdir23, open as open10, readFile as
|
|
105897
|
-
import { join as
|
|
106239
|
+
import { mkdir as mkdir23, open as open10, readFile as readFile39, stat as stat9, lstat as lstat26, chmod as chmod4 } from "node:fs/promises";
|
|
106240
|
+
import { join as join31, resolve as resolve32, relative as relative26, isAbsolute as isAbsolute22, basename as basename11 } from "node:path";
|
|
105898
106241
|
function decodeBuffer(value, label) {
|
|
105899
106242
|
if (value == null) return null;
|
|
105900
106243
|
if (Buffer.isBuffer(value)) return value;
|
|
@@ -105996,9 +106339,9 @@ function assertSafeArtifactId(id) {
|
|
|
105996
106339
|
}
|
|
105997
106340
|
async function assertNoSymlinksInPath(root, artifactId) {
|
|
105998
106341
|
const levels = [
|
|
105999
|
-
|
|
106000
|
-
|
|
106001
|
-
|
|
106342
|
+
join31(root, ".release-skill"),
|
|
106343
|
+
join31(root, ".release-skill", "resolution"),
|
|
106344
|
+
join31(root, ".release-skill", "resolution", artifactId)
|
|
106002
106345
|
];
|
|
106003
106346
|
for (const dir of levels) {
|
|
106004
106347
|
try {
|
|
@@ -106025,7 +106368,7 @@ async function assertSafeResolvedPath(root, artifactId, resolvedPath) {
|
|
|
106025
106368
|
{ resolvedPath, resolutionDir }
|
|
106026
106369
|
);
|
|
106027
106370
|
}
|
|
106028
|
-
const filename =
|
|
106371
|
+
const filename = basename11(resolvedPath);
|
|
106029
106372
|
if (filename !== `${artifactId}.resolved`) {
|
|
106030
106373
|
throw new ReleaseError(
|
|
106031
106374
|
PATH_UNSAFE,
|
|
@@ -106177,13 +106520,13 @@ async function materializeResolution({
|
|
|
106177
106520
|
const template = buildConflictTemplate(artifact.conflict ?? {}, decodedBuffers);
|
|
106178
106521
|
const templateDigest = sha256Hex(template);
|
|
106179
106522
|
await assertNoSymlinksInPath(root, artifactId);
|
|
106180
|
-
const resolutionDir =
|
|
106523
|
+
const resolutionDir = join31(root, ".release-skill", "resolution", artifactId);
|
|
106181
106524
|
await mkdir23(resolutionDir, { recursive: true, mode: 448 });
|
|
106182
|
-
const dirStat = await
|
|
106525
|
+
const dirStat = await stat9(resolutionDir);
|
|
106183
106526
|
if ((dirStat.mode & 511) !== 448) {
|
|
106184
106527
|
await chmod4(resolutionDir, 448);
|
|
106185
106528
|
}
|
|
106186
|
-
const resolvedPath =
|
|
106529
|
+
const resolvedPath = join31(resolutionDir, `${artifactId}.resolved`);
|
|
106187
106530
|
const fh = await open10(resolvedPath, "wx", 384);
|
|
106188
106531
|
try {
|
|
106189
106532
|
await fh.write(template, 0, template.length);
|
|
@@ -106225,7 +106568,7 @@ async function submitResolution({
|
|
|
106225
106568
|
async function readAndValidateResolvedFile(resolvedPath) {
|
|
106226
106569
|
let content;
|
|
106227
106570
|
try {
|
|
106228
|
-
content = await
|
|
106571
|
+
content = await readFile39(resolvedPath);
|
|
106229
106572
|
} catch (err) {
|
|
106230
106573
|
throw new ReleaseError(MISSING_PARAMETERS, `cannot read resolved file: ${err.message}`, { resolvedPath, cause: err.code });
|
|
106231
106574
|
}
|
|
@@ -106393,8 +106736,8 @@ var artifacts_exports = {};
|
|
|
106393
106736
|
__export(artifacts_exports, {
|
|
106394
106737
|
runArtifactsCommand: () => runArtifactsCommand
|
|
106395
106738
|
});
|
|
106396
|
-
import { readFile as
|
|
106397
|
-
import { join as
|
|
106739
|
+
import { readFile as readFile40 } from "node:fs/promises";
|
|
106740
|
+
import { join as join32 } from "node:path";
|
|
106398
106741
|
async function runArtifactsCommand({ subcommand, args: args2, root } = {}) {
|
|
106399
106742
|
if (!VALID_SUBCOMMANDS.has(subcommand)) {
|
|
106400
106743
|
throw new ReleaseError(
|
|
@@ -106522,7 +106865,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
106522
106865
|
{ subcommand: "adopt" }
|
|
106523
106866
|
);
|
|
106524
106867
|
}
|
|
106525
|
-
const planRaw = await
|
|
106868
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106526
106869
|
const plan = JSON.parse(planRaw);
|
|
106527
106870
|
if (expectedDigest && plan.planDigest !== expectedDigest) {
|
|
106528
106871
|
throw new ReleaseError(
|
|
@@ -106537,7 +106880,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
106537
106880
|
if (artifact.path) {
|
|
106538
106881
|
const entry = await readEntry({ root, path: artifact.path, source: "worktree" });
|
|
106539
106882
|
if (entry.kind === "regular") {
|
|
106540
|
-
const bytes = await
|
|
106883
|
+
const bytes = await readFile40(join32(root, artifact.path));
|
|
106541
106884
|
currentEntries.set(artifact.id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
106542
106885
|
} else {
|
|
106543
106886
|
currentEntries.set(artifact.id, entry);
|
|
@@ -106602,7 +106945,7 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
106602
106945
|
{ subcommand: "bootstrap" }
|
|
106603
106946
|
);
|
|
106604
106947
|
}
|
|
106605
|
-
const planRaw = await
|
|
106948
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106606
106949
|
const adoptionPlan = JSON.parse(planRaw);
|
|
106607
106950
|
const currentEntries = /* @__PURE__ */ new Map();
|
|
106608
106951
|
for (const id of new Set((adoptionPlan.protectedHunks ?? []).map((h) => h.artifactId))) {
|
|
@@ -106614,12 +106957,12 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
106614
106957
|
if (entry.kind !== "regular") {
|
|
106615
106958
|
throw new ReleaseError("PLAN_STALE", `artifact is no longer a regular file: ${id}`, { id });
|
|
106616
106959
|
}
|
|
106617
|
-
const bytes = await
|
|
106960
|
+
const bytes = await readFile40(join32(root, artifactPath));
|
|
106618
106961
|
currentEntries.set(id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
106619
106962
|
}
|
|
106620
106963
|
let replacementBytes;
|
|
106621
106964
|
if (action === "replace" && replacementPath) {
|
|
106622
|
-
replacementBytes = await
|
|
106965
|
+
replacementBytes = await readFile40(replacementPath);
|
|
106623
106966
|
}
|
|
106624
106967
|
const updated = await discardBootstrapHunk({
|
|
106625
106968
|
adoptionPlan,
|
|
@@ -106657,7 +107000,7 @@ async function handleResolve({ args: args2, root }) {
|
|
|
106657
107000
|
{ subcommand: "resolve" }
|
|
106658
107001
|
);
|
|
106659
107002
|
}
|
|
106660
|
-
const planRaw = await
|
|
107003
|
+
const planRaw = await readFile40(planPath, "utf8");
|
|
106661
107004
|
const plan = JSON.parse(planRaw);
|
|
106662
107005
|
if (plan.planDigest !== expectedDigest) {
|
|
106663
107006
|
throw new ReleaseError(
|
|
@@ -107436,7 +107779,7 @@ __export(route_exports, {
|
|
|
107436
107779
|
resolvePreviousReleaseCommit: () => resolvePreviousReleaseCommit
|
|
107437
107780
|
});
|
|
107438
107781
|
import { execFileSync } from "node:child_process";
|
|
107439
|
-
import { readdir as
|
|
107782
|
+
import { readdir as readdir20, readFile as readFile41 } from "node:fs/promises";
|
|
107440
107783
|
import { resolve as resolve33 } from "node:path";
|
|
107441
107784
|
function classifyPath(path15) {
|
|
107442
107785
|
if (typeof path15 !== "string" || path15.length === 0) return "ignore";
|
|
@@ -107517,13 +107860,13 @@ async function resolvePreviousReleaseCommit(root) {
|
|
|
107517
107860
|
const cwd = resolve33(root);
|
|
107518
107861
|
try {
|
|
107519
107862
|
const plansDir = resolve33(cwd, ".release-skill", "plans");
|
|
107520
|
-
const planFiles = await
|
|
107863
|
+
const planFiles = await readdir20(plansDir).catch(() => []);
|
|
107521
107864
|
let best = null;
|
|
107522
107865
|
for (const file of planFiles) {
|
|
107523
107866
|
if (!file.endsWith(".json")) continue;
|
|
107524
107867
|
let plan;
|
|
107525
107868
|
try {
|
|
107526
|
-
plan = JSON.parse(await
|
|
107869
|
+
plan = JSON.parse(await readFile41(resolve33(plansDir, file), "utf8"));
|
|
107527
107870
|
} catch {
|
|
107528
107871
|
continue;
|
|
107529
107872
|
}
|
|
@@ -107607,14 +107950,14 @@ async function hasPartialRun(root) {
|
|
|
107607
107950
|
const runsDir = resolve33(cwd, ".release-skill", "runs");
|
|
107608
107951
|
let runDirs;
|
|
107609
107952
|
try {
|
|
107610
|
-
runDirs = await
|
|
107953
|
+
runDirs = await readdir20(runsDir);
|
|
107611
107954
|
} catch {
|
|
107612
107955
|
return false;
|
|
107613
107956
|
}
|
|
107614
107957
|
for (const runDir of runDirs) {
|
|
107615
107958
|
const summaryPath = resolve33(runsDir, runDir, "summary.json");
|
|
107616
107959
|
try {
|
|
107617
|
-
const summary = JSON.parse(await
|
|
107960
|
+
const summary = JSON.parse(await readFile41(summaryPath, "utf8"));
|
|
107618
107961
|
if (summary?.status === "PARTIAL") return true;
|
|
107619
107962
|
} catch {
|
|
107620
107963
|
}
|
|
@@ -107899,7 +108242,7 @@ Workflow Profiles:
|
|
|
107899
108242
|
});
|
|
107900
108243
|
|
|
107901
108244
|
// bin/release-skill-cli.mjs
|
|
107902
|
-
import { basename as
|
|
108245
|
+
import { basename as basename12, dirname as dirname17, join as join33, resolve as resolve34 } from "node:path";
|
|
107903
108246
|
import { execFile as execFileCb17 } from "node:child_process";
|
|
107904
108247
|
import { promisify as promisify21 } from "node:util";
|
|
107905
108248
|
|
|
@@ -108133,6 +108476,9 @@ Options:
|
|
|
108133
108476
|
deterministically trim code-class gates (declared hooks, snapshot-verify gates,
|
|
108134
108477
|
source-authority closure, skill-resource-closure) and record workflowDecision in the plan;
|
|
108135
108478
|
config also reports whether the public bytes are unchanged (no publish path)
|
|
108479
|
+
--test-selection <full|incremental> Test selection for the test hook (prepare). Only 'full' is accepted at
|
|
108480
|
+
freeze time; 'incremental' is reserved for a future preflight mode and is rejected
|
|
108481
|
+
('incremental selection is not allowed at freeze time')
|
|
108136
108482
|
--answers <path> Human-reviewed setup answers JSON
|
|
108137
108483
|
--write Create an absent project.yaml during setup; never overwrites
|
|
108138
108484
|
--confirm-setup <digest> Confirm exact setup facts and answers before create
|
|
@@ -108185,7 +108531,7 @@ if (!command && (args.includes("--version") || args.includes("-v"))) {
|
|
|
108185
108531
|
} else {
|
|
108186
108532
|
const { readFileSync: readFileSync14 } = await import("node:fs");
|
|
108187
108533
|
const { fileURLToPath: fileURLToPath3 } = await import("node:url");
|
|
108188
|
-
const pkgPath =
|
|
108534
|
+
const pkgPath = join33(dirname17(fileURLToPath3(import.meta.url)), "..", "package.json");
|
|
108189
108535
|
pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
|
|
108190
108536
|
}
|
|
108191
108537
|
if (hasJson) {
|
|
@@ -108525,6 +108871,8 @@ if (command === "prepare") {
|
|
|
108525
108871
|
const production = args.includes("--production");
|
|
108526
108872
|
const workflowIdx = args.indexOf("--workflow");
|
|
108527
108873
|
const workflow = workflowIdx !== -1 && args[workflowIdx + 1] ? args[workflowIdx + 1] : "full";
|
|
108874
|
+
const testSelectionIdx = args.indexOf("--test-selection");
|
|
108875
|
+
const testSelection = testSelectionIdx !== -1 && args[testSelectionIdx + 1] ? args[testSelectionIdx + 1] : void 0;
|
|
108528
108876
|
const outputIdx = args.indexOf("--output");
|
|
108529
108877
|
const output = outputIdx !== -1 && args[outputIdx + 1] ? resolve34(args[outputIdx + 1]) : void 0;
|
|
108530
108878
|
const runDirIdx = args.indexOf("--run-dir");
|
|
@@ -108541,6 +108889,7 @@ if (command === "prepare") {
|
|
|
108541
108889
|
hookCache,
|
|
108542
108890
|
production,
|
|
108543
108891
|
workflow,
|
|
108892
|
+
testSelection,
|
|
108544
108893
|
output,
|
|
108545
108894
|
runDir
|
|
108546
108895
|
});
|
|
@@ -108630,8 +108979,8 @@ if (command === "approve") {
|
|
|
108630
108979
|
}
|
|
108631
108980
|
const resolvedPlanPath = resolve34(planPath);
|
|
108632
108981
|
const planDir = dirname17(resolvedPlanPath);
|
|
108633
|
-
const releaseDir =
|
|
108634
|
-
const approvalPath = outputPath ??
|
|
108982
|
+
const releaseDir = basename12(planDir) === "plans" && basename12(resolvedPlanPath) === `${resolvedDigest}.json` ? dirname17(planDir) : planDir;
|
|
108983
|
+
const approvalPath = outputPath ?? join33(releaseDir, "approval-record.json");
|
|
108635
108984
|
const record = await approvePlan2({ planPath, expectedDigest: resolvedDigest, actor, outputPath: approvalPath });
|
|
108636
108985
|
if (hasJson) {
|
|
108637
108986
|
console.log(JSON.stringify(record, null, 2));
|