release-skill 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +21 -0
- package/INSTALL.md +183 -21
- package/INSTALL.zh-CN.md +160 -16
- package/README.md +112 -11
- package/README.zh-CN.md +73 -10
- 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 +1718 -600
- package/adapters/claude/schemas/release-plan.schema.json +44 -2
- package/adapters/claude/schemas/release-project.schema.json +46 -4
- package/adapters/claude/schemas/release-run.schema.json +1 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/codex/schemas/release-plan.schema.json +44 -2
- package/adapters/codex/schemas/release-project.schema.json +46 -4
- package/adapters/codex/schemas/release-run.schema.json +1 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/kimi/schemas/release-plan.schema.json +44 -2
- package/adapters/kimi/schemas/release-project.schema.json +46 -4
- package/adapters/kimi/schemas/release-run.schema.json +1 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +4 -2
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/workbuddy/schemas/release-plan.schema.json +44 -2
- package/adapters/workbuddy/schemas/release-project.schema.json +46 -4
- package/adapters/workbuddy/schemas/release-run.schema.json +1 -0
- package/bin/release-skill-cli.mjs +46 -4
- package/bin/release-skill.bundle.mjs +1718 -600
- package/package.json +1 -1
- package/references/02-project-config.md +7 -0
- package/references/06-adapter-contract.md +21 -2
- package/schemas/release-plan.schema.json +44 -2
- package/schemas/release-project.schema.json +46 -4
- package/schemas/release-run.schema.json +1 -0
- package/scripts/sync-public-files.mjs +8 -4
- package/src/adapters/contract.mjs +1 -0
- package/src/adapters/plugin-marketplace.mjs +536 -23
- package/src/commands/assess.mjs +50 -1
- package/src/commands/prepare.mjs +273 -9
- package/src/commands/publish.mjs +1 -0
- package/src/commands/reconcile.mjs +1 -0
- package/src/commands/setup.mjs +7 -3
- package/src/commands/verify.mjs +2 -0
- package/src/core/checkpoints.mjs +7 -2
- package/src/core/plan.mjs +97 -4
- package/src/core/verification-gates.mjs +1 -1
- package/src/platforms/codebuddy.mjs +618 -0
- package/src/platforms/registry.mjs +100 -5
- package/src/producers/build-adapters.mjs +21 -13
|
@@ -9,7 +9,7 @@ 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.2.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.2.2"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -11041,7 +11041,7 @@ var require_compile = __commonJS({
|
|
|
11041
11041
|
const schOrFunc = root.refs[ref];
|
|
11042
11042
|
if (schOrFunc)
|
|
11043
11043
|
return schOrFunc;
|
|
11044
|
-
let _sch =
|
|
11044
|
+
let _sch = resolve25.call(this, root, ref);
|
|
11045
11045
|
if (_sch === void 0) {
|
|
11046
11046
|
const schema2 = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
11047
11047
|
const { schemaId } = this.opts;
|
|
@@ -11072,13 +11072,13 @@ var require_compile = __commonJS({
|
|
|
11072
11072
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
11073
11073
|
}
|
|
11074
11074
|
__name(sameSchemaEnv, "sameSchemaEnv");
|
|
11075
|
-
function
|
|
11075
|
+
function resolve25(root, ref) {
|
|
11076
11076
|
let sch;
|
|
11077
11077
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
11078
11078
|
ref = sch;
|
|
11079
11079
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
11080
11080
|
}
|
|
11081
|
-
__name(
|
|
11081
|
+
__name(resolve25, "resolve");
|
|
11082
11082
|
function resolveSchema(root, ref) {
|
|
11083
11083
|
const p = this.opts.uriResolver.parse(ref);
|
|
11084
11084
|
const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p);
|
|
@@ -11730,56 +11730,56 @@ var require_fast_uri = __commonJS({
|
|
|
11730
11730
|
return uri;
|
|
11731
11731
|
}
|
|
11732
11732
|
__name(normalize4, "normalize");
|
|
11733
|
-
function
|
|
11733
|
+
function resolve25(baseURI, relativeURI, options) {
|
|
11734
11734
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
11735
11735
|
const resolved = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
11736
11736
|
schemelessOptions.skipEscape = true;
|
|
11737
11737
|
return serialize(resolved, schemelessOptions);
|
|
11738
11738
|
}
|
|
11739
|
-
__name(
|
|
11740
|
-
function resolveComponent(base,
|
|
11739
|
+
__name(resolve25, "resolve");
|
|
11740
|
+
function resolveComponent(base, relative22, options, skipNormalization) {
|
|
11741
11741
|
const target = {};
|
|
11742
11742
|
if (!skipNormalization) {
|
|
11743
11743
|
base = parse2(serialize(base, options), options);
|
|
11744
|
-
|
|
11744
|
+
relative22 = parse2(serialize(relative22, options), options);
|
|
11745
11745
|
}
|
|
11746
11746
|
options = options || {};
|
|
11747
|
-
if (!options.tolerant &&
|
|
11748
|
-
target.scheme =
|
|
11749
|
-
target.userinfo =
|
|
11750
|
-
target.host =
|
|
11751
|
-
target.port =
|
|
11752
|
-
target.path = removeDotSegments(
|
|
11753
|
-
target.query =
|
|
11747
|
+
if (!options.tolerant && relative22.scheme) {
|
|
11748
|
+
target.scheme = relative22.scheme;
|
|
11749
|
+
target.userinfo = relative22.userinfo;
|
|
11750
|
+
target.host = relative22.host;
|
|
11751
|
+
target.port = relative22.port;
|
|
11752
|
+
target.path = removeDotSegments(relative22.path || "");
|
|
11753
|
+
target.query = relative22.query;
|
|
11754
11754
|
} else {
|
|
11755
|
-
if (
|
|
11756
|
-
target.userinfo =
|
|
11757
|
-
target.host =
|
|
11758
|
-
target.port =
|
|
11759
|
-
target.path = removeDotSegments(
|
|
11760
|
-
target.query =
|
|
11755
|
+
if (relative22.userinfo !== void 0 || relative22.host !== void 0 || relative22.port !== void 0) {
|
|
11756
|
+
target.userinfo = relative22.userinfo;
|
|
11757
|
+
target.host = relative22.host;
|
|
11758
|
+
target.port = relative22.port;
|
|
11759
|
+
target.path = removeDotSegments(relative22.path || "");
|
|
11760
|
+
target.query = relative22.query;
|
|
11761
11761
|
} else {
|
|
11762
|
-
if (!
|
|
11762
|
+
if (!relative22.path) {
|
|
11763
11763
|
target.path = base.path;
|
|
11764
|
-
if (
|
|
11765
|
-
target.query =
|
|
11764
|
+
if (relative22.query !== void 0) {
|
|
11765
|
+
target.query = relative22.query;
|
|
11766
11766
|
} else {
|
|
11767
11767
|
target.query = base.query;
|
|
11768
11768
|
}
|
|
11769
11769
|
} else {
|
|
11770
|
-
if (
|
|
11771
|
-
target.path = removeDotSegments(
|
|
11770
|
+
if (relative22.path[0] === "/") {
|
|
11771
|
+
target.path = removeDotSegments(relative22.path);
|
|
11772
11772
|
} else {
|
|
11773
11773
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
11774
|
-
target.path = "/" +
|
|
11774
|
+
target.path = "/" + relative22.path;
|
|
11775
11775
|
} else if (!base.path) {
|
|
11776
|
-
target.path =
|
|
11776
|
+
target.path = relative22.path;
|
|
11777
11777
|
} else {
|
|
11778
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
11778
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative22.path;
|
|
11779
11779
|
}
|
|
11780
11780
|
target.path = removeDotSegments(target.path);
|
|
11781
11781
|
}
|
|
11782
|
-
target.query =
|
|
11782
|
+
target.query = relative22.query;
|
|
11783
11783
|
}
|
|
11784
11784
|
target.userinfo = base.userinfo;
|
|
11785
11785
|
target.host = base.host;
|
|
@@ -11787,7 +11787,7 @@ var require_fast_uri = __commonJS({
|
|
|
11787
11787
|
}
|
|
11788
11788
|
target.scheme = base.scheme;
|
|
11789
11789
|
}
|
|
11790
|
-
target.fragment =
|
|
11790
|
+
target.fragment = relative22.fragment;
|
|
11791
11791
|
return target;
|
|
11792
11792
|
}
|
|
11793
11793
|
__name(resolveComponent, "resolveComponent");
|
|
@@ -11998,7 +11998,7 @@ var require_fast_uri = __commonJS({
|
|
|
11998
11998
|
var fastUri = {
|
|
11999
11999
|
SCHEMES,
|
|
12000
12000
|
normalize: normalize4,
|
|
12001
|
-
resolve:
|
|
12001
|
+
resolve: resolve25,
|
|
12002
12002
|
resolveComponent,
|
|
12003
12003
|
equal,
|
|
12004
12004
|
serialize,
|
|
@@ -16344,7 +16344,7 @@ async function walkDiscoveryFiles(root, maxDepth = 8) {
|
|
|
16344
16344
|
const absolute = join2(directory, child.name);
|
|
16345
16345
|
if (child.isDirectory()) {
|
|
16346
16346
|
if (!SKIP_DIRS.has(child.name)) await walk(absolute, depth + 1);
|
|
16347
|
-
} else if (child.isFile() && (child.name === "package.json" || child.name === "public-release.json" || child.name === "SKILL.md" || /^README(?:\.|$)/i.test(child.name) || /^LICENSE(?:\.|$)/i.test(child.name) || /^CHANGELOG(?:\.|$)/i.test(child.name) || absolute.endsWith("/.claude-plugin/plugin.json") || absolute.endsWith("/.codex-plugin/plugin.json") || absolute.endsWith("/.kimi-plugin/plugin.json") || absolute.endsWith("/.claude-plugin/marketplace.json") || absolute.endsWith("/.codex-plugin/marketplace.json"))) {
|
|
16347
|
+
} else if (child.isFile() && (child.name === "package.json" || child.name === "public-release.json" || child.name === "SKILL.md" || /^README(?:\.|$)/i.test(child.name) || /^LICENSE(?:\.|$)/i.test(child.name) || /^CHANGELOG(?:\.|$)/i.test(child.name) || absolute.endsWith("/.claude-plugin/plugin.json") || absolute.endsWith("/.codex-plugin/plugin.json") || absolute.endsWith("/.kimi-plugin/plugin.json") || absolute.endsWith("/.codebuddy-plugin/plugin.json") || absolute.endsWith("/.claude-plugin/marketplace.json") || absolute.endsWith("/.codex-plugin/marketplace.json"))) {
|
|
16348
16348
|
found.push(absolute);
|
|
16349
16349
|
}
|
|
16350
16350
|
}
|
|
@@ -16601,7 +16601,7 @@ async function discoverFacts(root) {
|
|
|
16601
16601
|
const value = await readJsonBounded(path3, "discovered plugin manifest");
|
|
16602
16602
|
manifests.push({
|
|
16603
16603
|
path: safeRelative(root, path3),
|
|
16604
|
-
host: path3.includes("/.claude-plugin/") ? "claude" : path3.includes("/.kimi-plugin/") ? "kimi" : "codex",
|
|
16604
|
+
host: path3.includes("/.claude-plugin/") ? "claude" : path3.includes("/.kimi-plugin/") ? "kimi" : path3.includes("/.codebuddy-plugin/") ? "codebuddy" : "codex",
|
|
16605
16605
|
kind: path3.endsWith("/marketplace.json") ? "marketplace" : "plugin",
|
|
16606
16606
|
name: typeof value.name === "string" ? value.name : null,
|
|
16607
16607
|
version: typeof value.version === "string" ? value.version : null
|
|
@@ -16620,7 +16620,7 @@ async function discoverFacts(root) {
|
|
|
16620
16620
|
return {
|
|
16621
16621
|
path: relPath,
|
|
16622
16622
|
name: skillIndex >= 0 ? segments[skillIndex + 1] ?? null : null,
|
|
16623
|
-
host: relPath.includes("/adapters/claude/") ? "claude" : relPath.includes("/adapters/codex/") ? "codex" : relPath.includes("/adapters/kimi/") ? "kimi" : "shared"
|
|
16623
|
+
host: relPath.includes("/adapters/claude/") ? "claude" : relPath.includes("/adapters/codex/") ? "codex" : relPath.includes("/adapters/kimi/") ? "kimi" : relPath.includes("/adapters/workbuddy/") ? "codebuddy" : "shared"
|
|
16624
16624
|
};
|
|
16625
16625
|
}).filter((item) => item.name).sort((a, b) => canonicalJson(a).localeCompare(canonicalJson(b)));
|
|
16626
16626
|
const unitGit = {};
|
|
@@ -16764,7 +16764,7 @@ function buildCandidates(facts) {
|
|
|
16764
16764
|
const ids = /* @__PURE__ */ new Set();
|
|
16765
16765
|
const knownFiles = new Set(facts.fileDigests.map((file) => file.path));
|
|
16766
16766
|
const manifestRoots = facts.manifests.map((manifest) => {
|
|
16767
|
-
const match = manifest.path.match(/^(.*?)(?:\/)?(?:\.claude-plugin|\.codex-plugin|\.kimi-plugin)\/(?:plugin|marketplace)\.json$/);
|
|
16767
|
+
const match = manifest.path.match(/^(.*?)(?:\/)?(?:\.claude-plugin|\.codex-plugin|\.kimi-plugin|\.codebuddy-plugin)\/(?:plugin|marketplace)\.json$/);
|
|
16768
16768
|
return { ...manifest, root: match?.[1] || "." };
|
|
16769
16769
|
});
|
|
16770
16770
|
const manifestOwners = /* @__PURE__ */ new Map();
|
|
@@ -16791,6 +16791,7 @@ function buildCandidates(facts) {
|
|
|
16791
16791
|
if (pluginHosts.includes("claude")) distributions.push("claude-plugin");
|
|
16792
16792
|
if (pluginHosts.includes("codex")) distributions.push("codex-plugin");
|
|
16793
16793
|
if (pluginHosts.includes("kimi")) distributions.push("kimi-plugin");
|
|
16794
|
+
if (pluginHosts.includes("codebuddy")) distributions.push("codebuddy-plugin");
|
|
16794
16795
|
if (pkg.private && matchingLegacyUnits.length === 0 && facts.legacyReleaseConfigs.length > 0) continue;
|
|
16795
16796
|
if (pkg.private && distributions.length === 0) continue;
|
|
16796
16797
|
const unitGitEntry = unitGit[pkg.directory];
|
|
@@ -18196,7 +18197,7 @@ function identifyTopology(config) {
|
|
|
18196
18197
|
const uniqueDistTypes = [...new Set(allDistTypes)];
|
|
18197
18198
|
let type = "unknown";
|
|
18198
18199
|
const hasNpm = uniqueDistTypes.includes("npm");
|
|
18199
|
-
const hasPlugin = uniqueDistTypes.includes("claude-plugin") || uniqueDistTypes.includes("codex-plugin") || uniqueDistTypes.includes("kimi-plugin");
|
|
18200
|
+
const hasPlugin = uniqueDistTypes.includes("claude-plugin") || uniqueDistTypes.includes("codex-plugin") || uniqueDistTypes.includes("kimi-plugin") || uniqueDistTypes.includes("codebuddy-plugin");
|
|
18200
18201
|
if (units.length === 0) {
|
|
18201
18202
|
type = "no-release-units";
|
|
18202
18203
|
} else if (units.length === 1) {
|
|
@@ -18453,6 +18454,53 @@ async function checkPluginManifests(root, config) {
|
|
|
18453
18454
|
}
|
|
18454
18455
|
}
|
|
18455
18456
|
}
|
|
18457
|
+
if (distributionTypes.has("codebuddy-plugin")) {
|
|
18458
|
+
const manifestPath = resolve7(unitRoot, ".codebuddy-plugin", "plugin.json");
|
|
18459
|
+
const displayPath = unitFile(unit, ".codebuddy-plugin/plugin.json");
|
|
18460
|
+
const exists = await fileExists(manifestPath);
|
|
18461
|
+
if (!exists) {
|
|
18462
|
+
gaps.push(
|
|
18463
|
+
createGap({
|
|
18464
|
+
scope: GapScope.PROFILE,
|
|
18465
|
+
category: GapCategory.MANIFEST,
|
|
18466
|
+
severity: Severity.ERROR,
|
|
18467
|
+
code: "CODEBUDDY_MANIFEST_MISSING",
|
|
18468
|
+
message: `\u53D1\u5E03\u5355\u5143 "${unit.id}" \u7F3A\u5C11 .codebuddy-plugin/plugin.json \u63D2\u4EF6\u6E05\u5355`,
|
|
18469
|
+
file: displayPath
|
|
18470
|
+
})
|
|
18471
|
+
);
|
|
18472
|
+
} else {
|
|
18473
|
+
try {
|
|
18474
|
+
const content = await readFile5(manifestPath, "utf8");
|
|
18475
|
+
const manifest = JSON.parse(content);
|
|
18476
|
+
const requiredFields = ["name", "version", "description"];
|
|
18477
|
+
const missingFields = requiredFields.filter((f) => !(f in manifest));
|
|
18478
|
+
if (missingFields.length > 0) {
|
|
18479
|
+
gaps.push(
|
|
18480
|
+
createGap({
|
|
18481
|
+
scope: GapScope.PROFILE,
|
|
18482
|
+
category: GapCategory.MANIFEST,
|
|
18483
|
+
severity: Severity.ERROR,
|
|
18484
|
+
code: "CODEBUDDY_MANIFEST_INCOMPLETE",
|
|
18485
|
+
message: `CodeBuddy \u63D2\u4EF6\u6E05\u5355\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5: ${missingFields.join(", ")}`,
|
|
18486
|
+
file: displayPath
|
|
18487
|
+
})
|
|
18488
|
+
);
|
|
18489
|
+
}
|
|
18490
|
+
} catch {
|
|
18491
|
+
gaps.push(
|
|
18492
|
+
createGap({
|
|
18493
|
+
scope: GapScope.PROFILE,
|
|
18494
|
+
category: GapCategory.MANIFEST,
|
|
18495
|
+
severity: Severity.ERROR,
|
|
18496
|
+
code: "CODEBUDDY_MANIFEST_INVALID",
|
|
18497
|
+
message: ".codebuddy-plugin/plugin.json \u89E3\u6790\u5931\u8D25",
|
|
18498
|
+
file: displayPath
|
|
18499
|
+
})
|
|
18500
|
+
);
|
|
18501
|
+
}
|
|
18502
|
+
}
|
|
18503
|
+
}
|
|
18456
18504
|
}
|
|
18457
18505
|
return gaps;
|
|
18458
18506
|
}
|
|
@@ -19717,7 +19765,7 @@ function validateGate(gate) {
|
|
|
19717
19765
|
if (!gate.scope || typeof gate.scope.unit !== "string") {
|
|
19718
19766
|
throw gateError(gate, "must declare scope.unit");
|
|
19719
19767
|
}
|
|
19720
|
-
if (gate.phase === "consumer-verify" && !["npm", "claude-plugin", "codex-plugin", "kimi-plugin"].includes(gate.scope.distribution)) {
|
|
19768
|
+
if (gate.phase === "consumer-verify" && !["npm", "claude-plugin", "codex-plugin", "kimi-plugin", "codebuddy-plugin"].includes(gate.scope.distribution)) {
|
|
19721
19769
|
throw gateError(gate, "consumer-verify must declare a supported scope.distribution");
|
|
19722
19770
|
}
|
|
19723
19771
|
if (!Array.isArray(gate.command) || gate.command.length === 0 || gate.command.some((value) => typeof value !== "string")) {
|
|
@@ -20376,6 +20424,7 @@ var init_contract = __esm({
|
|
|
20376
20424
|
CLAUDE_MARKETPLACE_INSTALL: "claude-marketplace-install",
|
|
20377
20425
|
CODEX_MARKETPLACE_INSTALL: "codex-marketplace-install",
|
|
20378
20426
|
KIMI_MARKETPLACE_INSTALL: "kimi-marketplace-install",
|
|
20427
|
+
CODEBUDDY_MARKETPLACE_INSTALL: "codebuddy-marketplace-install",
|
|
20379
20428
|
// default branch management
|
|
20380
20429
|
SET_DEFAULT_BRANCH: "set-default-branch"
|
|
20381
20430
|
});
|
|
@@ -20707,8 +20756,356 @@ var init_kimi = __esm({
|
|
|
20707
20756
|
}
|
|
20708
20757
|
});
|
|
20709
20758
|
|
|
20759
|
+
// src/platforms/codebuddy.mjs
|
|
20760
|
+
import { readFile as readFile8, mkdir as mkdir8 } from "node:fs/promises";
|
|
20761
|
+
import { join as join7, resolve as resolve12, relative as relative10, isAbsolute as isAbsolute9 } from "node:path";
|
|
20762
|
+
function normalizePlanForDigest2(plan) {
|
|
20763
|
+
const normalized = { ...plan, status: "PREPARED" };
|
|
20764
|
+
if (Array.isArray(plan.externalActions)) {
|
|
20765
|
+
normalized.externalActions = plan.externalActions.map((action) => action && typeof action === "object" && !Array.isArray(action) ? { ...action, status: "PENDING" } : action);
|
|
20766
|
+
}
|
|
20767
|
+
return normalized;
|
|
20768
|
+
}
|
|
20769
|
+
async function resolveCodeBuddyBoundPlanDigest(context) {
|
|
20770
|
+
const plan = context?.plan;
|
|
20771
|
+
if (!plan || typeof plan !== "object" || Array.isArray(plan)) {
|
|
20772
|
+
throw new Error("context.plan is required to bind the codebuddy plan digest");
|
|
20773
|
+
}
|
|
20774
|
+
const carried = plan.digest;
|
|
20775
|
+
if (typeof carried !== "string" || !HEX_DIGEST_RE2.test(carried)) {
|
|
20776
|
+
throw new Error("context.plan.digest must be a 64-char lowercase hex frozen plan digest");
|
|
20777
|
+
}
|
|
20778
|
+
const { computePlanDigest: computePlanDigest2 } = await init_plan().then(() => plan_exports);
|
|
20779
|
+
const normalized = normalizePlanForDigest2(plan);
|
|
20780
|
+
if (computePlanDigest2(normalized) !== carried) {
|
|
20781
|
+
throw new Error("context.plan.digest does not match the normalized frozen plan (a non-lifecycle field was tampered)");
|
|
20782
|
+
}
|
|
20783
|
+
return carried;
|
|
20784
|
+
}
|
|
20785
|
+
function codebuddyAuthorityDir(context, planDigest, plugin) {
|
|
20786
|
+
if (!context?.root) {
|
|
20787
|
+
throw new Error("context.root is required for the codebuddy attestation authority");
|
|
20788
|
+
}
|
|
20789
|
+
if (!HEX_DIGEST_RE2.test(planDigest)) {
|
|
20790
|
+
throw new Error("codebuddy attestation authority requires a 64-hex plan digest");
|
|
20791
|
+
}
|
|
20792
|
+
if (!SAFE_ID_RE.test(plugin)) {
|
|
20793
|
+
throw new Error(`codebuddy attestation authority requires a safe plugin id: "${plugin}"`);
|
|
20794
|
+
}
|
|
20795
|
+
const base = resolve12(context.root, ".release-skill", "codebuddy-attestations");
|
|
20796
|
+
const dir = resolve12(base, planDigest, plugin);
|
|
20797
|
+
const rel = relative10(base, dir);
|
|
20798
|
+
const sep4 = process.platform === "win32" ? "\\" : "/";
|
|
20799
|
+
if (rel === "" || rel === ".." || isAbsolute9(rel) || rel.startsWith(`..${sep4}`) || rel.split(sep4).some((segment) => segment === ".." || segment === "")) {
|
|
20800
|
+
throw new Error("codebuddy attestation authority path escapes its base");
|
|
20801
|
+
}
|
|
20802
|
+
return dir;
|
|
20803
|
+
}
|
|
20804
|
+
function codebuddyCliHome(attestationDir) {
|
|
20805
|
+
return resolve12(attestationDir, "codebuddy-home");
|
|
20806
|
+
}
|
|
20807
|
+
function codebuddyCliInstallRoot(cliHome, marketplace, plugin) {
|
|
20808
|
+
return resolve12(cliHome, CODEBUDDY_CLI_STATE_DIR, "plugins", "marketplaces", marketplace, "plugins", plugin);
|
|
20809
|
+
}
|
|
20810
|
+
function codebuddyDesktopTailSegments(marketplace, plugin) {
|
|
20811
|
+
return [CODEBUDDY_DESKTOP_HOME_DIR, "plugins", "marketplaces", marketplace, "plugins", plugin];
|
|
20812
|
+
}
|
|
20813
|
+
function matchesDesktopLayout(installPath, marketplace, plugin) {
|
|
20814
|
+
const segments = installPath.split(/[\\/]+/).filter((s) => s !== "" && s !== ".");
|
|
20815
|
+
const tail = codebuddyDesktopTailSegments(marketplace, plugin);
|
|
20816
|
+
if (segments.length < tail.length) return false;
|
|
20817
|
+
const offset = segments.length - tail.length;
|
|
20818
|
+
return tail.every((segment, index) => segments[offset + index] === segment);
|
|
20819
|
+
}
|
|
20820
|
+
function buildCodeBuddyManualInstructions({ plugin, version, ref, cliHome, attestationDir }) {
|
|
20821
|
+
const cliInstallRoot = codebuddyCliInstallRoot(cliHome, CODEBUDDY_MARKETPLACE_NAME, plugin);
|
|
20822
|
+
const desktopInstallRoot = `~/${CODEBUDDY_DESKTOP_HOME_DIR}/plugins/marketplaces/${CODEBUDDY_MARKETPLACE_NAME}/plugins/${plugin}`;
|
|
20823
|
+
return [
|
|
20824
|
+
`CodeBuddy/WorkBuddy plugin install cannot pin a frozen ref (the codebuddy CLI marketplace add/install have no ref option and track the default branch), so installation is a manual step proven by a human attestation.`,
|
|
20825
|
+
`1) publish fails closed at this codebuddy checkpoint and leaves the run PARTIAL (the automated Git branch/tag, npm, and GitHub Release writes still complete first).`,
|
|
20826
|
+
`2) PRIMARY PATH (WorkBuddy desktop): install release-skill from the unified marketplace "${CODEBUDDY_MARKETPLACE_NAME}" (${CODEBUDDY_MARKETPLACE_SOURCE}). Confirm "~/.workbuddy/settings.json" enabledPlugins contains "${plugin}@${CODEBUDDY_MARKETPLACE_NAME}": true. The plugin lands at "${desktopInstallRoot}/".`,
|
|
20827
|
+
`3) ALTERNATE PATH (bundled codebuddy CLI, isolatable): run the CLI with the ISOLATED home from this requirement so the clone lands inside it: HOME="${cliHome}" <codebuddy binary> plugin marketplace add ${CODEBUDDY_MARKETPLACE_SOURCE} ; then HOME="${cliHome}" <codebuddy binary> plugin install ${plugin}@${CODEBUDDY_MARKETPLACE_NAME}. The CLI ships with WorkBuddy.app (macOS known path /Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy). The plugin lands at "${cliInstallRoot}/".`,
|
|
20828
|
+
`4) REF LIMITATION WARNING: a codebuddy install tracks the marketplace default branch and CANNOT be pinned to frozen ref "${ref}". Before writing the attestation you MUST confirm the installed plugin manifest version equals the frozen version ${version}; otherwise do NOT issue an attestation.`,
|
|
20829
|
+
`5) Write the attestation JSON to: ${attestationDir}/${CODEBUDDY_ATTESTATION_FILE}. planDigest MUST be the frozen plan digest; payloadDigest MUST be the frozen snapshot payload digest; installChannel MUST be "desktop" or "cli"; marketplace MUST be "${CODEBUDDY_MARKETPLACE_NAME}"; installPath MUST be the actual installed plugin directory for the chosen channel. attestedAt must not be in the future and expiresAt must be within 24 hours of attestedAt.`,
|
|
20830
|
+
` Required fields: consumer="codebuddy", plugin, version, entrySkill, repo, ref, marketplace, installChannel, installPath, planDigest, payloadDigest, attestedBy, attestedAt, expiresAt.`,
|
|
20831
|
+
`6) Re-run release-skill reconcile (promotes PARTIAL -> PUBLISHED) and then verify (-> VERIFIED). Both read the attestation from this same plan-digest-keyed authority directory, so a fresh run directory does not lose the proof.`
|
|
20832
|
+
];
|
|
20833
|
+
}
|
|
20834
|
+
async function readCodeBuddyManifest(pluginRootReal) {
|
|
20835
|
+
const manifestRelative = CODEBUDDY_PLUGIN_MANIFEST_RELATIVE;
|
|
20836
|
+
const manifestPath = resolve12(pluginRootReal, manifestRelative);
|
|
20837
|
+
let content;
|
|
20838
|
+
try {
|
|
20839
|
+
content = await readFile8(manifestPath, "utf8");
|
|
20840
|
+
} catch {
|
|
20841
|
+
throw new Error(`no codebuddy plugin manifest found (expected ${manifestRelative})`);
|
|
20842
|
+
}
|
|
20843
|
+
let manifest;
|
|
20844
|
+
try {
|
|
20845
|
+
manifest = JSON.parse(content);
|
|
20846
|
+
} catch {
|
|
20847
|
+
throw new Error(`codebuddy plugin manifest ${manifestRelative} is not valid JSON`);
|
|
20848
|
+
}
|
|
20849
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
20850
|
+
throw new Error(`codebuddy plugin manifest ${manifestRelative} is not an object`);
|
|
20851
|
+
}
|
|
20852
|
+
return { manifest, manifestRelative };
|
|
20853
|
+
}
|
|
20854
|
+
function validateCodeBuddyAttestation(attestation, action, isoNow, boundPlanDigest) {
|
|
20855
|
+
if (!attestation || typeof attestation !== "object" || Array.isArray(attestation)) {
|
|
20856
|
+
return { valid: false, error: "codebuddy attestation is not an object" };
|
|
20857
|
+
}
|
|
20858
|
+
const requiredStrings = ["plugin", "version", "entrySkill", "repo", "ref", "installPath", "payloadDigest", "planDigest", "attestedBy", "attestedAt", "expiresAt", "marketplace", "installChannel"];
|
|
20859
|
+
for (const field of requiredStrings) {
|
|
20860
|
+
if (typeof attestation[field] !== "string" || attestation[field].length === 0) {
|
|
20861
|
+
return { valid: false, error: `codebuddy attestation missing required field "${field}"` };
|
|
20862
|
+
}
|
|
20863
|
+
}
|
|
20864
|
+
if (attestation.consumer !== "codebuddy") {
|
|
20865
|
+
return { valid: false, error: `codebuddy attestation consumer "${attestation.consumer}" must be "codebuddy"` };
|
|
20866
|
+
}
|
|
20867
|
+
if (!CODEBUDDY_INSTALL_CHANNELS.has(attestation.installChannel)) {
|
|
20868
|
+
return { valid: false, error: `codebuddy attestation installChannel "${attestation.installChannel}" must be "desktop" or "cli"` };
|
|
20869
|
+
}
|
|
20870
|
+
if (attestation.marketplace !== CODEBUDDY_MARKETPLACE_NAME) {
|
|
20871
|
+
return { valid: false, error: `codebuddy attestation marketplace "${attestation.marketplace}" must be "${CODEBUDDY_MARKETPLACE_NAME}"` };
|
|
20872
|
+
}
|
|
20873
|
+
if (!HEX_DIGEST_RE2.test(attestation.planDigest)) {
|
|
20874
|
+
return { valid: false, error: "codebuddy attestation planDigest must be a 64-char lowercase hex digest" };
|
|
20875
|
+
}
|
|
20876
|
+
if (attestation.planDigest !== boundPlanDigest) {
|
|
20877
|
+
return { valid: false, error: "codebuddy attestation planDigest does not match the frozen plan digest" };
|
|
20878
|
+
}
|
|
20879
|
+
if (attestation.plugin !== action.plugin) {
|
|
20880
|
+
return { valid: false, error: `codebuddy attestation plugin "${attestation.plugin}" does not match action plugin "${action.plugin}"` };
|
|
20881
|
+
}
|
|
20882
|
+
if (attestation.version !== action.version) {
|
|
20883
|
+
return { valid: false, error: `codebuddy attestation version "${attestation.version}" does not match action version "${action.version}"` };
|
|
20884
|
+
}
|
|
20885
|
+
if (attestation.entrySkill !== action.entrySkill) {
|
|
20886
|
+
return { valid: false, error: `codebuddy attestation entrySkill "${attestation.entrySkill}" does not match action entrySkill "${action.entrySkill}"` };
|
|
20887
|
+
}
|
|
20888
|
+
if (attestation.repo !== action.repo) {
|
|
20889
|
+
return { valid: false, error: `codebuddy attestation repo "${attestation.repo}" does not match action repo "${action.repo}"` };
|
|
20890
|
+
}
|
|
20891
|
+
const expectedRef = action.ref ?? `v${action.version}`;
|
|
20892
|
+
if (attestation.ref !== expectedRef) {
|
|
20893
|
+
return { valid: false, error: `codebuddy attestation ref "${attestation.ref}" does not match frozen ref "${expectedRef}"` };
|
|
20894
|
+
}
|
|
20895
|
+
if (attestation.payloadDigest !== action.manifestDigest) {
|
|
20896
|
+
return { valid: false, error: "codebuddy attestation payloadDigest does not match the frozen payload digest" };
|
|
20897
|
+
}
|
|
20898
|
+
const attestedMs = Date.parse(attestation.attestedAt);
|
|
20899
|
+
const expiresMs = Date.parse(attestation.expiresAt);
|
|
20900
|
+
const nowMs = Date.parse(isoNow);
|
|
20901
|
+
if (!Number.isFinite(attestedMs) || !Number.isFinite(expiresMs) || !Number.isFinite(nowMs)) {
|
|
20902
|
+
return { valid: false, error: "codebuddy attestation attestedAt/expiresAt must be valid ISO timestamps" };
|
|
20903
|
+
}
|
|
20904
|
+
if (attestedMs > nowMs) {
|
|
20905
|
+
return { valid: false, error: "codebuddy attestation attestedAt is in the future" };
|
|
20906
|
+
}
|
|
20907
|
+
if (expiresMs <= attestedMs) {
|
|
20908
|
+
return { valid: false, error: "codebuddy attestation expiresAt must be after attestedAt" };
|
|
20909
|
+
}
|
|
20910
|
+
if (expiresMs - attestedMs > CODEBUDDY_MAX_ATTESTATION_VALIDITY_MS) {
|
|
20911
|
+
return { valid: false, error: "codebuddy attestation validity must not exceed 24 hours" };
|
|
20912
|
+
}
|
|
20913
|
+
if (nowMs > expiresMs) {
|
|
20914
|
+
return { valid: false, error: "codebuddy attestation has expired" };
|
|
20915
|
+
}
|
|
20916
|
+
if (attestation.installChannel === "desktop" && !matchesDesktopLayout(attestation.installPath, attestation.marketplace, attestation.plugin)) {
|
|
20917
|
+
return { valid: false, error: `codebuddy attestation installPath does not match the WorkBuddy desktop marketplace layout (.workbuddy/plugins/marketplaces/${attestation.marketplace}/plugins/${attestation.plugin})` };
|
|
20918
|
+
}
|
|
20919
|
+
return { valid: true, error: null };
|
|
20920
|
+
}
|
|
20921
|
+
async function executeCodeBuddyManualRequirement(action, context) {
|
|
20922
|
+
const actionType = ActionType.CODEBUDDY_MARKETPLACE_INSTALL;
|
|
20923
|
+
let planDigest;
|
|
20924
|
+
try {
|
|
20925
|
+
planDigest = await resolveCodeBuddyBoundPlanDigest(context);
|
|
20926
|
+
} catch (planErr) {
|
|
20927
|
+
return createResult({
|
|
20928
|
+
actionType,
|
|
20929
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
20930
|
+
error: `cannot bind codebuddy requirement to the frozen plan: ${planErr.message}`
|
|
20931
|
+
});
|
|
20932
|
+
}
|
|
20933
|
+
try {
|
|
20934
|
+
resolveTimeoutMs(action);
|
|
20935
|
+
} catch (timeoutErr) {
|
|
20936
|
+
return createResult({
|
|
20937
|
+
actionType,
|
|
20938
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
20939
|
+
error: timeoutErr.message
|
|
20940
|
+
});
|
|
20941
|
+
}
|
|
20942
|
+
const ref = action.ref ?? `v${action.version}`;
|
|
20943
|
+
let attestationDir;
|
|
20944
|
+
try {
|
|
20945
|
+
attestationDir = codebuddyAuthorityDir(context, planDigest, action.plugin);
|
|
20946
|
+
} catch (dirErr) {
|
|
20947
|
+
return createResult({
|
|
20948
|
+
actionType,
|
|
20949
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
20950
|
+
error: dirErr.message
|
|
20951
|
+
});
|
|
20952
|
+
}
|
|
20953
|
+
const cliHome = codebuddyCliHome(attestationDir);
|
|
20954
|
+
const cliInstallRoot = codebuddyCliInstallRoot(cliHome, CODEBUDDY_MARKETPLACE_NAME, action.plugin);
|
|
20955
|
+
const desktopInstallRoot = `~/${CODEBUDDY_DESKTOP_HOME_DIR}/plugins/marketplaces/${CODEBUDDY_MARKETPLACE_NAME}/plugins/${action.plugin}`;
|
|
20956
|
+
const instructions = buildCodeBuddyManualInstructions({
|
|
20957
|
+
plugin: action.plugin,
|
|
20958
|
+
version: action.version,
|
|
20959
|
+
ref,
|
|
20960
|
+
cliHome,
|
|
20961
|
+
attestationDir
|
|
20962
|
+
});
|
|
20963
|
+
const requirement = {
|
|
20964
|
+
kind: "codebuddy-manual-install-requirement",
|
|
20965
|
+
consumer: "codebuddy",
|
|
20966
|
+
plugin: action.plugin,
|
|
20967
|
+
version: action.version,
|
|
20968
|
+
entrySkill: action.entrySkill,
|
|
20969
|
+
repo: action.repo,
|
|
20970
|
+
ref,
|
|
20971
|
+
marketplace: CODEBUDDY_MARKETPLACE_NAME,
|
|
20972
|
+
marketplaceSource: CODEBUDDY_MARKETPLACE_SOURCE,
|
|
20973
|
+
installChannels: ["desktop", "cli"],
|
|
20974
|
+
// (A) planDigest binds to the real frozen plan digest;
|
|
20975
|
+
// expectedPayloadDigest binds separately to the snapshot payload digest.
|
|
20976
|
+
planDigest,
|
|
20977
|
+
expectedPayloadDigest: action.manifestDigest,
|
|
20978
|
+
isolatedHome: cliHome,
|
|
20979
|
+
codebuddyHome: cliHome,
|
|
20980
|
+
cliInstallRoot,
|
|
20981
|
+
desktopInstallRoot,
|
|
20982
|
+
attestationDir,
|
|
20983
|
+
attestationFile: CODEBUDDY_ATTESTATION_FILE,
|
|
20984
|
+
attestationTemplate: {
|
|
20985
|
+
consumer: "codebuddy",
|
|
20986
|
+
plugin: action.plugin,
|
|
20987
|
+
version: action.version,
|
|
20988
|
+
entrySkill: action.entrySkill,
|
|
20989
|
+
repo: action.repo,
|
|
20990
|
+
ref,
|
|
20991
|
+
marketplace: CODEBUDDY_MARKETPLACE_NAME,
|
|
20992
|
+
installChannel: '<"desktop" or "cli">',
|
|
20993
|
+
installPath: "<actual installed plugin directory for the chosen channel>",
|
|
20994
|
+
planDigest,
|
|
20995
|
+
payloadDigest: action.manifestDigest,
|
|
20996
|
+
attestedBy: "<person responsible for the manual install>",
|
|
20997
|
+
attestedAt: "<ISO 8601 now; must not be in the future>",
|
|
20998
|
+
expiresAt: "<ISO 8601; within 24h of attestedAt>"
|
|
20999
|
+
},
|
|
21000
|
+
instructions
|
|
21001
|
+
};
|
|
21002
|
+
try {
|
|
21003
|
+
await mkdir8(cliHome, { recursive: true, mode: 448 });
|
|
21004
|
+
} catch (mkdirErr) {
|
|
21005
|
+
return createResult({
|
|
21006
|
+
actionType,
|
|
21007
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
21008
|
+
error: `cannot create codebuddy isolated home directory: ${mkdirErr.message}`
|
|
21009
|
+
});
|
|
21010
|
+
}
|
|
21011
|
+
const requirementPath = resolve12(attestationDir, CODEBUDDY_REQUIREMENT_FILE);
|
|
21012
|
+
let existing = null;
|
|
21013
|
+
let requirementMissing = false;
|
|
21014
|
+
try {
|
|
21015
|
+
const existingRaw = await readFile8(requirementPath, "utf8");
|
|
21016
|
+
try {
|
|
21017
|
+
existing = JSON.parse(existingRaw);
|
|
21018
|
+
} catch (parseErr) {
|
|
21019
|
+
return createResult({
|
|
21020
|
+
actionType,
|
|
21021
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
21022
|
+
error: `existing codebuddy manual-install requirement is invalid JSON; refusing to overwrite: ${parseErr.message}`
|
|
21023
|
+
});
|
|
21024
|
+
}
|
|
21025
|
+
} catch (readErr) {
|
|
21026
|
+
if (readErr?.code === "ENOENT") {
|
|
21027
|
+
requirementMissing = true;
|
|
21028
|
+
} else {
|
|
21029
|
+
return createResult({
|
|
21030
|
+
actionType,
|
|
21031
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
21032
|
+
error: `existing codebuddy manual-install requirement cannot be read; refusing to overwrite: ${readErr.message}`
|
|
21033
|
+
});
|
|
21034
|
+
}
|
|
21035
|
+
}
|
|
21036
|
+
if (!requirementMissing) {
|
|
21037
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
21038
|
+
return createResult({
|
|
21039
|
+
actionType,
|
|
21040
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
21041
|
+
error: "existing codebuddy manual-install requirement is not an object; refusing to overwrite"
|
|
21042
|
+
});
|
|
21043
|
+
}
|
|
21044
|
+
const { createdAt: _existingCreatedAt, ...existingBody } = existing;
|
|
21045
|
+
if (canonicalJson(existingBody) !== canonicalJson(requirement)) {
|
|
21046
|
+
return createResult({
|
|
21047
|
+
actionType,
|
|
21048
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
21049
|
+
error: "existing codebuddy manual-install requirement conflicts with the current frozen action; refusing to overwrite"
|
|
21050
|
+
});
|
|
21051
|
+
}
|
|
21052
|
+
} else {
|
|
21053
|
+
await writeEvidenceAtomic(requirementPath, { ...requirement, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
21054
|
+
}
|
|
21055
|
+
return createResult({
|
|
21056
|
+
actionType,
|
|
21057
|
+
status: ActionStatus.EXECUTED,
|
|
21058
|
+
observation: {
|
|
21059
|
+
installed: false,
|
|
21060
|
+
manualInstallRequired: true,
|
|
21061
|
+
consumer: "codebuddy",
|
|
21062
|
+
plugin: action.plugin,
|
|
21063
|
+
version: action.version,
|
|
21064
|
+
entrySkill: action.entrySkill,
|
|
21065
|
+
repo: action.repo,
|
|
21066
|
+
ref,
|
|
21067
|
+
marketplace: CODEBUDDY_MARKETPLACE_NAME,
|
|
21068
|
+
installChannels: ["desktop", "cli"],
|
|
21069
|
+
planDigest,
|
|
21070
|
+
attestationDir,
|
|
21071
|
+
codebuddyHome: cliHome,
|
|
21072
|
+
cliInstallRoot,
|
|
21073
|
+
desktopInstallRoot,
|
|
21074
|
+
instructions
|
|
21075
|
+
}
|
|
21076
|
+
});
|
|
21077
|
+
}
|
|
21078
|
+
var HEX_DIGEST_RE2, CODEBUDDY_REQUIREMENT_FILE, CODEBUDDY_ATTESTATION_FILE, CODEBUDDY_MAX_ATTESTATION_VALIDITY_MS, CODEBUDDY_MARKETPLACE_NAME, CODEBUDDY_MARKETPLACE_SOURCE, CODEBUDDY_PLUGIN_MANIFEST_RELATIVE, CODEBUDDY_INSTALL_CHANNELS, CODEBUDDY_DESKTOP_HOME_DIR, CODEBUDDY_CLI_STATE_DIR;
|
|
21079
|
+
var init_codebuddy = __esm({
|
|
21080
|
+
"src/platforms/codebuddy.mjs"() {
|
|
21081
|
+
init_contract();
|
|
21082
|
+
init_digest();
|
|
21083
|
+
HEX_DIGEST_RE2 = /^[a-f0-9]{64}$/;
|
|
21084
|
+
__name(normalizePlanForDigest2, "normalizePlanForDigest");
|
|
21085
|
+
CODEBUDDY_REQUIREMENT_FILE = "release-skill-codebuddy-manual-install.json";
|
|
21086
|
+
CODEBUDDY_ATTESTATION_FILE = "release-skill-codebuddy-attestation.json";
|
|
21087
|
+
CODEBUDDY_MAX_ATTESTATION_VALIDITY_MS = 24 * 60 * 60 * 1e3;
|
|
21088
|
+
CODEBUDDY_MARKETPLACE_NAME = "artifact-skill-set";
|
|
21089
|
+
CODEBUDDY_MARKETPLACE_SOURCE = "https://github.com/ifoohoo/artifact-skill-set";
|
|
21090
|
+
CODEBUDDY_PLUGIN_MANIFEST_RELATIVE = join7(".codebuddy-plugin", "plugin.json");
|
|
21091
|
+
CODEBUDDY_INSTALL_CHANNELS = /* @__PURE__ */ new Set(["desktop", "cli"]);
|
|
21092
|
+
CODEBUDDY_DESKTOP_HOME_DIR = ".workbuddy";
|
|
21093
|
+
CODEBUDDY_CLI_STATE_DIR = ".codebuddy";
|
|
21094
|
+
__name(resolveCodeBuddyBoundPlanDigest, "resolveCodeBuddyBoundPlanDigest");
|
|
21095
|
+
__name(codebuddyAuthorityDir, "codebuddyAuthorityDir");
|
|
21096
|
+
__name(codebuddyCliHome, "codebuddyCliHome");
|
|
21097
|
+
__name(codebuddyCliInstallRoot, "codebuddyCliInstallRoot");
|
|
21098
|
+
__name(codebuddyDesktopTailSegments, "codebuddyDesktopTailSegments");
|
|
21099
|
+
__name(matchesDesktopLayout, "matchesDesktopLayout");
|
|
21100
|
+
__name(buildCodeBuddyManualInstructions, "buildCodeBuddyManualInstructions");
|
|
21101
|
+
__name(readCodeBuddyManifest, "readCodeBuddyManifest");
|
|
21102
|
+
__name(validateCodeBuddyAttestation, "validateCodeBuddyAttestation");
|
|
21103
|
+
__name(executeCodeBuddyManualRequirement, "executeCodeBuddyManualRequirement");
|
|
21104
|
+
}
|
|
21105
|
+
});
|
|
21106
|
+
|
|
20710
21107
|
// src/platforms/registry.mjs
|
|
20711
|
-
import { join as
|
|
21108
|
+
import { join as join8 } from "node:path";
|
|
20712
21109
|
function claudeParseListOutput(listOutput, pluginId) {
|
|
20713
21110
|
if (!Array.isArray(listOutput)) {
|
|
20714
21111
|
return { ok: false, error: "Claude plugin list did not return an array" };
|
|
@@ -20805,6 +21202,9 @@ function assertRegistry(registry = PLATFORMS) {
|
|
|
20805
21202
|
if (!VALID_SOURCE_FORMS.has(platform.marketplaceSourceForm)) {
|
|
20806
21203
|
throw new Error(`platform registry: ${label} has illegal marketplaceSourceForm "${platform.marketplaceSourceForm}"`);
|
|
20807
21204
|
}
|
|
21205
|
+
if (!VALID_MARKETPLACE_REF_FORMS.has(platform.marketplaceRefForm)) {
|
|
21206
|
+
throw new Error(`platform registry: ${label} has illegal marketplaceRefForm "${platform.marketplaceRefForm}"`);
|
|
21207
|
+
}
|
|
20808
21208
|
if (!Array.isArray(platform.knownHostArtifacts)) {
|
|
20809
21209
|
throw new Error(`platform registry: ${label} knownHostArtifacts must be an array`);
|
|
20810
21210
|
}
|
|
@@ -20855,10 +21255,11 @@ function assertRegistry(registry = PLATFORMS) {
|
|
|
20855
21255
|
}
|
|
20856
21256
|
}
|
|
20857
21257
|
}
|
|
20858
|
-
var CLAUDE, CODEX, KIMI, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING;
|
|
21258
|
+
var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING;
|
|
20859
21259
|
var init_registry = __esm({
|
|
20860
21260
|
async "src/platforms/registry.mjs"() {
|
|
20861
21261
|
await init_kimi();
|
|
21262
|
+
init_codebuddy();
|
|
20862
21263
|
__name(claudeParseListOutput, "claudeParseListOutput");
|
|
20863
21264
|
__name(claudeExtractInstallPath, "claudeExtractInstallPath");
|
|
20864
21265
|
__name(claudeExtractListIdentity, "claudeExtractListIdentity");
|
|
@@ -20888,7 +21289,7 @@ var init_registry = __esm({
|
|
|
20888
21289
|
marketplaceAddOutput: null,
|
|
20889
21290
|
pluginInstallOutput: null
|
|
20890
21291
|
}),
|
|
20891
|
-
isolationEnv: /* @__PURE__ */ __name((home) => ({ HOME: home, CLAUDE_CONFIG_DIR:
|
|
21292
|
+
isolationEnv: /* @__PURE__ */ __name((home) => ({ HOME: home, CLAUDE_CONFIG_DIR: join8(home, ".claude") }), "isolationEnv"),
|
|
20892
21293
|
// execute pre-creates the claude config dir under the isolated HOME.
|
|
20893
21294
|
isolationSubdirs: Object.freeze([".claude"]),
|
|
20894
21295
|
manifestPaths: Object.freeze({
|
|
@@ -20899,6 +21300,10 @@ var init_registry = __esm({
|
|
|
20899
21300
|
// Claude carries the authoritative version in the marketplace entry: the
|
|
20900
21301
|
// preflight binds entry.version to the action version.
|
|
20901
21302
|
marketplaceEntryCarriesVersion: true,
|
|
21303
|
+
// External marketplace form: `claude plugin marketplace add repo@<ref>` can
|
|
21304
|
+
// only pin a branch/tag NAME (a bare commit sha fails to clone and the
|
|
21305
|
+
// resolved sha is not recorded locally) — name-form weak freeze.
|
|
21306
|
+
marketplaceRefForm: "name",
|
|
20902
21307
|
knownHostArtifacts: Object.freeze([".in_use"]),
|
|
20903
21308
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
20904
21309
|
skillRendering: Object.freeze({ mode: "verbatim", preamble: null, placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
@@ -20947,6 +21352,9 @@ var init_registry = __esm({
|
|
|
20947
21352
|
// Codex keeps the authoritative version in .codex-plugin/plugin.json; the
|
|
20948
21353
|
// marketplace entry version is not bound to the action version.
|
|
20949
21354
|
marketplaceEntryCarriesVersion: false,
|
|
21355
|
+
// External marketplace form: `codex plugin marketplace add repo --ref <ref>`
|
|
21356
|
+
// accepts a bare commit sha — sha-form strong freeze.
|
|
21357
|
+
marketplaceRefForm: "sha",
|
|
20950
21358
|
knownHostArtifacts: Object.freeze([".git", ".codex-plugin/migrated-command-skills"]),
|
|
20951
21359
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
20952
21360
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "codex", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
@@ -20993,6 +21401,9 @@ var init_registry = __esm({
|
|
|
20993
21401
|
// apply (null = N/A, never consulted: kimi preflight reads its manifest via
|
|
20994
21402
|
// strategy.readManifest).
|
|
20995
21403
|
marketplaceEntryCarriesVersion: null,
|
|
21404
|
+
// kimi has no marketplace add at all, so the marketplace ref form does not
|
|
21405
|
+
// apply (null = N/A, never consulted).
|
|
21406
|
+
marketplaceRefForm: null,
|
|
20996
21407
|
knownHostArtifacts: Object.freeze([".git"]),
|
|
20997
21408
|
schemaRequiredFields: Object.freeze(["plugin", "entrySkill"]),
|
|
20998
21409
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "kimi", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
@@ -21013,10 +21424,72 @@ var init_registry = __esm({
|
|
|
21013
21424
|
readManifest: readKimiManifest
|
|
21014
21425
|
})
|
|
21015
21426
|
});
|
|
21016
|
-
|
|
21017
|
-
|
|
21018
|
-
|
|
21427
|
+
CODEBUDDY = Object.freeze({
|
|
21428
|
+
id: "codebuddy",
|
|
21429
|
+
distributionType: "codebuddy-plugin",
|
|
21430
|
+
actionType: "codebuddy-marketplace-install",
|
|
21431
|
+
adapter: "plugin-marketplace",
|
|
21432
|
+
automatable: false,
|
|
21433
|
+
cli: null,
|
|
21434
|
+
jsonProtocol: Object.freeze({
|
|
21435
|
+
listOutput: null,
|
|
21436
|
+
installPathSource: null,
|
|
21437
|
+
marketplaceAddOutput: null,
|
|
21438
|
+
pluginInstallOutput: null
|
|
21439
|
+
}),
|
|
21440
|
+
// The closed loop never execs the codebuddy CLI; HOME is the only isolation
|
|
21441
|
+
// input and exists solely so the attestation's isolated cli-channel home has
|
|
21442
|
+
// a base. No unverified host env vars are fabricated.
|
|
21443
|
+
isolationEnv: /* @__PURE__ */ __name((home) => ({ HOME: home }), "isolationEnv"),
|
|
21444
|
+
// codebuddy never execs a CLI; its isolated cli home is created by the
|
|
21445
|
+
// manual-requirement strategy under the attestation authority.
|
|
21446
|
+
isolationSubdirs: Object.freeze([]),
|
|
21447
|
+
manifestPaths: Object.freeze({
|
|
21448
|
+
// Single authoritative manifest (no precedence chain, unlike kimi).
|
|
21449
|
+
plugin: ".codebuddy-plugin/plugin.json",
|
|
21450
|
+
marketplace: null
|
|
21451
|
+
}),
|
|
21452
|
+
marketplaceSourceForm: null,
|
|
21453
|
+
// codebuddy installs from a unified marketplace but carries no marketplace
|
|
21454
|
+
// identity in the action (the marketplace is a fixed constant in
|
|
21455
|
+
// ./codebuddy.mjs); the entry-version binding does not apply (null = N/A).
|
|
21456
|
+
marketplaceEntryCarriesVersion: null,
|
|
21457
|
+
// codebuddy has no marketplace add that can pin a frozen ref (attestation
|
|
21458
|
+
// loop instead), so the marketplace ref form does not apply (null = N/A).
|
|
21459
|
+
marketplaceRefForm: null,
|
|
21460
|
+
knownHostArtifacts: Object.freeze([".git"]),
|
|
21461
|
+
schemaRequiredFields: Object.freeze(["plugin", "entrySkill"]),
|
|
21462
|
+
// Declarative rendering intent (the build-adapters producer keys on
|
|
21463
|
+
// buildAdapter.name = 'workbuddy'): pure ${CLAUDE_PLUGIN_ROOT} ->
|
|
21464
|
+
// ${CODEBUDDY_PLUGIN_ROOT} substitution, no entry-resolution preamble
|
|
21465
|
+
// (CodeBuddy expands the variable inline in skill content).
|
|
21466
|
+
skillRendering: Object.freeze({ mode: "substitute", preamble: null, placeholder: "${CODEBUDDY_PLUGIN_ROOT}" }),
|
|
21467
|
+
buildAdapter: Object.freeze({
|
|
21468
|
+
// Build adapter keeps the historical `workbuddy` directory name; the fields
|
|
21469
|
+
// are byte-for-byte the legacy BUILD_ONLY workbuddy entry so the generated
|
|
21470
|
+
// adapters/workbuddy/ tree is unchanged.
|
|
21471
|
+
name: "workbuddy",
|
|
21472
|
+
pluginDirName: ".codebuddy-plugin",
|
|
21473
|
+
templateFileName: "plugin.json",
|
|
21474
|
+
marketplaceFileName: null,
|
|
21475
|
+
hasMarketplace: false
|
|
21476
|
+
}),
|
|
21477
|
+
strategy: Object.freeze({
|
|
21478
|
+
parseListOutput: null,
|
|
21479
|
+
extractInstallPath: null,
|
|
21480
|
+
extractListIdentity: null,
|
|
21481
|
+
crossValidateListEntry: null,
|
|
21482
|
+
// codebuddy's side-effecting manual-requirement builder and manifest reader
|
|
21483
|
+
// live in ./codebuddy.mjs (per-platform-module option, mirroring kimi).
|
|
21484
|
+
buildManualRequirement: executeCodeBuddyManualRequirement,
|
|
21485
|
+
readManifest: readCodeBuddyManifest
|
|
21486
|
+
})
|
|
21487
|
+
});
|
|
21488
|
+
PLATFORMS = Object.freeze([CLAUDE, CODEX, KIMI, CODEBUDDY]);
|
|
21489
|
+
VALID_DISTRIBUTION_TYPES = /* @__PURE__ */ new Set(["claude-plugin", "codex-plugin", "kimi-plugin", "codebuddy-plugin"]);
|
|
21490
|
+
VALID_ACTION_TYPES = /* @__PURE__ */ new Set(["claude-marketplace-install", "codex-marketplace-install", "kimi-marketplace-install", "codebuddy-marketplace-install"]);
|
|
21019
21491
|
VALID_SOURCE_FORMS = /* @__PURE__ */ new Set(["string", "local-path-object", null]);
|
|
21492
|
+
VALID_MARKETPLACE_REF_FORMS = /* @__PURE__ */ new Set(["sha", "name", null]);
|
|
21020
21493
|
VALID_LIST_OUTPUTS = /* @__PURE__ */ new Set(["array", "installed-object", null]);
|
|
21021
21494
|
VALID_CLI_OUTPUTS = /* @__PURE__ */ new Set(["json", null]);
|
|
21022
21495
|
VALID_ENTRY_VERSION_BINDING = /* @__PURE__ */ new Set([true, false, null]);
|
|
@@ -21027,17 +21500,28 @@ var init_registry = __esm({
|
|
|
21027
21500
|
});
|
|
21028
21501
|
|
|
21029
21502
|
// src/core/plan.mjs
|
|
21030
|
-
|
|
21031
|
-
|
|
21503
|
+
var plan_exports = {};
|
|
21504
|
+
__export(plan_exports, {
|
|
21505
|
+
assertAuthorityFileTarget: () => assertAuthorityFileTarget,
|
|
21506
|
+
assertImmutablePlanAuthority: () => assertImmutablePlanAuthority,
|
|
21507
|
+
computePlanDigest: () => computePlanDigest,
|
|
21508
|
+
prepareAuthorityDirectory: () => prepareAuthorityDirectory,
|
|
21509
|
+
validatePlan: () => validatePlan,
|
|
21510
|
+
validatePlanActionCompleteness: () => validatePlanActionCompleteness,
|
|
21511
|
+
writePlanAtomic: () => writePlanAtomic,
|
|
21512
|
+
writePlanImmutable: () => writePlanImmutable
|
|
21513
|
+
});
|
|
21514
|
+
import { readFile as readFile9, writeFile as writeFile6, rename as rename2, mkdir as mkdir9, open as open5, link, unlink as unlink2, lstat as lstat7 } from "node:fs/promises";
|
|
21515
|
+
import { basename as basename3, dirname as dirname5, join as join9, resolve as resolve13, parse, sep as sep2 } from "node:path";
|
|
21032
21516
|
async function assertNoSymlinkAncestors(directory) {
|
|
21033
|
-
const absolute =
|
|
21517
|
+
const absolute = resolve13(directory);
|
|
21034
21518
|
const parsed = parse(absolute);
|
|
21035
21519
|
const segments = absolute.slice(parsed.root.length).split(sep2).filter(Boolean);
|
|
21036
21520
|
const releaseIndex = segments.lastIndexOf(".release-skill");
|
|
21037
21521
|
const firstChecked = releaseIndex >= 0 ? releaseIndex : Math.max(0, segments.length - 1);
|
|
21038
|
-
let current =
|
|
21522
|
+
let current = join9(parsed.root, ...segments.slice(0, firstChecked));
|
|
21039
21523
|
for (const segment of segments.slice(firstChecked)) {
|
|
21040
|
-
current =
|
|
21524
|
+
current = join9(current, segment);
|
|
21041
21525
|
let stat9;
|
|
21042
21526
|
try {
|
|
21043
21527
|
stat9 = await lstat7(current);
|
|
@@ -21055,14 +21539,14 @@ async function assertNoSymlinkAncestors(directory) {
|
|
|
21055
21539
|
}
|
|
21056
21540
|
}
|
|
21057
21541
|
async function prepareAuthorityDirectory(directory) {
|
|
21058
|
-
const absolute =
|
|
21542
|
+
const absolute = resolve13(directory);
|
|
21059
21543
|
await assertNoSymlinkAncestors(absolute);
|
|
21060
|
-
await
|
|
21544
|
+
await mkdir9(absolute, { recursive: true });
|
|
21061
21545
|
await assertNoSymlinkAncestors(absolute);
|
|
21062
21546
|
return absolute;
|
|
21063
21547
|
}
|
|
21064
21548
|
async function assertAuthorityFileTarget(filePath) {
|
|
21065
|
-
const absolute =
|
|
21549
|
+
const absolute = resolve13(filePath);
|
|
21066
21550
|
await prepareAuthorityDirectory(dirname5(absolute));
|
|
21067
21551
|
try {
|
|
21068
21552
|
const stat9 = await lstat7(absolute);
|
|
@@ -21081,7 +21565,7 @@ async function assertAuthorityFileTarget(filePath) {
|
|
|
21081
21565
|
function assertImmutablePlanAuthority(planPath, plan) {
|
|
21082
21566
|
if (!plan?.production) return;
|
|
21083
21567
|
const digest = computePlanDigest(plan);
|
|
21084
|
-
const absolute =
|
|
21568
|
+
const absolute = resolve13(planPath);
|
|
21085
21569
|
if (basename3(dirname5(absolute)) !== "plans" || basename3(absolute) !== `${digest}.json`) {
|
|
21086
21570
|
throw new ReleaseError(
|
|
21087
21571
|
GATE_FAILED,
|
|
@@ -21173,7 +21657,7 @@ async function writePlanImmutable(planPath, plan) {
|
|
|
21173
21657
|
const dir = dirname5(planPath);
|
|
21174
21658
|
await prepareAuthorityDirectory(dir);
|
|
21175
21659
|
await assertAuthorityFileTarget(planPath);
|
|
21176
|
-
const tmpPath =
|
|
21660
|
+
const tmpPath = join9(dir, `.release-plan-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
21177
21661
|
const handle = await open5(tmpPath, "wx", 384);
|
|
21178
21662
|
try {
|
|
21179
21663
|
await handle.writeFile(json, "utf8");
|
|
@@ -21185,7 +21669,7 @@ async function writePlanImmutable(planPath, plan) {
|
|
|
21185
21669
|
await link(tmpPath, planPath);
|
|
21186
21670
|
} catch (error) {
|
|
21187
21671
|
if (error.code !== "EEXIST") throw error;
|
|
21188
|
-
const existing = await
|
|
21672
|
+
const existing = await readFile9(planPath, "utf8");
|
|
21189
21673
|
if (existing !== json) {
|
|
21190
21674
|
if (plan.planVersion === 2) {
|
|
21191
21675
|
let existingPlan = null;
|
|
@@ -21527,6 +22011,12 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
21527
22011
|
`unit "${unitId}", action "${action.id}": status is "${action.status ?? "(missing)"}", expected "PENDING"`
|
|
21528
22012
|
);
|
|
21529
22013
|
}
|
|
22014
|
+
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
22015
|
+
if (externalMarketplace && platform.marketplaceRefForm === null) {
|
|
22016
|
+
failures.push(
|
|
22017
|
+
`unit "${unitId}", action "${action.id}": ${platform.distributionType} distribution declares marketplaceRepo but the platform has no marketplace add capability`
|
|
22018
|
+
);
|
|
22019
|
+
}
|
|
21530
22020
|
_checkRequired(action, "parameters.consumer", action.parameters?.consumer, platform.id, unitId, failures);
|
|
21531
22021
|
_checkRequired(action, "parameters.plugin", action.parameters?.plugin, plugin, unitId, failures);
|
|
21532
22022
|
if (requiresMarketplace) {
|
|
@@ -21536,12 +22026,44 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
21536
22026
|
`unit "${unitId}", action "${action.id}": parameters.marketplace is "${action.parameters.marketplace}", expected optional legacy value "${marketplace}"`
|
|
21537
22027
|
);
|
|
21538
22028
|
}
|
|
21539
|
-
|
|
22029
|
+
if (externalMarketplace) {
|
|
22030
|
+
_checkRequired(action, "parameters.repo", action.parameters?.repo, dist.marketplaceRepo, unitId, failures);
|
|
22031
|
+
_checkRequired(action, "parameters.marketplaceLocation", action.parameters?.marketplaceLocation, "external", unitId, failures);
|
|
22032
|
+
} else {
|
|
22033
|
+
_checkRequired(action, "parameters.repo", action.parameters?.repo, publicRepo, unitId, failures);
|
|
22034
|
+
}
|
|
21540
22035
|
_checkRequired(action, "parameters.version", action.parameters?.version, targetVersion, unitId, failures);
|
|
21541
22036
|
_checkRequired(action, "parameters.entrySkill", action.parameters?.entrySkill, entrySkill, unitId, failures);
|
|
21542
22037
|
if (production) {
|
|
21543
22038
|
_checkRequired(action, "parameters.snapshotPath", action.parameters?.snapshotPath, frozen?.path, unitId, failures);
|
|
21544
|
-
|
|
22039
|
+
if (externalMarketplace) {
|
|
22040
|
+
const ref = action.parameters?.ref;
|
|
22041
|
+
if (ref === void 0 || ref === null) {
|
|
22042
|
+
failures.push(
|
|
22043
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is missing, expected the frozen external marketplace add-ref`
|
|
22044
|
+
);
|
|
22045
|
+
} else if (!_isStructurallySafeExternalRef(ref)) {
|
|
22046
|
+
failures.push(
|
|
22047
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is not a structurally safe ref: ${JSON.stringify(ref)}`
|
|
22048
|
+
);
|
|
22049
|
+
} else if (ref !== action.expected?.ref) {
|
|
22050
|
+
failures.push(
|
|
22051
|
+
`unit "${unitId}", action "${action.id}": parameters.ref is "${ref}", expected self-consistent expected.ref "${action.expected?.ref}"`
|
|
22052
|
+
);
|
|
22053
|
+
}
|
|
22054
|
+
const sha = action.parameters?.marketplaceCommitSha;
|
|
22055
|
+
if (sha === void 0 || sha === null) {
|
|
22056
|
+
failures.push(
|
|
22057
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplaceCommitSha is missing, expected a frozen 40-hex commit sha`
|
|
22058
|
+
);
|
|
22059
|
+
} else if (typeof sha !== "string" || !EXTERNAL_MARKETPLACE_SHA_RE.test(sha)) {
|
|
22060
|
+
failures.push(
|
|
22061
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplaceCommitSha must be a 40-hex commit sha, got: ${JSON.stringify(sha)}`
|
|
22062
|
+
);
|
|
22063
|
+
}
|
|
22064
|
+
} else {
|
|
22065
|
+
_checkRequired(action, "parameters.ref", action.parameters?.ref, expectedTag, unitId, failures);
|
|
22066
|
+
}
|
|
21545
22067
|
_checkRequired(action, "parameters.manifestDigest", action.parameters?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
21546
22068
|
}
|
|
21547
22069
|
{
|
|
@@ -21573,8 +22095,15 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
21573
22095
|
_checkRequired(action, "expected.entrySkill", action.expected?.entrySkill, entrySkill, unitId, failures);
|
|
21574
22096
|
if (production) {
|
|
21575
22097
|
_checkRequired(action, "expected.consumer", action.expected?.consumer, platform.id, unitId, failures);
|
|
21576
|
-
|
|
21577
|
-
|
|
22098
|
+
if (externalMarketplace) {
|
|
22099
|
+
_checkRequired(action, "expected.repo", action.expected?.repo, dist.marketplaceRepo, unitId, failures);
|
|
22100
|
+
_checkRequired(action, "expected.ref", action.expected?.ref, action.parameters?.ref, unitId, failures);
|
|
22101
|
+
_checkRequired(action, "expected.marketplaceLocation", action.expected?.marketplaceLocation, "external", unitId, failures);
|
|
22102
|
+
_checkRequired(action, "expected.marketplaceCommitSha", action.expected?.marketplaceCommitSha, action.parameters?.marketplaceCommitSha, unitId, failures);
|
|
22103
|
+
} else {
|
|
22104
|
+
_checkRequired(action, "expected.repo", action.expected?.repo, publicRepo, unitId, failures);
|
|
22105
|
+
_checkRequired(action, "expected.ref", action.expected?.ref, expectedTag, unitId, failures);
|
|
22106
|
+
}
|
|
21578
22107
|
_checkRequired(action, "expected.entrySkillFound", action.expected?.entrySkillFound, true, unitId, failures);
|
|
21579
22108
|
_checkRequired(action, "expected.manifestDigest", action.expected?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
21580
22109
|
}
|
|
@@ -21654,7 +22183,22 @@ function _checkRequired(action, fieldPath, actual, expected, unitId, failures) {
|
|
|
21654
22183
|
);
|
|
21655
22184
|
}
|
|
21656
22185
|
}
|
|
21657
|
-
|
|
22186
|
+
function _isStructurallySafeExternalRef(ref) {
|
|
22187
|
+
if (typeof ref !== "string" || ref.length === 0) return false;
|
|
22188
|
+
if (/[\x00-\x1f]/.test(ref)) return false;
|
|
22189
|
+
if (ref.startsWith("-")) return false;
|
|
22190
|
+
if (ref.includes("\\")) return false;
|
|
22191
|
+
if (ref.includes("//")) return false;
|
|
22192
|
+
if (ref.startsWith("/") || ref.endsWith("/")) return false;
|
|
22193
|
+
if (ref.endsWith(".")) return false;
|
|
22194
|
+
if (ref.endsWith(".lock")) return false;
|
|
22195
|
+
if (ref.includes("@{")) return false;
|
|
22196
|
+
if (ref === "@") return false;
|
|
22197
|
+
if (ref.includes("..")) return false;
|
|
22198
|
+
if (/[;|&`$(){}]/.test(ref)) return false;
|
|
22199
|
+
return /^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(ref);
|
|
22200
|
+
}
|
|
22201
|
+
var import_ajv3, import_ajv_formats3, RELEASE_PLAN_SCHEMA, ajv3, validatePlanSchema, CANONICAL_COMMIT_TIMESTAMP_RE, REQUIRED_ACTION_TYPES, EXTERNAL_MARKETPLACE_SHA_RE;
|
|
21658
22202
|
var init_plan = __esm({
|
|
21659
22203
|
async "src/core/plan.mjs"() {
|
|
21660
22204
|
import_ajv3 = __toESM(require_ajv(), 1);
|
|
@@ -21683,13 +22227,15 @@ var init_plan = __esm({
|
|
|
21683
22227
|
REQUIRED_ACTION_TYPES = ["push-snapshot", "create-tag", "github-release"];
|
|
21684
22228
|
__name(validatePlanActionCompleteness, "validatePlanActionCompleteness");
|
|
21685
22229
|
__name(_checkRequired, "_checkRequired");
|
|
22230
|
+
EXTERNAL_MARKETPLACE_SHA_RE = /^[0-9a-f]{40}$/;
|
|
22231
|
+
__name(_isStructurallySafeExternalRef, "_isStructurallySafeExternalRef");
|
|
21686
22232
|
}
|
|
21687
22233
|
});
|
|
21688
22234
|
|
|
21689
22235
|
// src/snapshot/public-map.mjs
|
|
21690
|
-
import { lstat as lstat8, readFile as
|
|
22236
|
+
import { lstat as lstat8, readFile as readFile10, mkdir as mkdir10, readdir as readdir6, realpath as realpath8, chmod as fsChmod } from "node:fs/promises";
|
|
21691
22237
|
import { open as fsOpen } from "node:fs/promises";
|
|
21692
|
-
import { relative as
|
|
22238
|
+
import { relative as relative11, resolve as resolve14, dirname as dirname6, sep as pathSep, isAbsolute as isAbsolute10 } from "node:path";
|
|
21693
22239
|
import { posix } from "node:path";
|
|
21694
22240
|
import { constants as fsConstants3 } from "node:fs";
|
|
21695
22241
|
import { createHash as createHash7 } from "node:crypto";
|
|
@@ -21698,14 +22244,14 @@ function _isContainedWith(relativeFn, isAbsoluteFn, root, candidate, relPathSep
|
|
|
21698
22244
|
return rel !== "" && rel !== ".." && !rel.startsWith(`..${relPathSep}`) && !isAbsoluteFn(rel);
|
|
21699
22245
|
}
|
|
21700
22246
|
function isContained(root, candidate) {
|
|
21701
|
-
return _isContainedWith(
|
|
22247
|
+
return _isContainedWith(relative11, isAbsolute10, root, candidate);
|
|
21702
22248
|
}
|
|
21703
22249
|
async function assertNoAncestorSymlinks(root, filePath, fs = { lstat: lstat8 }) {
|
|
21704
|
-
const rel =
|
|
22250
|
+
const rel = relative11(root, filePath);
|
|
21705
22251
|
const segments = rel.split(/[/\\]/);
|
|
21706
22252
|
let current = root;
|
|
21707
22253
|
for (const segment of segments) {
|
|
21708
|
-
current =
|
|
22254
|
+
current = resolve14(current, segment);
|
|
21709
22255
|
try {
|
|
21710
22256
|
const st = await fs.lstat(current, { stage: "source-ancestor" });
|
|
21711
22257
|
if (st.isSymbolicLink()) {
|
|
@@ -21762,11 +22308,11 @@ async function assertOutputAncestorsNoFollow(effectiveOutputDir, fs = { lstat: l
|
|
|
21762
22308
|
}
|
|
21763
22309
|
}
|
|
21764
22310
|
async function assertDestAncestorsNoFollow(realOutputRoot, destPath, fs = { lstat: lstat8 }) {
|
|
21765
|
-
const relDest =
|
|
22311
|
+
const relDest = relative11(realOutputRoot, destPath);
|
|
21766
22312
|
const segments = relDest.split(pathSep).filter(Boolean);
|
|
21767
22313
|
let current = realOutputRoot;
|
|
21768
22314
|
for (const segment of segments) {
|
|
21769
|
-
current =
|
|
22315
|
+
current = resolve14(current, segment);
|
|
21770
22316
|
try {
|
|
21771
22317
|
const st = await fs.lstat(current, { stage: "dest-ancestor" });
|
|
21772
22318
|
if (st.isSymbolicLink()) {
|
|
@@ -21922,9 +22468,9 @@ async function buildPublicStaging({
|
|
|
21922
22468
|
const fs = {
|
|
21923
22469
|
lstat: _fsOps.lstat ? (p, ctx) => _fsOps.lstat({ operation: "lstat", path: p, ...ctx }) : lstat8,
|
|
21924
22470
|
realpath: _fsOps.realpath ? (p, ctx) => _fsOps.realpath({ operation: "realpath", path: p, ...ctx }) : realpath8,
|
|
21925
|
-
readFile: _fsOps.readFile ? (p, ctx) => _fsOps.readFile({ operation: "readFile", path: p, ...ctx }) :
|
|
22471
|
+
readFile: _fsOps.readFile ? (p, ctx) => _fsOps.readFile({ operation: "readFile", path: p, ...ctx }) : readFile10,
|
|
21926
22472
|
open: _fsOps.open ? (p, flags, mode, ctx) => _fsOps.open({ operation: "open", path: p, flags, mode, ...ctx }) : fsOpen,
|
|
21927
|
-
mkdir: _fsOps.mkdir ? (p, opts, ctx) => _fsOps.mkdir({ operation: "mkdir", path: p, opts, ...ctx }) :
|
|
22473
|
+
mkdir: _fsOps.mkdir ? (p, opts, ctx) => _fsOps.mkdir({ operation: "mkdir", path: p, opts, ...ctx }) : mkdir10,
|
|
21928
22474
|
readdir: _fsOps.readdir ? (p, ctx) => _fsOps.readdir({ operation: "readdir", path: p, ...ctx }) : readdir6,
|
|
21929
22475
|
chmod: _fsOps.chmod ? (p, mode, ctx) => _fsOps.chmod({ operation: "chmod", path: p, mode, ...ctx }) : fsChmod
|
|
21930
22476
|
};
|
|
@@ -21957,7 +22503,7 @@ async function buildPublicStaging({
|
|
|
21957
22503
|
{ count: mappings.length, limit: MAX_MAPPINGS }
|
|
21958
22504
|
);
|
|
21959
22505
|
}
|
|
21960
|
-
const unitRootLexical =
|
|
22506
|
+
const unitRootLexical = resolve14(sourceRoot, unit.source);
|
|
21961
22507
|
let realUnitRoot;
|
|
21962
22508
|
try {
|
|
21963
22509
|
realUnitRoot = await fs.realpath(unitRootLexical, { stage: "unit-root-realpath" });
|
|
@@ -21970,14 +22516,14 @@ async function buildPublicStaging({
|
|
|
21970
22516
|
{ sourceRoot, unitSource: unit.source, cause: code }
|
|
21971
22517
|
);
|
|
21972
22518
|
}
|
|
21973
|
-
const effectiveOutputDir =
|
|
21974
|
-
outputDir ??
|
|
22519
|
+
const effectiveOutputDir = resolve14(
|
|
22520
|
+
outputDir ?? resolve14(sourceRoot, ".release-skill", "staging")
|
|
21975
22521
|
);
|
|
21976
22522
|
const preflightRecords = [];
|
|
21977
22523
|
const requiredTargetSet = new Set(unit.requiredPublicFiles ?? []);
|
|
21978
22524
|
for (const mapping of mappings) {
|
|
21979
|
-
const srcPath =
|
|
21980
|
-
const destPath =
|
|
22525
|
+
const srcPath = resolve14(sourceRoot, mapping.from);
|
|
22526
|
+
const destPath = resolve14(effectiveOutputDir, mapping.to);
|
|
21981
22527
|
if (srcPath.length > MAX_PATH_LENGTH || destPath.length > MAX_PATH_LENGTH) {
|
|
21982
22528
|
preflightRecords.push({
|
|
21983
22529
|
ok: false,
|
|
@@ -22464,11 +23010,11 @@ async function buildPublicStaging({
|
|
|
22464
23010
|
);
|
|
22465
23011
|
}
|
|
22466
23012
|
const destDir = dirname6(destPath);
|
|
22467
|
-
const relDest =
|
|
23013
|
+
const relDest = relative11(realOutputRoot, destDir);
|
|
22468
23014
|
const destSegments = relDest.split(pathSep).filter(Boolean);
|
|
22469
23015
|
let accumulatedPath = realOutputRoot;
|
|
22470
23016
|
for (const seg of destSegments) {
|
|
22471
|
-
accumulatedPath =
|
|
23017
|
+
accumulatedPath = resolve14(accumulatedPath, seg);
|
|
22472
23018
|
try {
|
|
22473
23019
|
const segStat = await fs.lstat(accumulatedPath, { stage: "dest-ancestor-pre-mkdir" });
|
|
22474
23020
|
if (segStat.isSymbolicLink()) {
|
|
@@ -22767,8 +23313,8 @@ var init_public_map = __esm({
|
|
|
22767
23313
|
});
|
|
22768
23314
|
|
|
22769
23315
|
// src/snapshot/scan.mjs
|
|
22770
|
-
import { readFile as
|
|
22771
|
-
import { join as
|
|
23316
|
+
import { readFile as readFile11, readdir as readdir7, stat as stat3 } from "node:fs/promises";
|
|
23317
|
+
import { join as join10, relative as relative12, extname, posix as posix2, win32 } from "node:path";
|
|
22772
23318
|
import { createHash as createHash8 } from "node:crypto";
|
|
22773
23319
|
async function collectFiles(dir, base = dir) {
|
|
22774
23320
|
const results = [];
|
|
@@ -22780,12 +23326,12 @@ async function collectFiles(dir, base = dir) {
|
|
|
22780
23326
|
}
|
|
22781
23327
|
for (const entry of entries) {
|
|
22782
23328
|
if (entry.name === ".git") continue;
|
|
22783
|
-
const abs =
|
|
23329
|
+
const abs = join10(dir, entry.name);
|
|
22784
23330
|
if (entry.isDirectory()) {
|
|
22785
23331
|
const sub = await collectFiles(abs, base);
|
|
22786
23332
|
results.push(...sub);
|
|
22787
23333
|
} else if (entry.isFile()) {
|
|
22788
|
-
results.push(
|
|
23334
|
+
results.push(relative12(base, abs));
|
|
22789
23335
|
}
|
|
22790
23336
|
}
|
|
22791
23337
|
return results;
|
|
@@ -22836,7 +23382,7 @@ async function scanFile(relPath, absPath, forbiddenPaths, forbiddenContentPatter
|
|
|
22836
23382
|
}
|
|
22837
23383
|
let content;
|
|
22838
23384
|
try {
|
|
22839
|
-
content = await
|
|
23385
|
+
content = await readFile11(absPath, "utf8");
|
|
22840
23386
|
} catch {
|
|
22841
23387
|
return findings;
|
|
22842
23388
|
}
|
|
@@ -22905,10 +23451,10 @@ async function scanFile(relPath, absPath, forbiddenPaths, forbiddenContentPatter
|
|
|
22905
23451
|
}
|
|
22906
23452
|
async function scanForStaleDist(snapshotDir) {
|
|
22907
23453
|
const findings = [];
|
|
22908
|
-
const manifestPath =
|
|
23454
|
+
const manifestPath = join10(snapshotDir, "dist", "manifest.json");
|
|
22909
23455
|
let manifest;
|
|
22910
23456
|
try {
|
|
22911
|
-
const raw = await
|
|
23457
|
+
const raw = await readFile11(manifestPath, "utf8");
|
|
22912
23458
|
manifest = JSON.parse(raw);
|
|
22913
23459
|
} catch {
|
|
22914
23460
|
return findings;
|
|
@@ -22916,13 +23462,13 @@ async function scanForStaleDist(snapshotDir) {
|
|
|
22916
23462
|
if (!manifest.files || typeof manifest.files !== "object") {
|
|
22917
23463
|
return findings;
|
|
22918
23464
|
}
|
|
22919
|
-
const distDir =
|
|
23465
|
+
const distDir = join10(snapshotDir, "dist");
|
|
22920
23466
|
for (const [fileRel, expectedHash] of Object.entries(manifest.files)) {
|
|
22921
23467
|
if (typeof expectedHash !== "string") continue;
|
|
22922
|
-
const fileAbs =
|
|
23468
|
+
const fileAbs = join10(distDir, fileRel);
|
|
22923
23469
|
let actualContent;
|
|
22924
23470
|
try {
|
|
22925
|
-
actualContent = await
|
|
23471
|
+
actualContent = await readFile11(fileAbs);
|
|
22926
23472
|
} catch {
|
|
22927
23473
|
findings.push({
|
|
22928
23474
|
kind: STALE_BUILD_ARTIFACT,
|
|
@@ -22963,7 +23509,7 @@ async function scanSnapshot({ snapshotDir, policy = {} } = {}) {
|
|
|
22963
23509
|
const relFiles = await collectFiles(snapshotDir);
|
|
22964
23510
|
const seenKinds = /* @__PURE__ */ new Set();
|
|
22965
23511
|
for (const relPath of relFiles) {
|
|
22966
|
-
const absPath =
|
|
23512
|
+
const absPath = join10(snapshotDir, relPath);
|
|
22967
23513
|
const normRel = relPath.replaceAll(win32.sep, posix2.sep);
|
|
22968
23514
|
if (await isBinaryFile(relPath, absPath)) continue;
|
|
22969
23515
|
const fileFindings = await scanFile(normRel, absPath, forbiddenPaths, forbiddenContentPatterns, seenKinds);
|
|
@@ -23054,7 +23600,7 @@ var init_scan = __esm({
|
|
|
23054
23600
|
});
|
|
23055
23601
|
|
|
23056
23602
|
// src/readme/contract.mjs
|
|
23057
|
-
import { readFile as
|
|
23603
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
23058
23604
|
import path2 from "node:path";
|
|
23059
23605
|
function extractMarkers(content) {
|
|
23060
23606
|
const regex = /<!--\s*release-skill:((?:[\w-]+:)*[\w-]+)\s*-->/g;
|
|
@@ -23084,7 +23630,7 @@ function extractExecBlocks(content) {
|
|
|
23084
23630
|
}
|
|
23085
23631
|
async function safeRead(filePath) {
|
|
23086
23632
|
try {
|
|
23087
|
-
return await
|
|
23633
|
+
return await readFile12(filePath, "utf8");
|
|
23088
23634
|
} catch {
|
|
23089
23635
|
return null;
|
|
23090
23636
|
}
|
|
@@ -24173,10 +24719,10 @@ var require_commonjs = __commonJS({
|
|
|
24173
24719
|
* Return a void Promise that resolves once the stream ends.
|
|
24174
24720
|
*/
|
|
24175
24721
|
async promise() {
|
|
24176
|
-
return new Promise((
|
|
24722
|
+
return new Promise((resolve25, reject) => {
|
|
24177
24723
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
24178
24724
|
this.on("error", (er) => reject(er));
|
|
24179
|
-
this.on("end", () =>
|
|
24725
|
+
this.on("end", () => resolve25());
|
|
24180
24726
|
});
|
|
24181
24727
|
}
|
|
24182
24728
|
/**
|
|
@@ -24200,7 +24746,7 @@ var require_commonjs = __commonJS({
|
|
|
24200
24746
|
return Promise.resolve({ done: false, value: res });
|
|
24201
24747
|
if (this[EOF])
|
|
24202
24748
|
return stop();
|
|
24203
|
-
let
|
|
24749
|
+
let resolve25;
|
|
24204
24750
|
let reject;
|
|
24205
24751
|
const onerr = /* @__PURE__ */ __name((er) => {
|
|
24206
24752
|
this.off("data", ondata);
|
|
@@ -24214,19 +24760,19 @@ var require_commonjs = __commonJS({
|
|
|
24214
24760
|
this.off("end", onend);
|
|
24215
24761
|
this.off(DESTROYED, ondestroy);
|
|
24216
24762
|
this.pause();
|
|
24217
|
-
|
|
24763
|
+
resolve25({ value, done: !!this[EOF] });
|
|
24218
24764
|
}, "ondata");
|
|
24219
24765
|
const onend = /* @__PURE__ */ __name(() => {
|
|
24220
24766
|
this.off("error", onerr);
|
|
24221
24767
|
this.off("data", ondata);
|
|
24222
24768
|
this.off(DESTROYED, ondestroy);
|
|
24223
24769
|
stop();
|
|
24224
|
-
|
|
24770
|
+
resolve25({ done: true, value: void 0 });
|
|
24225
24771
|
}, "onend");
|
|
24226
24772
|
const ondestroy = /* @__PURE__ */ __name(() => onerr(new Error("stream destroyed")), "ondestroy");
|
|
24227
24773
|
return new Promise((res2, rej) => {
|
|
24228
24774
|
reject = rej;
|
|
24229
|
-
|
|
24775
|
+
resolve25 = res2;
|
|
24230
24776
|
this.once(DESTROYED, ondestroy);
|
|
24231
24777
|
this.once("error", onerr);
|
|
24232
24778
|
this.once("end", onend);
|
|
@@ -25317,10 +25863,10 @@ var require_minipass = __commonJS({
|
|
|
25317
25863
|
}
|
|
25318
25864
|
// stream.promise().then(() => done, er => emitted error)
|
|
25319
25865
|
promise() {
|
|
25320
|
-
return new Promise((
|
|
25866
|
+
return new Promise((resolve25, reject) => {
|
|
25321
25867
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
25322
25868
|
this.on("error", (er) => reject(er));
|
|
25323
|
-
this.on("end", () =>
|
|
25869
|
+
this.on("end", () => resolve25());
|
|
25324
25870
|
});
|
|
25325
25871
|
}
|
|
25326
25872
|
// for await (let chunk of stream)
|
|
@@ -25331,7 +25877,7 @@ var require_minipass = __commonJS({
|
|
|
25331
25877
|
return Promise.resolve({ done: false, value: res });
|
|
25332
25878
|
if (this[EOF])
|
|
25333
25879
|
return Promise.resolve({ done: true });
|
|
25334
|
-
let
|
|
25880
|
+
let resolve25 = null;
|
|
25335
25881
|
let reject = null;
|
|
25336
25882
|
const onerr = /* @__PURE__ */ __name((er) => {
|
|
25337
25883
|
this.removeListener("data", ondata);
|
|
@@ -25342,17 +25888,17 @@ var require_minipass = __commonJS({
|
|
|
25342
25888
|
this.removeListener("error", onerr);
|
|
25343
25889
|
this.removeListener("end", onend);
|
|
25344
25890
|
this.pause();
|
|
25345
|
-
|
|
25891
|
+
resolve25({ value, done: !!this[EOF] });
|
|
25346
25892
|
}, "ondata");
|
|
25347
25893
|
const onend = /* @__PURE__ */ __name(() => {
|
|
25348
25894
|
this.removeListener("error", onerr);
|
|
25349
25895
|
this.removeListener("data", ondata);
|
|
25350
|
-
|
|
25896
|
+
resolve25({ done: true });
|
|
25351
25897
|
}, "onend");
|
|
25352
25898
|
const ondestroy = /* @__PURE__ */ __name(() => onerr(new Error("stream destroyed")), "ondestroy");
|
|
25353
25899
|
return new Promise((res2, rej) => {
|
|
25354
25900
|
reject = rej;
|
|
25355
|
-
|
|
25901
|
+
resolve25 = res2;
|
|
25356
25902
|
this.once(DESTROYED, ondestroy);
|
|
25357
25903
|
this.once("error", onerr);
|
|
25358
25904
|
this.once("end", onend);
|
|
@@ -29391,12 +29937,12 @@ var require_body = __commonJS({
|
|
|
29391
29937
|
if (resTimeout && resTimeout.unref) {
|
|
29392
29938
|
resTimeout.unref();
|
|
29393
29939
|
}
|
|
29394
|
-
return new Promise((
|
|
29940
|
+
return new Promise((resolve25) => {
|
|
29395
29941
|
if (stream !== upstream) {
|
|
29396
29942
|
upstream.on("error", (er) => stream.emit("error", er));
|
|
29397
29943
|
upstream.pipe(stream);
|
|
29398
29944
|
}
|
|
29399
|
-
|
|
29945
|
+
resolve25();
|
|
29400
29946
|
}).then(() => stream.concat()).then((buf) => {
|
|
29401
29947
|
clearTimeout(resTimeout);
|
|
29402
29948
|
return buf;
|
|
@@ -30161,7 +30707,7 @@ var require_lib2 = __commonJS({
|
|
|
30161
30707
|
var fetch = /* @__PURE__ */ __name(async (url, opts) => {
|
|
30162
30708
|
if (/^data:/.test(url)) {
|
|
30163
30709
|
const request = new Request(url, opts);
|
|
30164
|
-
return Promise.resolve().then(() => new Promise((
|
|
30710
|
+
return Promise.resolve().then(() => new Promise((resolve25, reject) => {
|
|
30165
30711
|
let type, data;
|
|
30166
30712
|
try {
|
|
30167
30713
|
const { pathname, search } = new URL2(url);
|
|
@@ -30185,10 +30731,10 @@ var require_lib2 = __commonJS({
|
|
|
30185
30731
|
if (type) {
|
|
30186
30732
|
headers["Content-Type"] = type;
|
|
30187
30733
|
}
|
|
30188
|
-
return
|
|
30734
|
+
return resolve25(new Response(data, { headers }));
|
|
30189
30735
|
}));
|
|
30190
30736
|
}
|
|
30191
|
-
return new Promise((
|
|
30737
|
+
return new Promise((resolve25, reject) => {
|
|
30192
30738
|
const request = new Request(url, opts);
|
|
30193
30739
|
let options;
|
|
30194
30740
|
try {
|
|
@@ -30307,7 +30853,7 @@ var require_lib2 = __commonJS({
|
|
|
30307
30853
|
requestOpts.body = void 0;
|
|
30308
30854
|
requestOpts.headers.delete("content-length");
|
|
30309
30855
|
}
|
|
30310
|
-
|
|
30856
|
+
resolve25(fetch(new Request(locationURL, requestOpts)));
|
|
30311
30857
|
finalize();
|
|
30312
30858
|
return;
|
|
30313
30859
|
}
|
|
@@ -30335,7 +30881,7 @@ var require_lib2 = __commonJS({
|
|
|
30335
30881
|
const codings = headers.get("Content-Encoding");
|
|
30336
30882
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
30337
30883
|
response = new Response(body, responseOptions);
|
|
30338
|
-
|
|
30884
|
+
resolve25(response);
|
|
30339
30885
|
return;
|
|
30340
30886
|
}
|
|
30341
30887
|
const zlibOptions = {
|
|
@@ -30354,7 +30900,7 @@ var require_lib2 = __commonJS({
|
|
|
30354
30900
|
).pipe(unzip),
|
|
30355
30901
|
responseOptions
|
|
30356
30902
|
);
|
|
30357
|
-
|
|
30903
|
+
resolve25(response);
|
|
30358
30904
|
return;
|
|
30359
30905
|
}
|
|
30360
30906
|
if (codings === "deflate" || codings === "x-deflate") {
|
|
@@ -30366,7 +30912,7 @@ var require_lib2 = __commonJS({
|
|
|
30366
30912
|
(er) => decoder2.emit("error", er)
|
|
30367
30913
|
).pipe(decoder2);
|
|
30368
30914
|
response = new Response(decoder2, responseOptions);
|
|
30369
|
-
|
|
30915
|
+
resolve25(response);
|
|
30370
30916
|
});
|
|
30371
30917
|
return;
|
|
30372
30918
|
}
|
|
@@ -30384,11 +30930,11 @@ var require_lib2 = __commonJS({
|
|
|
30384
30930
|
(er) => decoder.emit("error", er)
|
|
30385
30931
|
).pipe(decoder);
|
|
30386
30932
|
response = new Response(decoder, responseOptions);
|
|
30387
|
-
|
|
30933
|
+
resolve25(response);
|
|
30388
30934
|
return;
|
|
30389
30935
|
}
|
|
30390
30936
|
response = new Response(body, responseOptions);
|
|
30391
|
-
|
|
30937
|
+
resolve25(response);
|
|
30392
30938
|
});
|
|
30393
30939
|
writeToStream(req, request);
|
|
30394
30940
|
});
|
|
@@ -30642,12 +31188,12 @@ var require_lib3 = __commonJS({
|
|
|
30642
31188
|
return process.emit("input", "end");
|
|
30643
31189
|
}, "end"),
|
|
30644
31190
|
read: /* @__PURE__ */ __name(function(...args2) {
|
|
30645
|
-
let
|
|
31191
|
+
let resolve25, reject;
|
|
30646
31192
|
const promise = new Promise((_resolve, _reject) => {
|
|
30647
|
-
|
|
31193
|
+
resolve25 = _resolve;
|
|
30648
31194
|
reject = _reject;
|
|
30649
31195
|
});
|
|
30650
|
-
process.emit("input", "read",
|
|
31196
|
+
process.emit("input", "read", resolve25, reject, ...args2);
|
|
30651
31197
|
return promise;
|
|
30652
31198
|
}, "read")
|
|
30653
31199
|
}
|
|
@@ -35062,7 +35608,7 @@ var require_npa = __commonJS({
|
|
|
35062
35608
|
spec = arg;
|
|
35063
35609
|
}
|
|
35064
35610
|
}
|
|
35065
|
-
return
|
|
35611
|
+
return resolve25(name, spec, where, arg);
|
|
35066
35612
|
}
|
|
35067
35613
|
__name(npa, "npa");
|
|
35068
35614
|
function isFileSpec(spec) {
|
|
@@ -35085,7 +35631,7 @@ var require_npa = __commonJS({
|
|
|
35085
35631
|
return spec.toLowerCase().startsWith("npm:");
|
|
35086
35632
|
}
|
|
35087
35633
|
__name(isAliasSpec, "isAliasSpec");
|
|
35088
|
-
function
|
|
35634
|
+
function resolve25(name, spec, where, arg) {
|
|
35089
35635
|
const res = new Result({
|
|
35090
35636
|
raw: arg,
|
|
35091
35637
|
name,
|
|
@@ -35117,7 +35663,7 @@ var require_npa = __commonJS({
|
|
|
35117
35663
|
return fromRegistry(res);
|
|
35118
35664
|
}
|
|
35119
35665
|
}
|
|
35120
|
-
__name(
|
|
35666
|
+
__name(resolve25, "resolve");
|
|
35121
35667
|
function toPurl(arg, reg = defaultRegistry) {
|
|
35122
35668
|
const res = npa(arg);
|
|
35123
35669
|
if (res.type !== "version") {
|
|
@@ -35418,7 +35964,7 @@ var require_npa = __commonJS({
|
|
|
35418
35964
|
}
|
|
35419
35965
|
__name(fromRegistry, "fromRegistry");
|
|
35420
35966
|
module.exports = npa;
|
|
35421
|
-
module.exports.resolve =
|
|
35967
|
+
module.exports.resolve = resolve25;
|
|
35422
35968
|
module.exports.toPurl = toPurl;
|
|
35423
35969
|
module.exports.Result = Result;
|
|
35424
35970
|
}
|
|
@@ -37191,7 +37737,7 @@ var require_lib7 = __commonJS({
|
|
|
37191
37737
|
module.exports.fromStream = fromStream;
|
|
37192
37738
|
function fromStream(stream, opts) {
|
|
37193
37739
|
const istream = integrityStream(opts);
|
|
37194
|
-
return new Promise((
|
|
37740
|
+
return new Promise((resolve25, reject) => {
|
|
37195
37741
|
stream.pipe(istream);
|
|
37196
37742
|
stream.on("error", reject);
|
|
37197
37743
|
istream.on("error", reject);
|
|
@@ -37199,7 +37745,7 @@ var require_lib7 = __commonJS({
|
|
|
37199
37745
|
istream.on("integrity", (s) => {
|
|
37200
37746
|
sri = s;
|
|
37201
37747
|
});
|
|
37202
|
-
istream.on("end", () =>
|
|
37748
|
+
istream.on("end", () => resolve25(sri));
|
|
37203
37749
|
istream.resume();
|
|
37204
37750
|
});
|
|
37205
37751
|
}
|
|
@@ -37260,7 +37806,7 @@ var require_lib7 = __commonJS({
|
|
|
37260
37806
|
));
|
|
37261
37807
|
}
|
|
37262
37808
|
const checker = integrityStream(opts);
|
|
37263
|
-
return new Promise((
|
|
37809
|
+
return new Promise((resolve25, reject) => {
|
|
37264
37810
|
stream.pipe(checker);
|
|
37265
37811
|
stream.on("error", reject);
|
|
37266
37812
|
checker.on("error", reject);
|
|
@@ -37268,7 +37814,7 @@ var require_lib7 = __commonJS({
|
|
|
37268
37814
|
checker.on("verified", (s) => {
|
|
37269
37815
|
verified = s;
|
|
37270
37816
|
});
|
|
37271
|
-
checker.on("end", () =>
|
|
37817
|
+
checker.on("end", () => resolve25(verified));
|
|
37272
37818
|
checker.resume();
|
|
37273
37819
|
});
|
|
37274
37820
|
}
|
|
@@ -38150,7 +38696,7 @@ var require_polyfill = __commonJS({
|
|
|
38150
38696
|
chmod: chmod5,
|
|
38151
38697
|
copyFile,
|
|
38152
38698
|
lstat: lstat15,
|
|
38153
|
-
mkdir:
|
|
38699
|
+
mkdir: mkdir20,
|
|
38154
38700
|
readdir: readdir13,
|
|
38155
38701
|
readlink: readlink2,
|
|
38156
38702
|
stat: stat9,
|
|
@@ -38160,10 +38706,10 @@ var require_polyfill = __commonJS({
|
|
|
38160
38706
|
} = __require("fs/promises");
|
|
38161
38707
|
var {
|
|
38162
38708
|
dirname: dirname15,
|
|
38163
|
-
isAbsolute:
|
|
38164
|
-
join:
|
|
38709
|
+
isAbsolute: isAbsolute19,
|
|
38710
|
+
join: join26,
|
|
38165
38711
|
parse: parse2,
|
|
38166
|
-
resolve:
|
|
38712
|
+
resolve: resolve25,
|
|
38167
38713
|
sep: sep4,
|
|
38168
38714
|
toNamespacedPath
|
|
38169
38715
|
} = __require("path");
|
|
@@ -38268,7 +38814,7 @@ var require_polyfill = __commonJS({
|
|
|
38268
38814
|
if (dirExists) {
|
|
38269
38815
|
return getStatsForCopy(destStat, src, dest, opts);
|
|
38270
38816
|
}
|
|
38271
|
-
await
|
|
38817
|
+
await mkdir20(destParent, { recursive: true });
|
|
38272
38818
|
return getStatsForCopy(destStat, src, dest, opts);
|
|
38273
38819
|
}
|
|
38274
38820
|
__name(checkParentDir, "checkParentDir");
|
|
@@ -38281,8 +38827,8 @@ var require_polyfill = __commonJS({
|
|
|
38281
38827
|
}
|
|
38282
38828
|
__name(pathExists2, "pathExists");
|
|
38283
38829
|
async function checkParentPaths(src, srcStat, dest) {
|
|
38284
|
-
const srcParent =
|
|
38285
|
-
const destParent =
|
|
38830
|
+
const srcParent = resolve25(dirname15(src));
|
|
38831
|
+
const destParent = resolve25(dirname15(dest));
|
|
38286
38832
|
if (destParent === srcParent || destParent === parse2(destParent).root) {
|
|
38287
38833
|
return;
|
|
38288
38834
|
}
|
|
@@ -38306,7 +38852,7 @@ var require_polyfill = __commonJS({
|
|
|
38306
38852
|
return checkParentPaths(src, srcStat, destParent);
|
|
38307
38853
|
}
|
|
38308
38854
|
__name(checkParentPaths, "checkParentPaths");
|
|
38309
|
-
var normalizePathToArray = /* @__PURE__ */ __name((path3) =>
|
|
38855
|
+
var normalizePathToArray = /* @__PURE__ */ __name((path3) => resolve25(path3).split(sep4).filter(Boolean), "normalizePathToArray");
|
|
38310
38856
|
function isSrcSubdir(src, dest) {
|
|
38311
38857
|
const srcArr = normalizePathToArray(src);
|
|
38312
38858
|
const destArr = normalizePathToArray(dest);
|
|
@@ -38433,7 +38979,7 @@ var require_polyfill = __commonJS({
|
|
|
38433
38979
|
}
|
|
38434
38980
|
__name(onDir, "onDir");
|
|
38435
38981
|
async function mkDirAndCopy(srcMode, src, dest, opts) {
|
|
38436
|
-
await
|
|
38982
|
+
await mkdir20(dest);
|
|
38437
38983
|
await copyDir(src, dest, opts);
|
|
38438
38984
|
return setDestMode(dest, srcMode);
|
|
38439
38985
|
}
|
|
@@ -38442,8 +38988,8 @@ var require_polyfill = __commonJS({
|
|
|
38442
38988
|
const dir = await readdir13(src);
|
|
38443
38989
|
for (let i = 0; i < dir.length; i++) {
|
|
38444
38990
|
const item = dir[i];
|
|
38445
|
-
const srcItem =
|
|
38446
|
-
const destItem =
|
|
38991
|
+
const srcItem = join26(src, item);
|
|
38992
|
+
const destItem = join26(dest, item);
|
|
38447
38993
|
const { destStat } = await checkPaths(srcItem, destItem, opts);
|
|
38448
38994
|
await startCopy(destStat, srcItem, destItem, opts);
|
|
38449
38995
|
}
|
|
@@ -38451,8 +38997,8 @@ var require_polyfill = __commonJS({
|
|
|
38451
38997
|
__name(copyDir, "copyDir");
|
|
38452
38998
|
async function onLink(destStat, src, dest) {
|
|
38453
38999
|
let resolvedSrc = await readlink2(src);
|
|
38454
|
-
if (!
|
|
38455
|
-
resolvedSrc =
|
|
39000
|
+
if (!isAbsolute19(resolvedSrc)) {
|
|
39001
|
+
resolvedSrc = resolve25(dirname15(src), resolvedSrc);
|
|
38456
39002
|
}
|
|
38457
39003
|
if (!destStat) {
|
|
38458
39004
|
return symlink(resolvedSrc, dest);
|
|
@@ -38466,8 +39012,8 @@ var require_polyfill = __commonJS({
|
|
|
38466
39012
|
}
|
|
38467
39013
|
throw err;
|
|
38468
39014
|
}
|
|
38469
|
-
if (!
|
|
38470
|
-
resolvedDest =
|
|
39015
|
+
if (!isAbsolute19(resolvedDest)) {
|
|
39016
|
+
resolvedDest = resolve25(dirname15(dest), resolvedDest);
|
|
38471
39017
|
}
|
|
38472
39018
|
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
|
|
38473
39019
|
throw new ERR_FS_CP_EINVAL({
|
|
@@ -38519,15 +39065,15 @@ var require_cp = __commonJS({
|
|
|
38519
39065
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js
|
|
38520
39066
|
var require_with_temp_dir = __commonJS({
|
|
38521
39067
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/with-temp-dir.js"(exports, module) {
|
|
38522
|
-
var { join:
|
|
39068
|
+
var { join: join26, sep: sep4 } = __require("path");
|
|
38523
39069
|
var getOptions = require_get_options();
|
|
38524
|
-
var { mkdir:
|
|
39070
|
+
var { mkdir: mkdir20, mkdtemp: mkdtemp5, rm: rm9 } = __require("fs/promises");
|
|
38525
39071
|
var withTempDir = /* @__PURE__ */ __name(async (root, fn, opts) => {
|
|
38526
39072
|
const options = getOptions(opts, {
|
|
38527
39073
|
copy: ["tmpPrefix"]
|
|
38528
39074
|
});
|
|
38529
|
-
await
|
|
38530
|
-
const target = await mkdtemp5(
|
|
39075
|
+
await mkdir20(root, { recursive: true });
|
|
39076
|
+
const target = await mkdtemp5(join26(`${root}${sep4}`, options.tmpPrefix || ""));
|
|
38531
39077
|
let err;
|
|
38532
39078
|
let result;
|
|
38533
39079
|
try {
|
|
@@ -38552,13 +39098,13 @@ var require_with_temp_dir = __commonJS({
|
|
|
38552
39098
|
var require_readdir_scoped = __commonJS({
|
|
38553
39099
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/readdir-scoped.js"(exports, module) {
|
|
38554
39100
|
var { readdir: readdir13 } = __require("fs/promises");
|
|
38555
|
-
var { join:
|
|
39101
|
+
var { join: join26 } = __require("path");
|
|
38556
39102
|
var readdirScoped = /* @__PURE__ */ __name(async (dir) => {
|
|
38557
39103
|
const results = [];
|
|
38558
39104
|
for (const item of await readdir13(dir)) {
|
|
38559
39105
|
if (item.startsWith("@")) {
|
|
38560
|
-
for (const scopedItem of await readdir13(
|
|
38561
|
-
results.push(
|
|
39106
|
+
for (const scopedItem of await readdir13(join26(dir, item))) {
|
|
39107
|
+
results.push(join26(item, scopedItem));
|
|
38562
39108
|
}
|
|
38563
39109
|
} else {
|
|
38564
39110
|
results.push(item);
|
|
@@ -38573,7 +39119,7 @@ var require_readdir_scoped = __commonJS({
|
|
|
38573
39119
|
// ../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js
|
|
38574
39120
|
var require_move_file = __commonJS({
|
|
38575
39121
|
"../../node_modules/.pnpm/@npmcli+fs@4.0.0/node_modules/@npmcli/fs/lib/move-file.js"(exports, module) {
|
|
38576
|
-
var { dirname: dirname15, join:
|
|
39122
|
+
var { dirname: dirname15, join: join26, resolve: resolve25, relative: relative22, isAbsolute: isAbsolute19 } = __require("path");
|
|
38577
39123
|
var fs = __require("fs/promises");
|
|
38578
39124
|
var pathExists2 = /* @__PURE__ */ __name(async (path3) => {
|
|
38579
39125
|
try {
|
|
@@ -38603,7 +39149,7 @@ var require_move_file = __commonJS({
|
|
|
38603
39149
|
if (sourceStat.isDirectory()) {
|
|
38604
39150
|
const files = await fs.readdir(source);
|
|
38605
39151
|
await Promise.all(files.map(
|
|
38606
|
-
(file) => moveFile(
|
|
39152
|
+
(file) => moveFile(join26(source, file), join26(destination, file), options, false, symlinks)
|
|
38607
39153
|
));
|
|
38608
39154
|
} else if (sourceStat.isSymbolicLink()) {
|
|
38609
39155
|
symlinks.push({ source, destination });
|
|
@@ -38617,12 +39163,12 @@ var require_move_file = __commonJS({
|
|
|
38617
39163
|
if (root) {
|
|
38618
39164
|
await Promise.all(symlinks.map(async ({ source: symSource, destination: symDestination }) => {
|
|
38619
39165
|
let target = await fs.readlink(symSource);
|
|
38620
|
-
if (
|
|
38621
|
-
target =
|
|
39166
|
+
if (isAbsolute19(target)) {
|
|
39167
|
+
target = resolve25(symDestination, relative22(symSource, target));
|
|
38622
39168
|
}
|
|
38623
39169
|
let targetStat = "file";
|
|
38624
39170
|
try {
|
|
38625
|
-
targetStat = await fs.stat(
|
|
39171
|
+
targetStat = await fs.stat(resolve25(dirname15(symSource), target));
|
|
38626
39172
|
if (targetStat.isDirectory()) {
|
|
38627
39173
|
targetStat = "junction";
|
|
38628
39174
|
}
|
|
@@ -38695,7 +39241,7 @@ async function pMap(iterable, mapper, {
|
|
|
38695
39241
|
const cleanup = /* @__PURE__ */ __name(() => {
|
|
38696
39242
|
signal?.removeEventListener("abort", signalListener);
|
|
38697
39243
|
}, "cleanup");
|
|
38698
|
-
const
|
|
39244
|
+
const resolve25 = /* @__PURE__ */ __name((value) => {
|
|
38699
39245
|
resolve_(value);
|
|
38700
39246
|
cleanup();
|
|
38701
39247
|
}, "resolve");
|
|
@@ -38727,7 +39273,7 @@ async function pMap(iterable, mapper, {
|
|
|
38727
39273
|
}
|
|
38728
39274
|
isResolved = true;
|
|
38729
39275
|
if (skippedIndexesMap.size === 0) {
|
|
38730
|
-
|
|
39276
|
+
resolve25(result);
|
|
38731
39277
|
return;
|
|
38732
39278
|
}
|
|
38733
39279
|
const pureResult = [];
|
|
@@ -38737,7 +39283,7 @@ async function pMap(iterable, mapper, {
|
|
|
38737
39283
|
}
|
|
38738
39284
|
pureResult.push(value);
|
|
38739
39285
|
}
|
|
38740
|
-
|
|
39286
|
+
resolve25(pureResult);
|
|
38741
39287
|
}
|
|
38742
39288
|
return;
|
|
38743
39289
|
}
|
|
@@ -38876,8 +39422,8 @@ var require_entry_index = __commonJS({
|
|
|
38876
39422
|
var crypto = __require("crypto");
|
|
38877
39423
|
var {
|
|
38878
39424
|
appendFile,
|
|
38879
|
-
mkdir:
|
|
38880
|
-
readFile:
|
|
39425
|
+
mkdir: mkdir20,
|
|
39426
|
+
readFile: readFile30,
|
|
38881
39427
|
readdir: readdir13,
|
|
38882
39428
|
rm: rm9,
|
|
38883
39429
|
writeFile: writeFile11
|
|
@@ -38923,7 +39469,7 @@ var require_entry_index = __commonJS({
|
|
|
38923
39469
|
}).join("\n");
|
|
38924
39470
|
const setup = /* @__PURE__ */ __name(async () => {
|
|
38925
39471
|
const target = uniqueFilename(path3.join(cache, "tmp"), opts.tmpPrefix);
|
|
38926
|
-
await
|
|
39472
|
+
await mkdir20(path3.dirname(target), { recursive: true });
|
|
38927
39473
|
return {
|
|
38928
39474
|
target,
|
|
38929
39475
|
moved: false
|
|
@@ -38936,7 +39482,7 @@ var require_entry_index = __commonJS({
|
|
|
38936
39482
|
}, "teardown");
|
|
38937
39483
|
const write = /* @__PURE__ */ __name(async (tmp2) => {
|
|
38938
39484
|
await writeFile11(tmp2.target, newIndex, { flag: "wx" });
|
|
38939
|
-
await
|
|
39485
|
+
await mkdir20(path3.dirname(bucket), { recursive: true });
|
|
38940
39486
|
await moveFile(tmp2.target, bucket);
|
|
38941
39487
|
tmp2.moved = true;
|
|
38942
39488
|
}, "write");
|
|
@@ -38961,7 +39507,7 @@ var require_entry_index = __commonJS({
|
|
|
38961
39507
|
metadata
|
|
38962
39508
|
};
|
|
38963
39509
|
try {
|
|
38964
|
-
await
|
|
39510
|
+
await mkdir20(path3.dirname(bucket), { recursive: true });
|
|
38965
39511
|
const stringified = JSON.stringify(entry);
|
|
38966
39512
|
await appendFile(bucket, `
|
|
38967
39513
|
${hashEntry(stringified)} ${stringified}`);
|
|
@@ -39069,7 +39615,7 @@ ${hashEntry(stringified)} ${stringified}`);
|
|
|
39069
39615
|
__name(ls, "ls");
|
|
39070
39616
|
module.exports.bucketEntries = bucketEntries;
|
|
39071
39617
|
async function bucketEntries(bucket, filter) {
|
|
39072
|
-
const data = await
|
|
39618
|
+
const data = await readFile30(bucket, "utf8");
|
|
39073
39619
|
return _bucketEntries(data, filter);
|
|
39074
39620
|
}
|
|
39075
39621
|
__name(bucketEntries, "bucketEntries");
|
|
@@ -42943,9 +43489,9 @@ var require_commonjs5 = __commonJS({
|
|
|
42943
43489
|
if (this.#asyncReaddirInFlight) {
|
|
42944
43490
|
await this.#asyncReaddirInFlight;
|
|
42945
43491
|
} else {
|
|
42946
|
-
let
|
|
43492
|
+
let resolve25 = /* @__PURE__ */ __name(() => {
|
|
42947
43493
|
}, "resolve");
|
|
42948
|
-
this.#asyncReaddirInFlight = new Promise((res) =>
|
|
43494
|
+
this.#asyncReaddirInFlight = new Promise((res) => resolve25 = res);
|
|
42949
43495
|
try {
|
|
42950
43496
|
for (const e of await this.#fs.promises.readdir(fullpath, {
|
|
42951
43497
|
withFileTypes: true
|
|
@@ -42958,7 +43504,7 @@ var require_commonjs5 = __commonJS({
|
|
|
42958
43504
|
children.provisional = 0;
|
|
42959
43505
|
}
|
|
42960
43506
|
this.#asyncReaddirInFlight = void 0;
|
|
42961
|
-
|
|
43507
|
+
resolve25();
|
|
42962
43508
|
}
|
|
42963
43509
|
return children.slice(0, children.provisional);
|
|
42964
43510
|
}
|
|
@@ -44069,10 +44615,10 @@ var require_ignore = __commonJS({
|
|
|
44069
44615
|
ignored(p) {
|
|
44070
44616
|
const fullpath = p.fullpath();
|
|
44071
44617
|
const fullpaths = `${fullpath}/`;
|
|
44072
|
-
const
|
|
44073
|
-
const relatives = `${
|
|
44618
|
+
const relative22 = p.relative() || ".";
|
|
44619
|
+
const relatives = `${relative22}/`;
|
|
44074
44620
|
for (const m of this.relative) {
|
|
44075
|
-
if (m.match(
|
|
44621
|
+
if (m.match(relative22) || m.match(relatives))
|
|
44076
44622
|
return true;
|
|
44077
44623
|
}
|
|
44078
44624
|
for (const m of this.absolute) {
|
|
@@ -44083,9 +44629,9 @@ var require_ignore = __commonJS({
|
|
|
44083
44629
|
}
|
|
44084
44630
|
childrenIgnored(p) {
|
|
44085
44631
|
const fullpath = p.fullpath() + "/";
|
|
44086
|
-
const
|
|
44632
|
+
const relative22 = (p.relative() || ".") + "/";
|
|
44087
44633
|
for (const m of this.relativeChildren) {
|
|
44088
|
-
if (m.match(
|
|
44634
|
+
if (m.match(relative22))
|
|
44089
44635
|
return true;
|
|
44090
44636
|
}
|
|
44091
44637
|
for (const m of this.absoluteChildren) {
|
|
@@ -45088,8 +45634,8 @@ var require_verify = __commonJS({
|
|
|
45088
45634
|
"../../node_modules/.pnpm/cacache@19.0.1/node_modules/cacache/lib/verify.js"(exports, module) {
|
|
45089
45635
|
"use strict";
|
|
45090
45636
|
var {
|
|
45091
|
-
mkdir:
|
|
45092
|
-
readFile:
|
|
45637
|
+
mkdir: mkdir20,
|
|
45638
|
+
readFile: readFile30,
|
|
45093
45639
|
rm: rm9,
|
|
45094
45640
|
stat: stat9,
|
|
45095
45641
|
truncate,
|
|
@@ -45158,7 +45704,7 @@ var require_verify = __commonJS({
|
|
|
45158
45704
|
__name(markEndTime, "markEndTime");
|
|
45159
45705
|
async function fixPerms(cache, opts) {
|
|
45160
45706
|
opts.log.silly("verify", "fixing cache permissions");
|
|
45161
|
-
await
|
|
45707
|
+
await mkdir20(cache, { recursive: true });
|
|
45162
45708
|
return null;
|
|
45163
45709
|
}
|
|
45164
45710
|
__name(fixPerms, "fixPerms");
|
|
@@ -45176,8 +45722,8 @@ var require_verify = __commonJS({
|
|
|
45176
45722
|
liveContent.add(integrity[algo].toString());
|
|
45177
45723
|
}
|
|
45178
45724
|
});
|
|
45179
|
-
await new Promise((
|
|
45180
|
-
indexStream.on("end",
|
|
45725
|
+
await new Promise((resolve25, reject) => {
|
|
45726
|
+
indexStream.on("end", resolve25).on("error", reject);
|
|
45181
45727
|
});
|
|
45182
45728
|
const contentDir = contentPath.contentDir(cache);
|
|
45183
45729
|
const files = await glob(path3.join(contentDir, "**"), {
|
|
@@ -45316,7 +45862,7 @@ var require_verify = __commonJS({
|
|
|
45316
45862
|
__name(writeVerifile, "writeVerifile");
|
|
45317
45863
|
module.exports.lastRun = lastRun;
|
|
45318
45864
|
async function lastRun(cache) {
|
|
45319
|
-
const data = await
|
|
45865
|
+
const data = await readFile30(path3.join(cache, "_lastverified"), { encoding: "utf8" });
|
|
45320
45866
|
return /* @__PURE__ */ new Date(+data);
|
|
45321
45867
|
}
|
|
45322
45868
|
__name(lastRun, "lastRun");
|
|
@@ -45733,7 +46279,7 @@ var require_promise_retry = __commonJS({
|
|
|
45733
46279
|
fn = temp;
|
|
45734
46280
|
}
|
|
45735
46281
|
operation = retry.operation(options);
|
|
45736
|
-
return new Promise(function(
|
|
46282
|
+
return new Promise(function(resolve25, reject) {
|
|
45737
46283
|
operation.attempt(function(number) {
|
|
45738
46284
|
Promise.resolve().then(function() {
|
|
45739
46285
|
return fn(function(err) {
|
|
@@ -45742,7 +46288,7 @@ var require_promise_retry = __commonJS({
|
|
|
45742
46288
|
}
|
|
45743
46289
|
throw errcode(new Error("Retrying"), "EPROMISERETRY", { retried: err });
|
|
45744
46290
|
}, number);
|
|
45745
|
-
}).then(
|
|
46291
|
+
}).then(resolve25, function(err) {
|
|
45746
46292
|
if (isRetryError(err)) {
|
|
45747
46293
|
err = err.retried;
|
|
45748
46294
|
if (operation.retry(err || new Error())) {
|
|
@@ -46627,8 +47173,8 @@ var require_helpers = __commonJS({
|
|
|
46627
47173
|
function req(url, opts = {}) {
|
|
46628
47174
|
const href = typeof url === "string" ? url : url.href;
|
|
46629
47175
|
const req2 = (href.startsWith("https:") ? https : http).request(url, opts);
|
|
46630
|
-
const promise = new Promise((
|
|
46631
|
-
req2.once("response",
|
|
47176
|
+
const promise = new Promise((resolve25, reject) => {
|
|
47177
|
+
req2.once("response", resolve25).once("error", reject).end();
|
|
46632
47178
|
});
|
|
46633
47179
|
req2.then = promise.then.bind(promise);
|
|
46634
47180
|
return req2;
|
|
@@ -46943,7 +47489,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
46943
47489
|
var debug_1 = __importDefault(require_src());
|
|
46944
47490
|
var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
|
|
46945
47491
|
function parseProxyResponse(socket) {
|
|
46946
|
-
return new Promise((
|
|
47492
|
+
return new Promise((resolve25, reject) => {
|
|
46947
47493
|
let buffersLength = 0;
|
|
46948
47494
|
const buffers = [];
|
|
46949
47495
|
function read() {
|
|
@@ -47013,7 +47559,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
47013
47559
|
}
|
|
47014
47560
|
debug("got proxy server response: %o %o", firstLine, headers);
|
|
47015
47561
|
cleanup();
|
|
47016
|
-
|
|
47562
|
+
resolve25({
|
|
47017
47563
|
connect: {
|
|
47018
47564
|
statusCode,
|
|
47019
47565
|
statusText,
|
|
@@ -50692,12 +51238,12 @@ var require_socksclient = __commonJS({
|
|
|
50692
51238
|
"use strict";
|
|
50693
51239
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
50694
51240
|
function adopt(value) {
|
|
50695
|
-
return value instanceof P ? value : new P(function(
|
|
50696
|
-
|
|
51241
|
+
return value instanceof P ? value : new P(function(resolve25) {
|
|
51242
|
+
resolve25(value);
|
|
50697
51243
|
});
|
|
50698
51244
|
}
|
|
50699
51245
|
__name(adopt, "adopt");
|
|
50700
|
-
return new (P || (P = Promise))(function(
|
|
51246
|
+
return new (P || (P = Promise))(function(resolve25, reject) {
|
|
50701
51247
|
function fulfilled(value) {
|
|
50702
51248
|
try {
|
|
50703
51249
|
step(generator.next(value));
|
|
@@ -50715,7 +51261,7 @@ var require_socksclient = __commonJS({
|
|
|
50715
51261
|
}
|
|
50716
51262
|
__name(rejected, "rejected");
|
|
50717
51263
|
function step(result) {
|
|
50718
|
-
result.done ?
|
|
51264
|
+
result.done ? resolve25(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
50719
51265
|
}
|
|
50720
51266
|
__name(step, "step");
|
|
50721
51267
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
@@ -50753,13 +51299,13 @@ var require_socksclient = __commonJS({
|
|
|
50753
51299
|
* @returns { Promise }
|
|
50754
51300
|
*/
|
|
50755
51301
|
static createConnection(options, callback) {
|
|
50756
|
-
return new Promise((
|
|
51302
|
+
return new Promise((resolve25, reject) => {
|
|
50757
51303
|
try {
|
|
50758
51304
|
(0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
|
|
50759
51305
|
} catch (err) {
|
|
50760
51306
|
if (typeof callback === "function") {
|
|
50761
51307
|
callback(err);
|
|
50762
|
-
return
|
|
51308
|
+
return resolve25(err);
|
|
50763
51309
|
} else {
|
|
50764
51310
|
return reject(err);
|
|
50765
51311
|
}
|
|
@@ -50770,16 +51316,16 @@ var require_socksclient = __commonJS({
|
|
|
50770
51316
|
client.removeAllListeners();
|
|
50771
51317
|
if (typeof callback === "function") {
|
|
50772
51318
|
callback(null, info);
|
|
50773
|
-
|
|
51319
|
+
resolve25(info);
|
|
50774
51320
|
} else {
|
|
50775
|
-
|
|
51321
|
+
resolve25(info);
|
|
50776
51322
|
}
|
|
50777
51323
|
});
|
|
50778
51324
|
client.once("error", (err) => {
|
|
50779
51325
|
client.removeAllListeners();
|
|
50780
51326
|
if (typeof callback === "function") {
|
|
50781
51327
|
callback(err);
|
|
50782
|
-
|
|
51328
|
+
resolve25(err);
|
|
50783
51329
|
} else {
|
|
50784
51330
|
reject(err);
|
|
50785
51331
|
}
|
|
@@ -50796,13 +51342,13 @@ var require_socksclient = __commonJS({
|
|
|
50796
51342
|
* @returns { Promise }
|
|
50797
51343
|
*/
|
|
50798
51344
|
static createConnectionChain(options, callback) {
|
|
50799
|
-
return new Promise((
|
|
51345
|
+
return new Promise((resolve25, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
50800
51346
|
try {
|
|
50801
51347
|
(0, helpers_1.validateSocksClientChainOptions)(options);
|
|
50802
51348
|
} catch (err) {
|
|
50803
51349
|
if (typeof callback === "function") {
|
|
50804
51350
|
callback(err);
|
|
50805
|
-
return
|
|
51351
|
+
return resolve25(err);
|
|
50806
51352
|
} else {
|
|
50807
51353
|
return reject(err);
|
|
50808
51354
|
}
|
|
@@ -50828,14 +51374,14 @@ var require_socksclient = __commonJS({
|
|
|
50828
51374
|
}
|
|
50829
51375
|
if (typeof callback === "function") {
|
|
50830
51376
|
callback(null, { socket: sock });
|
|
50831
|
-
|
|
51377
|
+
resolve25({ socket: sock });
|
|
50832
51378
|
} else {
|
|
50833
|
-
|
|
51379
|
+
resolve25({ socket: sock });
|
|
50834
51380
|
}
|
|
50835
51381
|
} catch (err) {
|
|
50836
51382
|
if (typeof callback === "function") {
|
|
50837
51383
|
callback(err);
|
|
50838
|
-
|
|
51384
|
+
resolve25(err);
|
|
50839
51385
|
} else {
|
|
50840
51386
|
reject(err);
|
|
50841
51387
|
}
|
|
@@ -51523,12 +52069,12 @@ var require_dist6 = __commonJS({
|
|
|
51523
52069
|
let { host } = opts;
|
|
51524
52070
|
const { port, lookup: lookupFn = dns.lookup } = opts;
|
|
51525
52071
|
if (shouldLookup) {
|
|
51526
|
-
host = await new Promise((
|
|
52072
|
+
host = await new Promise((resolve25, reject) => {
|
|
51527
52073
|
lookupFn(host, {}, (err, res) => {
|
|
51528
52074
|
if (err) {
|
|
51529
52075
|
reject(err);
|
|
51530
52076
|
} else {
|
|
51531
|
-
|
|
52077
|
+
resolve25(res);
|
|
51532
52078
|
}
|
|
51533
52079
|
});
|
|
51534
52080
|
});
|
|
@@ -52340,8 +52886,8 @@ var require_entry = __commonJS({
|
|
|
52340
52886
|
let body = null;
|
|
52341
52887
|
if (this.response.status === 200) {
|
|
52342
52888
|
let cacheWriteResolve, cacheWriteReject;
|
|
52343
|
-
const cacheWritePromise = new Promise((
|
|
52344
|
-
cacheWriteResolve =
|
|
52889
|
+
const cacheWritePromise = new Promise((resolve25, reject) => {
|
|
52890
|
+
cacheWriteResolve = resolve25;
|
|
52345
52891
|
cacheWriteReject = reject;
|
|
52346
52892
|
}).catch((err) => {
|
|
52347
52893
|
body.emit("error", err);
|
|
@@ -53856,7 +54402,7 @@ var require_index_min = __commonJS({
|
|
|
53856
54402
|
var require_lib17 = __commonJS({
|
|
53857
54403
|
"../../node_modules/.pnpm/which@5.0.0/node_modules/which/lib/index.js"(exports, module) {
|
|
53858
54404
|
var { isexe, sync: isexeSync } = require_index_min();
|
|
53859
|
-
var { join:
|
|
54405
|
+
var { join: join26, delimiter, sep: sep4, posix: posix3 } = __require("path");
|
|
53860
54406
|
var isWindows = process.platform === "win32";
|
|
53861
54407
|
var rSlash = new RegExp(`[${posix3.sep}${sep4 === posix3.sep ? "" : sep4}]`.replace(/(\\)/g, "\\$1"));
|
|
53862
54408
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -53885,7 +54431,7 @@ var require_lib17 = __commonJS({
|
|
|
53885
54431
|
var getPathPart = /* @__PURE__ */ __name((raw, cmd) => {
|
|
53886
54432
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
53887
54433
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
53888
|
-
return prefix +
|
|
54434
|
+
return prefix + join26(pathPart, cmd);
|
|
53889
54435
|
}, "getPathPart");
|
|
53890
54436
|
var which = /* @__PURE__ */ __name(async (cmd, opt = {}) => {
|
|
53891
54437
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -54008,9 +54554,9 @@ var require_lib18 = __commonJS({
|
|
|
54008
54554
|
if (opts.shell) {
|
|
54009
54555
|
return spawnWithShell(cmd, args2, opts, extra);
|
|
54010
54556
|
}
|
|
54011
|
-
let
|
|
54557
|
+
let resolve25, reject;
|
|
54012
54558
|
const promise = new Promise((_resolve, _reject) => {
|
|
54013
|
-
|
|
54559
|
+
resolve25 = _resolve;
|
|
54014
54560
|
reject = _reject;
|
|
54015
54561
|
});
|
|
54016
54562
|
const closeError = new Error("command failed");
|
|
@@ -54043,7 +54589,7 @@ var require_lib18 = __commonJS({
|
|
|
54043
54589
|
if (code || signal) {
|
|
54044
54590
|
rejectWithOpts(closeError, { code, signal });
|
|
54045
54591
|
} else {
|
|
54046
|
-
|
|
54592
|
+
resolve25(getResult({ code, signal }));
|
|
54047
54593
|
}
|
|
54048
54594
|
});
|
|
54049
54595
|
return promise;
|
|
@@ -55024,7 +55570,7 @@ var require_lib19 = __commonJS({
|
|
|
55024
55570
|
// ../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js
|
|
55025
55571
|
var require_lib20 = __commonJS({
|
|
55026
55572
|
"../../node_modules/.pnpm/npm-normalize-package-bin@4.0.0/node_modules/npm-normalize-package-bin/lib/index.js"(exports, module) {
|
|
55027
|
-
var { join:
|
|
55573
|
+
var { join: join26, basename: basename10 } = __require("path");
|
|
55028
55574
|
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");
|
|
55029
55575
|
var normalizeString = /* @__PURE__ */ __name((pkg) => {
|
|
55030
55576
|
if (!pkg.name) {
|
|
@@ -55049,11 +55595,11 @@ var require_lib20 = __commonJS({
|
|
|
55049
55595
|
const clean = {};
|
|
55050
55596
|
let hasBins = false;
|
|
55051
55597
|
Object.keys(orig).forEach((binKey) => {
|
|
55052
|
-
const base =
|
|
55598
|
+
const base = join26("/", basename10(binKey.replace(/\\|:/g, "/"))).slice(1);
|
|
55053
55599
|
if (typeof orig[binKey] !== "string" || !base) {
|
|
55054
55600
|
return;
|
|
55055
55601
|
}
|
|
55056
|
-
const binTarget =
|
|
55602
|
+
const binTarget = join26("/", orig[binKey].replace(/\\/g, "/")).replace(/\\/g, "/").slice(1);
|
|
55057
55603
|
if (!binTarget) {
|
|
55058
55604
|
return;
|
|
55059
55605
|
}
|
|
@@ -57594,11 +58140,11 @@ var require_normalize = __commonJS({
|
|
|
57594
58140
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js
|
|
57595
58141
|
var require_read_package = __commonJS({
|
|
57596
58142
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/read-package.js"(exports, module) {
|
|
57597
|
-
var { readFile:
|
|
58143
|
+
var { readFile: readFile30 } = __require("fs/promises");
|
|
57598
58144
|
var parseJSON = require_lib16();
|
|
57599
58145
|
async function read(filename) {
|
|
57600
58146
|
try {
|
|
57601
|
-
const data = await
|
|
58147
|
+
const data = await readFile30(filename, "utf8");
|
|
57602
58148
|
return data;
|
|
57603
58149
|
} catch (err) {
|
|
57604
58150
|
err.message = `Could not read package.json: ${err}`;
|
|
@@ -57731,8 +58277,8 @@ var require_sort2 = __commonJS({
|
|
|
57731
58277
|
// ../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js
|
|
57732
58278
|
var require_lib23 = __commonJS({
|
|
57733
58279
|
"../../node_modules/.pnpm/@npmcli+package-json@6.2.0/node_modules/@npmcli/package-json/lib/index.js"(exports, module) {
|
|
57734
|
-
var { readFile:
|
|
57735
|
-
var { resolve:
|
|
58280
|
+
var { readFile: readFile30, writeFile: writeFile11 } = __require("node:fs/promises");
|
|
58281
|
+
var { resolve: resolve25 } = __require("node:path");
|
|
57736
58282
|
var parseJSON = require_lib16();
|
|
57737
58283
|
var updateDeps = require_update_dependencies();
|
|
57738
58284
|
var updateScripts = require_update_scripts();
|
|
@@ -57855,10 +58401,10 @@ var require_lib23 = __commonJS({
|
|
|
57855
58401
|
parseErr = err;
|
|
57856
58402
|
}
|
|
57857
58403
|
if (parseErr) {
|
|
57858
|
-
const indexFile =
|
|
58404
|
+
const indexFile = resolve25(this.path, "index.js");
|
|
57859
58405
|
let indexFileContent;
|
|
57860
58406
|
try {
|
|
57861
|
-
indexFileContent = await
|
|
58407
|
+
indexFileContent = await readFile30(indexFile, "utf8");
|
|
57862
58408
|
} catch (err) {
|
|
57863
58409
|
throw parseErr;
|
|
57864
58410
|
}
|
|
@@ -57907,7 +58453,7 @@ var require_lib23 = __commonJS({
|
|
|
57907
58453
|
}
|
|
57908
58454
|
get filename() {
|
|
57909
58455
|
if (this.path) {
|
|
57910
|
-
return
|
|
58456
|
+
return resolve25(this.path, "package.json");
|
|
57911
58457
|
}
|
|
57912
58458
|
return void 0;
|
|
57913
58459
|
}
|
|
@@ -64833,12 +65379,12 @@ var require_fetcher = __commonJS({
|
|
|
64833
65379
|
};
|
|
64834
65380
|
exports.DefaultFetcher = DefaultFetcher;
|
|
64835
65381
|
var writeBufferToStream = /* @__PURE__ */ __name(async (stream, buffer) => {
|
|
64836
|
-
return new Promise((
|
|
65382
|
+
return new Promise((resolve25, reject) => {
|
|
64837
65383
|
stream.write(buffer, (err) => {
|
|
64838
65384
|
if (err) {
|
|
64839
65385
|
reject(err);
|
|
64840
65386
|
}
|
|
64841
|
-
|
|
65387
|
+
resolve25(true);
|
|
64842
65388
|
});
|
|
64843
65389
|
});
|
|
64844
65390
|
}, "writeBufferToStream");
|
|
@@ -65057,12 +65603,12 @@ var require_url = __commonJS({
|
|
|
65057
65603
|
"../../node_modules/.pnpm/tuf-js@3.1.0/node_modules/tuf-js/dist/utils/url.js"(exports) {
|
|
65058
65604
|
"use strict";
|
|
65059
65605
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65060
|
-
exports.join =
|
|
65606
|
+
exports.join = join26;
|
|
65061
65607
|
var url_1 = __require("url");
|
|
65062
|
-
function
|
|
65608
|
+
function join26(base, path3) {
|
|
65063
65609
|
return new url_1.URL(ensureTrailingSlash(base) + removeLeadingSlash(path3)).toString();
|
|
65064
65610
|
}
|
|
65065
|
-
__name(
|
|
65611
|
+
__name(join26, "join");
|
|
65066
65612
|
function ensureTrailingSlash(path3) {
|
|
65067
65613
|
return path3.endsWith("/") ? path3 : path3 + "/";
|
|
65068
65614
|
}
|
|
@@ -65441,7 +65987,7 @@ var require_target = __commonJS({
|
|
|
65441
65987
|
var error_1 = require_error8();
|
|
65442
65988
|
async function readTarget(tuf, targetPath) {
|
|
65443
65989
|
const path3 = await getTargetPath(tuf, targetPath);
|
|
65444
|
-
return new Promise((
|
|
65990
|
+
return new Promise((resolve25, reject) => {
|
|
65445
65991
|
fs_1.default.readFile(path3, "utf-8", (err, data) => {
|
|
65446
65992
|
if (err) {
|
|
65447
65993
|
reject(new error_1.TUFError({
|
|
@@ -65450,7 +65996,7 @@ var require_target = __commonJS({
|
|
|
65450
65996
|
cause: err
|
|
65451
65997
|
}));
|
|
65452
65998
|
} else {
|
|
65453
|
-
|
|
65999
|
+
resolve25(data);
|
|
65454
66000
|
}
|
|
65455
66001
|
});
|
|
65456
66002
|
});
|
|
@@ -67167,7 +67713,7 @@ var require_dist15 = __commonJS({
|
|
|
67167
67713
|
var require_provenance = __commonJS({
|
|
67168
67714
|
"../../node_modules/.pnpm/libnpmpublish@11.1.0/node_modules/libnpmpublish/lib/provenance.js"(exports, module) {
|
|
67169
67715
|
var sigstore = require_dist15();
|
|
67170
|
-
var { readFile:
|
|
67716
|
+
var { readFile: readFile30 } = __require("node:fs/promises");
|
|
67171
67717
|
var ci = require_ci_info();
|
|
67172
67718
|
var { env } = process;
|
|
67173
67719
|
var INTOTO_PAYLOAD_TYPE = "application/vnd.in-toto+json";
|
|
@@ -67359,7 +67905,7 @@ var require_provenance = __commonJS({
|
|
|
67359
67905
|
var verifyProvenance = /* @__PURE__ */ __name(async (subject, provenancePath) => {
|
|
67360
67906
|
let provenanceBundle;
|
|
67361
67907
|
try {
|
|
67362
|
-
provenanceBundle = JSON.parse(await
|
|
67908
|
+
provenanceBundle = JSON.parse(await readFile30(provenancePath));
|
|
67363
67909
|
} catch (err) {
|
|
67364
67910
|
err.message = `Invalid provenance provided: ${err.message}`;
|
|
67365
67911
|
throw err;
|
|
@@ -67698,9 +68244,9 @@ import { createHash as createHash9, randomUUID } from "node:crypto";
|
|
|
67698
68244
|
import { execFile as execFileCb6, spawn as spawn3 } from "node:child_process";
|
|
67699
68245
|
import { gunzipSync } from "node:zlib";
|
|
67700
68246
|
import { promisify as promisify6 } from "node:util";
|
|
67701
|
-
import { dirname as dirname7, isAbsolute as
|
|
68247
|
+
import { dirname as dirname7, isAbsolute as isAbsolute11, join as join11, relative as relative13, resolve as resolve15 } from "node:path";
|
|
67702
68248
|
import { constants as fsConstants4 } from "node:fs";
|
|
67703
|
-
import { chmod as chmod3, lstat as lstat9, mkdtemp as mkdtemp2, open as open6, readFile as
|
|
68249
|
+
import { chmod as chmod3, lstat as lstat9, mkdtemp as mkdtemp2, open as open6, readFile as readFile13, realpath as realpath9, rm as rm5 } from "node:fs/promises";
|
|
67704
68250
|
function validatePackageName(value) {
|
|
67705
68251
|
if (typeof value !== "string" || value.length > 214 || !SAFE_PACKAGE_NAME.test(value)) {
|
|
67706
68252
|
throw new Error("npm package must be a safe lowercase package name or @scope/name");
|
|
@@ -67754,7 +68300,7 @@ function expandNpmrcValue(raw, env) {
|
|
|
67754
68300
|
async function tokensFromNpmrc(path3, key, env) {
|
|
67755
68301
|
let contents;
|
|
67756
68302
|
try {
|
|
67757
|
-
contents = await
|
|
68303
|
+
contents = await readFile13(path3, "utf8");
|
|
67758
68304
|
} catch (err) {
|
|
67759
68305
|
if (err?.code === "ENOENT") return [];
|
|
67760
68306
|
throw new Error("cannot read npm authentication config");
|
|
@@ -67777,7 +68323,7 @@ async function defaultResolveAuthToken({ registry, cwd, exec, env = process.env
|
|
|
67777
68323
|
if (env[name]) candidates.push(env[name]);
|
|
67778
68324
|
}
|
|
67779
68325
|
const key = registryTokenKey(registry);
|
|
67780
|
-
candidates.push(...await tokensFromNpmrc(
|
|
68326
|
+
candidates.push(...await tokensFromNpmrc(join11(cwd, ".npmrc"), key, env));
|
|
67781
68327
|
const npmUserConfigKey = ["npm", "config", "userconfig"].join("_");
|
|
67782
68328
|
const userConfig = env[npmUserConfigKey] ?? (await exec("npm", ["config", "get", "userconfig"], { cwd, shell: false })).stdout.trim();
|
|
67783
68329
|
if (userConfig) candidates.push(...await tokensFromNpmrc(userConfig, key, env));
|
|
@@ -67806,10 +68352,10 @@ async function defaultWhoamiWithToken({ registry, token, cwd, exec }) {
|
|
|
67806
68352
|
}
|
|
67807
68353
|
function resolvePackageCwd(cwd, root) {
|
|
67808
68354
|
if (!cwd || typeof cwd !== "string") throw new Error("NPM_PUBLISH requires a non-empty action.cwd (package directory)");
|
|
67809
|
-
const rootPath =
|
|
67810
|
-
const packagePath =
|
|
67811
|
-
const rel =
|
|
67812
|
-
if (
|
|
68355
|
+
const rootPath = resolve15(root);
|
|
68356
|
+
const packagePath = resolve15(root, cwd);
|
|
68357
|
+
const rel = relative13(rootPath, packagePath);
|
|
68358
|
+
if (isAbsolute11(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
67813
68359
|
throw new Error(`cwd "${cwd}" is outside project root "${root}"`);
|
|
67814
68360
|
}
|
|
67815
68361
|
return packagePath;
|
|
@@ -67822,12 +68368,12 @@ ${error?.message ?? ""}`;
|
|
|
67822
68368
|
return /\bE404\b|\b404\b.*not found|not found.*\b404\b/i.test(text);
|
|
67823
68369
|
}
|
|
67824
68370
|
async function readVerifiedTarballBytes(action, root) {
|
|
67825
|
-
if (!action.tarballPath ||
|
|
68371
|
+
if (!action.tarballPath || isAbsolute11(action.tarballPath)) throw new Error("tarballPath must be project-relative");
|
|
67826
68372
|
if (!/^[a-f0-9]{64}$/.test(action.tarballSha256 ?? "")) throw new Error("tarballSha256 must be a lowercase SHA-256 digest");
|
|
67827
68373
|
const rootReal = await realpath9(root);
|
|
67828
|
-
const lexical =
|
|
67829
|
-
const rel =
|
|
67830
|
-
if (
|
|
68374
|
+
const lexical = resolve15(rootReal, action.tarballPath);
|
|
68375
|
+
const rel = relative13(rootReal, lexical);
|
|
68376
|
+
if (isAbsolute11(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
67831
68377
|
throw new Error("tarballPath escapes project root");
|
|
67832
68378
|
}
|
|
67833
68379
|
const before = await lstat9(lexical);
|
|
@@ -68096,7 +68642,7 @@ function createNpmAdapter(deps = {}) {
|
|
|
68096
68642
|
throw new Error("npm bearer authentication does not match the frozen registry and publisher");
|
|
68097
68643
|
}
|
|
68098
68644
|
if (typeof beforeBufferPublishHook === "function") {
|
|
68099
|
-
await beforeBufferPublishHook(
|
|
68645
|
+
await beforeBufferPublishHook(resolve15(context.root, action.tarballPath));
|
|
68100
68646
|
}
|
|
68101
68647
|
try {
|
|
68102
68648
|
await publishTarballBuffer({
|
|
@@ -68258,11 +68804,11 @@ var init_npm = __esm({
|
|
|
68258
68804
|
});
|
|
68259
68805
|
|
|
68260
68806
|
// src/core/run.mjs
|
|
68261
|
-
import { link as link2, lstat as lstat10, mkdir as
|
|
68807
|
+
import { link as link2, lstat as lstat10, mkdir as mkdir11, open as open7, readFile as readFile14, unlink as unlink3 } from "node:fs/promises";
|
|
68262
68808
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
68263
|
-
import { dirname as dirname8, join as
|
|
68809
|
+
import { dirname as dirname8, join as join12, resolve as resolve16, basename as basename4, relative as relative14, isAbsolute as isAbsolute12 } from "node:path";
|
|
68264
68810
|
function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.now()}`) {
|
|
68265
|
-
const absolute =
|
|
68811
|
+
const absolute = resolve16(planPath);
|
|
68266
68812
|
const fileName = basename4(absolute);
|
|
68267
68813
|
const parentDir = dirname8(absolute);
|
|
68268
68814
|
if (fileName === "release-plan.json") {
|
|
@@ -68270,7 +68816,7 @@ function resolveDefaultRunDir(planPath, command2, runId = `${command2}-${Date.no
|
|
|
68270
68816
|
}
|
|
68271
68817
|
if (basename4(parentDir) === "plans") {
|
|
68272
68818
|
const releaseDir = dirname8(parentDir);
|
|
68273
|
-
return
|
|
68819
|
+
return join12(releaseDir, "runs", runId);
|
|
68274
68820
|
}
|
|
68275
68821
|
return `${parentDir}/runs/${runId}`;
|
|
68276
68822
|
}
|
|
@@ -68310,7 +68856,7 @@ function validateRun(run5, options = {}) {
|
|
|
68310
68856
|
async function loadRun(runPath, options = {}) {
|
|
68311
68857
|
let raw;
|
|
68312
68858
|
try {
|
|
68313
|
-
raw = await
|
|
68859
|
+
raw = await readFile14(runPath, "utf8");
|
|
68314
68860
|
} catch (err) {
|
|
68315
68861
|
throw new ReleaseError(
|
|
68316
68862
|
GATE_FAILED,
|
|
@@ -68335,7 +68881,7 @@ async function loadRun(runPath, options = {}) {
|
|
|
68335
68881
|
return run5;
|
|
68336
68882
|
}
|
|
68337
68883
|
function assertImmutableRunAuthority(runPath, planPath, run5) {
|
|
68338
|
-
const absolutePlan = realpathSync3(
|
|
68884
|
+
const absolutePlan = realpathSync3(resolve16(planPath));
|
|
68339
68885
|
const planDir = dirname8(absolutePlan);
|
|
68340
68886
|
if (basename4(planDir) !== "plans") {
|
|
68341
68887
|
throw new ReleaseError(GATE_FAILED, "run authority requires an immutable plans/<digest>.json plan path");
|
|
@@ -68349,10 +68895,10 @@ function assertImmutableRunAuthority(runPath, planPath, run5) {
|
|
|
68349
68895
|
}
|
|
68350
68896
|
cursor = dirname8(cursor);
|
|
68351
68897
|
}
|
|
68352
|
-
const runsDir =
|
|
68353
|
-
const absoluteRun = realpathSync3(
|
|
68354
|
-
const rel =
|
|
68355
|
-
if (
|
|
68898
|
+
const runsDir = join12(authorityRoot, "runs");
|
|
68899
|
+
const absoluteRun = realpathSync3(resolve16(runPath));
|
|
68900
|
+
const rel = relative14(runsDir, absoluteRun);
|
|
68901
|
+
if (isAbsolute12(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
68356
68902
|
throw new ReleaseError(GATE_FAILED, "production run authority must be inside the plan sibling runs/ directory");
|
|
68357
68903
|
}
|
|
68358
68904
|
const fileName = basename4(absoluteRun);
|
|
@@ -68367,7 +68913,7 @@ function assertImmutableRunAuthority(runPath, planPath, run5) {
|
|
|
68367
68913
|
}
|
|
68368
68914
|
}
|
|
68369
68915
|
async function createProductionRunDir(runDir, planPath) {
|
|
68370
|
-
const absolutePlan = realpathSync3(
|
|
68916
|
+
const absolutePlan = realpathSync3(resolve16(planPath));
|
|
68371
68917
|
const planDir = dirname8(absolutePlan);
|
|
68372
68918
|
if (basename4(planDir) !== "plans") {
|
|
68373
68919
|
throw new ReleaseError(GATE_FAILED, "production run directory requires an immutable plans/<digest>.json authority");
|
|
@@ -68376,7 +68922,7 @@ async function createProductionRunDir(runDir, planPath) {
|
|
|
68376
68922
|
return createProductionRunDirWithinAuthority(runDir, authorityRoot);
|
|
68377
68923
|
}
|
|
68378
68924
|
async function createProductionPrepareRunDir(runDir, releaseDir) {
|
|
68379
|
-
const authorityRoot =
|
|
68925
|
+
const authorityRoot = resolve16(releaseDir);
|
|
68380
68926
|
let authorityStat;
|
|
68381
68927
|
try {
|
|
68382
68928
|
authorityStat = await lstat10(authorityRoot);
|
|
@@ -68404,7 +68950,7 @@ async function createProductionPrepareRunDir(runDir, releaseDir) {
|
|
|
68404
68950
|
return createProductionRunDirWithinAuthority(runDir, physicalAuthorityRoot);
|
|
68405
68951
|
}
|
|
68406
68952
|
async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
68407
|
-
const runsDir =
|
|
68953
|
+
const runsDir = join12(authorityRoot, "runs");
|
|
68408
68954
|
let runsStat;
|
|
68409
68955
|
try {
|
|
68410
68956
|
runsStat = await lstat10(runsDir);
|
|
@@ -68416,7 +68962,7 @@ async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
|
68416
68962
|
});
|
|
68417
68963
|
}
|
|
68418
68964
|
try {
|
|
68419
|
-
await
|
|
68965
|
+
await mkdir11(runsDir, { mode: 448 });
|
|
68420
68966
|
} catch (mkdirError) {
|
|
68421
68967
|
if (mkdirError.code !== "EEXIST") {
|
|
68422
68968
|
throw new ReleaseError(GATE_FAILED, "cannot create production runs authority root", {
|
|
@@ -68442,7 +68988,7 @@ async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
|
68442
68988
|
{ runsDir, physicalRunsDir }
|
|
68443
68989
|
);
|
|
68444
68990
|
}
|
|
68445
|
-
const requested =
|
|
68991
|
+
const requested = resolve16(runDir);
|
|
68446
68992
|
let physicalParent;
|
|
68447
68993
|
try {
|
|
68448
68994
|
physicalParent = realpathSync3(dirname8(requested));
|
|
@@ -68472,7 +69018,7 @@ async function createProductionRunDirWithinAuthority(runDir, authorityRoot) {
|
|
|
68472
69018
|
}
|
|
68473
69019
|
}
|
|
68474
69020
|
try {
|
|
68475
|
-
await
|
|
69021
|
+
await mkdir11(requested, { mode: 448 });
|
|
68476
69022
|
} catch (error) {
|
|
68477
69023
|
throw new ReleaseError(GATE_FAILED, "cannot exclusively create production run directory", {
|
|
68478
69024
|
runDir,
|
|
@@ -68493,7 +69039,7 @@ async function validateStatePredecessorChain(run5, runPath, options = {}) {
|
|
|
68493
69039
|
return;
|
|
68494
69040
|
}
|
|
68495
69041
|
let current = run5;
|
|
68496
|
-
let currentPath = realpathSync3(
|
|
69042
|
+
let currentPath = realpathSync3(resolve16(runPath));
|
|
68497
69043
|
let traversed = 0;
|
|
68498
69044
|
while (true) {
|
|
68499
69045
|
const sequence = current.stateSequence;
|
|
@@ -68514,7 +69060,7 @@ async function validateStatePredecessorChain(run5, runPath, options = {}) {
|
|
|
68514
69060
|
if (traversed > 1e5) {
|
|
68515
69061
|
throw new ReleaseError(GATE_FAILED, "run state predecessor chain exceeds maximum depth");
|
|
68516
69062
|
}
|
|
68517
|
-
const previousPath =
|
|
69063
|
+
const previousPath = join12(dirname8(currentPath), `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
68518
69064
|
const previous = await loadRun(previousPath, {
|
|
68519
69065
|
requireDigest: true,
|
|
68520
69066
|
...options.production ? { authorityPlanPath: options.planPath } : {}
|
|
@@ -68607,7 +69153,7 @@ function validateRunPlanDigest(run5, plan, options = {}) {
|
|
|
68607
69153
|
{ runDigest: run5.planDigest, planDigest: expectedDigest }
|
|
68608
69154
|
);
|
|
68609
69155
|
}
|
|
68610
|
-
if (plan.production && run5.planPath && options.planPath &&
|
|
69156
|
+
if (plan.production && run5.planPath && options.planPath && resolve16(run5.planPath) !== resolve16(options.planPath)) {
|
|
68611
69157
|
throw new ReleaseError(
|
|
68612
69158
|
GATE_FAILED,
|
|
68613
69159
|
"source run immutable plan path does not match the supplied plan authority",
|
|
@@ -68691,7 +69237,7 @@ async function writeRunAtomic(runPath, run5) {
|
|
|
68691
69237
|
const json = JSON.stringify(sealed, null, 2);
|
|
68692
69238
|
const dir = dirname8(runPath);
|
|
68693
69239
|
const tmpPath = `${dir}/.release-run-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
|
|
68694
|
-
await
|
|
69240
|
+
await mkdir11(dir, { recursive: true });
|
|
68695
69241
|
const handle = await open7(tmpPath, "wx", 384);
|
|
68696
69242
|
try {
|
|
68697
69243
|
await handle.writeFile(json, "utf8");
|
|
@@ -68705,7 +69251,7 @@ async function writeRunAtomic(runPath, run5) {
|
|
|
68705
69251
|
await syncDirectory(dir);
|
|
68706
69252
|
} catch (error) {
|
|
68707
69253
|
if (error.code !== "EEXIST") throw error;
|
|
68708
|
-
const existing = await
|
|
69254
|
+
const existing = await readFile14(runPath, "utf8");
|
|
68709
69255
|
if (existing !== json) {
|
|
68710
69256
|
throw new ReleaseError(
|
|
68711
69257
|
GATE_FAILED,
|
|
@@ -68724,10 +69270,10 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
68724
69270
|
if (!Number.isSafeInteger(sequence) || sequence < 0) {
|
|
68725
69271
|
throw new ReleaseError(GATE_FAILED, "run state sequence must be a non-negative integer");
|
|
68726
69272
|
}
|
|
68727
|
-
const statesDir =
|
|
69273
|
+
const statesDir = join12(runDir, "states");
|
|
68728
69274
|
let previousStateDigest;
|
|
68729
69275
|
if (sequence > 0) {
|
|
68730
|
-
const previousPath =
|
|
69276
|
+
const previousPath = join12(statesDir, `${String(sequence - 1).padStart(6, "0")}.json`);
|
|
68731
69277
|
const previous = await loadRun(previousPath, { requireDigest: true });
|
|
68732
69278
|
if (previous.stateSequence !== sequence - 1 || previous.runId !== run5.runId || previous.command !== run5.command || previous.planDigest !== run5.planDigest) {
|
|
68733
69279
|
throw new ReleaseError(
|
|
@@ -68744,7 +69290,7 @@ async function appendRunState(runDir, sequence, run5) {
|
|
|
68744
69290
|
stateSequence: sequence,
|
|
68745
69291
|
...previousStateDigest ? { previousStateDigest } : {}
|
|
68746
69292
|
});
|
|
68747
|
-
const statePath =
|
|
69293
|
+
const statePath = join12(statesDir, `${String(sequence).padStart(6, "0")}.json`);
|
|
68748
69294
|
await writeRunAtomic(statePath, state);
|
|
68749
69295
|
return Object.freeze({ state, statePath });
|
|
68750
69296
|
}
|
|
@@ -68784,8 +69330,8 @@ var init_run = __esm({
|
|
|
68784
69330
|
});
|
|
68785
69331
|
|
|
68786
69332
|
// src/artifacts/transaction-journal.mjs
|
|
68787
|
-
import { readdir as readdir8, readFile as
|
|
68788
|
-
import { join as
|
|
69333
|
+
import { readdir as readdir8, readFile as readFile15, rm as rm6, stat as stat4 } from "node:fs/promises";
|
|
69334
|
+
import { join as join13 } from "node:path";
|
|
68789
69335
|
function failSchema(message, details) {
|
|
68790
69336
|
throw new ReleaseError(TRANSACTION_INCOMPLETE, message, details);
|
|
68791
69337
|
}
|
|
@@ -69792,11 +70338,11 @@ async function pruneTerminalTransactionRecords(transactionsRoot, {
|
|
|
69792
70338
|
if (txnDirs.length <= retentionMax) return summary;
|
|
69793
70339
|
const terminal = [];
|
|
69794
70340
|
for (const entry of txnDirs) {
|
|
69795
|
-
const recordDir =
|
|
70341
|
+
const recordDir = join13(transactionsRoot, entry.name);
|
|
69796
70342
|
let state = null;
|
|
69797
70343
|
let createdAt = null;
|
|
69798
70344
|
try {
|
|
69799
|
-
const raw = await
|
|
70345
|
+
const raw = await readFile15(join13(recordDir, "journal.json"), "utf8");
|
|
69800
70346
|
const journal = JSON.parse(raw);
|
|
69801
70347
|
if (journal && typeof journal === "object") {
|
|
69802
70348
|
state = typeof journal.state === "string" ? journal.state : null;
|
|
@@ -69860,7 +70406,7 @@ async function createTransactionJournal({
|
|
|
69860
70406
|
);
|
|
69861
70407
|
if (typeof root === "string" && root.length > 0) {
|
|
69862
70408
|
await pruneTerminalTransactionRecords(
|
|
69863
|
-
|
|
70409
|
+
join13(root, ".release-skill", "transactions"),
|
|
69864
70410
|
{ retentionMax }
|
|
69865
70411
|
);
|
|
69866
70412
|
}
|
|
@@ -70224,7 +70770,7 @@ __export(transaction_exports, {
|
|
|
70224
70770
|
applyWriteSetUnderLock: () => applyWriteSetUnderLock
|
|
70225
70771
|
});
|
|
70226
70772
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
70227
|
-
import { relative as
|
|
70773
|
+
import { relative as relative15 } from "node:path";
|
|
70228
70774
|
function computeCanonicalPlanDigest(plan) {
|
|
70229
70775
|
const { planDigest: _ignored, ...content } = plan;
|
|
70230
70776
|
return `sha256:${sha256Hex(canonicalJson(content))}`;
|
|
@@ -71137,7 +71683,7 @@ async function applyArtifactPlanUnderLock({
|
|
|
71137
71683
|
}
|
|
71138
71684
|
const handle = await safeFs.openRoot(root);
|
|
71139
71685
|
try {
|
|
71140
|
-
const relPlanPath = canonicalArtifactPath(
|
|
71686
|
+
const relPlanPath = canonicalArtifactPath(relative15(root, planPath)).path;
|
|
71141
71687
|
const planFileData = await withParentHandle(handle, relPlanPath, async (parent, leaf) => {
|
|
71142
71688
|
const planEntry = await parent.readEntry(leaf);
|
|
71143
71689
|
if (!planEntry || planEntry.kind === "absent") {
|
|
@@ -73552,7 +74098,7 @@ __export(refresh_service_exports, {
|
|
|
73552
74098
|
planReleaseDocsRefreshForUnit: () => planReleaseDocsRefreshForUnit,
|
|
73553
74099
|
runReleaseDocsRefresh: () => runReleaseDocsRefresh
|
|
73554
74100
|
});
|
|
73555
|
-
import { isAbsolute as
|
|
74101
|
+
import { isAbsolute as isAbsolute13, relative as relative16, resolve as resolve17, sep as sep3 } from "node:path";
|
|
73556
74102
|
function deepFreeze6(value) {
|
|
73557
74103
|
if (Array.isArray(value)) {
|
|
73558
74104
|
for (const item of value) deepFreeze6(item);
|
|
@@ -73635,7 +74181,7 @@ async function planReleaseDocsRefreshForUnit({
|
|
|
73635
74181
|
field: "unit.source"
|
|
73636
74182
|
});
|
|
73637
74183
|
}
|
|
73638
|
-
const unitRoot =
|
|
74184
|
+
const unitRoot = resolve17(root, unit.source);
|
|
73639
74185
|
const backend = await (backendFactory ?? loadSafeFs)();
|
|
73640
74186
|
const sharedFactory = /* @__PURE__ */ __name(async () => backend, "sharedFactory");
|
|
73641
74187
|
const notesSource = await loadReleaseNotesSource({
|
|
@@ -73845,9 +74391,9 @@ async function runReleaseDocsRefresh({
|
|
|
73845
74391
|
});
|
|
73846
74392
|
}
|
|
73847
74393
|
const changedFiles = plan.files.filter((file) => file.changed);
|
|
73848
|
-
const unitRoot =
|
|
73849
|
-
const unitLocation =
|
|
73850
|
-
if (unitLocation === ".." || unitLocation.startsWith(`..${sep3}`) ||
|
|
74394
|
+
const unitRoot = resolve17(root, unit.source);
|
|
74395
|
+
const unitLocation = relative16(root, unitRoot);
|
|
74396
|
+
if (unitLocation === ".." || unitLocation.startsWith(`..${sep3}`) || isAbsolute13(unitLocation)) {
|
|
73851
74397
|
throw new ReleaseError(
|
|
73852
74398
|
PATH_UNSAFE,
|
|
73853
74399
|
"release unit source escapes the project root",
|
|
@@ -73905,7 +74451,7 @@ async function runReleaseDocsRefresh({
|
|
|
73905
74451
|
if (err instanceof ReleaseError && err.code === TRANSACTION_INCOMPLETE && typeof err.details?.recover === "string") {
|
|
73906
74452
|
const restored = await tryRestoreOldBytes(
|
|
73907
74453
|
backend,
|
|
73908
|
-
|
|
74454
|
+
resolve17(root, unit.source),
|
|
73909
74455
|
changedFiles,
|
|
73910
74456
|
modes
|
|
73911
74457
|
);
|
|
@@ -73995,14 +74541,18 @@ var init_refresh_service = __esm({
|
|
|
73995
74541
|
// src/commands/prepare.mjs
|
|
73996
74542
|
var prepare_exports = {};
|
|
73997
74543
|
__export(prepare_exports, {
|
|
74544
|
+
buildExternalActions: () => buildExternalActions,
|
|
74545
|
+
decodeExternalMarketplaceIndex: () => decodeExternalMarketplaceIndex,
|
|
74546
|
+
parseExternalMarketplaceLsRemote: () => parseExternalMarketplaceLsRemote,
|
|
73998
74547
|
prepareRelease: () => prepareRelease,
|
|
73999
74548
|
readHeadCommitTimestamp: () => readHeadCommitTimestamp,
|
|
74000
74549
|
resolveAllUnitVersions: () => resolveAllUnitVersions,
|
|
74550
|
+
resolveExternalMarketplaceFreezes: () => resolveExternalMarketplaceFreezes,
|
|
74001
74551
|
resolveUnitVersion: () => resolveUnitVersion,
|
|
74002
74552
|
runDeclaredHooks: () => runDeclaredHooks
|
|
74003
74553
|
});
|
|
74004
|
-
import { resolve as
|
|
74005
|
-
import { readFile as
|
|
74554
|
+
import { resolve as resolve18, relative as relative17, isAbsolute as isAbsolute14, normalize as normalize3, dirname as dirname9 } from "node:path";
|
|
74555
|
+
import { readFile as readFile16, mkdir as mkdir12, realpath as realpath10 } from "node:fs/promises";
|
|
74006
74556
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
74007
74557
|
import { promisify as promisify7 } from "node:util";
|
|
74008
74558
|
async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
@@ -74014,18 +74564,18 @@ async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
|
74014
74564
|
{ unitId: unit.id }
|
|
74015
74565
|
);
|
|
74016
74566
|
}
|
|
74017
|
-
if (
|
|
74567
|
+
if (isAbsolute14(versionSource)) {
|
|
74018
74568
|
throw new ReleaseError(
|
|
74019
74569
|
CONFIG_INVALID,
|
|
74020
74570
|
`unit "${unit.id}" version.source must be a relative path, got absolute: "${versionSource}"`,
|
|
74021
74571
|
{ unitId: unit.id, versionSource }
|
|
74022
74572
|
);
|
|
74023
74573
|
}
|
|
74024
|
-
const unitRoot =
|
|
74025
|
-
const resolvedPath =
|
|
74574
|
+
const unitRoot = resolve18(root, unit.source);
|
|
74575
|
+
const resolvedPath = resolve18(unitRoot, versionSource);
|
|
74026
74576
|
const normalizedPath = normalize3(resolvedPath);
|
|
74027
|
-
const rel =
|
|
74028
|
-
if (rel.startsWith("..") || rel === ".." ||
|
|
74577
|
+
const rel = relative17(unitRoot, normalizedPath);
|
|
74578
|
+
if (rel.startsWith("..") || rel === ".." || isAbsolute14(rel)) {
|
|
74029
74579
|
throw new ReleaseError(
|
|
74030
74580
|
CONFIG_INVALID,
|
|
74031
74581
|
`unit "${unit.id}" version.source escapes unit root: "${versionSource}"`,
|
|
@@ -74034,7 +74584,7 @@ async function resolveUnitVersion(unit, root, explicitVersion) {
|
|
|
74034
74584
|
}
|
|
74035
74585
|
let content;
|
|
74036
74586
|
try {
|
|
74037
|
-
content = await
|
|
74587
|
+
content = await readFile16(normalizedPath, "utf8");
|
|
74038
74588
|
} catch (err) {
|
|
74039
74589
|
throw new ReleaseError(
|
|
74040
74590
|
CONFIG_INVALID,
|
|
@@ -74324,7 +74874,7 @@ async function processSnapshots(config, root, evidence, runDir, production = fal
|
|
|
74324
74874
|
const unitResults = [];
|
|
74325
74875
|
const snapshotDigests = [];
|
|
74326
74876
|
for (const unit of units) {
|
|
74327
|
-
const outputDir = resolveUnitScopedPath(
|
|
74877
|
+
const outputDir = resolveUnitScopedPath(resolve18(runDir, "snapshots"), unit.id);
|
|
74328
74878
|
await evidence.append({
|
|
74329
74879
|
phase: "snapshot",
|
|
74330
74880
|
status: "started",
|
|
@@ -74552,7 +75102,7 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74552
75102
|
const { unit, manifest } = unitResults[index];
|
|
74553
75103
|
const version = resolvedVersions[index];
|
|
74554
75104
|
const { tag, branch, branchStrategy } = resolveProductionBranch(unit, version);
|
|
74555
|
-
const snapshotPath =
|
|
75105
|
+
const snapshotPath = relative17(root, manifest.outputDir);
|
|
74556
75106
|
const observed = await computeFrozenSnapshot(manifest.outputDir);
|
|
74557
75107
|
if (observed.digest !== manifest.snapshotDigest) {
|
|
74558
75108
|
throw new ReleaseError(
|
|
@@ -74563,7 +75113,7 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74563
75113
|
}
|
|
74564
75114
|
await sealFrozenSnapshot(manifest.outputDir);
|
|
74565
75115
|
const sealed = await computeFrozenSnapshot(manifest.outputDir);
|
|
74566
|
-
const repositoryDir = resolveUnitScopedPath(
|
|
75116
|
+
const repositoryDir = resolveUnitScopedPath(resolve18(runDir, "git"), unit.id, { suffix: ".git" });
|
|
74567
75117
|
const unitBaseline = unitBaselineResults.get(unit.id);
|
|
74568
75118
|
const parent = branchStrategy === "create-release-branch" ? void 0 : {
|
|
74569
75119
|
githubHost: unitBaseline.githubHost,
|
|
@@ -74584,13 +75134,13 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74584
75134
|
if (npmDistribution) {
|
|
74585
75135
|
npm = await buildFrozenNpmTarball({
|
|
74586
75136
|
snapshotDir: manifest.outputDir,
|
|
74587
|
-
tarballDir: resolveUnitScopedPath(
|
|
75137
|
+
tarballDir: resolveUnitScopedPath(resolve18(runDir, "tarballs"), unit.id),
|
|
74588
75138
|
expectedSnapshotDigest: sealed.digest
|
|
74589
75139
|
});
|
|
74590
75140
|
await verifyFrozenNpmTarballIdentity({
|
|
74591
75141
|
package: npmDistribution.package,
|
|
74592
75142
|
version,
|
|
74593
|
-
tarballPath:
|
|
75143
|
+
tarballPath: relative17(root, npm.tarballPath),
|
|
74594
75144
|
tarballSha256: npm.sha256,
|
|
74595
75145
|
integrity: npm.integrity
|
|
74596
75146
|
}, root);
|
|
@@ -74598,7 +75148,7 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74598
75148
|
assets.push({
|
|
74599
75149
|
snapshotPath,
|
|
74600
75150
|
manifestDigest: sealed.digest,
|
|
74601
|
-
gitObjectDir:
|
|
75151
|
+
gitObjectDir: relative17(root, repositoryDir),
|
|
74602
75152
|
commit: git2.commit,
|
|
74603
75153
|
tree: git2.tree,
|
|
74604
75154
|
commitTimestamp: canonicalFreezeTimestamp,
|
|
@@ -74607,7 +75157,7 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74607
75157
|
branch,
|
|
74608
75158
|
tag,
|
|
74609
75159
|
npm: npm ? {
|
|
74610
|
-
tarballPath:
|
|
75160
|
+
tarballPath: relative17(root, npm.tarballPath),
|
|
74611
75161
|
tarballSha256: npm.sha256,
|
|
74612
75162
|
integrity: npm.integrity,
|
|
74613
75163
|
size: npm.size
|
|
@@ -74616,7 +75166,167 @@ async function buildProductionAssets(unitResults, resolvedVersions, root, runDir
|
|
|
74616
75166
|
}
|
|
74617
75167
|
return assets;
|
|
74618
75168
|
}
|
|
74619
|
-
function
|
|
75169
|
+
function parseExternalMarketplaceLsRemote(stdout) {
|
|
75170
|
+
if (typeof stdout !== "string") return null;
|
|
75171
|
+
const lines = stdout.trim().split("\n").filter((line) => line.length > 0);
|
|
75172
|
+
let defaultBranch = null;
|
|
75173
|
+
let sha = null;
|
|
75174
|
+
for (const line of lines) {
|
|
75175
|
+
const tabIndex = line.indexOf(" ");
|
|
75176
|
+
if (tabIndex < 0) continue;
|
|
75177
|
+
const left = line.slice(0, tabIndex);
|
|
75178
|
+
const right = line.slice(tabIndex + 1);
|
|
75179
|
+
if (right !== "HEAD") continue;
|
|
75180
|
+
if (left.startsWith("ref: refs/heads/")) {
|
|
75181
|
+
defaultBranch = left.slice("ref: refs/heads/".length);
|
|
75182
|
+
} else if (EXTERNAL_MARKETPLACE_SHA_RE2.test(left)) {
|
|
75183
|
+
sha = left;
|
|
75184
|
+
}
|
|
75185
|
+
}
|
|
75186
|
+
if (!sha || !defaultBranch) return null;
|
|
75187
|
+
return { sha, defaultBranch };
|
|
75188
|
+
}
|
|
75189
|
+
function decodeExternalMarketplaceIndex(base64Content) {
|
|
75190
|
+
if (typeof base64Content !== "string") return null;
|
|
75191
|
+
try {
|
|
75192
|
+
const base64 = base64Content.replace(/\s/g, "");
|
|
75193
|
+
const content = Buffer.from(base64, "base64").toString("utf8");
|
|
75194
|
+
const parsed = JSON.parse(content);
|
|
75195
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
75196
|
+
} catch {
|
|
75197
|
+
return null;
|
|
75198
|
+
}
|
|
75199
|
+
}
|
|
75200
|
+
async function defaultObserveExternalMarketplaceHead(repo, { githubHost = "github.com" } = {}) {
|
|
75201
|
+
try {
|
|
75202
|
+
const { stdout } = await execFile6(
|
|
75203
|
+
"git",
|
|
75204
|
+
["ls-remote", "--symref", `https://${githubHost}/${repo}.git`, "HEAD"],
|
|
75205
|
+
{ shell: false, encoding: "utf8", timeout: 3e4 }
|
|
75206
|
+
);
|
|
75207
|
+
const parsed = parseExternalMarketplaceLsRemote(stdout);
|
|
75208
|
+
if (!parsed) {
|
|
75209
|
+
return { status: "unknown", error: "could not resolve HEAD commit sha and default branch from ls-remote --symref output" };
|
|
75210
|
+
}
|
|
75211
|
+
return { status: "observed", sha: parsed.sha, defaultBranch: parsed.defaultBranch };
|
|
75212
|
+
} catch (error) {
|
|
75213
|
+
return { status: "unknown", error: error.message };
|
|
75214
|
+
}
|
|
75215
|
+
}
|
|
75216
|
+
async function defaultFetchExternalMarketplaceIndex(repo, manifestPath, ref, { githubHost = "github.com" } = {}) {
|
|
75217
|
+
try {
|
|
75218
|
+
const { stdout } = await execFile6(
|
|
75219
|
+
"gh",
|
|
75220
|
+
["api", `repos/${repo}/contents/${manifestPath}?ref=${ref}`, "--jq", ".content"],
|
|
75221
|
+
{
|
|
75222
|
+
shell: false,
|
|
75223
|
+
encoding: "utf8",
|
|
75224
|
+
timeout: 3e4,
|
|
75225
|
+
env: { ...process.env, GH_HOST: githubHost }
|
|
75226
|
+
}
|
|
75227
|
+
);
|
|
75228
|
+
const index = decodeExternalMarketplaceIndex(stdout);
|
|
75229
|
+
if (!index) {
|
|
75230
|
+
return { status: "unknown", error: "could not decode external marketplace index content" };
|
|
75231
|
+
}
|
|
75232
|
+
return { status: "fetched", index };
|
|
75233
|
+
} catch (error) {
|
|
75234
|
+
return { status: "unknown", error: error.message };
|
|
75235
|
+
}
|
|
75236
|
+
}
|
|
75237
|
+
async function resolveExternalMarketplaceFreezes({
|
|
75238
|
+
unitResults,
|
|
75239
|
+
resolvedVersions,
|
|
75240
|
+
offline,
|
|
75241
|
+
evidence,
|
|
75242
|
+
observeHeadFn,
|
|
75243
|
+
fetchIndexFn
|
|
75244
|
+
}) {
|
|
75245
|
+
const freezes = /* @__PURE__ */ new Map();
|
|
75246
|
+
for (let index = 0; index < unitResults.length; index += 1) {
|
|
75247
|
+
const { unit } = unitResults[index];
|
|
75248
|
+
const version = resolvedVersions[index];
|
|
75249
|
+
const githubHost = unit.production?.githubHost ?? "github.com";
|
|
75250
|
+
for (const dist of unit.distributions ?? []) {
|
|
75251
|
+
if (dist.marketplaceRepo === void 0 || dist.marketplaceRepo === null) continue;
|
|
75252
|
+
const platform = PLATFORMS.find((p) => p.distributionType === dist.type);
|
|
75253
|
+
if (!platform || platform.marketplaceRefForm === null) {
|
|
75254
|
+
throw new ReleaseError(
|
|
75255
|
+
GATE_FAILED,
|
|
75256
|
+
`unit "${unit.id}" ${dist.type} distribution declares marketplaceRepo but the platform has no marketplace add capability`,
|
|
75257
|
+
{ unitId: unit.id, distributionType: dist.type }
|
|
75258
|
+
);
|
|
75259
|
+
}
|
|
75260
|
+
if (offline) {
|
|
75261
|
+
throw new ReleaseError(
|
|
75262
|
+
GATE_FAILED,
|
|
75263
|
+
`unit "${unit.id}" ${dist.type} external marketplace form requires online production prepare to freeze the marketplace commit sha`,
|
|
75264
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75265
|
+
);
|
|
75266
|
+
}
|
|
75267
|
+
const observed = await observeHeadFn(dist.marketplaceRepo, { githubHost });
|
|
75268
|
+
if (observed.status !== "observed" || !EXTERNAL_MARKETPLACE_SHA_RE2.test(observed.sha ?? "") || !observed.defaultBranch) {
|
|
75269
|
+
throw new ReleaseError(
|
|
75270
|
+
GATE_FAILED,
|
|
75271
|
+
`unit "${unit.id}" could not freeze external marketplace "${dist.marketplaceRepo}" HEAD: ${observed.error ?? "unknown"}`,
|
|
75272
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75273
|
+
);
|
|
75274
|
+
}
|
|
75275
|
+
const sha = observed.sha;
|
|
75276
|
+
const manifestPath = platform.manifestPaths.marketplace;
|
|
75277
|
+
const fetched = await fetchIndexFn(dist.marketplaceRepo, manifestPath, sha, { githubHost });
|
|
75278
|
+
if (fetched.status !== "fetched" || !fetched.index || typeof fetched.index !== "object") {
|
|
75279
|
+
throw new ReleaseError(
|
|
75280
|
+
GATE_FAILED,
|
|
75281
|
+
`unit "${unit.id}" could not read external marketplace index for "${dist.marketplaceRepo}" at ${sha}: ${fetched.error ?? "unknown"}`,
|
|
75282
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75283
|
+
);
|
|
75284
|
+
}
|
|
75285
|
+
const marketplaceIndex = fetched.index;
|
|
75286
|
+
if (marketplaceIndex.name !== dist.marketplace) {
|
|
75287
|
+
throw new ReleaseError(
|
|
75288
|
+
GATE_FAILED,
|
|
75289
|
+
`unit "${unit.id}" external marketplace index name "${marketplaceIndex.name}" does not match distribution marketplace "${dist.marketplace}"`,
|
|
75290
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75291
|
+
);
|
|
75292
|
+
}
|
|
75293
|
+
const pluginEntries = Array.isArray(marketplaceIndex.plugins) ? marketplaceIndex.plugins.filter((entry) => entry && entry.name === dist.plugin) : [];
|
|
75294
|
+
if (pluginEntries.length !== 1) {
|
|
75295
|
+
throw new ReleaseError(
|
|
75296
|
+
GATE_FAILED,
|
|
75297
|
+
`unit "${unit.id}" external marketplace index must contain exactly one plugin entry named "${dist.plugin}", found ${pluginEntries.length}`,
|
|
75298
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75299
|
+
);
|
|
75300
|
+
}
|
|
75301
|
+
if (platform.marketplaceEntryCarriesVersion && pluginEntries[0].version !== version) {
|
|
75302
|
+
throw new ReleaseError(
|
|
75303
|
+
GATE_FAILED,
|
|
75304
|
+
`unit "${unit.id}" external marketplace index entry version "${pluginEntries[0].version}" does not match target version "${version}"`,
|
|
75305
|
+
{ unitId: unit.id, marketplaceRepo: dist.marketplaceRepo }
|
|
75306
|
+
);
|
|
75307
|
+
}
|
|
75308
|
+
const ref = platform.marketplaceRefForm === "sha" ? sha : observed.defaultBranch;
|
|
75309
|
+
freezes.set(`${unit.id} ${dist.type}`, {
|
|
75310
|
+
repo: dist.marketplaceRepo,
|
|
75311
|
+
ref,
|
|
75312
|
+
marketplaceCommitSha: sha,
|
|
75313
|
+
marketplace: dist.marketplace
|
|
75314
|
+
});
|
|
75315
|
+
await evidence.append({
|
|
75316
|
+
phase: "external-marketplace-freeze",
|
|
75317
|
+
unitId: unit.id,
|
|
75318
|
+
distributionType: dist.type,
|
|
75319
|
+
status: "completed",
|
|
75320
|
+
marketplaceRepo: dist.marketplaceRepo,
|
|
75321
|
+
marketplaceCommitSha: sha,
|
|
75322
|
+
defaultBranch: observed.defaultBranch,
|
|
75323
|
+
addRef: ref
|
|
75324
|
+
});
|
|
75325
|
+
}
|
|
75326
|
+
}
|
|
75327
|
+
return freezes;
|
|
75328
|
+
}
|
|
75329
|
+
function buildExternalActions(unitResults, resolvedVersions, productionAssets, externalFreezes = /* @__PURE__ */ new Map()) {
|
|
74620
75330
|
const actions = [];
|
|
74621
75331
|
if (!productionAssets) {
|
|
74622
75332
|
for (let index = 0; index < unitResults.length; index += 1) {
|
|
@@ -74677,6 +75387,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74677
75387
|
if (!dist) continue;
|
|
74678
75388
|
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
74679
75389
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
75390
|
+
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
74680
75391
|
actions.push({
|
|
74681
75392
|
id: `${platform.actionType}-${unit.id}`,
|
|
74682
75393
|
type: platform.actionType,
|
|
@@ -74686,7 +75397,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74686
75397
|
consumer: platform.id,
|
|
74687
75398
|
plugin: dist.plugin,
|
|
74688
75399
|
...requiresMarketplace ? { marketplace: dist.marketplace } : {},
|
|
74689
|
-
repo: unit.publicRepo,
|
|
75400
|
+
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
74690
75401
|
version,
|
|
74691
75402
|
entrySkill: dist.entrySkill,
|
|
74692
75403
|
timeoutMs,
|
|
@@ -74694,14 +75405,18 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74694
75405
|
// payload is verified by declared-manifest containment; host-added
|
|
74695
75406
|
// files are recorded, not failed. Frozen plans without this marker
|
|
74696
75407
|
// keep the legacy full-tree equality semantics byte-for-byte.
|
|
74697
|
-
|
|
75408
|
+
// External marketplace form uses the external-marketplace-v1
|
|
75409
|
+
// contract (whole-tree '.' containment; see plugin-marketplace).
|
|
75410
|
+
payloadContract: externalMarketplace ? "external-marketplace-v1" : "declared-manifest-v1",
|
|
75411
|
+
...externalMarketplace ? { marketplaceLocation: "external" } : {}
|
|
74698
75412
|
},
|
|
74699
75413
|
expected: {
|
|
74700
75414
|
installed: true,
|
|
74701
75415
|
plugin: dist.plugin,
|
|
74702
75416
|
...requiresMarketplace ? { marketplace: dist.marketplace } : {},
|
|
74703
75417
|
version,
|
|
74704
|
-
entrySkill: dist.entrySkill
|
|
75418
|
+
entrySkill: dist.entrySkill,
|
|
75419
|
+
...externalMarketplace ? { marketplaceLocation: "external", repo: dist.marketplaceRepo } : {}
|
|
74705
75420
|
},
|
|
74706
75421
|
status: "PENDING"
|
|
74707
75422
|
});
|
|
@@ -74836,6 +75551,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74836
75551
|
if (!dist) continue;
|
|
74837
75552
|
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
74838
75553
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
75554
|
+
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
75555
|
+
const freeze = externalMarketplace ? externalFreezes.get(`${unit.id} ${dist.type}`) : null;
|
|
74839
75556
|
actions.push({
|
|
74840
75557
|
id: `${platform.actionType}-${unit.id}`,
|
|
74841
75558
|
type: platform.actionType,
|
|
@@ -74845,8 +75562,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74845
75562
|
consumer: platform.id,
|
|
74846
75563
|
plugin: dist.plugin,
|
|
74847
75564
|
...requiresMarketplace ? { marketplace: dist.marketplace } : {},
|
|
74848
|
-
repo: unit.publicRepo,
|
|
74849
|
-
ref: resolvedTag,
|
|
75565
|
+
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
75566
|
+
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
|
74850
75567
|
version: unitVersion,
|
|
74851
75568
|
entrySkill: dist.entrySkill,
|
|
74852
75569
|
snapshotPath: asset.snapshotPath,
|
|
@@ -74856,19 +75573,23 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
74856
75573
|
// payload is verified by declared-manifest containment; host-added
|
|
74857
75574
|
// files are recorded, not failed. Frozen plans without this marker
|
|
74858
75575
|
// keep the legacy full-tree equality semantics byte-for-byte.
|
|
74859
|
-
|
|
75576
|
+
// External marketplace form uses the external-marketplace-v1
|
|
75577
|
+
// contract (whole-tree '.' containment; see plugin-marketplace).
|
|
75578
|
+
payloadContract: externalMarketplace ? "external-marketplace-v1" : "declared-manifest-v1",
|
|
75579
|
+
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {}
|
|
74860
75580
|
},
|
|
74861
75581
|
expected: {
|
|
74862
75582
|
installed: true,
|
|
74863
75583
|
consumer: platform.id,
|
|
74864
75584
|
plugin: dist.plugin,
|
|
74865
75585
|
...requiresMarketplace ? { marketplace: dist.marketplace } : {},
|
|
74866
|
-
repo: unit.publicRepo,
|
|
75586
|
+
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
74867
75587
|
version: unitVersion,
|
|
74868
|
-
ref: resolvedTag,
|
|
75588
|
+
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
|
74869
75589
|
entrySkill: dist.entrySkill,
|
|
74870
75590
|
entrySkillFound: true,
|
|
74871
|
-
manifestDigest: asset.manifestDigest
|
|
75591
|
+
manifestDigest: asset.manifestDigest,
|
|
75592
|
+
...externalMarketplace ? { marketplaceLocation: "external", marketplaceCommitSha: freeze.marketplaceCommitSha } : {}
|
|
74872
75593
|
},
|
|
74873
75594
|
status: "PENDING"
|
|
74874
75595
|
});
|
|
@@ -74903,25 +75624,25 @@ async function prepareRelease(options) {
|
|
|
74903
75624
|
);
|
|
74904
75625
|
}
|
|
74905
75626
|
if (production) {
|
|
74906
|
-
const canonicalOutput =
|
|
74907
|
-
if (output &&
|
|
75627
|
+
const canonicalOutput = resolve18(realRoot, ".release-skill", "release-plan.json");
|
|
75628
|
+
if (output && resolve18(output) !== canonicalOutput) {
|
|
74908
75629
|
throw new ReleaseError(
|
|
74909
75630
|
GATE_FAILED,
|
|
74910
75631
|
"production prepare requires the canonical .release-skill/release-plan.json output; custom --output is supported only outside production",
|
|
74911
|
-
{ output:
|
|
75632
|
+
{ output: resolve18(output), expected: canonicalOutput }
|
|
74912
75633
|
);
|
|
74913
75634
|
}
|
|
74914
75635
|
}
|
|
74915
75636
|
const lock = await acquireProjectLock({ root: realRoot, command: "prepare", mode: "exclusive" });
|
|
74916
|
-
const releaseDir =
|
|
75637
|
+
const releaseDir = resolve18(realRoot, ".release-skill");
|
|
74917
75638
|
const runId = `prepare-${Date.now()}`;
|
|
74918
|
-
const rawRunDir = runDirOpt ??
|
|
75639
|
+
const rawRunDir = runDirOpt ?? resolve18(releaseDir, "runs", runId);
|
|
74919
75640
|
let runDir;
|
|
74920
75641
|
try {
|
|
74921
75642
|
if (production) {
|
|
74922
75643
|
runDir = await createProductionPrepareRunDir(rawRunDir, releaseDir);
|
|
74923
75644
|
} else {
|
|
74924
|
-
await
|
|
75645
|
+
await mkdir12(rawRunDir, { recursive: true });
|
|
74925
75646
|
runDir = await realpath10(rawRunDir);
|
|
74926
75647
|
}
|
|
74927
75648
|
} catch (error) {
|
|
@@ -74936,7 +75657,7 @@ async function prepareRelease(options) {
|
|
|
74936
75657
|
await evidence.append({
|
|
74937
75658
|
phase: "config",
|
|
74938
75659
|
status: "completed",
|
|
74939
|
-
configPath:
|
|
75660
|
+
configPath: relative17(realRoot, configPath),
|
|
74940
75661
|
configDigest
|
|
74941
75662
|
});
|
|
74942
75663
|
const configUnits = config.releaseUnits ?? [];
|
|
@@ -75353,7 +76074,15 @@ To proceed, pass --acknowledge-hook-side-effects (CLI) or hooksAuthorized=true (
|
|
|
75353
76074
|
...unitBaseline ? { previousPublicBaseline: unitBaseline } : {}
|
|
75354
76075
|
};
|
|
75355
76076
|
});
|
|
75356
|
-
const
|
|
76077
|
+
const externalMarketplaceFreezes = production ? await resolveExternalMarketplaceFreezes({
|
|
76078
|
+
unitResults,
|
|
76079
|
+
resolvedVersions,
|
|
76080
|
+
offline,
|
|
76081
|
+
evidence,
|
|
76082
|
+
observeHeadFn: options.observeExternalMarketplaceHeadFn ?? defaultObserveExternalMarketplaceHead,
|
|
76083
|
+
fetchIndexFn: options.fetchExternalMarketplaceIndexFn ?? defaultFetchExternalMarketplaceIndex
|
|
76084
|
+
}) : /* @__PURE__ */ new Map();
|
|
76085
|
+
const externalActions = buildExternalActions(unitResults, resolvedVersions, productionAssets, externalMarketplaceFreezes);
|
|
75357
76086
|
const overallSnapshotDigest = sha256Hex(snapshotDigests.join(":"));
|
|
75358
76087
|
const plan = {
|
|
75359
76088
|
planVersion: 2,
|
|
@@ -75372,7 +76101,7 @@ To proceed, pass --acknowledge-hook-side-effects (CLI) or hooksAuthorized=true (
|
|
|
75372
76101
|
...production ? {
|
|
75373
76102
|
production: {
|
|
75374
76103
|
mode: "github-npm-v1",
|
|
75375
|
-
assetRoot:
|
|
76104
|
+
assetRoot: relative17(realRoot, runDir)
|
|
75376
76105
|
}
|
|
75377
76106
|
} : {},
|
|
75378
76107
|
units,
|
|
@@ -75386,9 +76115,9 @@ To proceed, pass --acknowledge-hook-side-effects (CLI) or hooksAuthorized=true (
|
|
|
75386
76115
|
actionCount: externalActions.length
|
|
75387
76116
|
});
|
|
75388
76117
|
await evidence.append({ phase: "plan-write", status: "started" });
|
|
75389
|
-
const latestPlanPath = output ??
|
|
76118
|
+
const latestPlanPath = output ?? resolve18(releaseDir, "release-plan.json");
|
|
75390
76119
|
const plannedDigest = computePlanDigest(plan);
|
|
75391
|
-
const immutablePlanPath =
|
|
76120
|
+
const immutablePlanPath = resolve18(dirname9(latestPlanPath), "plans", `${plannedDigest}.json`);
|
|
75392
76121
|
const { planPath: writtenPath, planDigest } = await writePlanImmutable(immutablePlanPath, plan);
|
|
75393
76122
|
await writePlanAtomic(latestPlanPath, plan);
|
|
75394
76123
|
await evidence.append({
|
|
@@ -75429,7 +76158,7 @@ To proceed, pass --acknowledge-hook-side-effects (CLI) or hooksAuthorized=true (
|
|
|
75429
76158
|
await lock.release();
|
|
75430
76159
|
}
|
|
75431
76160
|
}
|
|
75432
|
-
var execFile6;
|
|
76161
|
+
var execFile6, EXTERNAL_MARKETPLACE_SHA_RE2;
|
|
75433
76162
|
var init_prepare = __esm({
|
|
75434
76163
|
async "src/commands/prepare.mjs"() {
|
|
75435
76164
|
await init_config();
|
|
@@ -75462,14 +76191,20 @@ var init_prepare = __esm({
|
|
|
75462
76191
|
__name(normalizedProductionConfig, "normalizedProductionConfig");
|
|
75463
76192
|
__name(readHeadCommitTimestamp, "readHeadCommitTimestamp");
|
|
75464
76193
|
__name(buildProductionAssets, "buildProductionAssets");
|
|
76194
|
+
EXTERNAL_MARKETPLACE_SHA_RE2 = /^[0-9a-f]{40}$/;
|
|
76195
|
+
__name(parseExternalMarketplaceLsRemote, "parseExternalMarketplaceLsRemote");
|
|
76196
|
+
__name(decodeExternalMarketplaceIndex, "decodeExternalMarketplaceIndex");
|
|
76197
|
+
__name(defaultObserveExternalMarketplaceHead, "defaultObserveExternalMarketplaceHead");
|
|
76198
|
+
__name(defaultFetchExternalMarketplaceIndex, "defaultFetchExternalMarketplaceIndex");
|
|
76199
|
+
__name(resolveExternalMarketplaceFreezes, "resolveExternalMarketplaceFreezes");
|
|
75465
76200
|
__name(buildExternalActions, "buildExternalActions");
|
|
75466
76201
|
__name(prepareRelease, "prepareRelease");
|
|
75467
76202
|
}
|
|
75468
76203
|
});
|
|
75469
76204
|
|
|
75470
76205
|
// src/core/approval.mjs
|
|
75471
|
-
import { readFile as
|
|
75472
|
-
import { basename as basename5, dirname as dirname10, join as
|
|
76206
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
76207
|
+
import { basename as basename5, dirname as dirname10, join as join14, resolve as resolve19 } from "node:path";
|
|
75473
76208
|
function validateApprovalRecordSchema(approval) {
|
|
75474
76209
|
if (validateApprovalSchema(approval)) return;
|
|
75475
76210
|
const errors = validateApprovalSchema.errors ?? [];
|
|
@@ -75486,7 +76221,7 @@ function assertImmutableApprovalAuthority(approvalPath, plan, rawApproval) {
|
|
|
75486
76221
|
if (!plan?.production) return;
|
|
75487
76222
|
const planDigest = computePlanDigest(plan);
|
|
75488
76223
|
const approvalDigest = computeApprovalDigest(rawApproval);
|
|
75489
|
-
const absolute =
|
|
76224
|
+
const absolute = resolve19(approvalPath);
|
|
75490
76225
|
const planDirectory = dirname10(absolute);
|
|
75491
76226
|
if (basename5(absolute) !== `${approvalDigest}.json` || basename5(planDirectory) !== planDigest || basename5(dirname10(planDirectory)) !== "approvals") {
|
|
75492
76227
|
throw new ReleaseError(
|
|
@@ -75755,8 +76490,8 @@ var approve_exports = {};
|
|
|
75755
76490
|
__export(approve_exports, {
|
|
75756
76491
|
approvePlan: () => approvePlan
|
|
75757
76492
|
});
|
|
75758
|
-
import { readFile as
|
|
75759
|
-
import { resolve as
|
|
76493
|
+
import { readFile as readFile18, writeFile as writeFile7 } from "node:fs/promises";
|
|
76494
|
+
import { resolve as resolve20, dirname as dirname11, basename as basename6 } from "node:path";
|
|
75760
76495
|
function defaultClock() {
|
|
75761
76496
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
75762
76497
|
}
|
|
@@ -75782,7 +76517,7 @@ async function approvePlan(options) {
|
|
|
75782
76517
|
}
|
|
75783
76518
|
let planRaw;
|
|
75784
76519
|
try {
|
|
75785
|
-
planRaw = await
|
|
76520
|
+
planRaw = await readFile18(planPath, "utf8");
|
|
75786
76521
|
} catch (err) {
|
|
75787
76522
|
throw new ReleaseError(
|
|
75788
76523
|
GATE_FAILED,
|
|
@@ -75886,18 +76621,18 @@ async function approvePlan(options) {
|
|
|
75886
76621
|
expiresAt
|
|
75887
76622
|
};
|
|
75888
76623
|
validateApprovalRecordSchema(approvalRecord);
|
|
75889
|
-
const planDir = dirname11(
|
|
76624
|
+
const planDir = dirname11(resolve20(planPath));
|
|
75890
76625
|
const releaseDir = basename6(planDir) === "plans" && basename6(planPath) === `${actualDigest}.json` ? dirname11(planDir) : planDir;
|
|
75891
|
-
if (plan.production?.mode === "github-npm-v1" && outputPath &&
|
|
76626
|
+
if (plan.production?.mode === "github-npm-v1" && outputPath && resolve20(outputPath) !== resolve20(releaseDir, "approval-record.json")) {
|
|
75892
76627
|
throw new ReleaseError(
|
|
75893
76628
|
GATE_FAILED,
|
|
75894
76629
|
"production approve requires the canonical approval-record.json alias next to the immutable plan authority; custom --output is supported only outside production",
|
|
75895
|
-
{ outputPath:
|
|
76630
|
+
{ outputPath: resolve20(outputPath), expected: resolve20(releaseDir, "approval-record.json") }
|
|
75896
76631
|
);
|
|
75897
76632
|
}
|
|
75898
76633
|
const json = JSON.stringify(approvalRecord, null, 2);
|
|
75899
76634
|
const approvalDigest = computeApprovalDigest(json);
|
|
75900
|
-
const immutableApprovalPath =
|
|
76635
|
+
const immutableApprovalPath = resolve20(
|
|
75901
76636
|
releaseDir,
|
|
75902
76637
|
"approvals",
|
|
75903
76638
|
actualDigest,
|
|
@@ -75909,7 +76644,7 @@ async function approvePlan(options) {
|
|
|
75909
76644
|
await writeFile7(immutableApprovalPath, json, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
75910
76645
|
} catch (error) {
|
|
75911
76646
|
if (error.code !== "EEXIST") throw error;
|
|
75912
|
-
const existing = await
|
|
76647
|
+
const existing = await readFile18(immutableApprovalPath, "utf8");
|
|
75913
76648
|
if (existing !== json) {
|
|
75914
76649
|
throw new ReleaseError(
|
|
75915
76650
|
GATE_FAILED,
|
|
@@ -75918,7 +76653,7 @@ async function approvePlan(options) {
|
|
|
75918
76653
|
);
|
|
75919
76654
|
}
|
|
75920
76655
|
}
|
|
75921
|
-
const writePath = outputPath ??
|
|
76656
|
+
const writePath = outputPath ?? resolve20(releaseDir, "approval-record.json");
|
|
75922
76657
|
await prepareAuthorityDirectory(dirname11(writePath));
|
|
75923
76658
|
await assertAuthorityFileTarget(writePath);
|
|
75924
76659
|
await writeFile7(writePath, json, "utf8");
|
|
@@ -75976,7 +76711,8 @@ var init_checkpoints = __esm({
|
|
|
75976
76711
|
"github-release",
|
|
75977
76712
|
"claude-marketplace-install",
|
|
75978
76713
|
"codex-marketplace-install",
|
|
75979
|
-
"kimi-marketplace-install"
|
|
76714
|
+
"kimi-marketplace-install",
|
|
76715
|
+
"codebuddy-marketplace-install"
|
|
75980
76716
|
];
|
|
75981
76717
|
ADAPTER_ACTION_TYPE_MAP = {
|
|
75982
76718
|
"push-commit": "git-push",
|
|
@@ -75987,7 +76723,8 @@ var init_checkpoints = __esm({
|
|
|
75987
76723
|
"github-release": "github-release",
|
|
75988
76724
|
"claude-marketplace-install": "claude-marketplace-install",
|
|
75989
76725
|
"codex-marketplace-install": "codex-marketplace-install",
|
|
75990
|
-
"kimi-marketplace-install": "kimi-marketplace-install"
|
|
76726
|
+
"kimi-marketplace-install": "kimi-marketplace-install",
|
|
76727
|
+
"codebuddy-marketplace-install": "codebuddy-marketplace-install"
|
|
75991
76728
|
};
|
|
75992
76729
|
TIER_TABLE = [
|
|
75993
76730
|
["push-commit", "push-snapshot"],
|
|
@@ -75996,7 +76733,7 @@ var init_checkpoints = __esm({
|
|
|
75996
76733
|
// Tier 1
|
|
75997
76734
|
["github-release", "claude-marketplace-install", "codex-marketplace-install"],
|
|
75998
76735
|
// Tier 2
|
|
75999
|
-
["kimi-marketplace-install"]
|
|
76736
|
+
["kimi-marketplace-install", "codebuddy-marketplace-install"]
|
|
76000
76737
|
// Tier 3
|
|
76001
76738
|
];
|
|
76002
76739
|
TIER_OF = /* @__PURE__ */ new Map();
|
|
@@ -76096,7 +76833,7 @@ function defaultSleep(ms) {
|
|
|
76096
76833
|
if (process.env.RELEASE_SKILL_OBSERVE_RETRY_NO_WAIT === "1") {
|
|
76097
76834
|
return Promise.resolve();
|
|
76098
76835
|
}
|
|
76099
|
-
return new Promise((
|
|
76836
|
+
return new Promise((resolve25) => setTimeout(resolve25, ms));
|
|
76100
76837
|
}
|
|
76101
76838
|
function isPropagatingMissing(result) {
|
|
76102
76839
|
if (result == null) return true;
|
|
@@ -76185,8 +76922,8 @@ var reconcile_exports = {};
|
|
|
76185
76922
|
__export(reconcile_exports, {
|
|
76186
76923
|
reconcileRelease: () => reconcileRelease
|
|
76187
76924
|
});
|
|
76188
|
-
import { readFile as
|
|
76189
|
-
import { join as
|
|
76925
|
+
import { readFile as readFile19, mkdir as mkdir13 } from "node:fs/promises";
|
|
76926
|
+
import { join as join15 } from "node:path";
|
|
76190
76927
|
function defaultClock3() {
|
|
76191
76928
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
76192
76929
|
}
|
|
@@ -76215,7 +76952,7 @@ async function reconcileRelease(options) {
|
|
|
76215
76952
|
}
|
|
76216
76953
|
let planRaw;
|
|
76217
76954
|
try {
|
|
76218
|
-
planRaw = await
|
|
76955
|
+
planRaw = await readFile19(planPath, "utf8");
|
|
76219
76956
|
} catch (err) {
|
|
76220
76957
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
76221
76958
|
}
|
|
@@ -76233,7 +76970,7 @@ async function reconcileRelease(options) {
|
|
|
76233
76970
|
if (isProductionPlan) {
|
|
76234
76971
|
runDir = await createProductionRunDir(runDir, planPath);
|
|
76235
76972
|
} else {
|
|
76236
|
-
await
|
|
76973
|
+
await mkdir13(runDir, { recursive: true });
|
|
76237
76974
|
}
|
|
76238
76975
|
const evidence = createEvidenceWriter({ runDir, command: "reconcile", clock: clockFn });
|
|
76239
76976
|
try {
|
|
@@ -76294,7 +77031,7 @@ async function reconcileRelease(options) {
|
|
|
76294
77031
|
{ sourceRunId: sourceRun.runId }
|
|
76295
77032
|
);
|
|
76296
77033
|
}
|
|
76297
|
-
const sourceApprovalRaw = await
|
|
77034
|
+
const sourceApprovalRaw = await readFile19(consumedApprovalPath, "utf8").catch((error) => {
|
|
76298
77035
|
throw new ReleaseError(GATE_FAILED, "source run approval authority is unavailable", {
|
|
76299
77036
|
sourceRunId: sourceRun.runId,
|
|
76300
77037
|
cause: error.code
|
|
@@ -76472,7 +77209,7 @@ async function reconcileRelease(options) {
|
|
|
76472
77209
|
if (approvalPath) {
|
|
76473
77210
|
let approvalRaw;
|
|
76474
77211
|
try {
|
|
76475
|
-
approvalRaw = await
|
|
77212
|
+
approvalRaw = await readFile19(approvalPath, "utf8");
|
|
76476
77213
|
} catch (err) {
|
|
76477
77214
|
throw new ReleaseError(
|
|
76478
77215
|
GATE_FAILED,
|
|
@@ -77273,7 +78010,7 @@ async function reconcileRelease(options) {
|
|
|
77273
78010
|
status: status === "succeeded" ? "succeeded" : status === "failed" ? "failed" : status === "skipped" ? "skipped" : status === "uncertain" ? "uncertain" : "pending"
|
|
77274
78011
|
};
|
|
77275
78012
|
});
|
|
77276
|
-
const runPath =
|
|
78013
|
+
const runPath = join15(runDir, "release-run.json");
|
|
77277
78014
|
const sourceRunDigest = sourceAuthorityDigest;
|
|
77278
78015
|
const runState = {
|
|
77279
78016
|
runId,
|
|
@@ -77346,7 +78083,8 @@ var init_reconcile = __esm({
|
|
|
77346
78083
|
MARKETPLACE_TYPES = /* @__PURE__ */ new Set([
|
|
77347
78084
|
"claude-marketplace-install",
|
|
77348
78085
|
"codex-marketplace-install",
|
|
77349
|
-
"kimi-marketplace-install"
|
|
78086
|
+
"kimi-marketplace-install",
|
|
78087
|
+
"codebuddy-marketplace-install"
|
|
77350
78088
|
]);
|
|
77351
78089
|
__name(defaultClock3, "defaultClock");
|
|
77352
78090
|
__name(reconcileRelease, "reconcileRelease");
|
|
@@ -77943,8 +78681,8 @@ __export(plugin_marketplace_exports, {
|
|
|
77943
78681
|
});
|
|
77944
78682
|
import { execFile as execFileCb10 } from "node:child_process";
|
|
77945
78683
|
import { promisify as promisify10 } from "node:util";
|
|
77946
|
-
import { readFile as
|
|
77947
|
-
import { join as
|
|
78684
|
+
import { readFile as readFile20, stat as stat5, mkdir as mkdir14, readdir as readdir9, realpath as realpath11, lstat as lstat11 } from "node:fs/promises";
|
|
78685
|
+
import { join as join16, resolve as resolve21, relative as relative18, isAbsolute as isAbsolute15, basename as basename7 } from "node:path";
|
|
77948
78686
|
import { createHash as createHash10 } from "node:crypto";
|
|
77949
78687
|
function transportPayload(entries) {
|
|
77950
78688
|
return entries.map(({ path: path3, type, mode, size, contentDigest }) => ({
|
|
@@ -77974,13 +78712,16 @@ function extractDeclaredPluginSource(consumer, entry) {
|
|
|
77974
78712
|
return segments.length === 0 ? "." : segments.join("/");
|
|
77975
78713
|
}
|
|
77976
78714
|
async function resolveInstalledPayloadSubpath(snapshotDir, sourceEntries, action, consumer) {
|
|
78715
|
+
if (action.payloadContract === PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE || action.marketplaceLocation === "external") {
|
|
78716
|
+
return ".";
|
|
78717
|
+
}
|
|
77977
78718
|
const marketplaceRelative = getPlatform(consumer).manifestPaths.marketplace;
|
|
77978
78719
|
if (marketplaceRelative === null) return ".";
|
|
77979
78720
|
const anchored = sourceEntries.some((entry) => entry.type === "file" && entry.path === marketplaceRelative);
|
|
77980
78721
|
if (!anchored) {
|
|
77981
78722
|
throw new Error(`frozen snapshot is missing the marketplace manifest ${marketplaceRelative}`);
|
|
77982
78723
|
}
|
|
77983
|
-
const result = await validateManifestFile(
|
|
78724
|
+
const result = await validateManifestFile(resolve21(snapshotDir, marketplaceRelative), ["name", "plugins"]);
|
|
77984
78725
|
if (!result.valid) {
|
|
77985
78726
|
throw new Error(`frozen snapshot ${marketplaceRelative} invalid: ${result.error}`);
|
|
77986
78727
|
}
|
|
@@ -78019,10 +78760,10 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
78019
78760
|
throw new Error("frozen snapshot contains no payload under the declared marketplace source");
|
|
78020
78761
|
}
|
|
78021
78762
|
const payloadContract = action.payloadContract;
|
|
78022
|
-
if (payloadContract !== void 0 && payloadContract !== PAYLOAD_CONTRACT_DECLARED_MANIFEST) {
|
|
78763
|
+
if (payloadContract !== void 0 && payloadContract !== PAYLOAD_CONTRACT_DECLARED_MANIFEST && payloadContract !== PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE) {
|
|
78023
78764
|
throw new Error(`unsupported marketplace payload contract: ${JSON.stringify(payloadContract)}`);
|
|
78024
78765
|
}
|
|
78025
|
-
if (payloadContract === PAYLOAD_CONTRACT_DECLARED_MANIFEST) {
|
|
78766
|
+
if (payloadContract === PAYLOAD_CONTRACT_DECLARED_MANIFEST || payloadContract === PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE) {
|
|
78026
78767
|
const installedSnapshot2 = await computeFrozenSnapshot(installPath);
|
|
78027
78768
|
const authorityPayload = transportPayload(authorityEntries);
|
|
78028
78769
|
const installedByPath = new Map(
|
|
@@ -78047,7 +78788,7 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
78047
78788
|
const listed = conflicts.slice(0, PAYLOAD_CONFLICT_REPORT_CAP).join("; ");
|
|
78048
78789
|
const overflow = conflicts.length > PAYLOAD_CONFLICT_REPORT_CAP ? `; and ${conflicts.length - PAYLOAD_CONFLICT_REPORT_CAP} more conflicting path(s)` : "";
|
|
78049
78790
|
throw new Error(
|
|
78050
|
-
`installed marketplace payload differs in path, bytes, size, or non-write mode bits (${
|
|
78791
|
+
`installed marketplace payload differs in path, bytes, size, or non-write mode bits (${payloadContract}): ${listed}${overflow}`
|
|
78051
78792
|
);
|
|
78052
78793
|
}
|
|
78053
78794
|
const authorityPaths = new Set(authorityPayload.map((entry) => entry.path));
|
|
@@ -78094,26 +78835,26 @@ async function resolveKimiEntrySkillFile(pluginRootReal, manifest, entrySkill) {
|
|
|
78094
78835
|
}
|
|
78095
78836
|
let entryAbs;
|
|
78096
78837
|
if (manifest.skills === void 0 || manifest.skills === null) {
|
|
78097
|
-
entryAbs =
|
|
78838
|
+
entryAbs = resolve21(pluginRootReal, "SKILL.md");
|
|
78098
78839
|
} else {
|
|
78099
78840
|
const skillsRel = normalizeKimiSkillsRel(manifest.skills);
|
|
78100
|
-
const skillsRootAbs = skillsRel === "" ? pluginRootReal :
|
|
78841
|
+
const skillsRootAbs = skillsRel === "" ? pluginRootReal : resolve21(pluginRootReal, skillsRel);
|
|
78101
78842
|
const skillsRootReal = await realpath11(skillsRootAbs).catch(() => null);
|
|
78102
78843
|
if (!skillsRootReal) {
|
|
78103
78844
|
throw new Error(`kimi manifest skills root does not exist: ${manifest.skills}`);
|
|
78104
78845
|
}
|
|
78105
|
-
const skillsContainment =
|
|
78846
|
+
const skillsContainment = relative18(pluginRootReal, skillsRootReal);
|
|
78106
78847
|
const sepK = process.platform === "win32" ? "\\" : "/";
|
|
78107
|
-
if (skillsContainment !== "" && (
|
|
78848
|
+
if (skillsContainment !== "" && (isAbsolute15(skillsContainment) || skillsContainment === ".." || skillsContainment.startsWith(`..${sepK}`))) {
|
|
78108
78849
|
throw new Error(`kimi manifest skills "${manifest.skills}" escapes the plugin root after symlink resolution`);
|
|
78109
78850
|
}
|
|
78110
|
-
entryAbs =
|
|
78851
|
+
entryAbs = resolve21(skillsRootReal, entrySkill, "SKILL.md");
|
|
78111
78852
|
}
|
|
78112
78853
|
let entryLexicalStat;
|
|
78113
78854
|
try {
|
|
78114
78855
|
entryLexicalStat = await lstat11(entryAbs);
|
|
78115
78856
|
} catch {
|
|
78116
|
-
throw new Error(`kimi entry skill not found: ${
|
|
78857
|
+
throw new Error(`kimi entry skill not found: ${relative18(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
78117
78858
|
}
|
|
78118
78859
|
if (entryLexicalStat.isSymbolicLink()) {
|
|
78119
78860
|
throw new Error("kimi entry skill must not be a symlink");
|
|
@@ -78123,15 +78864,73 @@ async function resolveKimiEntrySkillFile(pluginRootReal, manifest, entrySkill) {
|
|
|
78123
78864
|
}
|
|
78124
78865
|
const entryReal = await realpath11(entryAbs).catch(() => null);
|
|
78125
78866
|
if (!entryReal) {
|
|
78126
|
-
throw new Error(`kimi entry skill not found: ${
|
|
78867
|
+
throw new Error(`kimi entry skill not found: ${relative18(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
78127
78868
|
}
|
|
78128
|
-
const entryContainment =
|
|
78869
|
+
const entryContainment = relative18(pluginRootReal, entryReal);
|
|
78129
78870
|
const sepE = process.platform === "win32" ? "\\" : "/";
|
|
78130
|
-
if (entryContainment !== "" && (
|
|
78871
|
+
if (entryContainment !== "" && (isAbsolute15(entryContainment) || entryContainment === ".." || entryContainment.startsWith(`..${sepE}`))) {
|
|
78131
78872
|
throw new Error("kimi entry skill escapes the plugin root after symlink resolution");
|
|
78132
78873
|
}
|
|
78133
78874
|
return entryReal;
|
|
78134
78875
|
}
|
|
78876
|
+
function normalizeCodeBuddySkillsRel(skillsRaw) {
|
|
78877
|
+
if (typeof skillsRaw !== "string" || skillsRaw.length === 0) {
|
|
78878
|
+
throw new Error("codebuddy manifest skills must be a non-empty relative path when present");
|
|
78879
|
+
}
|
|
78880
|
+
if (skillsRaw.startsWith("/") || skillsRaw.includes("..") || skillsRaw.includes("\\") || /^https?:\/\//i.test(skillsRaw)) {
|
|
78881
|
+
throw new Error(`codebuddy manifest skills "${skillsRaw}" is not a safe relative path`);
|
|
78882
|
+
}
|
|
78883
|
+
let rel = skillsRaw.replace(/^\.\//, "");
|
|
78884
|
+
rel = rel.replace(/\/+$/, "");
|
|
78885
|
+
if (rel.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
78886
|
+
throw new Error(`codebuddy manifest skills "${skillsRaw}" is not a safe relative path`);
|
|
78887
|
+
}
|
|
78888
|
+
return rel;
|
|
78889
|
+
}
|
|
78890
|
+
async function resolveCodeBuddyEntrySkillFile(pluginRootReal, manifest, entrySkill) {
|
|
78891
|
+
if (!entrySkill || typeof entrySkill !== "string" || !SAFE_ID_RE.test(entrySkill)) {
|
|
78892
|
+
throw new Error(`unsafe entrySkill: "${entrySkill}"`);
|
|
78893
|
+
}
|
|
78894
|
+
let entryAbs;
|
|
78895
|
+
if (manifest.skills === void 0 || manifest.skills === null) {
|
|
78896
|
+
entryAbs = resolve21(pluginRootReal, "SKILL.md");
|
|
78897
|
+
} else {
|
|
78898
|
+
const skillsRel = normalizeCodeBuddySkillsRel(manifest.skills);
|
|
78899
|
+
const skillsRootAbs = skillsRel === "" ? pluginRootReal : resolve21(pluginRootReal, skillsRel);
|
|
78900
|
+
const skillsRootReal = await realpath11(skillsRootAbs).catch(() => null);
|
|
78901
|
+
if (!skillsRootReal) {
|
|
78902
|
+
throw new Error(`codebuddy manifest skills root does not exist: ${manifest.skills}`);
|
|
78903
|
+
}
|
|
78904
|
+
const skillsContainment = relative18(pluginRootReal, skillsRootReal);
|
|
78905
|
+
const sepK = process.platform === "win32" ? "\\" : "/";
|
|
78906
|
+
if (skillsContainment !== "" && (isAbsolute15(skillsContainment) || skillsContainment === ".." || skillsContainment.startsWith(`..${sepK}`))) {
|
|
78907
|
+
throw new Error(`codebuddy manifest skills "${manifest.skills}" escapes the plugin root after symlink resolution`);
|
|
78908
|
+
}
|
|
78909
|
+
entryAbs = resolve21(skillsRootReal, entrySkill, "SKILL.md");
|
|
78910
|
+
}
|
|
78911
|
+
let entryLexicalStat;
|
|
78912
|
+
try {
|
|
78913
|
+
entryLexicalStat = await lstat11(entryAbs);
|
|
78914
|
+
} catch {
|
|
78915
|
+
throw new Error(`codebuddy entry skill not found: ${relative18(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
78916
|
+
}
|
|
78917
|
+
if (entryLexicalStat.isSymbolicLink()) {
|
|
78918
|
+
throw new Error("codebuddy entry skill must not be a symlink");
|
|
78919
|
+
}
|
|
78920
|
+
if (!entryLexicalStat.isFile()) {
|
|
78921
|
+
throw new Error("codebuddy entry skill is not a regular file");
|
|
78922
|
+
}
|
|
78923
|
+
const entryReal = await realpath11(entryAbs).catch(() => null);
|
|
78924
|
+
if (!entryReal) {
|
|
78925
|
+
throw new Error(`codebuddy entry skill not found: ${relative18(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
78926
|
+
}
|
|
78927
|
+
const entryContainment = relative18(pluginRootReal, entryReal);
|
|
78928
|
+
const sepE = process.platform === "win32" ? "\\" : "/";
|
|
78929
|
+
if (entryContainment !== "" && (isAbsolute15(entryContainment) || entryContainment === ".." || entryContainment.startsWith(`..${sepE}`))) {
|
|
78930
|
+
throw new Error("codebuddy entry skill escapes the plugin root after symlink resolution");
|
|
78931
|
+
}
|
|
78932
|
+
return entryReal;
|
|
78933
|
+
}
|
|
78135
78934
|
function validateSafeRef(ref) {
|
|
78136
78935
|
if (!ref || typeof ref !== "string") {
|
|
78137
78936
|
return { valid: false, error: "ref is required" };
|
|
@@ -78213,7 +79012,7 @@ async function run4(cmd, args2, options = {}) {
|
|
|
78213
79012
|
}
|
|
78214
79013
|
async function validateManifestFile(manifestPath, requiredFields) {
|
|
78215
79014
|
try {
|
|
78216
|
-
const content = await
|
|
79015
|
+
const content = await readFile20(manifestPath, "utf8");
|
|
78217
79016
|
const manifest = JSON.parse(content);
|
|
78218
79017
|
const missing = requiredFields.filter((f) => !(f in manifest));
|
|
78219
79018
|
return {
|
|
@@ -78235,7 +79034,7 @@ async function checkRequiredFiles(dir, requiredFiles) {
|
|
|
78235
79034
|
const missing = [];
|
|
78236
79035
|
for (const file of requiredFiles) {
|
|
78237
79036
|
try {
|
|
78238
|
-
await stat5(
|
|
79037
|
+
await stat5(resolve21(dir, file));
|
|
78239
79038
|
} catch {
|
|
78240
79039
|
missing.push(file);
|
|
78241
79040
|
}
|
|
@@ -78311,7 +79110,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78311
79110
|
status: ActionStatus.PREFLIGHT_PASSED
|
|
78312
79111
|
});
|
|
78313
79112
|
}
|
|
78314
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
79113
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL || actionType === ActionType.CODEBUDDY_MARKETPLACE_INSTALL) {
|
|
78315
79114
|
const validation = validateMarketplaceParams(action);
|
|
78316
79115
|
if (!validation.valid) {
|
|
78317
79116
|
return createResult({
|
|
@@ -78387,6 +79186,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78387
79186
|
});
|
|
78388
79187
|
}
|
|
78389
79188
|
if (!platform.automatable) {
|
|
79189
|
+
const manifestLabel = consumer === "codebuddy" ? "codebuddy" : "kimi";
|
|
78390
79190
|
let kimiManifestResult;
|
|
78391
79191
|
try {
|
|
78392
79192
|
kimiManifestResult = await platform.strategy.readManifest(snapshotDirReal);
|
|
@@ -78394,7 +79194,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78394
79194
|
return createResult({
|
|
78395
79195
|
actionType,
|
|
78396
79196
|
status: ActionStatus.PREFLIGHT_FAILED,
|
|
78397
|
-
error: `frozen snapshot
|
|
79197
|
+
error: `frozen snapshot ${manifestLabel} manifest invalid: ${manifestErr.message}`
|
|
78398
79198
|
});
|
|
78399
79199
|
}
|
|
78400
79200
|
const kimiManifest = kimiManifestResult.manifest;
|
|
@@ -78415,110 +79215,152 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78415
79215
|
kimiSnapshotManifest = kimiManifest;
|
|
78416
79216
|
}
|
|
78417
79217
|
if (platform.automatable) {
|
|
78418
|
-
|
|
78419
|
-
|
|
78420
|
-
|
|
78421
|
-
|
|
78422
|
-
|
|
78423
|
-
|
|
78424
|
-
|
|
78425
|
-
|
|
78426
|
-
|
|
78427
|
-
|
|
78428
|
-
|
|
78429
|
-
|
|
78430
|
-
|
|
78431
|
-
|
|
78432
|
-
|
|
78433
|
-
|
|
78434
|
-
|
|
78435
|
-
|
|
78436
|
-
|
|
78437
|
-
|
|
78438
|
-
|
|
78439
|
-
|
|
78440
|
-
|
|
78441
|
-
|
|
78442
|
-
|
|
78443
|
-
|
|
78444
|
-
|
|
78445
|
-
|
|
78446
|
-
|
|
78447
|
-
|
|
78448
|
-
|
|
78449
|
-
}
|
|
78450
|
-
|
|
78451
|
-
|
|
78452
|
-
|
|
78453
|
-
|
|
78454
|
-
|
|
78455
|
-
|
|
78456
|
-
|
|
78457
|
-
|
|
78458
|
-
|
|
78459
|
-
|
|
78460
|
-
|
|
78461
|
-
|
|
78462
|
-
|
|
78463
|
-
|
|
78464
|
-
|
|
78465
|
-
|
|
78466
|
-
|
|
78467
|
-
|
|
78468
|
-
|
|
78469
|
-
|
|
78470
|
-
|
|
78471
|
-
|
|
78472
|
-
|
|
78473
|
-
|
|
78474
|
-
|
|
78475
|
-
|
|
78476
|
-
|
|
78477
|
-
|
|
78478
|
-
|
|
78479
|
-
|
|
78480
|
-
|
|
78481
|
-
|
|
78482
|
-
|
|
78483
|
-
|
|
78484
|
-
|
|
78485
|
-
|
|
78486
|
-
|
|
78487
|
-
|
|
78488
|
-
|
|
78489
|
-
|
|
78490
|
-
|
|
78491
|
-
|
|
78492
|
-
|
|
78493
|
-
|
|
78494
|
-
|
|
78495
|
-
|
|
78496
|
-
|
|
78497
|
-
|
|
78498
|
-
|
|
78499
|
-
|
|
78500
|
-
|
|
78501
|
-
|
|
78502
|
-
|
|
78503
|
-
|
|
78504
|
-
|
|
78505
|
-
|
|
78506
|
-
|
|
78507
|
-
|
|
78508
|
-
|
|
78509
|
-
|
|
78510
|
-
|
|
78511
|
-
|
|
78512
|
-
|
|
78513
|
-
|
|
78514
|
-
|
|
78515
|
-
|
|
78516
|
-
|
|
79218
|
+
if (action.marketplaceLocation === "external") {
|
|
79219
|
+
if (typeof action.marketplaceCommitSha !== "string" || !/^[0-9a-f]{40}$/.test(action.marketplaceCommitSha)) {
|
|
79220
|
+
return createResult({
|
|
79221
|
+
actionType,
|
|
79222
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79223
|
+
error: `external marketplace marketplaceCommitSha must be a 40-hex commit sha, got ${JSON.stringify(action.marketplaceCommitSha)}`
|
|
79224
|
+
});
|
|
79225
|
+
}
|
|
79226
|
+
if (typeof action.repo !== "string" || !/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/.test(action.repo)) {
|
|
79227
|
+
return createResult({
|
|
79228
|
+
actionType,
|
|
79229
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79230
|
+
error: `external marketplace repo must be an owner/name repository, got ${JSON.stringify(action.repo)}`
|
|
79231
|
+
});
|
|
79232
|
+
}
|
|
79233
|
+
const externalManifestRelative = platform.manifestPaths.plugin;
|
|
79234
|
+
const externalManifestPath = resolve21(snapshotDirReal, externalManifestRelative);
|
|
79235
|
+
const externalManifestResult = await validateManifestFile(externalManifestPath, ["name", "version"]);
|
|
79236
|
+
if (!externalManifestResult.valid) {
|
|
79237
|
+
return createResult({
|
|
79238
|
+
actionType,
|
|
79239
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79240
|
+
error: `frozen snapshot ${externalManifestRelative} invalid: ${externalManifestResult.error}`
|
|
79241
|
+
});
|
|
79242
|
+
}
|
|
79243
|
+
if (externalManifestResult.manifest.name !== action.plugin) {
|
|
79244
|
+
return createResult({
|
|
79245
|
+
actionType,
|
|
79246
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79247
|
+
error: `plugin manifest name "${externalManifestResult.manifest.name}" does not match action plugin "${action.plugin}"`
|
|
79248
|
+
});
|
|
79249
|
+
}
|
|
79250
|
+
if (externalManifestResult.manifest.version !== action.version) {
|
|
79251
|
+
return createResult({
|
|
79252
|
+
actionType,
|
|
79253
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79254
|
+
error: `plugin manifest version "${externalManifestResult.manifest.version}" does not match action version "${action.version}"`
|
|
79255
|
+
});
|
|
79256
|
+
}
|
|
79257
|
+
} else {
|
|
79258
|
+
const marketplaceRelative = platform.manifestPaths.marketplace;
|
|
79259
|
+
const marketplacePath = resolve21(snapshotDirReal, marketplaceRelative);
|
|
79260
|
+
const marketplaceResult = await validateManifestFile(marketplacePath, ["name"]);
|
|
79261
|
+
if (!marketplaceResult.valid) {
|
|
79262
|
+
return createResult({
|
|
79263
|
+
actionType,
|
|
79264
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79265
|
+
error: `frozen snapshot ${marketplaceRelative} invalid: ${marketplaceResult.error}`
|
|
79266
|
+
});
|
|
79267
|
+
}
|
|
79268
|
+
if (marketplaceResult.manifest.name !== action.marketplace) {
|
|
79269
|
+
return createResult({
|
|
79270
|
+
actionType,
|
|
79271
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79272
|
+
error: `marketplace.json name "${marketplaceResult.manifest.name}" does not match action marketplace "${action.marketplace}"`
|
|
79273
|
+
});
|
|
79274
|
+
}
|
|
79275
|
+
const plugins = marketplaceResult.manifest.plugins;
|
|
79276
|
+
if (!Array.isArray(plugins)) {
|
|
79277
|
+
return createResult({
|
|
79278
|
+
actionType,
|
|
79279
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79280
|
+
error: `${marketplaceRelative} must have a plugins[] array`
|
|
79281
|
+
});
|
|
79282
|
+
}
|
|
79283
|
+
const pluginEntry = plugins.filter((p) => p.name === action.plugin);
|
|
79284
|
+
if (pluginEntry.length !== 1) {
|
|
79285
|
+
return createResult({
|
|
79286
|
+
actionType,
|
|
79287
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79288
|
+
error: `expected exactly one plugins[] entry with name "${action.plugin}", found ${pluginEntry.length}`
|
|
79289
|
+
});
|
|
79290
|
+
}
|
|
79291
|
+
const entry = pluginEntry[0];
|
|
79292
|
+
let sourcePath;
|
|
79293
|
+
try {
|
|
79294
|
+
sourcePath = extractDeclaredPluginSource(consumer, entry);
|
|
79295
|
+
} catch (sourceErr) {
|
|
79296
|
+
return createResult({
|
|
79297
|
+
actionType,
|
|
79298
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79299
|
+
error: sourceErr.message
|
|
79300
|
+
});
|
|
79301
|
+
}
|
|
79302
|
+
const sourceDirAbs = resolve21(snapshotDirReal, sourcePath);
|
|
79303
|
+
const sourceDirReal = await realpath11(sourceDirAbs).catch(() => null);
|
|
79304
|
+
if (!sourceDirReal) {
|
|
79305
|
+
return createResult({
|
|
79306
|
+
actionType,
|
|
79307
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79308
|
+
error: `marketplace plugin entry source directory does not exist: ${sourcePath}`
|
|
79309
|
+
});
|
|
79310
|
+
}
|
|
79311
|
+
const sourceRelCheck = relative18(snapshotDirReal, sourceDirReal);
|
|
79312
|
+
if (sourceRelCheck.startsWith("..") || isAbsolute15(sourceRelCheck)) {
|
|
79313
|
+
return createResult({
|
|
79314
|
+
actionType,
|
|
79315
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79316
|
+
error: `marketplace plugin entry source "${sourcePath}" escapes the frozen snapshot`
|
|
79317
|
+
});
|
|
79318
|
+
}
|
|
79319
|
+
const manifestRelative = join16(sourcePath, platform.manifestPaths.plugin);
|
|
79320
|
+
const manifestPath = resolve21(snapshotDirReal, manifestRelative);
|
|
79321
|
+
const manifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
79322
|
+
if (!manifestResult.valid) {
|
|
79323
|
+
return createResult({
|
|
79324
|
+
actionType,
|
|
79325
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79326
|
+
error: `frozen snapshot ${manifestRelative} invalid: ${manifestResult.error}`
|
|
79327
|
+
});
|
|
79328
|
+
}
|
|
79329
|
+
if (platform.marketplaceEntryCarriesVersion && entry.version !== action.version) {
|
|
79330
|
+
return createResult({
|
|
79331
|
+
actionType,
|
|
79332
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79333
|
+
error: `marketplace plugin entry version "${entry.version}" does not match action version "${action.version}"`
|
|
79334
|
+
});
|
|
79335
|
+
}
|
|
79336
|
+
const pluginManifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
79337
|
+
if (!pluginManifestResult.valid) {
|
|
79338
|
+
return createResult({
|
|
79339
|
+
actionType,
|
|
79340
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79341
|
+
error: `frozen snapshot ${manifestRelative} invalid: ${pluginManifestResult.error}`
|
|
79342
|
+
});
|
|
79343
|
+
}
|
|
79344
|
+
if (pluginManifestResult.manifest.name !== entry.name) {
|
|
79345
|
+
return createResult({
|
|
79346
|
+
actionType,
|
|
79347
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79348
|
+
error: `plugin manifest name "${pluginManifestResult.manifest.name}" does not match marketplace entry name "${entry.name}"`
|
|
79349
|
+
});
|
|
79350
|
+
}
|
|
79351
|
+
if (pluginManifestResult.manifest.version !== action.version) {
|
|
79352
|
+
return createResult({
|
|
79353
|
+
actionType,
|
|
79354
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
79355
|
+
error: `plugin manifest version "${pluginManifestResult.manifest.version}" does not match action version "${action.version}"`
|
|
79356
|
+
});
|
|
79357
|
+
}
|
|
78517
79358
|
}
|
|
78518
79359
|
}
|
|
78519
79360
|
if (!platform.automatable) {
|
|
79361
|
+
const resolveEntrySkillFile = consumer === "codebuddy" ? resolveCodeBuddyEntrySkillFile : resolveKimiEntrySkillFile;
|
|
78520
79362
|
try {
|
|
78521
|
-
await
|
|
79363
|
+
await resolveEntrySkillFile(snapshotDirReal, kimiSnapshotManifest, action.entrySkill);
|
|
78522
79364
|
} catch (entryErr) {
|
|
78523
79365
|
return createResult({
|
|
78524
79366
|
actionType,
|
|
@@ -78527,7 +79369,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78527
79369
|
});
|
|
78528
79370
|
}
|
|
78529
79371
|
} else {
|
|
78530
|
-
const entrySkillFile =
|
|
79372
|
+
const entrySkillFile = resolve21(snapshotDirReal, "skills", action.entrySkill, "SKILL.md");
|
|
78531
79373
|
try {
|
|
78532
79374
|
await stat5(entrySkillFile);
|
|
78533
79375
|
} catch {
|
|
@@ -78634,7 +79476,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78634
79476
|
}
|
|
78635
79477
|
if (action.entryPoint) {
|
|
78636
79478
|
try {
|
|
78637
|
-
await exec(process.execPath, ["--check",
|
|
79479
|
+
await exec(process.execPath, ["--check", resolve21(pluginDir, action.entryPoint)]);
|
|
78638
79480
|
} catch (checkErr) {
|
|
78639
79481
|
return createResult({
|
|
78640
79482
|
actionType,
|
|
@@ -78660,7 +79502,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78660
79502
|
});
|
|
78661
79503
|
}
|
|
78662
79504
|
}
|
|
78663
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
79505
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL || actionType === ActionType.CODEBUDDY_MARKETPLACE_INSTALL) {
|
|
78664
79506
|
try {
|
|
78665
79507
|
assertIsolatedConsumerWritesAuthorized(context, actionType);
|
|
78666
79508
|
const validation = validateMarketplaceParams(action);
|
|
@@ -78691,21 +79533,21 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78691
79533
|
}
|
|
78692
79534
|
const consumer = action.consumer;
|
|
78693
79535
|
const runDir = context.runDir;
|
|
78694
|
-
const isolatedHome =
|
|
79536
|
+
const isolatedHome = resolve21(runDir, "consumers", `${consumer}-${action.plugin}`);
|
|
78695
79537
|
const runDirReal = await realpath11(runDir).catch(() => runDir);
|
|
78696
79538
|
const isolatedHomePreReal = await realpath11(isolatedHome).catch(() => isolatedHome);
|
|
78697
|
-
const relToRun =
|
|
79539
|
+
const relToRun = relative18(runDirReal, isolatedHomePreReal);
|
|
78698
79540
|
const sepE = process.platform === "win32" ? "\\" : "/";
|
|
78699
|
-
if (relToRun !== "" && (
|
|
79541
|
+
if (relToRun !== "" && (isAbsolute15(relToRun) || relToRun === ".." || relToRun.startsWith(`..${sepE}`))) {
|
|
78700
79542
|
return createResult({
|
|
78701
79543
|
actionType,
|
|
78702
79544
|
status: ActionStatus.EXECUTE_FAILED,
|
|
78703
79545
|
error: `consumer directory escapes runDir: ${isolatedHome}`
|
|
78704
79546
|
});
|
|
78705
79547
|
}
|
|
78706
|
-
await
|
|
79548
|
+
await mkdir14(isolatedHome, { recursive: true, mode: 448 });
|
|
78707
79549
|
for (const subdir of platform.isolationSubdirs) {
|
|
78708
|
-
await
|
|
79550
|
+
await mkdir14(resolve21(isolatedHome, subdir), { recursive: true, mode: 448 });
|
|
78709
79551
|
}
|
|
78710
79552
|
const cliCmd = platform.cli.binary;
|
|
78711
79553
|
const baseEnv = { ...process.env, ...context.env };
|
|
@@ -78799,9 +79641,9 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78799
79641
|
error: `plugin install JSON missing installedPath`
|
|
78800
79642
|
});
|
|
78801
79643
|
}
|
|
78802
|
-
const installPathAbs =
|
|
78803
|
-
const installPathRel =
|
|
78804
|
-
if (
|
|
79644
|
+
const installPathAbs = resolve21(installFields.installedPath);
|
|
79645
|
+
const installPathRel = relative18(isolatedHome, installPathAbs);
|
|
79646
|
+
if (isAbsolute15(installPathRel) || installPathRel === ".." || installPathRel.startsWith(`..${sepE}`)) {
|
|
78805
79647
|
return createResult({
|
|
78806
79648
|
actionType,
|
|
78807
79649
|
status: ActionStatus.EXECUTE_FAILED,
|
|
@@ -78859,9 +79701,9 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78859
79701
|
executedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
78860
79702
|
...extraInstalledPathsAudit(executeBinding)
|
|
78861
79703
|
};
|
|
78862
|
-
const evidenceDir =
|
|
78863
|
-
await
|
|
78864
|
-
const evidencePath =
|
|
79704
|
+
const evidenceDir = resolve21(runDir, "evidence", `${consumer}-${action.plugin}`);
|
|
79705
|
+
await mkdir14(evidenceDir, { recursive: true, mode: 448 });
|
|
79706
|
+
const evidencePath = resolve21(evidenceDir, "release-skill-install-evidence.json");
|
|
78865
79707
|
await writeEvidenceAtomic(evidencePath, evidence);
|
|
78866
79708
|
const executeObservation = {
|
|
78867
79709
|
...evidence,
|
|
@@ -78910,7 +79752,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78910
79752
|
if (actionType === ActionType.PLUGIN_MANIFEST_VALIDATE) {
|
|
78911
79753
|
const manifestPath = action.manifestPath;
|
|
78912
79754
|
try {
|
|
78913
|
-
const content = await
|
|
79755
|
+
const content = await readFile20(manifestPath, "utf8");
|
|
78914
79756
|
const manifest = JSON.parse(content);
|
|
78915
79757
|
return createResult({
|
|
78916
79758
|
actionType,
|
|
@@ -78943,7 +79785,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78943
79785
|
}
|
|
78944
79786
|
});
|
|
78945
79787
|
}
|
|
78946
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
79788
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL || actionType === ActionType.CODEBUDDY_MARKETPLACE_INSTALL) {
|
|
78947
79789
|
const consumer = action.consumer;
|
|
78948
79790
|
const runDir = context.runDir;
|
|
78949
79791
|
if (!runDir) {
|
|
@@ -78953,7 +79795,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78953
79795
|
observation: { installed: false, error: "context.runDir is required" }
|
|
78954
79796
|
});
|
|
78955
79797
|
}
|
|
78956
|
-
const isolatedHome =
|
|
79798
|
+
const isolatedHome = resolve21(runDir, "consumers", `${consumer}-${action.plugin}`);
|
|
78957
79799
|
const platform = PLATFORMS.find((p) => p.id === consumer) ?? null;
|
|
78958
79800
|
const cliCmd = platform ? platform.cli ? platform.cli.binary : null : "kimi";
|
|
78959
79801
|
const baseEnv = { ...process.env, ...context.env ?? {} };
|
|
@@ -78972,7 +79814,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78972
79814
|
error: timeoutErr.message
|
|
78973
79815
|
});
|
|
78974
79816
|
}
|
|
78975
|
-
if (platform && !platform.automatable) {
|
|
79817
|
+
if (platform && !platform.automatable && actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
78976
79818
|
const expectedRef = action.ref ?? `v${action.version}`;
|
|
78977
79819
|
let boundPlanDigest;
|
|
78978
79820
|
try {
|
|
@@ -78999,7 +79841,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78999
79841
|
}
|
|
79000
79842
|
let requirement = null;
|
|
79001
79843
|
try {
|
|
79002
|
-
requirement = JSON.parse(await
|
|
79844
|
+
requirement = JSON.parse(await readFile20(resolve21(attestationDir, KIMI_REQUIREMENT_FILE), "utf8"));
|
|
79003
79845
|
} catch {
|
|
79004
79846
|
return createResult({
|
|
79005
79847
|
actionType,
|
|
@@ -79023,7 +79865,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79023
79865
|
}
|
|
79024
79866
|
let attestation = null;
|
|
79025
79867
|
try {
|
|
79026
|
-
attestation = JSON.parse(await
|
|
79868
|
+
attestation = JSON.parse(await readFile20(resolve21(attestationDir, KIMI_ATTESTATION_FILE), "utf8"));
|
|
79027
79869
|
} catch {
|
|
79028
79870
|
return createResult({
|
|
79029
79871
|
actionType,
|
|
@@ -79033,7 +79875,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79033
79875
|
manualInstallRequired: true,
|
|
79034
79876
|
installUrl: requirement.installUrl,
|
|
79035
79877
|
attestationDir,
|
|
79036
|
-
error: `kimi attestation is missing; write ${
|
|
79878
|
+
error: `kimi attestation is missing; write ${resolve21(attestationDir, KIMI_ATTESTATION_FILE)} after the interactive install (${requirement.installUrl})`
|
|
79037
79879
|
}
|
|
79038
79880
|
});
|
|
79039
79881
|
}
|
|
@@ -79045,7 +79887,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79045
79887
|
observation: { installed: false, error: attestationCheck.error }
|
|
79046
79888
|
});
|
|
79047
79889
|
}
|
|
79048
|
-
const kimiCodeHome =
|
|
79890
|
+
const kimiCodeHome = resolve21(attestationDir, "kimi-home");
|
|
79049
79891
|
const kimiCodeHomeReal = await realpath11(kimiCodeHome).catch(() => null);
|
|
79050
79892
|
if (!kimiCodeHomeReal) {
|
|
79051
79893
|
return createResult({
|
|
@@ -79057,18 +79899,18 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79057
79899
|
}
|
|
79058
79900
|
});
|
|
79059
79901
|
}
|
|
79060
|
-
const managedRootReal = await realpath11(
|
|
79902
|
+
const managedRootReal = await realpath11(resolve21(kimiCodeHomeReal, KIMI_MANAGED_SUBPATH, action.plugin)).catch(() => null);
|
|
79061
79903
|
if (!managedRootReal) {
|
|
79062
79904
|
return createResult({
|
|
79063
79905
|
actionType,
|
|
79064
79906
|
status: ActionStatus.OBSERVED,
|
|
79065
79907
|
observation: {
|
|
79066
79908
|
installed: false,
|
|
79067
|
-
error: `kimi managed plugin root does not exist: ${
|
|
79909
|
+
error: `kimi managed plugin root does not exist: ${resolve21(kimiCodeHomeReal, KIMI_MANAGED_SUBPATH, action.plugin)}`
|
|
79068
79910
|
}
|
|
79069
79911
|
});
|
|
79070
79912
|
}
|
|
79071
|
-
const installPath2 =
|
|
79913
|
+
const installPath2 = resolve21(attestation.installPath);
|
|
79072
79914
|
let installPathStat;
|
|
79073
79915
|
try {
|
|
79074
79916
|
installPathStat = await lstat11(installPath2);
|
|
@@ -79102,8 +79944,8 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79102
79944
|
});
|
|
79103
79945
|
}
|
|
79104
79946
|
const sepK = process.platform === "win32" ? "\\" : "/";
|
|
79105
|
-
const relToManaged =
|
|
79106
|
-
if (relToManaged !== "" && (
|
|
79947
|
+
const relToManaged = relative18(managedRootReal, installPathReal2);
|
|
79948
|
+
if (relToManaged !== "" && (isAbsolute15(relToManaged) || relToManaged === ".." || relToManaged.startsWith(`..${sepK}`))) {
|
|
79107
79949
|
return createResult({
|
|
79108
79950
|
actionType,
|
|
79109
79951
|
status: ActionStatus.OBSERVED,
|
|
@@ -79205,9 +80047,245 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79205
80047
|
observation: observation2
|
|
79206
80048
|
});
|
|
79207
80049
|
}
|
|
80050
|
+
if (platform && !platform.automatable && actionType === ActionType.CODEBUDDY_MARKETPLACE_INSTALL) {
|
|
80051
|
+
const expectedRef = action.ref ?? `v${action.version}`;
|
|
80052
|
+
let boundPlanDigest;
|
|
80053
|
+
try {
|
|
80054
|
+
boundPlanDigest = await resolveCodeBuddyBoundPlanDigest(context);
|
|
80055
|
+
} catch (planErr) {
|
|
80056
|
+
return createResult({
|
|
80057
|
+
actionType,
|
|
80058
|
+
status: ActionStatus.OBSERVED,
|
|
80059
|
+
observation: {
|
|
80060
|
+
installed: false,
|
|
80061
|
+
error: `cannot bind codebuddy observation to the frozen plan: ${planErr.message}`
|
|
80062
|
+
}
|
|
80063
|
+
});
|
|
80064
|
+
}
|
|
80065
|
+
let attestationDir;
|
|
80066
|
+
try {
|
|
80067
|
+
attestationDir = codebuddyAuthorityDir(context, boundPlanDigest, action.plugin);
|
|
80068
|
+
} catch (dirErr) {
|
|
80069
|
+
return createResult({
|
|
80070
|
+
actionType,
|
|
80071
|
+
status: ActionStatus.OBSERVED,
|
|
80072
|
+
observation: { installed: false, error: dirErr.message }
|
|
80073
|
+
});
|
|
80074
|
+
}
|
|
80075
|
+
let requirement = null;
|
|
80076
|
+
try {
|
|
80077
|
+
requirement = JSON.parse(await readFile20(resolve21(attestationDir, CODEBUDDY_REQUIREMENT_FILE), "utf8"));
|
|
80078
|
+
} catch {
|
|
80079
|
+
return createResult({
|
|
80080
|
+
actionType,
|
|
80081
|
+
status: ActionStatus.OBSERVED,
|
|
80082
|
+
observation: {
|
|
80083
|
+
installed: false,
|
|
80084
|
+
manualInstallRequired: true,
|
|
80085
|
+
error: "codebuddy manual-install requirement is missing; run execute first"
|
|
80086
|
+
}
|
|
80087
|
+
});
|
|
80088
|
+
}
|
|
80089
|
+
if (requirement.planDigest !== boundPlanDigest || requirement.plugin !== action.plugin || requirement.version !== action.version || requirement.entrySkill !== action.entrySkill || requirement.repo !== action.repo || requirement.ref !== expectedRef) {
|
|
80090
|
+
return createResult({
|
|
80091
|
+
actionType,
|
|
80092
|
+
status: ActionStatus.OBSERVED,
|
|
80093
|
+
observation: {
|
|
80094
|
+
installed: false,
|
|
80095
|
+
error: "codebuddy manual-install requirement does not match the frozen plan/action"
|
|
80096
|
+
}
|
|
80097
|
+
});
|
|
80098
|
+
}
|
|
80099
|
+
let attestation = null;
|
|
80100
|
+
try {
|
|
80101
|
+
attestation = JSON.parse(await readFile20(resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE), "utf8"));
|
|
80102
|
+
} catch {
|
|
80103
|
+
return createResult({
|
|
80104
|
+
actionType,
|
|
80105
|
+
status: ActionStatus.OBSERVED,
|
|
80106
|
+
observation: {
|
|
80107
|
+
installed: false,
|
|
80108
|
+
manualInstallRequired: true,
|
|
80109
|
+
marketplaceSource: CODEBUDDY_MARKETPLACE_SOURCE,
|
|
80110
|
+
attestationDir,
|
|
80111
|
+
error: `codebuddy attestation is missing; write ${resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE)} after the manual install (marketplace ${CODEBUDDY_MARKETPLACE_SOURCE})`
|
|
80112
|
+
}
|
|
80113
|
+
});
|
|
80114
|
+
}
|
|
80115
|
+
const attestationCheck = validateCodeBuddyAttestation(attestation, action, (/* @__PURE__ */ new Date()).toISOString(), boundPlanDigest);
|
|
80116
|
+
if (!attestationCheck.valid) {
|
|
80117
|
+
return createResult({
|
|
80118
|
+
actionType,
|
|
80119
|
+
status: ActionStatus.OBSERVED,
|
|
80120
|
+
observation: { installed: false, error: attestationCheck.error }
|
|
80121
|
+
});
|
|
80122
|
+
}
|
|
80123
|
+
const installPath2 = resolve21(attestation.installPath);
|
|
80124
|
+
let installPathStat;
|
|
80125
|
+
try {
|
|
80126
|
+
installPathStat = await lstat11(installPath2);
|
|
80127
|
+
} catch {
|
|
80128
|
+
return createResult({
|
|
80129
|
+
actionType,
|
|
80130
|
+
status: ActionStatus.OBSERVED,
|
|
80131
|
+
observation: { installed: false, error: `codebuddy install path does not exist: ${attestation.installPath}` }
|
|
80132
|
+
});
|
|
80133
|
+
}
|
|
80134
|
+
if (installPathStat.isSymbolicLink()) {
|
|
80135
|
+
return createResult({
|
|
80136
|
+
actionType,
|
|
80137
|
+
status: ActionStatus.OBSERVED,
|
|
80138
|
+
observation: { installed: false, error: `codebuddy install path must not be a symlink: ${attestation.installPath}` }
|
|
80139
|
+
});
|
|
80140
|
+
}
|
|
80141
|
+
if (!installPathStat.isDirectory()) {
|
|
80142
|
+
return createResult({
|
|
80143
|
+
actionType,
|
|
80144
|
+
status: ActionStatus.OBSERVED,
|
|
80145
|
+
observation: { installed: false, error: `codebuddy install path must be a directory: ${attestation.installPath}` }
|
|
80146
|
+
});
|
|
80147
|
+
}
|
|
80148
|
+
const installPathReal2 = await realpath11(installPath2).catch(() => null);
|
|
80149
|
+
if (!installPathReal2) {
|
|
80150
|
+
return createResult({
|
|
80151
|
+
actionType,
|
|
80152
|
+
status: ActionStatus.OBSERVED,
|
|
80153
|
+
observation: { installed: false, error: `codebuddy install path cannot be resolved: ${attestation.installPath}` }
|
|
80154
|
+
});
|
|
80155
|
+
}
|
|
80156
|
+
if (attestation.installChannel === "cli") {
|
|
80157
|
+
const cliHome = codebuddyCliHome(attestationDir);
|
|
80158
|
+
const cliHomeReal = await realpath11(cliHome).catch(() => null);
|
|
80159
|
+
if (!cliHomeReal) {
|
|
80160
|
+
return createResult({
|
|
80161
|
+
actionType,
|
|
80162
|
+
status: ActionStatus.OBSERVED,
|
|
80163
|
+
observation: {
|
|
80164
|
+
installed: false,
|
|
80165
|
+
error: `codebuddy isolated CLI home does not exist or cannot be resolved: ${cliHome}`
|
|
80166
|
+
}
|
|
80167
|
+
});
|
|
80168
|
+
}
|
|
80169
|
+
const cliRootAbs = codebuddyCliInstallRoot(cliHomeReal, attestation.marketplace, action.plugin);
|
|
80170
|
+
const cliRootReal = await realpath11(cliRootAbs).catch(() => null);
|
|
80171
|
+
if (!cliRootReal) {
|
|
80172
|
+
return createResult({
|
|
80173
|
+
actionType,
|
|
80174
|
+
status: ActionStatus.OBSERVED,
|
|
80175
|
+
observation: {
|
|
80176
|
+
installed: false,
|
|
80177
|
+
error: `codebuddy CLI marketplace plugin root does not exist: ${cliRootAbs}`
|
|
80178
|
+
}
|
|
80179
|
+
});
|
|
80180
|
+
}
|
|
80181
|
+
const sepC = process.platform === "win32" ? "\\" : "/";
|
|
80182
|
+
const relToRoot = relative18(cliRootReal, installPathReal2);
|
|
80183
|
+
if (relToRoot !== "" && (isAbsolute15(relToRoot) || relToRoot === ".." || relToRoot.startsWith(`..${sepC}`))) {
|
|
80184
|
+
return createResult({
|
|
80185
|
+
actionType,
|
|
80186
|
+
status: ActionStatus.OBSERVED,
|
|
80187
|
+
observation: {
|
|
80188
|
+
installed: false,
|
|
80189
|
+
error: `codebuddy install path escapes the isolated CLI marketplace root (${cliRootReal}): ${attestation.installPath}`
|
|
80190
|
+
}
|
|
80191
|
+
});
|
|
80192
|
+
}
|
|
80193
|
+
}
|
|
80194
|
+
let manifestDigest2;
|
|
80195
|
+
let payloadBinding2 = null;
|
|
80196
|
+
try {
|
|
80197
|
+
payloadBinding2 = await verifyInstalledMarketplacePayload(action, context, installPathReal2, consumer);
|
|
80198
|
+
manifestDigest2 = payloadBinding2.manifestDigest;
|
|
80199
|
+
} catch (digestErr) {
|
|
80200
|
+
return createResult({
|
|
80201
|
+
actionType,
|
|
80202
|
+
status: ActionStatus.OBSERVED,
|
|
80203
|
+
observation: {
|
|
80204
|
+
installed: true,
|
|
80205
|
+
installPath: installPathReal2,
|
|
80206
|
+
error: `failed to bind installed codebuddy payload to frozen authority: ${digestErr.message}`
|
|
80207
|
+
}
|
|
80208
|
+
});
|
|
80209
|
+
}
|
|
80210
|
+
if (manifestDigest2 !== action.manifestDigest) {
|
|
80211
|
+
return createResult({
|
|
80212
|
+
actionType,
|
|
80213
|
+
status: ActionStatus.OBSERVED,
|
|
80214
|
+
observation: {
|
|
80215
|
+
installed: true,
|
|
80216
|
+
installPath: installPathReal2,
|
|
80217
|
+
error: "installed codebuddy payload digest does not match the frozen plan digest"
|
|
80218
|
+
}
|
|
80219
|
+
});
|
|
80220
|
+
}
|
|
80221
|
+
let installedManifest;
|
|
80222
|
+
try {
|
|
80223
|
+
const readManifest = await platform.strategy.readManifest(installPathReal2);
|
|
80224
|
+
installedManifest = readManifest.manifest;
|
|
80225
|
+
await resolveCodeBuddyEntrySkillFile(installPathReal2, installedManifest, action.entrySkill);
|
|
80226
|
+
} catch (entryErr) {
|
|
80227
|
+
return createResult({
|
|
80228
|
+
actionType,
|
|
80229
|
+
status: ActionStatus.OBSERVED,
|
|
80230
|
+
observation: {
|
|
80231
|
+
installed: true,
|
|
80232
|
+
installPath: installPathReal2,
|
|
80233
|
+
manifestDigest: manifestDigest2,
|
|
80234
|
+
entrySkillFound: false,
|
|
80235
|
+
error: `codebuddy entry skill not resolvable in installed copy: ${entryErr.message}`
|
|
80236
|
+
}
|
|
80237
|
+
});
|
|
80238
|
+
}
|
|
80239
|
+
if (installedManifest.name !== action.plugin) {
|
|
80240
|
+
return createResult({
|
|
80241
|
+
actionType,
|
|
80242
|
+
status: ActionStatus.OBSERVED,
|
|
80243
|
+
observation: {
|
|
80244
|
+
installed: true,
|
|
80245
|
+
installPath: installPathReal2,
|
|
80246
|
+
manifestDigest: manifestDigest2,
|
|
80247
|
+
entrySkillFound: true,
|
|
80248
|
+
error: `installed codebuddy manifest name "${installedManifest.name}" does not match action plugin "${action.plugin}"`
|
|
80249
|
+
}
|
|
80250
|
+
});
|
|
80251
|
+
}
|
|
80252
|
+
if (installedManifest.version !== action.version) {
|
|
80253
|
+
return createResult({
|
|
80254
|
+
actionType,
|
|
80255
|
+
status: ActionStatus.OBSERVED,
|
|
80256
|
+
observation: {
|
|
80257
|
+
installed: true,
|
|
80258
|
+
installPath: installPathReal2,
|
|
80259
|
+
manifestDigest: manifestDigest2,
|
|
80260
|
+
entrySkillFound: true,
|
|
80261
|
+
error: `installed codebuddy manifest version "${installedManifest.version}" does not match action version "${action.version}"`
|
|
80262
|
+
}
|
|
80263
|
+
});
|
|
80264
|
+
}
|
|
80265
|
+
const observation2 = {
|
|
80266
|
+
installed: true,
|
|
80267
|
+
installPath: installPathReal2,
|
|
80268
|
+
entrySkillFound: true,
|
|
80269
|
+
entrySkill: action.entrySkill,
|
|
80270
|
+
manifestDigest: manifestDigest2,
|
|
80271
|
+
consumer,
|
|
80272
|
+
plugin: installedManifest.name,
|
|
80273
|
+
version: installedManifest.version,
|
|
80274
|
+
repo: action.repo,
|
|
80275
|
+
ref: expectedRef,
|
|
80276
|
+
marketplace: attestation.marketplace,
|
|
80277
|
+
installChannel: attestation.installChannel,
|
|
80278
|
+
...extraInstalledPathsAudit(payloadBinding2)
|
|
80279
|
+
};
|
|
80280
|
+
return createResult({
|
|
80281
|
+
actionType,
|
|
80282
|
+
status: ActionStatus.OBSERVED,
|
|
80283
|
+
observation: observation2
|
|
80284
|
+
});
|
|
80285
|
+
}
|
|
79208
80286
|
let evidence = null;
|
|
79209
80287
|
try {
|
|
79210
|
-
const evidenceRaw = await
|
|
80288
|
+
const evidenceRaw = await readFile20(resolve21(runDir, "evidence", `${consumer}-${action.plugin}`, "release-skill-install-evidence.json"), "utf8");
|
|
79211
80289
|
evidence = JSON.parse(evidenceRaw);
|
|
79212
80290
|
} catch {
|
|
79213
80291
|
return createResult({
|
|
@@ -79292,9 +80370,9 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79292
80370
|
}
|
|
79293
80371
|
const isolatedHomeReal = await realpath11(isolatedHome).catch(() => isolatedHome);
|
|
79294
80372
|
const installPathReal = await realpath11(installPath).catch(() => installPath);
|
|
79295
|
-
const relToHome =
|
|
80373
|
+
const relToHome = relative18(isolatedHomeReal, installPathReal);
|
|
79296
80374
|
const sep4 = process.platform === "win32" ? "\\" : "/";
|
|
79297
|
-
if (relToHome !== "" && (
|
|
80375
|
+
if (relToHome !== "" && (isAbsolute15(relToHome) || relToHome === ".." || relToHome.startsWith(`..${sep4}`))) {
|
|
79298
80376
|
return createResult({
|
|
79299
80377
|
actionType,
|
|
79300
80378
|
status: ActionStatus.OBSERVED,
|
|
@@ -79304,7 +80382,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79304
80382
|
}
|
|
79305
80383
|
});
|
|
79306
80384
|
}
|
|
79307
|
-
const entrySkillPath =
|
|
80385
|
+
const entrySkillPath = resolve21(installPath, "skills", action.entrySkill, "SKILL.md");
|
|
79308
80386
|
let entrySkillFound = false;
|
|
79309
80387
|
try {
|
|
79310
80388
|
const skillStat = await lstat11(entrySkillPath);
|
|
@@ -79373,8 +80451,8 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79373
80451
|
});
|
|
79374
80452
|
}
|
|
79375
80453
|
try {
|
|
79376
|
-
const installedManifestPath =
|
|
79377
|
-
const installedManifestContent = await
|
|
80454
|
+
const installedManifestPath = resolve21(installPath, platform.manifestPaths.plugin);
|
|
80455
|
+
const installedManifestContent = await readFile20(installedManifestPath, "utf8");
|
|
79378
80456
|
const installedManifest = JSON.parse(installedManifestContent);
|
|
79379
80457
|
const expectedName = observation.plugin;
|
|
79380
80458
|
if (expectedName && installedManifest.name !== expectedName) {
|
|
@@ -79444,6 +80522,10 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79444
80522
|
}
|
|
79445
80523
|
if (evidence.repo) observation.repo = evidence.repo;
|
|
79446
80524
|
if (evidence.ref) observation.ref = evidence.ref;
|
|
80525
|
+
if (action.marketplaceLocation === "external") {
|
|
80526
|
+
observation.marketplaceLocation = action.marketplaceLocation;
|
|
80527
|
+
observation.marketplaceCommitSha = action.marketplaceCommitSha;
|
|
80528
|
+
}
|
|
79447
80529
|
return createResult({
|
|
79448
80530
|
actionType,
|
|
79449
80531
|
status: ActionStatus.OBSERVED,
|
|
@@ -79489,17 +80571,19 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
79489
80571
|
}
|
|
79490
80572
|
});
|
|
79491
80573
|
}
|
|
79492
|
-
var execFile9, NAME4, PAYLOAD_CONTRACT_DECLARED_MANIFEST, EXTRA_INSTALLED_PATHS_CAP, PAYLOAD_CONFLICT_REPORT_CAP, SUPPORTED_TYPES, SAFE_REPO_RE, CONSUMER_IDS, STRICT_SEMVER_RE;
|
|
80574
|
+
var execFile9, NAME4, PAYLOAD_CONTRACT_DECLARED_MANIFEST, PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE, EXTRA_INSTALLED_PATHS_CAP, PAYLOAD_CONFLICT_REPORT_CAP, SUPPORTED_TYPES, SAFE_REPO_RE, CONSUMER_IDS, STRICT_SEMVER_RE;
|
|
79493
80575
|
var init_plugin_marketplace = __esm({
|
|
79494
80576
|
async "src/adapters/plugin-marketplace.mjs"() {
|
|
79495
80577
|
init_contract();
|
|
79496
80578
|
init_frozen();
|
|
79497
80579
|
await init_registry();
|
|
79498
80580
|
await init_kimi();
|
|
80581
|
+
init_codebuddy();
|
|
79499
80582
|
execFile9 = promisify10(execFileCb10);
|
|
79500
80583
|
NAME4 = "plugin-marketplace";
|
|
79501
80584
|
__name(transportPayload, "transportPayload");
|
|
79502
80585
|
PAYLOAD_CONTRACT_DECLARED_MANIFEST = "declared-manifest-v1";
|
|
80586
|
+
PAYLOAD_CONTRACT_EXTERNAL_MARKETPLACE = "external-marketplace-v1";
|
|
79503
80587
|
EXTRA_INSTALLED_PATHS_CAP = 200;
|
|
79504
80588
|
PAYLOAD_CONFLICT_REPORT_CAP = 10;
|
|
79505
80589
|
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
@@ -79508,12 +80592,15 @@ var init_plugin_marketplace = __esm({
|
|
|
79508
80592
|
__name(extraInstalledPathsAudit, "extraInstalledPathsAudit");
|
|
79509
80593
|
__name(normalizeKimiSkillsRel, "normalizeKimiSkillsRel");
|
|
79510
80594
|
__name(resolveKimiEntrySkillFile, "resolveKimiEntrySkillFile");
|
|
80595
|
+
__name(normalizeCodeBuddySkillsRel, "normalizeCodeBuddySkillsRel");
|
|
80596
|
+
__name(resolveCodeBuddyEntrySkillFile, "resolveCodeBuddyEntrySkillFile");
|
|
79511
80597
|
SUPPORTED_TYPES = [
|
|
79512
80598
|
ActionType.PLUGIN_MANIFEST_VALIDATE,
|
|
79513
80599
|
ActionType.PLUGIN_INSTALL_CHECK,
|
|
79514
80600
|
ActionType.CLAUDE_MARKETPLACE_INSTALL,
|
|
79515
80601
|
ActionType.CODEX_MARKETPLACE_INSTALL,
|
|
79516
|
-
ActionType.KIMI_MARKETPLACE_INSTALL
|
|
80602
|
+
ActionType.KIMI_MARKETPLACE_INSTALL,
|
|
80603
|
+
ActionType.CODEBUDDY_MARKETPLACE_INSTALL
|
|
79517
80604
|
];
|
|
79518
80605
|
SAFE_REPO_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
79519
80606
|
CONSUMER_IDS = new Set(PLATFORMS.map((p) => p.id));
|
|
@@ -79533,8 +80620,8 @@ __export(verify_exports, {
|
|
|
79533
80620
|
runSmokeTest: () => runSmokeTest,
|
|
79534
80621
|
verifyRelease: () => verifyRelease
|
|
79535
80622
|
});
|
|
79536
|
-
import { readFile as
|
|
79537
|
-
import { dirname as dirname12, join as
|
|
80623
|
+
import { readFile as readFile21, writeFile as writeFile8, mkdtemp as mkdtemp3, rm as rm7, mkdir as mkdir15, lstat as lstat12, realpath as realpath12 } from "node:fs/promises";
|
|
80624
|
+
import { dirname as dirname12, join as join17, relative as relative19, isAbsolute as isAbsolute16, resolve as resolve22 } from "node:path";
|
|
79538
80625
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
79539
80626
|
import { execFile as execFileCb11 } from "node:child_process";
|
|
79540
80627
|
import { promisify as promisify11 } from "node:util";
|
|
@@ -79560,8 +80647,8 @@ function matchesSubset2(actual, expected) {
|
|
|
79560
80647
|
}
|
|
79561
80648
|
async function runSmokeTest(plan, root, options = {}) {
|
|
79562
80649
|
const baseDir = options.baseDir ?? tmpdir2();
|
|
79563
|
-
await
|
|
79564
|
-
const tmpDir = await mkdtemp3(
|
|
80650
|
+
await mkdir15(baseDir, { recursive: true });
|
|
80651
|
+
const tmpDir = await mkdtemp3(join17(baseDir, "verify-smoke-"));
|
|
79565
80652
|
const npmExec = options.npmExecutor ?? defaultNpmExecutor;
|
|
79566
80653
|
const installFlags = [
|
|
79567
80654
|
"--ignore-scripts",
|
|
@@ -79607,7 +80694,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
79607
80694
|
for (const { package: pkgName, registry, targetVersion, unitId, smokeBin, smokeArgs, smokeExpectedJson } of npmDistributions) {
|
|
79608
80695
|
const packageAtVersion = `${pkgName}@${targetVersion}`;
|
|
79609
80696
|
const installDir = resolveUnitScopedPath(tmpDir, unitId);
|
|
79610
|
-
await
|
|
80697
|
+
await mkdir15(join17(installDir, "node_modules"), { recursive: true });
|
|
79611
80698
|
const registryFlags = [...installFlags, "--registry", registry];
|
|
79612
80699
|
const installResult = await npmExec.install(
|
|
79613
80700
|
packageAtVersion,
|
|
@@ -79625,10 +80712,10 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
79625
80712
|
}
|
|
79626
80713
|
};
|
|
79627
80714
|
}
|
|
79628
|
-
const installedPkgPath =
|
|
80715
|
+
const installedPkgPath = join17(installDir, "node_modules", pkgName, "package.json");
|
|
79629
80716
|
let installedPkg;
|
|
79630
80717
|
try {
|
|
79631
|
-
installedPkg = JSON.parse(await
|
|
80718
|
+
installedPkg = JSON.parse(await readFile21(installedPkgPath, "utf8"));
|
|
79632
80719
|
} catch {
|
|
79633
80720
|
return {
|
|
79634
80721
|
passed: false,
|
|
@@ -79659,7 +80746,7 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
79659
80746
|
}
|
|
79660
80747
|
};
|
|
79661
80748
|
}
|
|
79662
|
-
const pkgRoot =
|
|
80749
|
+
const pkgRoot = join17(installDir, "node_modules", pkgName);
|
|
79663
80750
|
gateResults.push(...await runConsumerVerificationGates({
|
|
79664
80751
|
plan,
|
|
79665
80752
|
unitId,
|
|
@@ -79701,10 +80788,10 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
79701
80788
|
}
|
|
79702
80789
|
};
|
|
79703
80790
|
}
|
|
79704
|
-
const binPath =
|
|
79705
|
-
const relBin =
|
|
80791
|
+
const binPath = resolve22(pkgRoot, binRelative);
|
|
80792
|
+
const relBin = relative19(pkgRoot, binPath);
|
|
79706
80793
|
const sep4 = process.platform === "win32" ? "\\" : "/";
|
|
79707
|
-
if (
|
|
80794
|
+
if (isAbsolute16(relBin) || relBin === ".." || relBin.startsWith(`..${sep4}`)) {
|
|
79708
80795
|
return {
|
|
79709
80796
|
passed: false,
|
|
79710
80797
|
details: {
|
|
@@ -79718,8 +80805,8 @@ async function runSmokeTest(plan, root, options = {}) {
|
|
|
79718
80805
|
try {
|
|
79719
80806
|
binStat = await lstat12(binPath);
|
|
79720
80807
|
const [pkgRootReal, binPathReal] = await Promise.all([realpath12(pkgRoot), realpath12(binPath)]);
|
|
79721
|
-
const relReal =
|
|
79722
|
-
if (!binStat.isFile() || binStat.isSymbolicLink() ||
|
|
80808
|
+
const relReal = relative19(pkgRootReal, binPathReal);
|
|
80809
|
+
if (!binStat.isFile() || binStat.isSymbolicLink() || isAbsolute16(relReal) || relReal === ".." || relReal.startsWith(`..${sep4}`)) {
|
|
79723
80810
|
throw new Error("bin is not a regular file inside the installed package");
|
|
79724
80811
|
}
|
|
79725
80812
|
} catch (err) {
|
|
@@ -79849,7 +80936,7 @@ async function verifyRelease(options) {
|
|
|
79849
80936
|
}
|
|
79850
80937
|
let planRaw;
|
|
79851
80938
|
try {
|
|
79852
|
-
planRaw = await
|
|
80939
|
+
planRaw = await readFile21(planPath, "utf8");
|
|
79853
80940
|
} catch (err) {
|
|
79854
80941
|
throw new ReleaseError(
|
|
79855
80942
|
GATE_FAILED,
|
|
@@ -79871,7 +80958,7 @@ async function verifyRelease(options) {
|
|
|
79871
80958
|
const runId = `verify-${Date.now()}`;
|
|
79872
80959
|
const requestedRunDir = runDirOpt ?? resolveDefaultRunDir(planPath, "verify", runId);
|
|
79873
80960
|
const runDir = plan.production ? await createProductionRunDir(requestedRunDir, planPath) : requestedRunDir;
|
|
79874
|
-
if (!plan.production) await
|
|
80961
|
+
if (!plan.production) await mkdir15(runDir, { recursive: true });
|
|
79875
80962
|
const evidence = createEvidenceWriter({ runDir, command: "verify", clock: clockFn });
|
|
79876
80963
|
try {
|
|
79877
80964
|
await evidence.append({ phase: "verify", step: "plan-load", status: "started" });
|
|
@@ -79919,7 +81006,7 @@ async function verifyRelease(options) {
|
|
|
79919
81006
|
}
|
|
79920
81007
|
let approvalRaw;
|
|
79921
81008
|
try {
|
|
79922
|
-
approvalRaw = await
|
|
81009
|
+
approvalRaw = await readFile21(sourceRun.approvalPath, "utf8");
|
|
79923
81010
|
} catch (error) {
|
|
79924
81011
|
throw new ReleaseError(
|
|
79925
81012
|
GATE_FAILED,
|
|
@@ -79978,7 +81065,8 @@ async function verifyRelease(options) {
|
|
|
79978
81065
|
const MARKETPLACE_TYPES3 = /* @__PURE__ */ new Set([
|
|
79979
81066
|
"claude-marketplace-install",
|
|
79980
81067
|
"codex-marketplace-install",
|
|
79981
|
-
"kimi-marketplace-install"
|
|
81068
|
+
"kimi-marketplace-install",
|
|
81069
|
+
"codebuddy-marketplace-install"
|
|
79982
81070
|
]);
|
|
79983
81071
|
for (const action of actions) {
|
|
79984
81072
|
const adapterActionType = ADAPTER_ACTION_TYPE_MAP2[action.type];
|
|
@@ -80077,14 +81165,14 @@ async function verifyRelease(options) {
|
|
|
80077
81165
|
evidence,
|
|
80078
81166
|
env: gateEnv ?? process.env,
|
|
80079
81167
|
fixedEnv: action.type === "claude-marketplace-install" ? {
|
|
80080
|
-
HOME:
|
|
80081
|
-
CLAUDE_CONFIG_DIR:
|
|
81168
|
+
HOME: resolve22(runDir, "consumers", `claude-${action.parameters.plugin}`),
|
|
81169
|
+
CLAUDE_CONFIG_DIR: resolve22(runDir, "consumers", `claude-${action.parameters.plugin}`, ".claude")
|
|
80082
81170
|
} : action.type === "codex-marketplace-install" ? {
|
|
80083
|
-
HOME:
|
|
80084
|
-
CODEX_HOME:
|
|
81171
|
+
HOME: resolve22(runDir, "consumers", `codex-${action.parameters.plugin}`),
|
|
81172
|
+
CODEX_HOME: resolve22(runDir, "consumers", `codex-${action.parameters.plugin}`)
|
|
80085
81173
|
} : {
|
|
80086
|
-
HOME:
|
|
80087
|
-
KIMI_CODE_HOME:
|
|
81174
|
+
HOME: resolve22(runDir, "consumers", `kimi-${action.parameters.plugin}`),
|
|
81175
|
+
KIMI_CODE_HOME: resolve22(runDir, "consumers", `kimi-${action.parameters.plugin}`)
|
|
80088
81176
|
}
|
|
80089
81177
|
}));
|
|
80090
81178
|
} else {
|
|
@@ -80165,7 +81253,7 @@ async function verifyRelease(options) {
|
|
|
80165
81253
|
assertTransition(PUBLISHED, VERIFIED);
|
|
80166
81254
|
await evidence.append({ phase: "verify", status: "completed", overallStatus: VERIFIED });
|
|
80167
81255
|
const sourceRunDigest = sourceRun.runDigest ?? computeRunDigest(sourceRun);
|
|
80168
|
-
const verifyRunPath =
|
|
81256
|
+
const verifyRunPath = join17(runDir, "release-run.json");
|
|
80169
81257
|
const verifyRunState = {
|
|
80170
81258
|
runId,
|
|
80171
81259
|
command: "verify",
|
|
@@ -80246,7 +81334,8 @@ var init_verify = __esm({
|
|
|
80246
81334
|
"github-release": "github-release",
|
|
80247
81335
|
"claude-marketplace-install": "claude-marketplace-install",
|
|
80248
81336
|
"codex-marketplace-install": "codex-marketplace-install",
|
|
80249
|
-
"kimi-marketplace-install": "kimi-marketplace-install"
|
|
81337
|
+
"kimi-marketplace-install": "kimi-marketplace-install",
|
|
81338
|
+
"codebuddy-marketplace-install": "codebuddy-marketplace-install"
|
|
80250
81339
|
};
|
|
80251
81340
|
__name(defaultClock4, "defaultClock");
|
|
80252
81341
|
__name(matchesSubset2, "matchesSubset");
|
|
@@ -80260,7 +81349,7 @@ var init_verify = __esm({
|
|
|
80260
81349
|
exec: execFile10,
|
|
80261
81350
|
env: process.env
|
|
80262
81351
|
});
|
|
80263
|
-
const userConfig =
|
|
81352
|
+
const userConfig = join17(cwd, ".release-skill-npmrc");
|
|
80264
81353
|
await writeFile8(
|
|
80265
81354
|
userConfig,
|
|
80266
81355
|
`registry=${normalizedRegistry}/
|
|
@@ -80320,11 +81409,11 @@ __export(publish_exports, {
|
|
|
80320
81409
|
classifyPreObservation: () => classifyPreObservation,
|
|
80321
81410
|
publishRelease: () => publishRelease
|
|
80322
81411
|
});
|
|
80323
|
-
import { readFile as
|
|
80324
|
-
import { isAbsolute as
|
|
81412
|
+
import { readFile as readFile22, mkdir as mkdir16 } from "node:fs/promises";
|
|
81413
|
+
import { isAbsolute as isAbsolute17, join as join18, relative as relative20 } from "node:path";
|
|
80325
81414
|
function assertInsideAssetRoot(assetRoot, candidate, label) {
|
|
80326
|
-
const rel =
|
|
80327
|
-
if (rel === "" ||
|
|
81415
|
+
const rel = relative20(assetRoot, candidate);
|
|
81416
|
+
if (rel === "" || isAbsolute17(rel) || rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
|
|
80328
81417
|
throw new ReleaseError(GATE_FAILED, `${label} must be a child of the production asset root`);
|
|
80329
81418
|
}
|
|
80330
81419
|
}
|
|
@@ -80554,7 +81643,7 @@ async function publishRelease(options) {
|
|
|
80554
81643
|
const captureBaselineActual = typeof captureBaselineFn === "function" ? captureBaselineFn : captureBaseline;
|
|
80555
81644
|
let planRaw;
|
|
80556
81645
|
try {
|
|
80557
|
-
planRaw = await
|
|
81646
|
+
planRaw = await readFile22(planPath, "utf8");
|
|
80558
81647
|
} catch (err) {
|
|
80559
81648
|
throw new ReleaseError(GATE_FAILED, `cannot read release plan: ${err.message}`, { planPath, cause: err.code });
|
|
80560
81649
|
}
|
|
@@ -80572,7 +81661,7 @@ async function publishRelease(options) {
|
|
|
80572
81661
|
if (isProductionPlan) {
|
|
80573
81662
|
runDir = await createProductionRunDir(runDir, planPath);
|
|
80574
81663
|
} else {
|
|
80575
|
-
await
|
|
81664
|
+
await mkdir16(runDir, { recursive: true });
|
|
80576
81665
|
}
|
|
80577
81666
|
const evidence = createEvidenceWriter({ runDir, command: "publish", clock: clockFn });
|
|
80578
81667
|
try {
|
|
@@ -80664,7 +81753,7 @@ async function publishRelease(options) {
|
|
|
80664
81753
|
await evidence.append({ phase: "safety-gate", gate: "approval-load", status: "started" });
|
|
80665
81754
|
let approvalRaw;
|
|
80666
81755
|
try {
|
|
80667
|
-
approvalRaw = await
|
|
81756
|
+
approvalRaw = await readFile22(approvalPath, "utf8");
|
|
80668
81757
|
} catch (err) {
|
|
80669
81758
|
throw new ReleaseError(
|
|
80670
81759
|
GATE_FAILED,
|
|
@@ -80936,7 +82025,7 @@ async function publishRelease(options) {
|
|
|
80936
82025
|
}
|
|
80937
82026
|
}
|
|
80938
82027
|
await evidence.append({ phase: "safety-gate", gate: "global-preflight", status: "passed" });
|
|
80939
|
-
const runPath =
|
|
82028
|
+
const runPath = join18(runDir, "release-run.json");
|
|
80940
82029
|
const checkpoints = orderedActions.map((action) => ({
|
|
80941
82030
|
actionId: action.id,
|
|
80942
82031
|
actionType: action.type,
|
|
@@ -81165,7 +82254,8 @@ var init_publish = __esm({
|
|
|
81165
82254
|
MARKETPLACE_TYPES2 = /* @__PURE__ */ new Set([
|
|
81166
82255
|
"claude-marketplace-install",
|
|
81167
82256
|
"codex-marketplace-install",
|
|
81168
|
-
"kimi-marketplace-install"
|
|
82257
|
+
"kimi-marketplace-install",
|
|
82258
|
+
"codebuddy-marketplace-install"
|
|
81169
82259
|
]);
|
|
81170
82260
|
__name(defaultClock5, "defaultClock");
|
|
81171
82261
|
__name(deepClone, "deepClone");
|
|
@@ -81183,8 +82273,8 @@ var init_publish = __esm({
|
|
|
81183
82273
|
});
|
|
81184
82274
|
|
|
81185
82275
|
// src/artifacts/policy.mjs
|
|
81186
|
-
import { readFile as
|
|
81187
|
-
import { join as
|
|
82276
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
82277
|
+
import { join as join19 } from "node:path";
|
|
81188
82278
|
import { createHash as createHash11 } from "node:crypto";
|
|
81189
82279
|
function validateArtifactPolicy(policy) {
|
|
81190
82280
|
const ok = _validate(policy);
|
|
@@ -81280,10 +82370,10 @@ async function parseSafeYamlWithinRoot(root, policyPath) {
|
|
|
81280
82370
|
}
|
|
81281
82371
|
throw err;
|
|
81282
82372
|
}
|
|
81283
|
-
const fullPath =
|
|
82373
|
+
const fullPath = join19(root, policyPath);
|
|
81284
82374
|
let content;
|
|
81285
82375
|
try {
|
|
81286
|
-
content = await
|
|
82376
|
+
content = await readFile23(fullPath, "utf8");
|
|
81287
82377
|
} catch (err) {
|
|
81288
82378
|
throw new ReleaseError(
|
|
81289
82379
|
ARTIFACT_POLICY_INVALID,
|
|
@@ -81394,8 +82484,8 @@ var init_policy = __esm({
|
|
|
81394
82484
|
});
|
|
81395
82485
|
|
|
81396
82486
|
// src/artifacts/entry.mjs
|
|
81397
|
-
import { lstat as lstat13, readdir as readdir10, readFile as
|
|
81398
|
-
import { join as
|
|
82487
|
+
import { lstat as lstat13, readdir as readdir10, readFile as readFile24 } from "node:fs/promises";
|
|
82488
|
+
import { join as join20 } from "node:path";
|
|
81399
82489
|
import { promisify as promisify12 } from "node:util";
|
|
81400
82490
|
import { execFile as execFile11 } from "node:child_process";
|
|
81401
82491
|
function statToGitMode(stat9) {
|
|
@@ -81418,7 +82508,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
81418
82508
|
const items = await readdir10(dirPath, { withFileTypes: true });
|
|
81419
82509
|
for (const item of items) {
|
|
81420
82510
|
if (SKIP_DIRS2.has(item.name)) continue;
|
|
81421
|
-
const absPath =
|
|
82511
|
+
const absPath = join20(dirPath, item.name);
|
|
81422
82512
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
81423
82513
|
const st = await lstat13(absPath);
|
|
81424
82514
|
if (st.isSymbolicLink()) {
|
|
@@ -81439,7 +82529,7 @@ async function enumerateTreeEntries(root, dirPath, relBase) {
|
|
|
81439
82529
|
const subEntries = await enumerateTreeEntries(root, absPath, relPath);
|
|
81440
82530
|
entries.push(...subEntries);
|
|
81441
82531
|
} else {
|
|
81442
|
-
const content = await
|
|
82532
|
+
const content = await readFile24(absPath);
|
|
81443
82533
|
entries.push(
|
|
81444
82534
|
Object.freeze({
|
|
81445
82535
|
path: relPath,
|
|
@@ -81469,7 +82559,7 @@ async function readEntry({ root, path: path3, source = "worktree" } = {}) {
|
|
|
81469
82559
|
if (source !== "worktree") {
|
|
81470
82560
|
throw new ReleaseError(PATH_UNSAFE, `unsupported readEntry source: ${source}`, { source });
|
|
81471
82561
|
}
|
|
81472
|
-
const absPath =
|
|
82562
|
+
const absPath = join20(root, path3);
|
|
81473
82563
|
let st;
|
|
81474
82564
|
try {
|
|
81475
82565
|
st = await lstat13(absPath);
|
|
@@ -81502,7 +82592,7 @@ async function readEntry({ root, path: path3, source = "worktree" } = {}) {
|
|
|
81502
82592
|
{ path: path3, nlink: st.nlink }
|
|
81503
82593
|
);
|
|
81504
82594
|
}
|
|
81505
|
-
const content = await
|
|
82595
|
+
const content = await readFile24(absPath);
|
|
81506
82596
|
return Object.freeze({
|
|
81507
82597
|
kind: "regular",
|
|
81508
82598
|
path: path3,
|
|
@@ -81765,8 +82855,8 @@ var init_graph = __esm({
|
|
|
81765
82855
|
});
|
|
81766
82856
|
|
|
81767
82857
|
// src/artifacts/producer-registry.mjs
|
|
81768
|
-
import { readFile as
|
|
81769
|
-
import { join as
|
|
82858
|
+
import { readFile as readFile25, readdir as readdir11, stat as stat6, mkdir as mkdir17, writeFile as writeFile9, rm as rm8 } from "node:fs/promises";
|
|
82859
|
+
import { join as join21 } from "node:path";
|
|
81770
82860
|
import { mkdtemp as mkdtemp4 } from "node:fs/promises";
|
|
81771
82861
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
81772
82862
|
import { createHash as createHash12 } from "node:crypto";
|
|
@@ -81787,7 +82877,7 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
81787
82877
|
const dir = abs.replace(/\/[^/]*$/, "");
|
|
81788
82878
|
while ((match = importRe.exec(source)) !== null) {
|
|
81789
82879
|
const spec = match[1];
|
|
81790
|
-
let resolved =
|
|
82880
|
+
let resolved = join21(dir, spec);
|
|
81791
82881
|
if (!resolved.endsWith(".mjs")) resolved += ".mjs";
|
|
81792
82882
|
results.push(...collectStaticImports(resolved, visited));
|
|
81793
82883
|
}
|
|
@@ -81795,10 +82885,10 @@ function collectStaticImports(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
|
81795
82885
|
}
|
|
81796
82886
|
async function createBuiltInProducerRegistry() {
|
|
81797
82887
|
const producers = /* @__PURE__ */ new Map();
|
|
81798
|
-
const lockfilePath =
|
|
82888
|
+
const lockfilePath = join21(new URL("../../..", import.meta.url).pathname, "pnpm-lock.yaml");
|
|
81799
82889
|
let lockfileBytes;
|
|
81800
82890
|
try {
|
|
81801
|
-
lockfileBytes = await
|
|
82891
|
+
lockfileBytes = await readFile25(lockfilePath);
|
|
81802
82892
|
} catch {
|
|
81803
82893
|
lockfileBytes = Buffer.from("");
|
|
81804
82894
|
}
|
|
@@ -81815,7 +82905,7 @@ async function createBuiltInProducerRegistry() {
|
|
|
81815
82905
|
const allModuleBytes = await Promise.all(
|
|
81816
82906
|
allModulePaths.map(async (p) => {
|
|
81817
82907
|
try {
|
|
81818
|
-
return await
|
|
82908
|
+
return await readFile25(p);
|
|
81819
82909
|
} catch {
|
|
81820
82910
|
return Buffer.from("");
|
|
81821
82911
|
}
|
|
@@ -81835,13 +82925,13 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
81835
82925
|
const items = await readdir11(dirPath, { withFileTypes: true });
|
|
81836
82926
|
for (const item of items) {
|
|
81837
82927
|
if (item.name === ".git") continue;
|
|
81838
|
-
const absPath =
|
|
82928
|
+
const absPath = join21(dirPath, item.name);
|
|
81839
82929
|
const relPath = relBase ? `${relBase}/${item.name}` : item.name;
|
|
81840
82930
|
const st = await stat6(absPath);
|
|
81841
82931
|
if (st.isDirectory()) {
|
|
81842
82932
|
entries.push(...await readDirEntries(absPath, relPath));
|
|
81843
82933
|
} else {
|
|
81844
|
-
const content = await
|
|
82934
|
+
const content = await readFile25(absPath);
|
|
81845
82935
|
entries.push(Object.freeze({
|
|
81846
82936
|
path: relPath,
|
|
81847
82937
|
type: "blob",
|
|
@@ -81858,11 +82948,11 @@ async function readDirEntries(dirPath, relBase = "") {
|
|
|
81858
82948
|
async function materializeEntries(entries, dirPath) {
|
|
81859
82949
|
for (const entry of entries) {
|
|
81860
82950
|
if (!entry.path) continue;
|
|
81861
|
-
const targetPath =
|
|
82951
|
+
const targetPath = join21(dirPath, entry.path);
|
|
81862
82952
|
if (entry.type === "tree" || entry.kind === "tree") {
|
|
81863
|
-
await
|
|
82953
|
+
await mkdir17(targetPath, { recursive: true });
|
|
81864
82954
|
} else {
|
|
81865
|
-
await
|
|
82955
|
+
await mkdir17(join21(targetPath, ".."), { recursive: true });
|
|
81866
82956
|
if (entry.content) {
|
|
81867
82957
|
await writeFile9(targetPath, entry.content);
|
|
81868
82958
|
}
|
|
@@ -81906,7 +82996,7 @@ async function runProducerClosure({
|
|
|
81906
82996
|
graph,
|
|
81907
82997
|
inputSnapshot,
|
|
81908
82998
|
artifactIds,
|
|
81909
|
-
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp4(
|
|
82999
|
+
tempRootFactory = /* @__PURE__ */ __name(async () => mkdtemp4(join21(tmpdir3(), "producer-")), "tempRootFactory")
|
|
81910
83000
|
} = {}) {
|
|
81911
83001
|
const generatedSet = new Set(graph.topologicalOrder);
|
|
81912
83002
|
for (const id of artifactIds) {
|
|
@@ -81943,7 +83033,7 @@ async function runProducerClosure({
|
|
|
81943
83033
|
if (inputEntries) {
|
|
81944
83034
|
const first = inputEntries[0];
|
|
81945
83035
|
if (first && first.path) {
|
|
81946
|
-
const absPath = first.path.startsWith("/") ? first.path :
|
|
83036
|
+
const absPath = first.path.startsWith("/") ? first.path : join21(process.cwd(), first.path);
|
|
81947
83037
|
try {
|
|
81948
83038
|
const st = await stat6(absPath);
|
|
81949
83039
|
if (st.isDirectory()) {
|
|
@@ -82367,7 +83457,7 @@ var init_state = __esm({
|
|
|
82367
83457
|
});
|
|
82368
83458
|
|
|
82369
83459
|
// src/artifacts/artifact-plan.mjs
|
|
82370
|
-
import { writeFile as writeFile10, mkdir as
|
|
83460
|
+
import { writeFile as writeFile10, mkdir as mkdir18, readFile as readFile26, rename as rename3, open as open8 } from "node:fs/promises";
|
|
82371
83461
|
import { dirname as dirname13 } from "node:path";
|
|
82372
83462
|
function assemblePlan({
|
|
82373
83463
|
operation,
|
|
@@ -82392,7 +83482,7 @@ function assemblePlan({
|
|
|
82392
83482
|
}
|
|
82393
83483
|
async function writePlan(plan, outputPath) {
|
|
82394
83484
|
const dir = dirname13(outputPath);
|
|
82395
|
-
await
|
|
83485
|
+
await mkdir18(dir, { recursive: true });
|
|
82396
83486
|
const tmpPath = `${outputPath}.tmp`;
|
|
82397
83487
|
const content = JSON.stringify(plan, null, 2);
|
|
82398
83488
|
const fh = await open8(tmpPath, "w");
|
|
@@ -83056,8 +84146,8 @@ var init_adoption = __esm({
|
|
|
83056
84146
|
// src/artifacts/inspect.mjs
|
|
83057
84147
|
import { promisify as promisify15 } from "node:util";
|
|
83058
84148
|
import { execFile as execFile14 } from "node:child_process";
|
|
83059
|
-
import { readdir as readdir12, stat as stat7, readFile as
|
|
83060
|
-
import { join as
|
|
84149
|
+
import { readdir as readdir12, stat as stat7, readFile as readFile27 } from "node:fs/promises";
|
|
84150
|
+
import { join as join22 } from "node:path";
|
|
83061
84151
|
async function hasNestedGitRoots(root) {
|
|
83062
84152
|
try {
|
|
83063
84153
|
const { stdout } = await execFileAsync5(
|
|
@@ -83067,9 +84157,9 @@ async function hasNestedGitRoots(root) {
|
|
|
83067
84157
|
);
|
|
83068
84158
|
const dirs = stdout.split("\n").filter((s) => s.length > 0);
|
|
83069
84159
|
for (const dir of dirs) {
|
|
83070
|
-
const absDir =
|
|
84160
|
+
const absDir = join22(root, dir);
|
|
83071
84161
|
try {
|
|
83072
|
-
const nestedGit =
|
|
84162
|
+
const nestedGit = join22(absDir, ".git");
|
|
83073
84163
|
await stat7(nestedGit);
|
|
83074
84164
|
return true;
|
|
83075
84165
|
} catch {
|
|
@@ -83328,8 +84418,8 @@ var init_inspect = __esm({
|
|
|
83328
84418
|
});
|
|
83329
84419
|
|
|
83330
84420
|
// src/artifacts/resolution.mjs
|
|
83331
|
-
import { mkdir as
|
|
83332
|
-
import { join as
|
|
84421
|
+
import { mkdir as mkdir19, open as open9, readFile as readFile28, stat as stat8, lstat as lstat14, chmod as chmod4 } from "node:fs/promises";
|
|
84422
|
+
import { join as join23, resolve as resolve23, relative as relative21, isAbsolute as isAbsolute18, basename as basename8 } from "node:path";
|
|
83333
84423
|
function decodeBuffer(value, label) {
|
|
83334
84424
|
if (value == null) return null;
|
|
83335
84425
|
if (Buffer.isBuffer(value)) return value;
|
|
@@ -83431,9 +84521,9 @@ function assertSafeArtifactId(id) {
|
|
|
83431
84521
|
}
|
|
83432
84522
|
async function assertNoSymlinksInPath(root, artifactId) {
|
|
83433
84523
|
const levels = [
|
|
83434
|
-
|
|
83435
|
-
|
|
83436
|
-
|
|
84524
|
+
join23(root, ".release-skill"),
|
|
84525
|
+
join23(root, ".release-skill", "resolution"),
|
|
84526
|
+
join23(root, ".release-skill", "resolution", artifactId)
|
|
83437
84527
|
];
|
|
83438
84528
|
for (const dir of levels) {
|
|
83439
84529
|
try {
|
|
@@ -83449,11 +84539,11 @@ async function assertNoSymlinksInPath(root, artifactId) {
|
|
|
83449
84539
|
}
|
|
83450
84540
|
}
|
|
83451
84541
|
async function assertSafeResolvedPath(root, artifactId, resolvedPath) {
|
|
83452
|
-
const resolutionDir =
|
|
83453
|
-
const resolved =
|
|
84542
|
+
const resolutionDir = resolve23(root, ".release-skill", "resolution", artifactId);
|
|
84543
|
+
const resolved = resolve23(resolvedPath);
|
|
83454
84544
|
await assertNoSymlinksInPath(root, artifactId);
|
|
83455
|
-
const rel =
|
|
83456
|
-
if (rel.startsWith("..") ||
|
|
84545
|
+
const rel = relative21(resolutionDir, resolved);
|
|
84546
|
+
if (rel.startsWith("..") || isAbsolute18(rel)) {
|
|
83457
84547
|
throw new ReleaseError(
|
|
83458
84548
|
PATH_UNSAFE,
|
|
83459
84549
|
`resolvedPath must be inside resolution directory ${resolutionDir}`,
|
|
@@ -83468,7 +84558,7 @@ async function assertSafeResolvedPath(root, artifactId, resolvedPath) {
|
|
|
83468
84558
|
{ resolvedPath, expected: `${artifactId}.resolved`, actual: filename }
|
|
83469
84559
|
);
|
|
83470
84560
|
}
|
|
83471
|
-
if (resolved !==
|
|
84561
|
+
if (resolved !== resolve23(resolutionDir, `${artifactId}.resolved`)) {
|
|
83472
84562
|
throw new ReleaseError(
|
|
83473
84563
|
PATH_UNSAFE,
|
|
83474
84564
|
"resolvedPath must be the exact materialized resolution file",
|
|
@@ -83612,13 +84702,13 @@ async function materializeResolution({
|
|
|
83612
84702
|
const template = buildConflictTemplate(artifact.conflict ?? {}, decodedBuffers);
|
|
83613
84703
|
const templateDigest = sha256Hex(template);
|
|
83614
84704
|
await assertNoSymlinksInPath(root, artifactId);
|
|
83615
|
-
const resolutionDir =
|
|
83616
|
-
await
|
|
84705
|
+
const resolutionDir = join23(root, ".release-skill", "resolution", artifactId);
|
|
84706
|
+
await mkdir19(resolutionDir, { recursive: true, mode: 448 });
|
|
83617
84707
|
const dirStat = await stat8(resolutionDir);
|
|
83618
84708
|
if ((dirStat.mode & 511) !== 448) {
|
|
83619
84709
|
await chmod4(resolutionDir, 448);
|
|
83620
84710
|
}
|
|
83621
|
-
const resolvedPath =
|
|
84711
|
+
const resolvedPath = join23(resolutionDir, `${artifactId}.resolved`);
|
|
83622
84712
|
const fh = await open9(resolvedPath, "wx", 384);
|
|
83623
84713
|
try {
|
|
83624
84714
|
await fh.write(template, 0, template.length);
|
|
@@ -83660,7 +84750,7 @@ async function submitResolution({
|
|
|
83660
84750
|
async function readAndValidateResolvedFile(resolvedPath) {
|
|
83661
84751
|
let content;
|
|
83662
84752
|
try {
|
|
83663
|
-
content = await
|
|
84753
|
+
content = await readFile28(resolvedPath);
|
|
83664
84754
|
} catch (err) {
|
|
83665
84755
|
throw new ReleaseError(MISSING_PARAMETERS, `cannot read resolved file: ${err.message}`, { resolvedPath, cause: err.code });
|
|
83666
84756
|
}
|
|
@@ -83828,8 +84918,8 @@ var artifacts_exports = {};
|
|
|
83828
84918
|
__export(artifacts_exports, {
|
|
83829
84919
|
runArtifactsCommand: () => runArtifactsCommand
|
|
83830
84920
|
});
|
|
83831
|
-
import { readFile as
|
|
83832
|
-
import { join as
|
|
84921
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
84922
|
+
import { join as join24 } from "node:path";
|
|
83833
84923
|
async function runArtifactsCommand({ subcommand, args: args2, root } = {}) {
|
|
83834
84924
|
if (!VALID_SUBCOMMANDS.has(subcommand)) {
|
|
83835
84925
|
throw new ReleaseError(
|
|
@@ -83957,7 +85047,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
83957
85047
|
{ subcommand: "adopt" }
|
|
83958
85048
|
);
|
|
83959
85049
|
}
|
|
83960
|
-
const planRaw = await
|
|
85050
|
+
const planRaw = await readFile29(planPath, "utf8");
|
|
83961
85051
|
const plan = JSON.parse(planRaw);
|
|
83962
85052
|
if (expectedDigest && plan.planDigest !== expectedDigest) {
|
|
83963
85053
|
throw new ReleaseError(
|
|
@@ -83972,7 +85062,7 @@ async function handleAdopt({ args: args2, root }) {
|
|
|
83972
85062
|
if (artifact.path) {
|
|
83973
85063
|
const entry = await readEntry({ root, path: artifact.path, source: "worktree" });
|
|
83974
85064
|
if (entry.kind === "regular") {
|
|
83975
|
-
const bytes = await
|
|
85065
|
+
const bytes = await readFile29(join24(root, artifact.path));
|
|
83976
85066
|
currentEntries.set(artifact.id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
83977
85067
|
} else {
|
|
83978
85068
|
currentEntries.set(artifact.id, entry);
|
|
@@ -84037,7 +85127,7 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
84037
85127
|
{ subcommand: "bootstrap" }
|
|
84038
85128
|
);
|
|
84039
85129
|
}
|
|
84040
|
-
const planRaw = await
|
|
85130
|
+
const planRaw = await readFile29(planPath, "utf8");
|
|
84041
85131
|
const adoptionPlan = JSON.parse(planRaw);
|
|
84042
85132
|
const currentEntries = /* @__PURE__ */ new Map();
|
|
84043
85133
|
for (const id of new Set((adoptionPlan.protectedHunks ?? []).map((h) => h.artifactId))) {
|
|
@@ -84049,12 +85139,12 @@ async function handleBootstrap({ args: args2, root }) {
|
|
|
84049
85139
|
if (entry.kind !== "regular") {
|
|
84050
85140
|
throw new ReleaseError("PLAN_STALE", `artifact is no longer a regular file: ${id}`, { id });
|
|
84051
85141
|
}
|
|
84052
|
-
const bytes = await
|
|
85142
|
+
const bytes = await readFile29(join24(root, artifactPath));
|
|
84053
85143
|
currentEntries.set(id, Object.freeze({ ...entry, bytes, content: bytes }));
|
|
84054
85144
|
}
|
|
84055
85145
|
let replacementBytes;
|
|
84056
85146
|
if (action === "replace" && replacementPath) {
|
|
84057
|
-
replacementBytes = await
|
|
85147
|
+
replacementBytes = await readFile29(replacementPath);
|
|
84058
85148
|
}
|
|
84059
85149
|
const updated = await discardBootstrapHunk({
|
|
84060
85150
|
adoptionPlan,
|
|
@@ -84092,7 +85182,7 @@ async function handleResolve({ args: args2, root }) {
|
|
|
84092
85182
|
{ subcommand: "resolve" }
|
|
84093
85183
|
);
|
|
84094
85184
|
}
|
|
84095
|
-
const planRaw = await
|
|
85185
|
+
const planRaw = await readFile29(planPath, "utf8");
|
|
84096
85186
|
const plan = JSON.parse(planRaw);
|
|
84097
85187
|
if (plan.planDigest !== expectedDigest) {
|
|
84098
85188
|
throw new ReleaseError(
|
|
@@ -84460,7 +85550,7 @@ var init_docs = __esm({
|
|
|
84460
85550
|
});
|
|
84461
85551
|
|
|
84462
85552
|
// bin/release-skill-cli.mjs
|
|
84463
|
-
import { basename as basename9, dirname as dirname14, join as
|
|
85553
|
+
import { basename as basename9, dirname as dirname14, join as join25, resolve as resolve24 } from "node:path";
|
|
84464
85554
|
import { execFile as execFileCb12 } from "node:child_process";
|
|
84465
85555
|
import { promisify as promisify16 } from "node:util";
|
|
84466
85556
|
|
|
@@ -84525,6 +85615,24 @@ async function checkDependency(command2, versionArgs = ["--version"]) {
|
|
|
84525
85615
|
}
|
|
84526
85616
|
}
|
|
84527
85617
|
__name(checkDependency, "checkDependency");
|
|
85618
|
+
var CODEBUDDY_MACOS_ABS_PATH = "/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy";
|
|
85619
|
+
async function checkCodeBuddyDependency() {
|
|
85620
|
+
const candidates = [
|
|
85621
|
+
{ source: "PATH:codebuddy", command: "codebuddy" },
|
|
85622
|
+
{ source: "PATH:cbc", command: "cbc" },
|
|
85623
|
+
{ source: "macOS-bundle", command: CODEBUDDY_MACOS_ABS_PATH }
|
|
85624
|
+
];
|
|
85625
|
+
const diagnostics = [];
|
|
85626
|
+
for (const { source, command: command2 } of candidates) {
|
|
85627
|
+
const result = await checkDependency(command2, ["--version"]);
|
|
85628
|
+
if (result.available) {
|
|
85629
|
+
return { available: true, version: result.version, diagnostic: "ok", source };
|
|
85630
|
+
}
|
|
85631
|
+
diagnostics.push(`${source}: ${result.diagnostic}`);
|
|
85632
|
+
}
|
|
85633
|
+
return { available: false, version: null, diagnostic: diagnostics.join("; "), source: null };
|
|
85634
|
+
}
|
|
85635
|
+
__name(checkCodeBuddyDependency, "checkCodeBuddyDependency");
|
|
84528
85636
|
async function performEnvironmentChecks() {
|
|
84529
85637
|
const checks = {};
|
|
84530
85638
|
const nodeCheck = await checkDependency("node", ["--version"]);
|
|
@@ -84576,6 +85684,12 @@ async function performEnvironmentChecks() {
|
|
|
84576
85684
|
required: false,
|
|
84577
85685
|
usage: "\u4EC5\u5F53\u8BA1\u5212\u58F0\u660E kimi-plugin distribution \u65F6\u7528\u4E8E\u6D88\u8D39\u8005\u5B89\u88C5\u9A8C\u8BC1"
|
|
84578
85686
|
};
|
|
85687
|
+
const codebuddyCheck = await checkCodeBuddyDependency();
|
|
85688
|
+
checks.codebuddy = {
|
|
85689
|
+
...codebuddyCheck,
|
|
85690
|
+
required: false,
|
|
85691
|
+
usage: "\u4EC5\u5F53\u8BA1\u5212\u58F0\u660E codebuddy-plugin distribution \u65F6\u7528\u4E8E\u6D88\u8D39\u8005\u5B89\u88C5\u9A8C\u8BC1\uFF08\u4EBA\u5DE5 attestation \u95ED\u73AF\uFF1BCLI \u65E0\u6CD5\u9489\u6B7B\u51BB\u7ED3 ref\uFF0C\u5B89\u88C5\u7531\u4EBA\u5DE5\u5B8C\u6210\u5E76\u51FA\u5177 attestation\uFF09"
|
|
85692
|
+
};
|
|
84579
85693
|
return checks;
|
|
84580
85694
|
}
|
|
84581
85695
|
__name(performEnvironmentChecks, "performEnvironmentChecks");
|
|
@@ -84604,7 +85718,7 @@ function getCapabilityMaturity() {
|
|
|
84604
85718
|
publish: {
|
|
84605
85719
|
available: true,
|
|
84606
85720
|
mode: "controlled production (protocol-tested; no OS/network sandbox)",
|
|
84607
|
-
description: "Publishes frozen GitHub/npm artifacts and runs configured Claude/Codex/Kimi consumer checkpoints with approval and exact digest confirmation"
|
|
85721
|
+
description: "Publishes frozen GitHub/npm artifacts and runs configured Claude/Codex/Kimi/CodeBuddy consumer checkpoints (CodeBuddy via human attestation closed loop) with approval and exact digest confirmation"
|
|
84608
85722
|
},
|
|
84609
85723
|
reconcile: {
|
|
84610
85724
|
available: true,
|
|
@@ -84614,7 +85728,7 @@ function getCapabilityMaturity() {
|
|
|
84614
85728
|
verify: {
|
|
84615
85729
|
available: true,
|
|
84616
85730
|
mode: "fresh consumer verification (protocol-tested; no OS/network sandbox)",
|
|
84617
|
-
description: "Recheck remote state, exact npm installation, CLI help, and configured Claude/Codex/Kimi installs before VERIFIED"
|
|
85731
|
+
description: "Recheck remote state, exact npm installation, CLI help, and configured Claude/Codex/Kimi/CodeBuddy installs (CodeBuddy via human attestation) before VERIFIED"
|
|
84618
85732
|
}
|
|
84619
85733
|
};
|
|
84620
85734
|
}
|
|
@@ -84690,7 +85804,7 @@ if (!command && (args.includes("--version") || args.includes("-v"))) {
|
|
|
84690
85804
|
} else {
|
|
84691
85805
|
const { readFileSync: readFileSync5 } = await import("node:fs");
|
|
84692
85806
|
const { fileURLToPath: fileURLToPath3 } = await import("node:url");
|
|
84693
|
-
const pkgPath =
|
|
85807
|
+
const pkgPath = join25(dirname14(fileURLToPath3(import.meta.url)), "..", "package.json");
|
|
84694
85808
|
pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
|
|
84695
85809
|
}
|
|
84696
85810
|
if (hasJson) {
|
|
@@ -84739,7 +85853,8 @@ if (!command || command === "help") {
|
|
|
84739
85853
|
conditionalConsumers: {
|
|
84740
85854
|
claude: "\u58F0\u660E claude-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528",
|
|
84741
85855
|
codex: "\u58F0\u660E codex-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528",
|
|
84742
|
-
kimi: "\u58F0\u660E kimi-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528"
|
|
85856
|
+
kimi: "\u58F0\u660E kimi-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528",
|
|
85857
|
+
codebuddy: "\u58F0\u660E codebuddy-plugin distribution \u65F6\u7528\u4E8E\u4EBA\u5DE5 attestation \u95ED\u73AF\uFF08CLI \u65E0\u6CD5\u9489\u6B7B\u51BB\u7ED3 ref\uFF0C\u5B89\u88C5\u7531\u4EBA\u5DE5\u5B8C\u6210\u5E76\u51FA\u5177 attestation\uFF09"
|
|
84743
85858
|
}
|
|
84744
85859
|
}
|
|
84745
85860
|
},
|
|
@@ -84751,9 +85866,9 @@ if (!command || command === "help") {
|
|
|
84751
85866
|
prepare: "offline local writes; configured hooks/gates require their explicit side-effect acknowledgements",
|
|
84752
85867
|
docs: "read-only dry-run by default; write requires --write, exact --confirm-refresh, and --ack-local-document-write; never commits, pushes, or publishes",
|
|
84753
85868
|
onlinePrepare: "previous-public-baseline observation available; production mode freezes publish artifacts and fails closed on drift or unknown state",
|
|
84754
|
-
publish: "GitHub/npm plus configured Claude/Codex/Kimi consumer checkpoints are protocol-tested without an OS/network sandbox; approval and exact digest confirmation required",
|
|
85869
|
+
publish: "GitHub/npm plus configured Claude/Codex/Kimi/CodeBuddy consumer checkpoints are protocol-tested without an OS/network sandbox (CodeBuddy via human attestation closed loop); approval and exact digest confirmation required",
|
|
84755
85870
|
reconcile: "PARTIAL recovery is protocol-tested without an OS/network sandbox; remote conflicts require human intervention",
|
|
84756
|
-
verify: "fresh exact npm and Claude/Codex/Kimi consumer installation checks are protocol-tested without an OS/network sandbox; configured consumer processes require explicit acknowledgement; success reaches VERIFIED"
|
|
85871
|
+
verify: "fresh exact npm and Claude/Codex/Kimi/CodeBuddy consumer installation checks are protocol-tested without an OS/network sandbox (CodeBuddy via human attestation); configured consumer processes require explicit acknowledgement; success reaches VERIFIED"
|
|
84757
85872
|
},
|
|
84758
85873
|
recommendations: []
|
|
84759
85874
|
};
|
|
@@ -84783,6 +85898,9 @@ if (!command || command === "help") {
|
|
|
84783
85898
|
if (!checks.kimi.available) {
|
|
84784
85899
|
output.recommendations.push("Install Kimi Code CLI before releasing a configured kimi-plugin distribution");
|
|
84785
85900
|
}
|
|
85901
|
+
if (!checks.codebuddy.available) {
|
|
85902
|
+
output.recommendations.push("Install WorkBuddy (bundled codebuddy CLI) before releasing a configured codebuddy-plugin distribution; the install is a manual attestation closed loop because the CLI cannot pin a frozen ref");
|
|
85903
|
+
}
|
|
84786
85904
|
console.log(JSON.stringify(output, null, 2));
|
|
84787
85905
|
process.exit(readiness.status === "READY" ? 0 : 1);
|
|
84788
85906
|
} else {
|
|
@@ -84807,7 +85925,7 @@ if (!COMMANDS.has(command)) {
|
|
|
84807
85925
|
if (command === "setup") {
|
|
84808
85926
|
const rootIdx = args.indexOf("--root");
|
|
84809
85927
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
84810
|
-
const root =
|
|
85928
|
+
const root = resolve24(rawRoot);
|
|
84811
85929
|
const answersIdx = args.indexOf("--answers");
|
|
84812
85930
|
const answersPath = answersIdx !== -1 && args[answersIdx + 1] ? args[answersIdx + 1] : void 0;
|
|
84813
85931
|
const confirmationIdx = args.indexOf("--confirm-setup");
|
|
@@ -84842,7 +85960,7 @@ if (command === "setup") {
|
|
|
84842
85960
|
if (command === "assess") {
|
|
84843
85961
|
const rootIdx = args.indexOf("--root");
|
|
84844
85962
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
84845
|
-
const root =
|
|
85963
|
+
const root = resolve24(rawRoot);
|
|
84846
85964
|
const offline = args.includes("--offline") || !args.includes("--online");
|
|
84847
85965
|
const outputIdx = args.indexOf("--output");
|
|
84848
85966
|
const output = outputIdx !== -1 && args[outputIdx + 1] ? args[outputIdx + 1] : void 0;
|
|
@@ -84873,7 +85991,7 @@ if (command === "assess") {
|
|
|
84873
85991
|
if (command === "prepare") {
|
|
84874
85992
|
const rootIdx = args.indexOf("--root");
|
|
84875
85993
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
84876
|
-
const root =
|
|
85994
|
+
const root = resolve24(rawRoot);
|
|
84877
85995
|
const offline = args.includes("--offline") || !args.includes("--online");
|
|
84878
85996
|
let targetVersion;
|
|
84879
85997
|
for (const flag of ["--target-version", "--version"]) {
|
|
@@ -84888,9 +86006,9 @@ if (command === "prepare") {
|
|
|
84888
86006
|
const hookCache = !args.includes("--no-hook-cache");
|
|
84889
86007
|
const production = args.includes("--production");
|
|
84890
86008
|
const outputIdx = args.indexOf("--output");
|
|
84891
|
-
const output = outputIdx !== -1 && args[outputIdx + 1] ?
|
|
86009
|
+
const output = outputIdx !== -1 && args[outputIdx + 1] ? resolve24(args[outputIdx + 1]) : void 0;
|
|
84892
86010
|
const runDirIdx = args.indexOf("--run-dir");
|
|
84893
|
-
const runDir = runDirIdx !== -1 && args[runDirIdx + 1] ?
|
|
86011
|
+
const runDir = runDirIdx !== -1 && args[runDirIdx + 1] ? resolve24(args[runDirIdx + 1]) : void 0;
|
|
84894
86012
|
try {
|
|
84895
86013
|
const { prepareRelease: prepareRelease2 } = await init_prepare().then(() => prepare_exports);
|
|
84896
86014
|
const { readFile: readFileFs } = await import("node:fs/promises");
|
|
@@ -84943,7 +86061,7 @@ if (command === "approve") {
|
|
|
84943
86061
|
const actorIdx = args.indexOf("--actor");
|
|
84944
86062
|
const actor = actorIdx !== -1 && args[actorIdx + 1] ? args[actorIdx + 1] : void 0;
|
|
84945
86063
|
const outputIdx = args.indexOf("--output");
|
|
84946
|
-
const outputPath = outputIdx !== -1 && args[outputIdx + 1] ?
|
|
86064
|
+
const outputPath = outputIdx !== -1 && args[outputIdx + 1] ? resolve24(args[outputIdx + 1]) : void 0;
|
|
84947
86065
|
if (!planPath || !expectedDigest || !actor) {
|
|
84948
86066
|
const msg = "approve requires --plan <path>, --digest <sha256>, and --actor <name>";
|
|
84949
86067
|
if (hasJson) {
|
|
@@ -84955,10 +86073,10 @@ if (command === "approve") {
|
|
|
84955
86073
|
}
|
|
84956
86074
|
try {
|
|
84957
86075
|
const { approvePlan: approvePlan2 } = await init_approve().then(() => approve_exports);
|
|
84958
|
-
const resolvedPlanPath =
|
|
86076
|
+
const resolvedPlanPath = resolve24(planPath);
|
|
84959
86077
|
const planDir = dirname14(resolvedPlanPath);
|
|
84960
86078
|
const releaseDir = basename9(planDir) === "plans" && basename9(resolvedPlanPath) === `${expectedDigest}.json` ? dirname14(planDir) : planDir;
|
|
84961
|
-
const approvalPath = outputPath ??
|
|
86079
|
+
const approvalPath = outputPath ?? join25(releaseDir, "approval-record.json");
|
|
84962
86080
|
const record = await approvePlan2({ planPath, expectedDigest, actor, outputPath: approvalPath });
|
|
84963
86081
|
if (hasJson) {
|
|
84964
86082
|
console.log(JSON.stringify(record, null, 2));
|
|
@@ -84985,13 +86103,13 @@ if (command === "approve") {
|
|
|
84985
86103
|
if (command === "reconcile") {
|
|
84986
86104
|
const rootIdx = args.indexOf("--root");
|
|
84987
86105
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
84988
|
-
const root =
|
|
86106
|
+
const root = resolve24(rawRoot);
|
|
84989
86107
|
const planIdx = args.indexOf("--plan");
|
|
84990
|
-
const planPath = planIdx !== -1 && args[planIdx + 1] ?
|
|
86108
|
+
const planPath = planIdx !== -1 && args[planIdx + 1] ? resolve24(args[planIdx + 1]) : void 0;
|
|
84991
86109
|
const runIdx = args.indexOf("--run");
|
|
84992
|
-
const runPath = runIdx !== -1 && args[runIdx + 1] ?
|
|
86110
|
+
const runPath = runIdx !== -1 && args[runIdx + 1] ? resolve24(args[runIdx + 1]) : void 0;
|
|
84993
86111
|
const approvalIdx = args.indexOf("--approval");
|
|
84994
|
-
const approvalPath = approvalIdx !== -1 && args[approvalIdx + 1] ?
|
|
86112
|
+
const approvalPath = approvalIdx !== -1 && args[approvalIdx + 1] ? resolve24(args[approvalIdx + 1]) : void 0;
|
|
84995
86113
|
const confirmationIdx = args.indexOf("--confirm-production");
|
|
84996
86114
|
const productionConfirmation = confirmationIdx !== -1 && args[confirmationIdx + 1] ? args[confirmationIdx + 1] : void 0;
|
|
84997
86115
|
if (!planPath || !runPath) {
|
|
@@ -85050,11 +86168,11 @@ if (command === "reconcile") {
|
|
|
85050
86168
|
if (command === "verify") {
|
|
85051
86169
|
const rootIdx = args.indexOf("--root");
|
|
85052
86170
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
85053
|
-
const root =
|
|
86171
|
+
const root = resolve24(rawRoot);
|
|
85054
86172
|
const planIdx = args.indexOf("--plan");
|
|
85055
|
-
const planPath = planIdx !== -1 && args[planIdx + 1] ?
|
|
86173
|
+
const planPath = planIdx !== -1 && args[planIdx + 1] ? resolve24(args[planIdx + 1]) : void 0;
|
|
85056
86174
|
const runIdx = args.indexOf("--run");
|
|
85057
|
-
const runPath = runIdx !== -1 && args[runIdx + 1] ?
|
|
86175
|
+
const runPath = runIdx !== -1 && args[runIdx + 1] ? resolve24(args[runIdx + 1]) : void 0;
|
|
85058
86176
|
const verificationGatesAuthorized = args.includes("--acknowledge-gate-side-effects");
|
|
85059
86177
|
if (!planPath || !runPath) {
|
|
85060
86178
|
const msg = "verify requires --plan <path> and --run <path>";
|
|
@@ -85110,11 +86228,11 @@ if (command === "verify") {
|
|
|
85110
86228
|
if (command === "publish") {
|
|
85111
86229
|
const rootIdx = args.indexOf("--root");
|
|
85112
86230
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
85113
|
-
const root =
|
|
86231
|
+
const root = resolve24(rawRoot);
|
|
85114
86232
|
const planIdx = args.indexOf("--plan");
|
|
85115
|
-
const planPath = planIdx !== -1 && args[planIdx + 1] ?
|
|
86233
|
+
const planPath = planIdx !== -1 && args[planIdx + 1] ? resolve24(args[planIdx + 1]) : void 0;
|
|
85116
86234
|
const approvalIdx = args.indexOf("--approval");
|
|
85117
|
-
const approvalPath = approvalIdx !== -1 && args[approvalIdx + 1] ?
|
|
86235
|
+
const approvalPath = approvalIdx !== -1 && args[approvalIdx + 1] ? resolve24(args[approvalIdx + 1]) : void 0;
|
|
85118
86236
|
const confirmationIdx = args.indexOf("--confirm-production");
|
|
85119
86237
|
const productionConfirmation = confirmationIdx !== -1 && args[confirmationIdx + 1] ? args[confirmationIdx + 1] : void 0;
|
|
85120
86238
|
if (!planPath || !approvalPath || !productionConfirmation) {
|
|
@@ -85173,9 +86291,9 @@ if (command === "publish") {
|
|
|
85173
86291
|
if (command === "artifacts") {
|
|
85174
86292
|
const rootIdx = args.indexOf("--root");
|
|
85175
86293
|
const rawRoot = rootIdx !== -1 && args[rootIdx + 1] ? args[rootIdx + 1] : process.cwd();
|
|
85176
|
-
const root =
|
|
86294
|
+
const root = resolve24(rawRoot);
|
|
85177
86295
|
const outputIdx = args.indexOf("--output");
|
|
85178
|
-
const output = outputIdx !== -1 && args[outputIdx + 1] ?
|
|
86296
|
+
const output = outputIdx !== -1 && args[outputIdx + 1] ? resolve24(args[outputIdx + 1]) : void 0;
|
|
85179
86297
|
const subcommand = positional[1] ?? "status";
|
|
85180
86298
|
try {
|
|
85181
86299
|
const { runArtifactsCommand: runArtifactsCommand2 } = await Promise.resolve().then(() => (init_artifacts(), artifacts_exports));
|
|
@@ -85242,7 +86360,7 @@ if (command === "docs") {
|
|
|
85242
86360
|
);
|
|
85243
86361
|
}
|
|
85244
86362
|
}
|
|
85245
|
-
const root =
|
|
86363
|
+
const root = resolve24(rawRoot);
|
|
85246
86364
|
const valuedDocsFlags = /* @__PURE__ */ new Set(["--root", "--unit", "--confirm-refresh"]);
|
|
85247
86365
|
const booleanDocsFlags = /* @__PURE__ */ new Set(["--json", "--write", "--ack-local-document-write"]);
|
|
85248
86366
|
let docsSubcommand;
|