@smartergpt/lexrunner 2.0.2 → 2.2.0
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/BRAND.md +14 -0
- package/CHANGELOG.md +49 -0
- package/GOVERNANCE.md +18 -0
- package/LICENSE.md +201 -110
- package/NOTICE.md +12 -1
- package/README.mcp.md +5 -1
- package/README.md +48 -35
- package/dist/{api-QBPBKYOC.js → api-UIWVFU7M.js} +1 -1
- package/dist/{audit-SKMMC2U4.js → audit-HVB2HJPU.js} +2 -2
- package/dist/{autopilot-3OHEUTHD.js → autopilot-7PX6YG55.js} +2 -2
- package/dist/{chunk-6PZDSWCG.js → chunk-37UC53OG.js} +2 -2
- package/dist/{chunk-ARDKZW7F.js → chunk-M6AAYMHH.js} +363 -293
- package/dist/{chunk-V3BU2VDU.js → chunk-PDDULIDL.js} +13 -1
- package/dist/cli.cjs +3672 -2774
- package/dist/cli.d.ts +201 -24
- package/dist/cli.js +1073 -275
- package/dist/{commandValidator-LVEMJTZP.js → commandValidator-XFVNCZXX.js} +1 -1
- package/dist/{constraints-2ZK5FJFA.js → constraints-LE2MW5NS.js} +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/frames/index.js +1 -1
- package/dist/{gateMapping-R3RJYKMS.js → gateMapping-V4DTL5WD.js} +1 -1
- package/dist/hooks/events.js +1 -1
- package/dist/{jsonEnvelope-K2U5CWKU.js → jsonEnvelope-MXJM5ZQH.js} +1 -1
- package/dist/{mergeTreeSimulator-QCFSOU25.js → mergeTreeSimulator-GWZ77NF2.js} +1 -1
- package/dist/package-schemas/behavior-rule.js +1 -1
- package/dist/package-schemas/execution-plan-v1.js +1 -1
- package/dist/package-schemas/gates.js +1 -1
- package/dist/package-schemas/runner-scope.js +1 -1
- package/dist/package-schemas/runner-stack.js +1 -1
- package/dist/{planDiff-IHLFNZUT.js → planDiff-4D3AERAW.js} +1 -1
- package/dist/{planHistory-GLRI356L.js → planHistory-VPV4WDPW.js} +1 -1
- package/dist/{planReview-UUMCGZJ6.js → planReview-FV6INFLQ.js} +1 -1
- package/dist/{planViewer-TRSQVMH4.js → planViewer-WOV6A2HZ.js} +1 -1
- package/dist/{sarif-2C6RKOUX.js → sarif-QXVE3LYD.js} +1 -1
- package/dist/sdk/index.d.ts +5 -5
- package/dist/sdk/index.js +1 -1
- package/dist/{security-OE4VLUFK.js → security-W7TOUXSB.js} +1 -1
- package/dist/{signing-KLZYZZMP.js → signing-WGVPHJGG.js} +1 -1
- package/dist/{verify-3UVMA62I.js → verify-Y34CJAKB.js} +1 -1
- package/package.json +8 -6
- package/schemas/plan.schema.json +203 -73
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
finalizeAudit,
|
|
25
25
|
initAuditEmitter,
|
|
26
26
|
redactSecrets
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-37UC53OG.js";
|
|
28
28
|
import "./chunk-6KK5JFFE.js";
|
|
29
29
|
import {
|
|
30
30
|
simulateBatchMerges
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
AutopilotConfigError,
|
|
34
34
|
FileAnalyzer,
|
|
35
|
+
FrozenGitInputs,
|
|
35
36
|
GATE_EXECUTION_RECEIPT_SCHEMA_VERSION,
|
|
36
37
|
GitHubAuthError,
|
|
37
38
|
GitHubClientImpl,
|
|
@@ -75,6 +76,7 @@ import {
|
|
|
75
76
|
readRunLog,
|
|
76
77
|
readRunState,
|
|
77
78
|
removeIndexEntry,
|
|
79
|
+
repositoryIdentity,
|
|
78
80
|
resolveProfile,
|
|
79
81
|
resolveSpawnExecutable,
|
|
80
82
|
runEnvironmentQualityCheck,
|
|
@@ -83,7 +85,7 @@ import {
|
|
|
83
85
|
validateWriteOperation,
|
|
84
86
|
verifyToolchainPins,
|
|
85
87
|
writeRunState
|
|
86
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-M6AAYMHH.js";
|
|
87
89
|
import {
|
|
88
90
|
ExecutionState,
|
|
89
91
|
generateMarkdownSummary,
|
|
@@ -135,9 +137,13 @@ import "./chunk-AXOAVRTU.js";
|
|
|
135
137
|
import {
|
|
136
138
|
__esm,
|
|
137
139
|
__export,
|
|
140
|
+
__privateAdd,
|
|
141
|
+
__privateGet,
|
|
142
|
+
__privateMethod,
|
|
143
|
+
__privateSet,
|
|
138
144
|
__require,
|
|
139
145
|
__toCommonJS
|
|
140
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-PDDULIDL.js";
|
|
141
147
|
|
|
142
148
|
// src/metrics/export.ts
|
|
143
149
|
var export_exports = {};
|
|
@@ -470,7 +476,7 @@ import "dotenv/config";
|
|
|
470
476
|
// package.json
|
|
471
477
|
var package_default = {
|
|
472
478
|
name: "@smartergpt/lexrunner",
|
|
473
|
-
version: "2.0
|
|
479
|
+
version: "2.2.0",
|
|
474
480
|
type: "module",
|
|
475
481
|
engines: {
|
|
476
482
|
node: ">=24"
|
|
@@ -480,13 +486,13 @@ var package_default = {
|
|
|
480
486
|
description: "Fan-out tasks as multiple PRs in parallel, then build a merge pyramid from the blocks. Compute dependency order, run gates locally, and merge cleanly.",
|
|
481
487
|
repository: {
|
|
482
488
|
type: "git",
|
|
483
|
-
url: "git+https://github.com/
|
|
489
|
+
url: "git+https://github.com/SmarterGPT/lexrunner.git"
|
|
484
490
|
},
|
|
485
491
|
publishConfig: {
|
|
486
|
-
access: "
|
|
492
|
+
access: "public",
|
|
487
493
|
registry: "https://registry.npmjs.org/"
|
|
488
494
|
},
|
|
489
|
-
license: "
|
|
495
|
+
license: "Apache-2.0",
|
|
490
496
|
files: [
|
|
491
497
|
"dist/",
|
|
492
498
|
"schemas/",
|
|
@@ -495,7 +501,9 @@ var package_default = {
|
|
|
495
501
|
"README.mcp.md",
|
|
496
502
|
"CHANGELOG.md",
|
|
497
503
|
"NOTICE.md",
|
|
498
|
-
"LICENSE.md"
|
|
504
|
+
"LICENSE.md",
|
|
505
|
+
"GOVERNANCE.md",
|
|
506
|
+
"BRAND.md"
|
|
499
507
|
],
|
|
500
508
|
bin: {
|
|
501
509
|
lexrunner: "dist/cli.js",
|
|
@@ -571,7 +579,7 @@ var package_default = {
|
|
|
571
579
|
"docs:surface:check": "node scripts/render-doc-surfaces.mjs --check",
|
|
572
580
|
"dogfood:ecosystem": "tsx scripts/dogfood-ecosystem.ts",
|
|
573
581
|
test: "vitest run",
|
|
574
|
-
"test:git": "vitest run -c vitest.git.config.ts tests/release-prepare.spec.ts tests/promptsResolver.spec.ts tests/e2e-comprehensive.test.ts tests/autopilot-e2e-level3-4.spec.ts tests/deterministic-build.test.ts tests/e2e-merge-resume.spec.ts",
|
|
582
|
+
"test:git": "vitest run -c vitest.git.config.ts tests/release-prepare.spec.ts tests/promptsResolver.spec.ts tests/e2e-comprehensive.test.ts tests/autopilot-e2e-level3-4.spec.ts tests/deterministic-build.test.ts tests/e2e-merge-resume.spec.ts tests/e2e-frozen-git-inputs.spec.ts",
|
|
575
583
|
"test:isolation": "node scripts/verify-parallel-isolation.mjs",
|
|
576
584
|
"test:cli:slow": "vitest run -c vitest.slow-cli.config.ts",
|
|
577
585
|
benchmark: "vitest bench -c vitest.benchmark.config.ts",
|
|
@@ -649,7 +657,7 @@ var package_default = {
|
|
|
649
657
|
// src/cli.ts
|
|
650
658
|
import { Command as Command6, CommanderError } from "commander";
|
|
651
659
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
652
|
-
import { resolve as
|
|
660
|
+
import { resolve as resolve15 } from "path";
|
|
653
661
|
import chalk11 from "chalk";
|
|
654
662
|
|
|
655
663
|
// src/core/inputs.ts
|
|
@@ -1106,8 +1114,8 @@ function generateSnapshot(plan, inputs) {
|
|
|
1106
1114
|
}
|
|
1107
1115
|
function getPackageVersion() {
|
|
1108
1116
|
try {
|
|
1109
|
-
const
|
|
1110
|
-
const packageJson = JSON.parse(
|
|
1117
|
+
const fs51 = __require("fs");
|
|
1118
|
+
const packageJson = JSON.parse(fs51.readFileSync("package.json", "utf8"));
|
|
1111
1119
|
return packageJson.version || "unknown";
|
|
1112
1120
|
} catch {
|
|
1113
1121
|
return "unknown";
|
|
@@ -2432,10 +2440,10 @@ async function promptGitHubToken() {
|
|
|
2432
2440
|
input: process.stdin,
|
|
2433
2441
|
output: process.stdout
|
|
2434
2442
|
});
|
|
2435
|
-
return new Promise((
|
|
2443
|
+
return new Promise((resolve16) => {
|
|
2436
2444
|
rl.question("GitHub token (optional, press Enter to skip): ", (answer) => {
|
|
2437
2445
|
rl.close();
|
|
2438
|
-
|
|
2446
|
+
resolve16(answer.trim());
|
|
2439
2447
|
});
|
|
2440
2448
|
});
|
|
2441
2449
|
}
|
|
@@ -2638,13 +2646,41 @@ function installUnhandledRejectionHandler() {
|
|
|
2638
2646
|
unhandledRejectionHandlerInstalled = true;
|
|
2639
2647
|
}
|
|
2640
2648
|
|
|
2649
|
+
// src/core/standardGateCommands.ts
|
|
2650
|
+
function getStandardGateCommand(gateName) {
|
|
2651
|
+
const commands = {
|
|
2652
|
+
lint: "npm run lint",
|
|
2653
|
+
test: "npm test",
|
|
2654
|
+
unit: "npm test",
|
|
2655
|
+
typecheck: "npm run typecheck",
|
|
2656
|
+
build: "npm run build",
|
|
2657
|
+
format: "npm run format"
|
|
2658
|
+
};
|
|
2659
|
+
if (!Object.prototype.hasOwnProperty.call(commands, gateName)) {
|
|
2660
|
+
throw new Error(
|
|
2661
|
+
`No executable command is defined for gate ${JSON.stringify(gateName)}. Author an explicit gate run command in a manual plan, or select a supported standard gate.`
|
|
2662
|
+
);
|
|
2663
|
+
}
|
|
2664
|
+
return commands[gateName];
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2641
2667
|
// src/core/githubPlan.ts
|
|
2642
2668
|
var STANDARD_TEST_GATE_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2643
2669
|
async function generatePlanFromGitHub(client, options = {}) {
|
|
2644
2670
|
const repoInfo = await client.validateRepository();
|
|
2645
2671
|
const target = options.target || repoInfo.defaultBranch;
|
|
2672
|
+
const targetCommit = await client.getBranchHead(target);
|
|
2673
|
+
const gitInputs = {
|
|
2674
|
+
schemaVersion: "1.0.0",
|
|
2675
|
+
repository: `${repoInfo.url.replace(/\/$/, "").replace(/\.git$/, "")}.git`,
|
|
2676
|
+
checkoutRemote: "origin",
|
|
2677
|
+
acquisition: options.gitAcquisition ?? "fetch",
|
|
2678
|
+
target: { ref: `refs/heads/${target}`, commit: targetCommit },
|
|
2679
|
+
sources: []
|
|
2680
|
+
};
|
|
2646
2681
|
const prs = await client.listOpenPRs({
|
|
2647
2682
|
state: "open",
|
|
2683
|
+
base: target,
|
|
2648
2684
|
labels: options.labels,
|
|
2649
2685
|
// If no specific query, find PRs with stack labels or open PRs
|
|
2650
2686
|
...options.query ? { query: options.query } : {}
|
|
@@ -2655,8 +2691,9 @@ async function generatePlanFromGitHub(client, options = {}) {
|
|
|
2655
2691
|
const finalPRs = excludePRs.length > 0 ? filteredPRs.filter((pr) => !excludePRs.includes(pr.number)) : filteredPRs;
|
|
2656
2692
|
if (finalPRs.length === 0) {
|
|
2657
2693
|
const emptyPlan = {
|
|
2658
|
-
schemaVersion: "1.0.
|
|
2694
|
+
schemaVersion: "1.0.1",
|
|
2659
2695
|
target,
|
|
2696
|
+
gitInputs,
|
|
2660
2697
|
items: []
|
|
2661
2698
|
};
|
|
2662
2699
|
if (options.policy) {
|
|
@@ -2670,15 +2707,28 @@ async function generatePlanFromGitHub(client, options = {}) {
|
|
|
2670
2707
|
mergeRule: { type: "strict-required" }
|
|
2671
2708
|
};
|
|
2672
2709
|
}
|
|
2673
|
-
return emptyPlan;
|
|
2710
|
+
return Plan.parse(emptyPlan);
|
|
2674
2711
|
}
|
|
2675
2712
|
const prDetails = await Promise.all(finalPRs.map((pr) => client.getPRDetails(pr.number)));
|
|
2676
|
-
|
|
2713
|
+
if (prDetails.some((pr) => pr.base.ref !== target)) {
|
|
2714
|
+
throw new Error(
|
|
2715
|
+
"Selected PR targets a different branch; refresh discovery for the intended target"
|
|
2716
|
+
);
|
|
2717
|
+
}
|
|
2718
|
+
const planItems = prDetails.map(
|
|
2719
|
+
(pr) => transformPRToPlanItem(pr, options, `${repoInfo.owner}/${repoInfo.repo}`)
|
|
2720
|
+
);
|
|
2721
|
+
gitInputs.sources = prDetails.map((pr) => ({
|
|
2722
|
+
item: `PR-${pr.number}`,
|
|
2723
|
+
ref: `refs/pull/${pr.number}/head`,
|
|
2724
|
+
commit: pr.head.sha
|
|
2725
|
+
})).sort((a, b) => a.item.localeCompare(b.item));
|
|
2677
2726
|
planItems.sort((a, b) => a.name.localeCompare(b.name));
|
|
2678
2727
|
validateGitHubDependencies(planItems, prDetails);
|
|
2679
2728
|
const plan = {
|
|
2680
|
-
schemaVersion: "1.0.
|
|
2729
|
+
schemaVersion: "1.0.1",
|
|
2681
2730
|
target,
|
|
2731
|
+
gitInputs,
|
|
2682
2732
|
items: planItems
|
|
2683
2733
|
};
|
|
2684
2734
|
if (options.policy) {
|
|
@@ -2692,12 +2742,18 @@ async function generatePlanFromGitHub(client, options = {}) {
|
|
|
2692
2742
|
mergeRule: { type: "strict-required" }
|
|
2693
2743
|
};
|
|
2694
2744
|
}
|
|
2695
|
-
return plan;
|
|
2745
|
+
return Plan.parse(plan);
|
|
2696
2746
|
}
|
|
2697
|
-
function transformPRToPlanItem(pr, options) {
|
|
2747
|
+
function transformPRToPlanItem(pr, options, repository) {
|
|
2698
2748
|
const name = `PR-${pr.number}`;
|
|
2699
2749
|
const deps = pr.dependencies.filter((dep) => {
|
|
2700
|
-
|
|
2750
|
+
const match = /^(?:([^#]+))?#([1-9][0-9]*)$/.exec(dep);
|
|
2751
|
+
if (!match || match[1] && match[1].toLowerCase() !== repository.toLowerCase()) {
|
|
2752
|
+
throw new Error(
|
|
2753
|
+
`Dependency ${JSON.stringify(dep)} is outside this single-repository plan; declare a valid repository-bound dependency`
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
return true;
|
|
2701
2757
|
}).map((dep) => {
|
|
2702
2758
|
const prNumber = dep.includes("#") ? dep.split("#")[1] : dep;
|
|
2703
2759
|
return `PR-${prNumber}`;
|
|
@@ -2732,47 +2788,7 @@ function createStandardGate(gateName, pr) {
|
|
|
2732
2788
|
runtime: "local",
|
|
2733
2789
|
artifacts: []
|
|
2734
2790
|
};
|
|
2735
|
-
|
|
2736
|
-
case "lint":
|
|
2737
|
-
return {
|
|
2738
|
-
...baseGate,
|
|
2739
|
-
run: "npm run lint",
|
|
2740
|
-
artifacts: ["lint-results.txt"]
|
|
2741
|
-
};
|
|
2742
|
-
case "test":
|
|
2743
|
-
case "unit":
|
|
2744
|
-
return {
|
|
2745
|
-
...baseGate,
|
|
2746
|
-
run: "npm test",
|
|
2747
|
-
artifacts: ["test-results.xml", "coverage/"],
|
|
2748
|
-
timeoutMs: STANDARD_TEST_GATE_TIMEOUT_MS
|
|
2749
|
-
};
|
|
2750
|
-
case "typecheck":
|
|
2751
|
-
return {
|
|
2752
|
-
...baseGate,
|
|
2753
|
-
run: "npm run typecheck",
|
|
2754
|
-
artifacts: ["typecheck-results.txt"]
|
|
2755
|
-
};
|
|
2756
|
-
case "build":
|
|
2757
|
-
return {
|
|
2758
|
-
...baseGate,
|
|
2759
|
-
run: "npm run build",
|
|
2760
|
-
artifacts: ["dist/", "build-log.txt"]
|
|
2761
|
-
};
|
|
2762
|
-
default:
|
|
2763
|
-
return baseGate;
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
|
-
function getStandardGateCommand(gateName) {
|
|
2767
|
-
const standardCommands = {
|
|
2768
|
-
lint: "npm run lint",
|
|
2769
|
-
test: "npm test",
|
|
2770
|
-
unit: "npm test",
|
|
2771
|
-
typecheck: "npm run typecheck",
|
|
2772
|
-
build: "npm run build",
|
|
2773
|
-
format: "npm run format"
|
|
2774
|
-
};
|
|
2775
|
-
return standardCommands[gateName] || `echo "Running ${gateName} gate"`;
|
|
2791
|
+
return gateName === "test" || gateName === "unit" ? { ...baseGate, timeoutMs: STANDARD_TEST_GATE_TIMEOUT_MS } : baseGate;
|
|
2776
2792
|
}
|
|
2777
2793
|
function validateGitHubDependencies(planItems, prDetails) {
|
|
2778
2794
|
const itemNames = new Set(planItems.map((item) => item.name));
|
|
@@ -2922,7 +2938,7 @@ function generateGatesForMultiRepoPR(pr, options) {
|
|
|
2922
2938
|
for (const gateName of requiredGates) {
|
|
2923
2939
|
gates.push({
|
|
2924
2940
|
name: gateName,
|
|
2925
|
-
run:
|
|
2941
|
+
run: getStandardGateCommand(gateName),
|
|
2926
2942
|
env: {
|
|
2927
2943
|
PR_NUMBER: pr.number.toString(),
|
|
2928
2944
|
PR_BRANCH: pr.head.ref,
|
|
@@ -2931,33 +2947,13 @@ function generateGatesForMultiRepoPR(pr, options) {
|
|
|
2931
2947
|
REPO_NAME: pr.repoName
|
|
2932
2948
|
},
|
|
2933
2949
|
runtime: "local",
|
|
2934
|
-
artifacts:
|
|
2950
|
+
artifacts: [],
|
|
2935
2951
|
...isStandardTestGate(gateName) ? { timeoutMs: STANDARD_TEST_GATE_TIMEOUT_MS2 } : {}
|
|
2936
2952
|
});
|
|
2937
2953
|
}
|
|
2938
2954
|
gates.sort((a, b) => a.name.localeCompare(b.name));
|
|
2939
2955
|
return gates;
|
|
2940
2956
|
}
|
|
2941
|
-
function getGateCommand(gateName) {
|
|
2942
|
-
const commands = {
|
|
2943
|
-
lint: "npm run lint",
|
|
2944
|
-
test: "npm test",
|
|
2945
|
-
unit: "npm test",
|
|
2946
|
-
typecheck: "npm run typecheck",
|
|
2947
|
-
build: "npm run build"
|
|
2948
|
-
};
|
|
2949
|
-
return commands[gateName] || `echo "Running ${gateName}"`;
|
|
2950
|
-
}
|
|
2951
|
-
function getGateArtifacts(gateName) {
|
|
2952
|
-
const artifacts = {
|
|
2953
|
-
lint: ["lint-results.txt"],
|
|
2954
|
-
test: ["test-results.xml", "coverage/"],
|
|
2955
|
-
unit: ["test-results.xml", "coverage/"],
|
|
2956
|
-
typecheck: ["typecheck-results.txt"],
|
|
2957
|
-
build: ["dist/"]
|
|
2958
|
-
};
|
|
2959
|
-
return artifacts[gateName] || [];
|
|
2960
|
-
}
|
|
2961
2957
|
function isStandardTestGate(gateName) {
|
|
2962
2958
|
return gateName === "test" || gateName === "unit";
|
|
2963
2959
|
}
|
|
@@ -3404,8 +3400,8 @@ function containedRegularFile(root, candidate) {
|
|
|
3404
3400
|
}
|
|
3405
3401
|
}
|
|
3406
3402
|
function isContained(root, candidate) {
|
|
3407
|
-
const
|
|
3408
|
-
return
|
|
3403
|
+
const relative5 = path8.relative(path8.resolve(root), path8.resolve(candidate));
|
|
3404
|
+
return relative5 !== ".." && !relative5.startsWith(`..${path8.sep}`) && !path8.isAbsolute(relative5);
|
|
3409
3405
|
}
|
|
3410
3406
|
function evidenceError(code, message) {
|
|
3411
3407
|
return new GateEvidenceServiceError(code, message);
|
|
@@ -3485,6 +3481,7 @@ var IntegrationStatusQueryService = class {
|
|
|
3485
3481
|
schemaVersion: validated.schemaVersion,
|
|
3486
3482
|
target: bounded(validated.target),
|
|
3487
3483
|
itemCount: validated.items.length,
|
|
3484
|
+
gitInputBinding: validated.gitInputs ? "frozen" : "legacy-unbound",
|
|
3488
3485
|
...validated.policy ? { policy: validated.policy } : {}
|
|
3489
3486
|
},
|
|
3490
3487
|
mergeSummary: evaluator.getMergeSummary(),
|
|
@@ -4528,7 +4525,7 @@ function registerGateImportChecksCommand(program2) {
|
|
|
4528
4525
|
version: "1.0.0",
|
|
4529
4526
|
mappings: []
|
|
4530
4527
|
};
|
|
4531
|
-
const { DEFAULT_GATE_MAPPINGS } = await import("./gateMapping-
|
|
4528
|
+
const { DEFAULT_GATE_MAPPINGS } = await import("./gateMapping-V4DTL5WD.js");
|
|
4532
4529
|
mappingConfig.mappings = DEFAULT_GATE_MAPPINGS;
|
|
4533
4530
|
}
|
|
4534
4531
|
let githubClient;
|
|
@@ -4841,11 +4838,11 @@ function isTestFile(file) {
|
|
|
4841
4838
|
}
|
|
4842
4839
|
function directOwnerCandidates(file) {
|
|
4843
4840
|
if (!file.startsWith("src/") || !/\.[cm]?tsx?$/.test(file)) return [];
|
|
4844
|
-
const
|
|
4845
|
-
const basename4 = path12.posix.basename(
|
|
4841
|
+
const relative5 = file.replace(/^src\//, "").replace(/\.[cm]?tsx?$/, "");
|
|
4842
|
+
const basename4 = path12.posix.basename(relative5);
|
|
4846
4843
|
return [
|
|
4847
|
-
`tests/${
|
|
4848
|
-
`tests/${
|
|
4844
|
+
`tests/${relative5}.spec.ts`,
|
|
4845
|
+
`tests/${relative5}.test.ts`,
|
|
4849
4846
|
`tests/${basename4}.spec.ts`,
|
|
4850
4847
|
`tests/${basename4}.test.ts`
|
|
4851
4848
|
];
|
|
@@ -6071,10 +6068,10 @@ async function readInput(inputPath) {
|
|
|
6071
6068
|
}
|
|
6072
6069
|
return fs17.readFileSync(inputPath, "utf-8");
|
|
6073
6070
|
} else {
|
|
6074
|
-
return new Promise((
|
|
6071
|
+
return new Promise((resolve16, reject) => {
|
|
6075
6072
|
const chunks = [];
|
|
6076
6073
|
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
6077
|
-
process.stdin.on("end", () =>
|
|
6074
|
+
process.stdin.on("end", () => resolve16(Buffer.concat(chunks).toString("utf-8")));
|
|
6078
6075
|
process.stdin.on("error", reject);
|
|
6079
6076
|
});
|
|
6080
6077
|
}
|
|
@@ -6711,20 +6708,20 @@ async function registerSecurityCommands(program2) {
|
|
|
6711
6708
|
program2.command("security").description("Security operations: token rotation, secrets scanning, validation").addCommand(
|
|
6712
6709
|
new Command3("check-rotation").description("Check if secrets need rotation based on age").argument("[secrets...]", "Secret IDs to check (without LEX_PR_ prefix)", ["GITHUB_TOKEN"]).option("--max-age <days>", "Maximum age in days before rotation needed", "90").option("--format <format>", "Output format: text or json", "text").option("--no-color", "Disable ANSI colors in text output").action(
|
|
6713
6710
|
async (secretIds, opts) => {
|
|
6714
|
-
const { checkRotation } = await import("./security-
|
|
6711
|
+
const { checkRotation } = await import("./security-W7TOUXSB.js");
|
|
6715
6712
|
const result = await checkRotation(secretIds, parseInt(opts.maxAge));
|
|
6716
6713
|
outputSecurityResult("check-rotation", result, opts.format, opts.color !== false);
|
|
6717
6714
|
}
|
|
6718
6715
|
)
|
|
6719
6716
|
).addCommand(
|
|
6720
6717
|
new Command3("scan-plan").description("Scan plan file for accidentally exposed secrets").argument("[plan-file]", "Path to plan file", "plan.json").option("--format <format>", "Output format: text or json", "text").option("--no-color", "Disable ANSI colors in text output").action(async (planFile, opts) => {
|
|
6721
|
-
const { scanPlan } = await import("./security-
|
|
6718
|
+
const { scanPlan } = await import("./security-W7TOUXSB.js");
|
|
6722
6719
|
const result = await scanPlan(planFile);
|
|
6723
6720
|
outputSecurityResult("scan-plan", result, opts.format, opts.color !== false);
|
|
6724
6721
|
})
|
|
6725
6722
|
).addCommand(
|
|
6726
6723
|
new Command3("validate-secrets").description("Validate that required secrets are present").argument("<secrets...>", "Required secret IDs (without LEX_PR_ prefix)").option("--format <format>", "Output format: text or json", "text").option("--no-color", "Disable ANSI colors in text output").action(async (secretIds, opts) => {
|
|
6727
|
-
const { validateSecrets } = await import("./security-
|
|
6724
|
+
const { validateSecrets } = await import("./security-W7TOUXSB.js");
|
|
6728
6725
|
const result = await validateSecrets(secretIds);
|
|
6729
6726
|
outputSecurityResult("validate-secrets", result, opts.format, opts.color !== false);
|
|
6730
6727
|
})
|
|
@@ -6765,7 +6762,7 @@ function outputAuditResult(command, result, format, color) {
|
|
|
6765
6762
|
async function registerAuditCommands(program2) {
|
|
6766
6763
|
program2.command("audit").description("Audit operations: signature verification, manifest validation").addCommand(
|
|
6767
6764
|
new Command4("verify").description("Verify audit manifest signature").argument("[manifest-file]", "Path to audit manifest file", "audit-manifest.json").option("--format <format>", "Output format: text or json", "text").option("--no-color", "Disable ANSI colors in text output").action(async (manifestFile, opts) => {
|
|
6768
|
-
const { verifyCommand } = await import("./verify-
|
|
6765
|
+
const { verifyCommand } = await import("./verify-Y34CJAKB.js");
|
|
6769
6766
|
const result = await verifyCommand(manifestFile);
|
|
6770
6767
|
outputAuditResult("verify", result, opts.format, opts.color !== false);
|
|
6771
6768
|
})
|
|
@@ -8387,8 +8384,8 @@ Details:`);
|
|
|
8387
8384
|
if (opts.json || deps.jsonModeActive()) {
|
|
8388
8385
|
const output = JSON.stringify(plan, null, 2);
|
|
8389
8386
|
if (opts.output) {
|
|
8390
|
-
const
|
|
8391
|
-
await
|
|
8387
|
+
const fs51 = await import("fs/promises");
|
|
8388
|
+
await fs51.writeFile(opts.output, output, "utf-8");
|
|
8392
8389
|
console.log(`Plan written to: ${opts.output}`);
|
|
8393
8390
|
} else {
|
|
8394
8391
|
console.log(output);
|
|
@@ -8411,8 +8408,8 @@ Details:`);
|
|
|
8411
8408
|
console.log(` ${phase}: ${count}`);
|
|
8412
8409
|
}
|
|
8413
8410
|
if (opts.output) {
|
|
8414
|
-
const
|
|
8415
|
-
await
|
|
8411
|
+
const fs51 = await import("fs/promises");
|
|
8412
|
+
await fs51.writeFile(opts.output, JSON.stringify(plan, null, 2), "utf-8");
|
|
8416
8413
|
console.log(`
|
|
8417
8414
|
Plan written to: ${opts.output}`);
|
|
8418
8415
|
}
|
|
@@ -8664,8 +8661,8 @@ function registerHarvestCommand(fanoutCommand) {
|
|
|
8664
8661
|
});
|
|
8665
8662
|
const output = JSON.stringify(harvestBundle, null, 2);
|
|
8666
8663
|
if (opts.output) {
|
|
8667
|
-
const
|
|
8668
|
-
await
|
|
8664
|
+
const fs51 = await import("fs/promises");
|
|
8665
|
+
await fs51.writeFile(opts.output, output, "utf-8");
|
|
8669
8666
|
console.error(`\u2713 Harvest bundle written to ${opts.output}`);
|
|
8670
8667
|
console.error(` ${harvestBundle.bundle.pullRequests.length} PRs`);
|
|
8671
8668
|
console.error(` ${harvestBundle.bundle.issues.length} issues`);
|
|
@@ -9054,10 +9051,10 @@ function analyzeBundle(harvest) {
|
|
|
9054
9051
|
function registerAnalyzeCommand(fanoutCommand) {
|
|
9055
9052
|
fanoutCommand.command("analyze").description("D1: Analyze harvest bundle into facts pool (deterministic)").option("--input <file>", "Path to harvest bundle JSON file (default: stdin)").option("--json", "Output JSON format (default)").option("--output <file>", "Write output to file").action(async (opts) => {
|
|
9056
9053
|
try {
|
|
9057
|
-
const
|
|
9054
|
+
const fs51 = await import("fs/promises");
|
|
9058
9055
|
let content;
|
|
9059
9056
|
if (opts.input) {
|
|
9060
|
-
content = await
|
|
9057
|
+
content = await fs51.readFile(opts.input, "utf-8");
|
|
9061
9058
|
} else {
|
|
9062
9059
|
const chunks = [];
|
|
9063
9060
|
for await (const chunk of process.stdin) {
|
|
@@ -9099,7 +9096,7 @@ function registerAnalyzeCommand(fanoutCommand) {
|
|
|
9099
9096
|
const analysisPool = analyzeBundle(harvest);
|
|
9100
9097
|
const output = JSON.stringify(analysisPool, null, 2);
|
|
9101
9098
|
if (opts.output) {
|
|
9102
|
-
await
|
|
9099
|
+
await fs51.writeFile(opts.output, output, "utf-8");
|
|
9103
9100
|
console.error(`\u2713 Analysis pool written to ${opts.output}`);
|
|
9104
9101
|
console.error(` ${analysisPool.pool.entities.length} entities`);
|
|
9105
9102
|
console.error(` ${analysisPool.pool.relations.length} relations`);
|
|
@@ -9196,9 +9193,9 @@ var DEFAULT_FANOUT_TEMPLATES_PATHS = [
|
|
|
9196
9193
|
"fanout-templates.yml"
|
|
9197
9194
|
];
|
|
9198
9195
|
var FanoutTemplatesLoadError = class extends Error {
|
|
9199
|
-
constructor(message,
|
|
9196
|
+
constructor(message, path60, cause) {
|
|
9200
9197
|
super(message);
|
|
9201
|
-
this.path =
|
|
9198
|
+
this.path = path60;
|
|
9202
9199
|
this.cause = cause;
|
|
9203
9200
|
this.name = "FanoutTemplatesLoadError";
|
|
9204
9201
|
}
|
|
@@ -9529,7 +9526,7 @@ function registerFanoutCommands(weaveCommand) {
|
|
|
9529
9526
|
}
|
|
9530
9527
|
});
|
|
9531
9528
|
fanout.command("validate").description("Validate fanout templates file").option("-f, --file <path>", "Path to templates file").action(async (options) => {
|
|
9532
|
-
const
|
|
9529
|
+
const fs51 = await import("fs/promises");
|
|
9533
9530
|
try {
|
|
9534
9531
|
let filePath;
|
|
9535
9532
|
if (options.file) {
|
|
@@ -9542,7 +9539,7 @@ function registerFanoutCommands(weaveCommand) {
|
|
|
9542
9539
|
}
|
|
9543
9540
|
filePath = result2.path;
|
|
9544
9541
|
}
|
|
9545
|
-
const content = await
|
|
9542
|
+
const content = await fs51.readFile(filePath, "utf-8");
|
|
9546
9543
|
const result = validateFanoutTemplatesContent(content);
|
|
9547
9544
|
if (result.valid) {
|
|
9548
9545
|
console.log(`\u2713 Valid: ${filePath}`);
|
|
@@ -10013,6 +10010,70 @@ import { join as join15 } from "path";
|
|
|
10013
10010
|
import { simpleGit as simpleGit2 } from "simple-git";
|
|
10014
10011
|
import { ulid } from "ulid";
|
|
10015
10012
|
|
|
10013
|
+
// src/git/frozen-inputs.ts
|
|
10014
|
+
var FrozenGitInputError = class extends Error {
|
|
10015
|
+
constructor(message) {
|
|
10016
|
+
super(message);
|
|
10017
|
+
this.name = "FrozenGitInputError";
|
|
10018
|
+
}
|
|
10019
|
+
};
|
|
10020
|
+
async function verifyFrozenGitInputs(git2, value) {
|
|
10021
|
+
const inputs = FrozenGitInputs.parse(value);
|
|
10022
|
+
let remote;
|
|
10023
|
+
try {
|
|
10024
|
+
remote = (await git2.raw(["remote", "get-url", inputs.checkoutRemote])).trim();
|
|
10025
|
+
if (repositoryIdentity(remote) !== repositoryIdentity(inputs.repository)) throw new Error();
|
|
10026
|
+
} catch {
|
|
10027
|
+
throw new FrozenGitInputError(
|
|
10028
|
+
"Checkout repository does not match gitInputs; use the declared checkout"
|
|
10029
|
+
);
|
|
10030
|
+
}
|
|
10031
|
+
const resolve16 = async (input) => {
|
|
10032
|
+
let ref = input.ref;
|
|
10033
|
+
if (inputs.acquisition === "fetch") {
|
|
10034
|
+
ref = `refs/lexrunner/inputs/${sha256(Buffer.from(`${inputs.repository}
|
|
10035
|
+
${input.ref}
|
|
10036
|
+
${input.commit}`))}`;
|
|
10037
|
+
try {
|
|
10038
|
+
await git2.raw([
|
|
10039
|
+
"fetch",
|
|
10040
|
+
"--no-tags",
|
|
10041
|
+
"--no-recurse-submodules",
|
|
10042
|
+
"--no-write-fetch-head",
|
|
10043
|
+
"--",
|
|
10044
|
+
inputs.repository,
|
|
10045
|
+
`+${input.ref}:${ref}`
|
|
10046
|
+
]);
|
|
10047
|
+
} catch {
|
|
10048
|
+
throw new FrozenGitInputError(
|
|
10049
|
+
`Declared acquisition failed for ${input.ref}; restore access and retry without changing frozen expectations`
|
|
10050
|
+
);
|
|
10051
|
+
}
|
|
10052
|
+
}
|
|
10053
|
+
let observed;
|
|
10054
|
+
try {
|
|
10055
|
+
observed = (await git2.raw(["rev-parse", "--verify", ref])).trim();
|
|
10056
|
+
} catch {
|
|
10057
|
+
throw new FrozenGitInputError(
|
|
10058
|
+
`Declared ref ${input.ref} is unavailable; explicitly acquire it or create a new plan permitting fetch`
|
|
10059
|
+
);
|
|
10060
|
+
}
|
|
10061
|
+
if (observed !== input.commit) {
|
|
10062
|
+
throw new FrozenGitInputError(
|
|
10063
|
+
`Stale Git input ${input.ref}; reassess and generate a new plan instead of replacing its expected commit`
|
|
10064
|
+
);
|
|
10065
|
+
}
|
|
10066
|
+
if ((await git2.raw(["cat-file", "-t", input.commit])).trim() !== "commit") {
|
|
10067
|
+
throw new FrozenGitInputError(`Declared input ${input.ref} is not a commit object`);
|
|
10068
|
+
}
|
|
10069
|
+
return observed;
|
|
10070
|
+
};
|
|
10071
|
+
const targetHeadSha = await resolve16(inputs.target);
|
|
10072
|
+
const sourceHeads = /* @__PURE__ */ Object.create(null);
|
|
10073
|
+
for (const source of inputs.sources) sourceHeads[source.item] = await resolve16(source);
|
|
10074
|
+
return { targetHeadSha, sourceHeads };
|
|
10075
|
+
}
|
|
10076
|
+
|
|
10016
10077
|
// src/weave/resume-service.ts
|
|
10017
10078
|
import { z as z7 } from "zod";
|
|
10018
10079
|
async function resumePersistedWeave(input) {
|
|
@@ -10161,6 +10222,15 @@ function validateResumeJournal(checkpoint) {
|
|
|
10161
10222
|
};
|
|
10162
10223
|
}
|
|
10163
10224
|
const ids = /* @__PURE__ */ new Set();
|
|
10225
|
+
const inputs = parsedPlan.data.gitInputs;
|
|
10226
|
+
if (inputs && journal.repository.integrationBranch !== `weave/resume-${checkpoint.runId.toLowerCase()}`) {
|
|
10227
|
+
return { valid: false, reason: "checkpoint integration branch does not match its bound run" };
|
|
10228
|
+
}
|
|
10229
|
+
if (inputs && (inputs.target.commit !== journal.repository.targetHeadSha || inputs.sources.some(
|
|
10230
|
+
(source) => source.commit !== journal.repository.sourceHeads[source.item]
|
|
10231
|
+
))) {
|
|
10232
|
+
return { valid: false, reason: "checkpoint commits do not match the plan's frozen Git inputs" };
|
|
10233
|
+
}
|
|
10164
10234
|
let seenIncomplete = false;
|
|
10165
10235
|
for (const operation of journal.operations) {
|
|
10166
10236
|
if (!operation.id || ids.has(operation.id)) {
|
|
@@ -10326,11 +10396,22 @@ async function createLocalResumeCheckpoint(input) {
|
|
|
10326
10396
|
const runId = input.runId ?? ulid();
|
|
10327
10397
|
const at = input.now ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
10328
10398
|
const levels = computeMergeOrder(input.plan);
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10399
|
+
Plan.parse(input.plan);
|
|
10400
|
+
const sourceHeads = /* @__PURE__ */ Object.create(null);
|
|
10401
|
+
let targetHeadSha;
|
|
10402
|
+
if (input.plan.gitInputs) {
|
|
10403
|
+
const status = await git2.status();
|
|
10404
|
+
if (status.files.some(isUnexpectedBoundChange)) {
|
|
10405
|
+
throw new Error("Working tree must be clean before acquiring frozen Git inputs");
|
|
10406
|
+
}
|
|
10407
|
+
const verified = await verifyFrozenGitInputs(git2, input.plan.gitInputs);
|
|
10408
|
+
Object.assign(sourceHeads, verified.sourceHeads);
|
|
10409
|
+
targetHeadSha = verified.targetHeadSha;
|
|
10410
|
+
} else {
|
|
10411
|
+
for (const item of input.plan.items)
|
|
10412
|
+
sourceHeads[item.name] = await exactRefHead(git2, item.name);
|
|
10413
|
+
targetHeadSha = await exactRefHead(git2, input.plan.target);
|
|
10332
10414
|
}
|
|
10333
|
-
const targetHeadSha = await exactRefHead(git2, input.plan.target);
|
|
10334
10415
|
const integrationBranch = `weave/resume-${runId.toLowerCase()}`;
|
|
10335
10416
|
const operations = planResumeOperations(input.plan);
|
|
10336
10417
|
const planHash = sha256(Buffer.from(canonicalJSONStringify(input.plan)));
|
|
@@ -10352,7 +10433,7 @@ async function createLocalResumeCheckpoint(input) {
|
|
|
10352
10433
|
lastUpdatedAt: at,
|
|
10353
10434
|
metadata: {
|
|
10354
10435
|
target: input.plan.target,
|
|
10355
|
-
warnings: [],
|
|
10436
|
+
warnings: input.plan.gitInputs ? [] : ["Legacy unbound plan: Git heads are selected at preparation, not frozen at synthesis"],
|
|
10356
10437
|
resume: createResumeJournal({
|
|
10357
10438
|
operations,
|
|
10358
10439
|
target: input.plan.target,
|
|
@@ -10374,23 +10455,34 @@ var LocalWeaveResumeDriver = class {
|
|
|
10374
10455
|
if (!journal) return { valid: false, reason: "resume journal is missing" };
|
|
10375
10456
|
try {
|
|
10376
10457
|
const status = await this.git.status();
|
|
10377
|
-
const unexpectedChanges = status.files.filter(
|
|
10458
|
+
const unexpectedChanges = status.files.filter(
|
|
10459
|
+
checkpoint.plan.gitInputs ? isUnexpectedBoundChange : (file) => !isRunnerStatePath(file.path)
|
|
10460
|
+
);
|
|
10378
10461
|
if (unexpectedChanges.length > 0) {
|
|
10379
10462
|
return {
|
|
10380
10463
|
valid: false,
|
|
10381
10464
|
reason: "working tree is not clean; resolve or abort the interrupted operation first"
|
|
10382
10465
|
};
|
|
10383
10466
|
}
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10467
|
+
if (checkpoint.plan.gitInputs) {
|
|
10468
|
+
const verified = await verifyFrozenGitInputs(this.git, checkpoint.plan.gitInputs);
|
|
10469
|
+
if (verified.targetHeadSha !== journal.repository.targetHeadSha || Object.entries(verified.sourceHeads).some(
|
|
10470
|
+
([name, commit]) => journal.repository.sourceHeads[name] !== commit
|
|
10471
|
+
)) {
|
|
10472
|
+
return { valid: false, reason: "Journal commit evidence differs from frozen Git inputs" };
|
|
10473
|
+
}
|
|
10474
|
+
} else {
|
|
10475
|
+
const targetHead = await exactRefHead(this.git, journal.repository.target);
|
|
10476
|
+
if (targetHead !== journal.repository.targetHeadSha) {
|
|
10477
|
+
return { valid: false, reason: "target branch changed after the checkpoint was created" };
|
|
10478
|
+
}
|
|
10479
|
+
for (const [name, expected] of Object.entries(journal.repository.sourceHeads)) {
|
|
10480
|
+
if (await exactRefHead(this.git, name) !== expected) {
|
|
10481
|
+
return {
|
|
10482
|
+
valid: false,
|
|
10483
|
+
reason: `source branch ${name} changed after checkpoint creation`
|
|
10484
|
+
};
|
|
10485
|
+
}
|
|
10394
10486
|
}
|
|
10395
10487
|
}
|
|
10396
10488
|
const integrationHead = await localBranchHead(this.git, journal.repository.integrationBranch);
|
|
@@ -10441,29 +10533,66 @@ var LocalWeaveResumeDriver = class {
|
|
|
10441
10533
|
}
|
|
10442
10534
|
async execute(operation, checkpoint) {
|
|
10443
10535
|
const journal = checkpoint.metadata.resume;
|
|
10536
|
+
const bound4 = !!checkpoint.plan.gitInputs;
|
|
10537
|
+
const expectedIntegration = lastCompletedMergeSha(journal.operations) ?? journal.repository.targetHeadSha;
|
|
10538
|
+
if (bound4) {
|
|
10539
|
+
const stateError = await this.boundStateError();
|
|
10540
|
+
if (stateError) return { completed: false, reason: stateError };
|
|
10541
|
+
const integrationHead = await localBranchHead(this.git, journal.repository.integrationBranch);
|
|
10542
|
+
if (integrationHead && integrationHead !== expectedIntegration || !integrationHead && lastCompletedMergeSha(journal.operations)) {
|
|
10543
|
+
return {
|
|
10544
|
+
completed: false,
|
|
10545
|
+
reason: "Frozen integration branch changed before operation; preserve and inspect it"
|
|
10546
|
+
};
|
|
10547
|
+
}
|
|
10548
|
+
}
|
|
10444
10549
|
await this.ensureIntegrationBranch(
|
|
10445
10550
|
journal.repository.integrationBranch,
|
|
10446
10551
|
journal.repository.targetHeadSha
|
|
10447
10552
|
);
|
|
10448
10553
|
if (operation.phase === "merge") {
|
|
10449
10554
|
await this.git.checkout(journal.repository.integrationBranch);
|
|
10555
|
+
if (bound4) {
|
|
10556
|
+
const stateError = await this.boundStateError(expectedIntegration);
|
|
10557
|
+
if (stateError) return { completed: false, reason: stateError };
|
|
10558
|
+
}
|
|
10450
10559
|
const item = checkpoint.plan.items.find((candidate) => candidate.name === operation.item);
|
|
10451
10560
|
if (!item) return { completed: false, reason: "plan item is missing" };
|
|
10452
10561
|
const result2 = await this.operations.executeMergeOperation({
|
|
10453
10562
|
item,
|
|
10454
10563
|
targetBranch: journal.repository.integrationBranch,
|
|
10455
|
-
strategy: "merge-weave"
|
|
10564
|
+
strategy: "merge-weave",
|
|
10565
|
+
...checkpoint.plan.gitInputs ? { sourceCommit: journal.repository.sourceHeads[operation.item] } : {}
|
|
10456
10566
|
});
|
|
10567
|
+
if (bound4 && result2.success && result2.sha) {
|
|
10568
|
+
const stateError = await this.boundStateError(result2.sha);
|
|
10569
|
+
if (stateError) return { completed: false, reason: stateError };
|
|
10570
|
+
}
|
|
10457
10571
|
return result2.success && result2.sha ? { completed: true, externalId: result2.sha } : { completed: false, reason: result2.message ?? "merge failed" };
|
|
10458
10572
|
}
|
|
10459
10573
|
const gate = gateForOperation(checkpoint.plan, operation);
|
|
10460
10574
|
if (!gate) return { completed: false, reason: "gate definition is missing" };
|
|
10461
10575
|
if (operation.phase === "gate") {
|
|
10462
|
-
|
|
10576
|
+
if (checkpoint.plan.gitInputs) {
|
|
10577
|
+
await this.git.checkout(["--detach", journal.repository.sourceHeads[operation.item]]);
|
|
10578
|
+
} else {
|
|
10579
|
+
await this.git.checkout(`origin/${operation.item}`).catch(() => this.git.checkout(operation.item));
|
|
10580
|
+
}
|
|
10463
10581
|
} else {
|
|
10464
10582
|
await this.git.checkout(journal.repository.integrationBranch);
|
|
10465
10583
|
}
|
|
10466
|
-
const
|
|
10584
|
+
const expectedGateHead = operation.phase === "gate" ? journal.repository.sourceHeads[operation.item] : expectedIntegration;
|
|
10585
|
+
if (bound4) {
|
|
10586
|
+
const stateError = await this.boundStateError(expectedGateHead);
|
|
10587
|
+
if (stateError) return { completed: false, reason: stateError };
|
|
10588
|
+
}
|
|
10589
|
+
const artifactDir = join15(
|
|
10590
|
+
this.workingDir,
|
|
10591
|
+
".lexrunner",
|
|
10592
|
+
"runs",
|
|
10593
|
+
checkpoint.runId,
|
|
10594
|
+
operation.phase
|
|
10595
|
+
);
|
|
10467
10596
|
await mkdir2(artifactDir, { recursive: true });
|
|
10468
10597
|
const policy = Policy.parse(checkpoint.plan.policy ?? {});
|
|
10469
10598
|
const result = await executeGate(
|
|
@@ -10475,12 +10604,38 @@ var LocalWeaveResumeDriver = class {
|
|
|
10475
10604
|
false,
|
|
10476
10605
|
this.workingDir
|
|
10477
10606
|
);
|
|
10478
|
-
|
|
10607
|
+
if (bound4) {
|
|
10608
|
+
const stateError = await this.boundStateError(expectedGateHead);
|
|
10609
|
+
if (stateError) return { completed: false, reason: stateError };
|
|
10610
|
+
if (await localBranchHead(this.git, journal.repository.integrationBranch) !== expectedIntegration) {
|
|
10611
|
+
return {
|
|
10612
|
+
completed: false,
|
|
10613
|
+
reason: "Gate changed the frozen integration branch; preserve and inspect it"
|
|
10614
|
+
};
|
|
10615
|
+
}
|
|
10616
|
+
}
|
|
10617
|
+
const receipt = result.artifacts?.find(
|
|
10618
|
+
(path60) => /gate-execution-receipt\.attempt-\d+\.json$/.test(path60)
|
|
10619
|
+
);
|
|
10620
|
+
return result.status === "pass" ? {
|
|
10621
|
+
completed: true,
|
|
10622
|
+
externalId: receipt ?? `${gate.name}:${result.lastAttempt ?? "pass"}`
|
|
10623
|
+
} : { completed: false, reason: result.stderr || `gate ${gate.name} failed` };
|
|
10479
10624
|
}
|
|
10480
10625
|
async ensureIntegrationBranch(branch, targetHeadSha) {
|
|
10481
10626
|
if (await localBranchHead(this.git, branch)) return;
|
|
10482
10627
|
await this.git.checkoutBranch(branch, targetHeadSha);
|
|
10483
10628
|
}
|
|
10629
|
+
async boundStateError(expectedHead) {
|
|
10630
|
+
if (expectedHead && (await this.git.revparse(["HEAD"])).trim() !== expectedHead) {
|
|
10631
|
+
return "Frozen checkout HEAD changed during the operation; preserve and inspect the new commit";
|
|
10632
|
+
}
|
|
10633
|
+
const status = await this.git.status();
|
|
10634
|
+
if (status.files.some(isUnexpectedBoundChange)) {
|
|
10635
|
+
return "Frozen checkout index or working tree changed; preserve and inspect the modifications before continuing";
|
|
10636
|
+
}
|
|
10637
|
+
return null;
|
|
10638
|
+
}
|
|
10484
10639
|
};
|
|
10485
10640
|
function gateForOperation(plan, operation) {
|
|
10486
10641
|
const parts = operation.id.split(":");
|
|
@@ -10523,8 +10678,11 @@ function lastCompletedMergeSha(operations) {
|
|
|
10523
10678
|
(operation) => operation.phase === "merge" && operation.status === "completed" && operation.result?.externalId
|
|
10524
10679
|
)?.result?.externalId;
|
|
10525
10680
|
}
|
|
10526
|
-
function isRunnerStatePath(
|
|
10527
|
-
return
|
|
10681
|
+
function isRunnerStatePath(path60) {
|
|
10682
|
+
return path60 === ".lexrunner" || path60.startsWith(".lexrunner/") || path60 === "weave-lock.json" || path60.endsWith("/weave-lock.json");
|
|
10683
|
+
}
|
|
10684
|
+
function isUnexpectedBoundChange(file) {
|
|
10685
|
+
return !(file.index === "?" && file.working_dir === "?" && isRunnerStatePath(file.path));
|
|
10528
10686
|
}
|
|
10529
10687
|
|
|
10530
10688
|
// src/commands/weave.ts
|
|
@@ -10532,6 +10690,7 @@ import fs22 from "fs";
|
|
|
10532
10690
|
import path15 from "path";
|
|
10533
10691
|
|
|
10534
10692
|
// src/application/merge-application-service.ts
|
|
10693
|
+
import { join as join16 } from "path";
|
|
10535
10694
|
var MAX_OPERATIONS = 256;
|
|
10536
10695
|
var MAX_LABEL_BYTES2 = 512;
|
|
10537
10696
|
var MAX_RESULT_BYTES2 = 256 * 1024;
|
|
@@ -10558,6 +10717,7 @@ var MergeApplicationService = class {
|
|
|
10558
10717
|
ok: true,
|
|
10559
10718
|
status: "preview",
|
|
10560
10719
|
totalItems: input.plan.items.length,
|
|
10720
|
+
gitInputBinding: input.plan.gitInputs ? "frozen" : "legacy-unbound",
|
|
10561
10721
|
levels,
|
|
10562
10722
|
maxParallelism: levels.length === 0 ? 0 : Math.max(...levels.map((level) => level.length)),
|
|
10563
10723
|
artifactRefs: []
|
|
@@ -10579,10 +10739,10 @@ var MergeApplicationService = class {
|
|
|
10579
10739
|
let runId;
|
|
10580
10740
|
try {
|
|
10581
10741
|
runId = await this.runtime.prepare(input.plan, input.workingDir);
|
|
10582
|
-
} catch {
|
|
10742
|
+
} catch (error) {
|
|
10583
10743
|
throw new MergeApplicationServiceError(
|
|
10584
10744
|
"MERGE_STALE_INPUT",
|
|
10585
|
-
"Merge input could not be bound to current source and target heads"
|
|
10745
|
+
error instanceof FrozenGitInputError ? error.message : "Merge input could not be bound to current source and target heads"
|
|
10586
10746
|
);
|
|
10587
10747
|
}
|
|
10588
10748
|
return this.executePrepared({ plan: input.plan, workingDir: input.workingDir, runId });
|
|
@@ -10612,6 +10772,7 @@ var MergeApplicationService = class {
|
|
|
10612
10772
|
ok: completed,
|
|
10613
10773
|
status: execution.result.ok ? execution.result.outcome : "failed",
|
|
10614
10774
|
totalItems: input.plan.items.length,
|
|
10775
|
+
gitInputBinding: input.plan.gitInputs ? "frozen" : "legacy-unbound",
|
|
10615
10776
|
runId: bound2(input.runId),
|
|
10616
10777
|
operations: execution.operations.map((operation) => ({
|
|
10617
10778
|
id: bound2(operation.id),
|
|
@@ -10632,15 +10793,22 @@ var LocalMergeApplicationRuntime = class {
|
|
|
10632
10793
|
}
|
|
10633
10794
|
async prepare(plan, workingDir) {
|
|
10634
10795
|
const checkpoint = await createLocalResumeCheckpoint({ plan, workingDir });
|
|
10635
|
-
await saveCheckpoint(checkpoint, {
|
|
10796
|
+
await saveCheckpoint(checkpoint, {
|
|
10797
|
+
checkpointDir: join16(workingDir, ".lexrunner", "checkpoints"),
|
|
10798
|
+
skipCleanup: true
|
|
10799
|
+
});
|
|
10636
10800
|
return checkpoint.runId;
|
|
10637
10801
|
}
|
|
10638
10802
|
async resume(runId, workingDir) {
|
|
10639
10803
|
const result = await resumePersistedWeave({
|
|
10640
10804
|
runId,
|
|
10805
|
+
checkpointDir: join16(workingDir, ".lexrunner", "checkpoints"),
|
|
10641
10806
|
driver: new LocalWeaveResumeDriver(workingDir)
|
|
10642
10807
|
});
|
|
10643
|
-
const checkpoint = await loadCheckpoint(runId, {
|
|
10808
|
+
const checkpoint = await loadCheckpoint(runId, {
|
|
10809
|
+
checkpointDir: join16(workingDir, ".lexrunner", "checkpoints"),
|
|
10810
|
+
validatePlanHash: false
|
|
10811
|
+
});
|
|
10644
10812
|
return { result, operations: checkpoint.metadata?.resume?.operations ?? [] };
|
|
10645
10813
|
}
|
|
10646
10814
|
};
|
|
@@ -10936,7 +11104,7 @@ async function runWeaveApply(opts, deps) {
|
|
|
10936
11104
|
if (json2) {
|
|
10937
11105
|
const output = { ...preview.summary };
|
|
10938
11106
|
if (showConstraints) {
|
|
10939
|
-
const { previewConstraints: previewConstraints2 } = await import("./constraints-
|
|
11107
|
+
const { previewConstraints: previewConstraints2 } = await import("./constraints-LE2MW5NS.js");
|
|
10940
11108
|
output.constraints = await previewConstraints2(plan);
|
|
10941
11109
|
}
|
|
10942
11110
|
console.log(canonicalJSONStringify(output));
|
|
@@ -10946,13 +11114,17 @@ async function runWeaveApply(opts, deps) {
|
|
|
10946
11114
|
\u{1F50D} Merge-Weave Dry Run
|
|
10947
11115
|
`);
|
|
10948
11116
|
if (showConstraints) {
|
|
10949
|
-
const { previewConstraints: previewConstraints2, formatConstraintPreview: formatConstraintPreview2 } = await import("./constraints-
|
|
11117
|
+
const { previewConstraints: previewConstraints2, formatConstraintPreview: formatConstraintPreview2 } = await import("./constraints-LE2MW5NS.js");
|
|
10950
11118
|
console.log(formatConstraintPreview2(await previewConstraints2(plan)));
|
|
10951
11119
|
}
|
|
10952
11120
|
console.log(`Plan: ${opts.plan}`);
|
|
10953
11121
|
console.log(`Items: ${plan.items.length}`);
|
|
10954
11122
|
console.log(`Target: ${plan.target}
|
|
10955
11123
|
`);
|
|
11124
|
+
console.log(
|
|
11125
|
+
`Git inputs: ${preview.summary.gitInputBinding}${plan.gitInputs ? `; acquisition: ${plan.gitInputs.acquisition}` : ""}
|
|
11126
|
+
`
|
|
11127
|
+
);
|
|
10956
11128
|
console.log("\u{1F4E6} Execution Plan\n");
|
|
10957
11129
|
console.log("Execution Order (topological):\n");
|
|
10958
11130
|
levels.forEach((level, index) => {
|
|
@@ -10976,7 +11148,7 @@ async function runWeaveApply(opts, deps) {
|
|
|
10976
11148
|
console.log(`Items: ${plan.items.length}
|
|
10977
11149
|
`);
|
|
10978
11150
|
}
|
|
10979
|
-
if (!opts.skipGates) {
|
|
11151
|
+
if (!opts.skipGates && !(opts.execute && plan.gitInputs)) {
|
|
10980
11152
|
if (!json2) console.log("Running gates...\n");
|
|
10981
11153
|
const executionState = new ExecutionState(plan);
|
|
10982
11154
|
const gatesDir = path15.join(process.cwd(), ".smartergpt", "runner", "gates");
|
|
@@ -11142,7 +11314,7 @@ function registerPlanDiffCommand(program2, deps) {
|
|
|
11142
11314
|
const plan2Content = fs24.readFileSync(plan2Path, "utf-8");
|
|
11143
11315
|
const plan1 = loadPlan(plan1Content);
|
|
11144
11316
|
const plan2 = loadPlan(plan2Content);
|
|
11145
|
-
const { comparePlans, formatPlanDiff } = await import("./planDiff-
|
|
11317
|
+
const { comparePlans, formatPlanDiff } = await import("./planDiff-4D3AERAW.js");
|
|
11146
11318
|
const diff = comparePlans(plan1, plan2);
|
|
11147
11319
|
if (opts.json || deps.jsonModeActive()) {
|
|
11148
11320
|
writeJsonOutput(diff);
|
|
@@ -11626,12 +11798,12 @@ ${prefix} Plan validation failed: ${error.message}`);
|
|
|
11626
11798
|
}
|
|
11627
11799
|
fs25.mkdirSync(outDir, { recursive: true });
|
|
11628
11800
|
const planPath = path16.join(outDir, "plan.json");
|
|
11629
|
-
const
|
|
11801
|
+
const snapshotPath2 = path16.join(outDir, "snapshot.md");
|
|
11630
11802
|
fs25.writeFileSync(planPath, planJSON);
|
|
11631
|
-
fs25.writeFileSync(
|
|
11803
|
+
fs25.writeFileSync(snapshotPath2, snapshot);
|
|
11632
11804
|
console.log(`\u2713 Generated plan artifacts:`);
|
|
11633
11805
|
console.log(` \u{1F4C1} ${planPath}`);
|
|
11634
|
-
console.log(` \u{1F4C1} ${
|
|
11806
|
+
console.log(` \u{1F4C1} ${snapshotPath2}`);
|
|
11635
11807
|
console.log("");
|
|
11636
11808
|
console.log(generatePlanSummary(validatedPlan));
|
|
11637
11809
|
return;
|
|
@@ -11772,7 +11944,7 @@ function registerAutopilotCommand(program2, deps) {
|
|
|
11772
11944
|
argv: process.argv.slice(2)
|
|
11773
11945
|
});
|
|
11774
11946
|
}
|
|
11775
|
-
const { AutopilotLevel0, AutopilotLevel1, AutopilotLevel2: AutopilotLevel22 } = await import("./autopilot-
|
|
11947
|
+
const { AutopilotLevel0, AutopilotLevel1, AutopilotLevel2: AutopilotLevel22 } = await import("./autopilot-7PX6YG55.js");
|
|
11776
11948
|
const context = {
|
|
11777
11949
|
plan,
|
|
11778
11950
|
profilePath: profile.path,
|
|
@@ -11820,7 +11992,7 @@ function registerAutopilotCommand(program2, deps) {
|
|
|
11820
11992
|
// src/application/gate-execution-service.ts
|
|
11821
11993
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
11822
11994
|
import { mkdirSync as mkdirSync12 } from "fs";
|
|
11823
|
-
import { join as
|
|
11995
|
+
import { join as join19, resolve as resolve9 } from "path";
|
|
11824
11996
|
var MAX_ITEMS = 256;
|
|
11825
11997
|
var MAX_GATES_PER_ITEM = 64;
|
|
11826
11998
|
var MAX_LABEL_BYTES3 = 512;
|
|
@@ -11923,7 +12095,7 @@ var GateExecutionService = class {
|
|
|
11923
12095
|
function prepareOwnedArtifactDirectory(requestedRoot) {
|
|
11924
12096
|
const root = resolve9(bounded2(requestedRoot, MAX_ARTIFACT_REF_BYTES));
|
|
11925
12097
|
mkdirSync12(root, { recursive: true });
|
|
11926
|
-
const runDirectory =
|
|
12098
|
+
const runDirectory = join19(root, `gate-run-${Date.now()}-${randomUUID4()}`);
|
|
11927
12099
|
mkdirSync12(runDirectory);
|
|
11928
12100
|
return runDirectory;
|
|
11929
12101
|
}
|
|
@@ -12797,7 +12969,7 @@ import * as fs28 from "fs";
|
|
|
12797
12969
|
import * as path18 from "path";
|
|
12798
12970
|
async function finalizeAuditGuard(emitter, status) {
|
|
12799
12971
|
try {
|
|
12800
|
-
const { finalizeAudit: finalizeAudit2 } = await import("./audit-
|
|
12972
|
+
const { finalizeAudit: finalizeAudit2 } = await import("./audit-HVB2HJPU.js");
|
|
12801
12973
|
await finalizeAudit2(emitter, status);
|
|
12802
12974
|
} catch (e) {
|
|
12803
12975
|
if (e instanceof Error && typeof e.message === "string" && e.message.startsWith("HIPAA:")) {
|
|
@@ -13363,8 +13535,8 @@ function registerPlanReviewCommand(program2, deps) {
|
|
|
13363
13535
|
}
|
|
13364
13536
|
const planContent = fs29.readFileSync(planFile, "utf-8");
|
|
13365
13537
|
const plan = loadPlan(planContent);
|
|
13366
|
-
const { reviewPlan } = await import("./planReview-
|
|
13367
|
-
const { savePlanVersion, getPlanHistoryPath } = await import("./planHistory-
|
|
13538
|
+
const { reviewPlan } = await import("./planReview-FV6INFLQ.js");
|
|
13539
|
+
const { savePlanVersion, getPlanHistoryPath } = await import("./planHistory-VPV4WDPW.js");
|
|
13368
13540
|
const result = await reviewPlan({
|
|
13369
13541
|
plan,
|
|
13370
13542
|
interactive: !opts.nonInteractive,
|
|
@@ -14064,7 +14236,7 @@ async function predictConflicts(options) {
|
|
|
14064
14236
|
const pr2Head = prHeads.get(edge.to);
|
|
14065
14237
|
if (pr1Head && pr2Head) {
|
|
14066
14238
|
const key = `${edge.from}-${edge.to}`;
|
|
14067
|
-
const result = await import("./mergeTreeSimulator-
|
|
14239
|
+
const result = await import("./mergeTreeSimulator-GWZ77NF2.js").then(
|
|
14068
14240
|
(m) => m.simulateMerge(baseBranch, pr1Head, pr2Head, workingDir)
|
|
14069
14241
|
);
|
|
14070
14242
|
mergeTreeSimulation[key] = result;
|
|
@@ -14140,7 +14312,7 @@ function generateRecommendations(misBatches, mergeTreeSimulation) {
|
|
|
14140
14312
|
|
|
14141
14313
|
// src/orchestration/agentAssigner.ts
|
|
14142
14314
|
function sleep(ms) {
|
|
14143
|
-
return new Promise((
|
|
14315
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
14144
14316
|
}
|
|
14145
14317
|
async function assignAgentWithRetry(issueNumber, repo, assignFn, maxRetries = 4) {
|
|
14146
14318
|
let retries = 0;
|
|
@@ -14759,8 +14931,8 @@ function registerGenerateDeliverablesCommand(program2) {
|
|
|
14759
14931
|
console.log(`\u2705 Created: ${path23.join(outputDir, "GATE5_cleanup.md")}`);
|
|
14760
14932
|
console.log(`\u2705 Created: ${path23.join(outputDir, "SUMMARY.md")}`);
|
|
14761
14933
|
console.log("");
|
|
14762
|
-
const
|
|
14763
|
-
const planHashContent =
|
|
14934
|
+
const fs51 = await import("fs");
|
|
14935
|
+
const planHashContent = fs51.readFileSync(path23.join(outputDir, "plan-hash.txt"), "utf-8");
|
|
14764
14936
|
const planHashMatch = planHashContent.match(/SHA256: ([a-f0-9]+)/);
|
|
14765
14937
|
if (planHashMatch) {
|
|
14766
14938
|
console.log(`Plan hash: ${planHashMatch[1]}`);
|
|
@@ -15551,7 +15723,7 @@ function formatMonitor(monitor) {
|
|
|
15551
15723
|
async function runCheck(opts) {
|
|
15552
15724
|
let githubAPI = await createGitHubAPI();
|
|
15553
15725
|
if (opts.owner && opts.repo) {
|
|
15554
|
-
const { GitHubAPI: GitHubAPI2 } = await import("./api-
|
|
15726
|
+
const { GitHubAPI: GitHubAPI2 } = await import("./api-UIWVFU7M.js");
|
|
15555
15727
|
githubAPI = new GitHubAPI2({
|
|
15556
15728
|
owner: opts.owner,
|
|
15557
15729
|
repo: opts.repo,
|
|
@@ -16762,9 +16934,9 @@ async function promptInteractive(defaults) {
|
|
|
16762
16934
|
output: process.stdout
|
|
16763
16935
|
});
|
|
16764
16936
|
const question = (prompt) => {
|
|
16765
|
-
return new Promise((
|
|
16937
|
+
return new Promise((resolve16) => {
|
|
16766
16938
|
rl.question(prompt, (answer) => {
|
|
16767
|
-
|
|
16939
|
+
resolve16(answer.trim());
|
|
16768
16940
|
});
|
|
16769
16941
|
});
|
|
16770
16942
|
};
|
|
@@ -18621,8 +18793,8 @@ Total: ${entries.length} counter-examples (${entries.filter((e) => e.shouldLearn
|
|
|
18621
18793
|
counterExamples.command("export").description("Export counter-examples for analysis").option("--format <format>", "Export format (json|csv)", "json").option("--base-dir <dir>", "Base directory for lexrunner", process.cwd()).option("--output <file>", "Output file (prints to stdout if not specified)").action(async (options) => {
|
|
18622
18794
|
const output = exportCounterExamples(options.format, options.baseDir);
|
|
18623
18795
|
if (options.output) {
|
|
18624
|
-
const
|
|
18625
|
-
|
|
18796
|
+
const fs51 = await import("fs");
|
|
18797
|
+
fs51.writeFileSync(options.output, output, "utf-8");
|
|
18626
18798
|
console.log(chalk9.green(`\u2713 Exported counter-examples to ${options.output}`));
|
|
18627
18799
|
} else {
|
|
18628
18800
|
console.log(output);
|
|
@@ -19202,7 +19374,7 @@ function nativePathsOverlap(runtimePlatform, left, right, comparison) {
|
|
|
19202
19374
|
if (api.parse(normalizedLeft).root !== api.parse(normalizedRight).root) return false;
|
|
19203
19375
|
const relativeLeft = api.relative(normalizedLeft, normalizedRight);
|
|
19204
19376
|
const relativeRight = api.relative(normalizedRight, normalizedLeft);
|
|
19205
|
-
const isDescendant = (
|
|
19377
|
+
const isDescendant = (relative5) => relative5.length > 0 && relative5 !== ".." && !relative5.startsWith(`..${api.sep}`);
|
|
19206
19378
|
return isDescendant(relativeLeft) || isDescendant(relativeRight);
|
|
19207
19379
|
}
|
|
19208
19380
|
function digestBinding(runtime) {
|
|
@@ -20547,8 +20719,8 @@ function parseGitStatusPorcelainV1Z(input) {
|
|
|
20547
20719
|
}
|
|
20548
20720
|
const indexStatus = field[0];
|
|
20549
20721
|
const worktreeStatus = field[1];
|
|
20550
|
-
const
|
|
20551
|
-
if (
|
|
20722
|
+
const path60 = field.slice(3);
|
|
20723
|
+
if (path60.length === 0) {
|
|
20552
20724
|
throw new Error("Malformed git status porcelain: path is empty");
|
|
20553
20725
|
}
|
|
20554
20726
|
const renameOrCopy = [indexStatus, worktreeStatus].find(
|
|
@@ -20566,7 +20738,7 @@ function parseGitStatusPorcelainV1Z(input) {
|
|
|
20566
20738
|
records.push({
|
|
20567
20739
|
indexStatus,
|
|
20568
20740
|
worktreeStatus,
|
|
20569
|
-
path:
|
|
20741
|
+
path: path60,
|
|
20570
20742
|
...originalPath === void 0 ? {} : { originalPath },
|
|
20571
20743
|
kind
|
|
20572
20744
|
});
|
|
@@ -21018,8 +21190,8 @@ function copyIssues(result, context) {
|
|
|
21018
21190
|
context.addIssue({ code: "custom", path: issue.path, message: issue.message });
|
|
21019
21191
|
}
|
|
21020
21192
|
}
|
|
21021
|
-
function addIssue(context,
|
|
21022
|
-
context.addIssue({ code: "custom", path:
|
|
21193
|
+
function addIssue(context, path60, message) {
|
|
21194
|
+
context.addIssue({ code: "custom", path: path60, message });
|
|
21023
21195
|
}
|
|
21024
21196
|
|
|
21025
21197
|
// src/workspaces/linux-workspace-boundary.ts
|
|
@@ -22060,8 +22232,8 @@ var NodeGitWorktreeBroker = class {
|
|
|
22060
22232
|
"The worktree root was replaced after broker initialization"
|
|
22061
22233
|
);
|
|
22062
22234
|
}
|
|
22063
|
-
const
|
|
22064
|
-
const components =
|
|
22235
|
+
const relative5 = path34.relative(this.worktreeRoot, path34.resolve(target.worktreePath));
|
|
22236
|
+
const components = relative5.split(path34.sep);
|
|
22065
22237
|
const targetName = components.pop();
|
|
22066
22238
|
if (!targetName) {
|
|
22067
22239
|
throw new DirectoryBoundaryError("invalid_path", "The worktree target has no basename");
|
|
@@ -22265,8 +22437,8 @@ var NodeGitWorktreeBroker = class {
|
|
|
22265
22437
|
);
|
|
22266
22438
|
}
|
|
22267
22439
|
const normalized = path34.resolve(gitDirectoryPath);
|
|
22268
|
-
const
|
|
22269
|
-
if (!
|
|
22440
|
+
const relative5 = path34.relative(this.repositoryGitIdentity.path, normalized);
|
|
22441
|
+
if (!relative5 || relative5 === ".." || relative5.startsWith(`..${path34.sep}`)) {
|
|
22270
22442
|
return this.failure(
|
|
22271
22443
|
operation,
|
|
22272
22444
|
"containment_violation",
|
|
@@ -22275,7 +22447,7 @@ var NodeGitWorktreeBroker = class {
|
|
|
22275
22447
|
}
|
|
22276
22448
|
let current = null;
|
|
22277
22449
|
try {
|
|
22278
|
-
for (const component of
|
|
22450
|
+
for (const component of relative5.split(path34.sep)) {
|
|
22279
22451
|
const child = await boundary.lease.openChild(
|
|
22280
22452
|
current ?? boundary.repositoryGit,
|
|
22281
22453
|
component,
|
|
@@ -22329,8 +22501,8 @@ var NodeGitWorktreeBroker = class {
|
|
|
22329
22501
|
const normalizedRoot = path34.resolve(root);
|
|
22330
22502
|
const comparedCandidate = this.pathComparison === "case-insensitive" ? normalizedCandidate.toLocaleLowerCase("en-US") : normalizedCandidate;
|
|
22331
22503
|
const comparedRoot = this.pathComparison === "case-insensitive" ? normalizedRoot.toLocaleLowerCase("en-US") : normalizedRoot;
|
|
22332
|
-
const
|
|
22333
|
-
return
|
|
22504
|
+
const relative5 = path34.relative(comparedRoot, comparedCandidate);
|
|
22505
|
+
return relative5.length > 0 && relative5 !== ".." && !relative5.startsWith(`..${path34.sep}`);
|
|
22334
22506
|
}
|
|
22335
22507
|
async git(boundary, operation, args, cwd, options, allowedNonzeroExitCodes = [], evidence) {
|
|
22336
22508
|
const result = await boundary.lease.runProcess({
|
|
@@ -22435,7 +22607,7 @@ function nativePathsOverlap2(left, right, comparison) {
|
|
|
22435
22607
|
if (normalizedLeft === normalizedRight) return true;
|
|
22436
22608
|
const relativeLeft = path34.relative(normalizedLeft, normalizedRight);
|
|
22437
22609
|
const relativeRight = path34.relative(normalizedRight, normalizedLeft);
|
|
22438
|
-
const isDescendant = (
|
|
22610
|
+
const isDescendant = (relative5) => relative5.length > 0 && relative5 !== ".." && !relative5.startsWith(`..${path34.sep}`);
|
|
22439
22611
|
return isDescendant(relativeLeft) || isDescendant(relativeRight);
|
|
22440
22612
|
}
|
|
22441
22613
|
function branchName(ref) {
|
|
@@ -23478,7 +23650,7 @@ var NativeWslProjectionEngine = class {
|
|
|
23478
23650
|
"native publication target became occupied"
|
|
23479
23651
|
);
|
|
23480
23652
|
}
|
|
23481
|
-
const
|
|
23653
|
+
const repositoryIdentity2 = identityOf(staging.repository);
|
|
23482
23654
|
const allocationIdentity = identityOf(staging.allocation);
|
|
23483
23655
|
staging.repository.close();
|
|
23484
23656
|
staging.repository = void 0;
|
|
@@ -23491,7 +23663,7 @@ var NativeWslProjectionEngine = class {
|
|
|
23491
23663
|
staging.repositoryPublished = true;
|
|
23492
23664
|
assertPublishedIdentity(
|
|
23493
23665
|
path35.join(boundary.projectionRoot.path, projectionId),
|
|
23494
|
-
|
|
23666
|
+
repositoryIdentity2,
|
|
23495
23667
|
"native projection"
|
|
23496
23668
|
);
|
|
23497
23669
|
await rename(
|
|
@@ -24377,11 +24549,11 @@ function loadNativeWslProjectionSelection(repositoryRoot, expectedSelectionDiges
|
|
|
24377
24549
|
if (!/^sha256:[a-f0-9]{64}$/u.test(expectedSelectionDigest)) {
|
|
24378
24550
|
throw new Error("Projection selection authority is invalid");
|
|
24379
24551
|
}
|
|
24380
|
-
const
|
|
24552
|
+
const repositoryIdentity2 = captureDirectoryIdentity(
|
|
24381
24553
|
repositoryRoot,
|
|
24382
24554
|
"native projection repository"
|
|
24383
24555
|
);
|
|
24384
|
-
const repository = reopenDirectoryIdentity(
|
|
24556
|
+
const repository = reopenDirectoryIdentity(repositoryIdentity2, "native projection repository");
|
|
24385
24557
|
let gitDirectory;
|
|
24386
24558
|
try {
|
|
24387
24559
|
gitDirectory = openChildDirectory(repository, ".git", "native projection Git directory");
|
|
@@ -24975,24 +25147,24 @@ var AcceptanceCriterion = z19.object({
|
|
|
24975
25147
|
function isMachineLocalAbsolutePath(value) {
|
|
24976
25148
|
return /(?:^|\s)\/(?!\/)[^\s]*/.test(value) || /(?:^|\s)~\/[^\s]*/.test(value) || /(?:^|\s)\\\\[^\s]*/.test(value) || /(?:^|\s)[a-z]:[\\/][^\s]*/i.test(value) || /(?:^|\s)file:/i.test(value);
|
|
24977
25149
|
}
|
|
24978
|
-
function rejectMachineLocalPaths(value, ctx,
|
|
25150
|
+
function rejectMachineLocalPaths(value, ctx, path60 = []) {
|
|
24979
25151
|
if (typeof value === "string") {
|
|
24980
25152
|
if (isMachineLocalAbsolutePath(value)) {
|
|
24981
25153
|
ctx.addIssue({
|
|
24982
25154
|
code: "custom",
|
|
24983
|
-
path:
|
|
25155
|
+
path: path60,
|
|
24984
25156
|
message: "AgentTaskPacket_v1 must not contain machine-local absolute paths"
|
|
24985
25157
|
});
|
|
24986
25158
|
}
|
|
24987
25159
|
return;
|
|
24988
25160
|
}
|
|
24989
25161
|
if (Array.isArray(value)) {
|
|
24990
|
-
value.forEach((item, index) => rejectMachineLocalPaths(item, ctx, [...
|
|
25162
|
+
value.forEach((item, index) => rejectMachineLocalPaths(item, ctx, [...path60, index]));
|
|
24991
25163
|
return;
|
|
24992
25164
|
}
|
|
24993
25165
|
if (value !== null && typeof value === "object") {
|
|
24994
25166
|
for (const [key, item] of Object.entries(value)) {
|
|
24995
|
-
rejectMachineLocalPaths(item, ctx, [...
|
|
25167
|
+
rejectMachineLocalPaths(item, ctx, [...path60, key]);
|
|
24996
25168
|
}
|
|
24997
25169
|
}
|
|
24998
25170
|
}
|
|
@@ -27166,10 +27338,10 @@ function captureBoundIdentities(input) {
|
|
|
27166
27338
|
worktree: captureDirectoryIdentity(input.worktreePath, "execution mapping worktree")
|
|
27167
27339
|
};
|
|
27168
27340
|
}
|
|
27169
|
-
function verifiedRoot(runtimeId,
|
|
27341
|
+
function verifiedRoot(runtimeId, path60, identity) {
|
|
27170
27342
|
return {
|
|
27171
27343
|
runtime_id: runtimeId,
|
|
27172
|
-
path:
|
|
27344
|
+
path: path60,
|
|
27173
27345
|
verification: "directory_identity",
|
|
27174
27346
|
directory_identity: identityClaim2(identity)
|
|
27175
27347
|
};
|
|
@@ -27288,8 +27460,8 @@ async function requireDirectoryWithin(directory, root, field) {
|
|
|
27288
27460
|
realpath(directory),
|
|
27289
27461
|
realpath(root)
|
|
27290
27462
|
]);
|
|
27291
|
-
const
|
|
27292
|
-
if (
|
|
27463
|
+
const relative5 = path36.relative(resolvedRoot, resolvedDirectory);
|
|
27464
|
+
if (relative5 === ".." || relative5.startsWith(`..${path36.sep}`) || path36.isAbsolute(relative5)) {
|
|
27293
27465
|
throw new Error(`${field} must resolve within its authorized root`);
|
|
27294
27466
|
}
|
|
27295
27467
|
}
|
|
@@ -32481,8 +32653,8 @@ async function requireDirectoryWithin2(directory, root, field) {
|
|
|
32481
32653
|
realpath2(directory),
|
|
32482
32654
|
realpath2(root)
|
|
32483
32655
|
]);
|
|
32484
|
-
const
|
|
32485
|
-
if (
|
|
32656
|
+
const relative5 = path37.relative(resolvedRoot, resolvedDirectory);
|
|
32657
|
+
if (relative5 === ".." || relative5.startsWith(`..${path37.sep}`) || path37.isAbsolute(relative5)) {
|
|
32486
32658
|
throw new Error(`${field} must resolve within the authorized worktree`);
|
|
32487
32659
|
}
|
|
32488
32660
|
}
|
|
@@ -35259,10 +35431,10 @@ var WorkerSessionDelegationBinding_v1 = z29.object({
|
|
|
35259
35431
|
function decisionReceiptMatchesOffer(receipt, offer, offerHash) {
|
|
35260
35432
|
return receipt.delegation_id === offer.delegation_id && receipt.attempt_id === offer.attempt_id && receipt.offer_hash === offerHash && receipt.worker_thread_id === offer.worker.thread_id && receipt.transcript_start_hash === offer.transcript_start_hash && Date.parse(receipt.decided_at) >= Date.parse(offer.offered_at);
|
|
35261
35433
|
}
|
|
35262
|
-
function requireTimeOrder(earlier, later,
|
|
35434
|
+
function requireTimeOrder(earlier, later, path60, context, equalAllowed = true) {
|
|
35263
35435
|
const ordered = equalAllowed ? Date.parse(earlier) <= Date.parse(later) : Date.parse(earlier) < Date.parse(later);
|
|
35264
35436
|
if (!ordered) {
|
|
35265
|
-
context.addIssue({ code: "custom", path: [
|
|
35437
|
+
context.addIssue({ code: "custom", path: [path60], message: `${path60} is out of order` });
|
|
35266
35438
|
}
|
|
35267
35439
|
}
|
|
35268
35440
|
|
|
@@ -36372,12 +36544,12 @@ function grantWithinRequirements(grant, requirements) {
|
|
|
36372
36544
|
);
|
|
36373
36545
|
return grant.authorized_model_provider === requirements.authorized_model_provider && grant.source_disclosure_allowed === requirements.source_disclosure_allowed && grant.max_duration_ms <= requirements.max_duration_ms && grant.max_output_bytes <= requirements.max_output_bytes && grant.controls.every((control) => required2.get(control.control) === control.minimum_strength) && grant.tools.length <= 1;
|
|
36374
36546
|
}
|
|
36375
|
-
function requireExactControls(controls, context,
|
|
36547
|
+
function requireExactControls(controls, context, path60) {
|
|
36376
36548
|
const actual = new Set(controls.map((control) => control.control));
|
|
36377
36549
|
if (actual.size !== GovernedControlId.options.length || GovernedControlId.options.some((control) => !actual.has(control))) {
|
|
36378
36550
|
context.addIssue({
|
|
36379
36551
|
code: "custom",
|
|
36380
|
-
path:
|
|
36552
|
+
path: path60,
|
|
36381
36553
|
message: "every governed denial control must appear exactly once"
|
|
36382
36554
|
});
|
|
36383
36555
|
}
|
|
@@ -37327,10 +37499,10 @@ function requireAbsent(value, fields, context) {
|
|
|
37327
37499
|
function addStateIssue(message, context) {
|
|
37328
37500
|
context.addIssue({ code: "custom", path: ["status"], message });
|
|
37329
37501
|
}
|
|
37330
|
-
function requireOrdered(earlier, later,
|
|
37502
|
+
function requireOrdered(earlier, later, path60, context, equalAllowed = true) {
|
|
37331
37503
|
const ordered = equalAllowed ? Date.parse(earlier) <= Date.parse(later) : Date.parse(earlier) < Date.parse(later);
|
|
37332
37504
|
if (!ordered) {
|
|
37333
|
-
context.addIssue({ code: "custom", path: [
|
|
37505
|
+
context.addIssue({ code: "custom", path: [path60], message: `${path60} is out of order` });
|
|
37334
37506
|
}
|
|
37335
37507
|
}
|
|
37336
37508
|
|
|
@@ -39050,8 +39222,8 @@ function normalizeInstant4(value) {
|
|
|
39050
39222
|
return new Date(timestamp).toISOString();
|
|
39051
39223
|
}
|
|
39052
39224
|
function assertDescendant(parent, candidate) {
|
|
39053
|
-
const
|
|
39054
|
-
if (
|
|
39225
|
+
const relative5 = path46.relative(path46.resolve(parent), path46.resolve(candidate));
|
|
39226
|
+
if (relative5.startsWith("..") || path46.isAbsolute(relative5)) {
|
|
39055
39227
|
throw new LocalProtectedEvidenceVerificationError("container_invalid");
|
|
39056
39228
|
}
|
|
39057
39229
|
}
|
|
@@ -39206,14 +39378,14 @@ var WindowsProtectedEvidenceAuthority = class {
|
|
|
39206
39378
|
this.child = null;
|
|
39207
39379
|
child?.stdin.end();
|
|
39208
39380
|
if (child && child.exitCode === null) {
|
|
39209
|
-
await new Promise((
|
|
39381
|
+
await new Promise((resolve16) => {
|
|
39210
39382
|
const timeout = setTimeout(() => {
|
|
39211
39383
|
child.kill();
|
|
39212
|
-
|
|
39384
|
+
resolve16();
|
|
39213
39385
|
}, 5e3);
|
|
39214
39386
|
child.once("close", () => {
|
|
39215
39387
|
clearTimeout(timeout);
|
|
39216
|
-
|
|
39388
|
+
resolve16();
|
|
39217
39389
|
});
|
|
39218
39390
|
});
|
|
39219
39391
|
}
|
|
@@ -39224,8 +39396,8 @@ var WindowsProtectedEvidenceAuthority = class {
|
|
|
39224
39396
|
const child = this.ensureChild();
|
|
39225
39397
|
const id = this.nextId;
|
|
39226
39398
|
this.nextId += 1;
|
|
39227
|
-
return new Promise((
|
|
39228
|
-
this.pending.set(id, { resolve:
|
|
39399
|
+
return new Promise((resolve16, reject) => {
|
|
39400
|
+
this.pending.set(id, { resolve: resolve16, reject });
|
|
39229
39401
|
child.stdin.write(`${JSON.stringify({ id, op: operation, path: target })}
|
|
39230
39402
|
`, (error) => {
|
|
39231
39403
|
if (!error) return;
|
|
@@ -39877,7 +40049,7 @@ var repositoryCorpusHeaderBody = z41.object({
|
|
|
39877
40049
|
var GovernedRepositoryCorpusHeader_v1 = repositoryCorpusHeaderBody.superRefine(
|
|
39878
40050
|
(value, context) => {
|
|
39879
40051
|
const paths = value.entries.map((entry) => entry.path);
|
|
39880
|
-
if (new Set(paths).size !== paths.length || paths.some((
|
|
40052
|
+
if (new Set(paths).size !== paths.length || paths.some((path60, index) => index > 0 && path60 <= paths[index - 1])) {
|
|
39881
40053
|
context.addIssue({
|
|
39882
40054
|
code: "custom",
|
|
39883
40055
|
path: ["entries"],
|
|
@@ -40304,7 +40476,7 @@ function sanitizedWslEnvironment() {
|
|
|
40304
40476
|
return environment;
|
|
40305
40477
|
}
|
|
40306
40478
|
function waitForExit(child, timeoutMs) {
|
|
40307
|
-
return new Promise((
|
|
40479
|
+
return new Promise((resolve16, reject) => {
|
|
40308
40480
|
const timeout = setTimeout(() => {
|
|
40309
40481
|
child.kill();
|
|
40310
40482
|
reject(new Error("WSL2 provider control request timed out"));
|
|
@@ -40315,7 +40487,7 @@ function waitForExit(child, timeoutMs) {
|
|
|
40315
40487
|
});
|
|
40316
40488
|
child.once("close", (code) => {
|
|
40317
40489
|
clearTimeout(timeout);
|
|
40318
|
-
|
|
40490
|
+
resolve16(code);
|
|
40319
40491
|
});
|
|
40320
40492
|
});
|
|
40321
40493
|
}
|
|
@@ -41430,8 +41602,8 @@ var LocalProtectedEvidenceStore = class {
|
|
|
41430
41602
|
exclusive(operation) {
|
|
41431
41603
|
const previous = this.queue;
|
|
41432
41604
|
let release;
|
|
41433
|
-
this.queue = new Promise((
|
|
41434
|
-
release =
|
|
41605
|
+
this.queue = new Promise((resolve16) => {
|
|
41606
|
+
release = resolve16;
|
|
41435
41607
|
});
|
|
41436
41608
|
return previous.then(operation).finally(release);
|
|
41437
41609
|
}
|
|
@@ -41594,8 +41766,8 @@ function sameToken(expected, candidate) {
|
|
|
41594
41766
|
return left.length === right.length && timingSafeEqual(left, right);
|
|
41595
41767
|
}
|
|
41596
41768
|
function assertDescendant2(root, candidate) {
|
|
41597
|
-
const
|
|
41598
|
-
if (!
|
|
41769
|
+
const relative5 = path50.relative(root, candidate);
|
|
41770
|
+
if (!relative5 || relative5.startsWith("..") || path50.isAbsolute(relative5)) {
|
|
41599
41771
|
throw new Error("protected evidence deletion target escaped its root");
|
|
41600
41772
|
}
|
|
41601
41773
|
}
|
|
@@ -42443,11 +42615,11 @@ async function launchDetachedSupervisor(input) {
|
|
|
42443
42615
|
env: sanitizedSupervisorEnvironment()
|
|
42444
42616
|
}
|
|
42445
42617
|
);
|
|
42446
|
-
return await new Promise((
|
|
42447
|
-
child.once("error", () =>
|
|
42618
|
+
return await new Promise((resolve16) => {
|
|
42619
|
+
child.once("error", () => resolve16(false));
|
|
42448
42620
|
child.once("spawn", () => {
|
|
42449
42621
|
child.unref();
|
|
42450
|
-
|
|
42622
|
+
resolve16(true);
|
|
42451
42623
|
});
|
|
42452
42624
|
});
|
|
42453
42625
|
} catch {
|
|
@@ -43193,10 +43365,10 @@ function commandPath(command) {
|
|
|
43193
43365
|
}
|
|
43194
43366
|
return components.join(" ");
|
|
43195
43367
|
}
|
|
43196
|
-
function aliasWarning(
|
|
43197
|
-
const policy = POLICY_BY_PATH.get(
|
|
43368
|
+
function aliasWarning(path60) {
|
|
43369
|
+
const policy = POLICY_BY_PATH.get(path60);
|
|
43198
43370
|
if (!policy) return null;
|
|
43199
|
-
return policy.disposition === "deprecated" ? `[lexrunner] deprecated alias "${
|
|
43371
|
+
return policy.disposition === "deprecated" ? `[lexrunner] deprecated alias "${path60}"; use "${policy.replacement}"; removal: ${policy.removeIn}.` : `[lexrunner] compatibility alias "${path60}"; use "${policy.replacement}"; supported through 2.x and reviewed at 3.0.0.`;
|
|
43200
43372
|
}
|
|
43201
43373
|
function emitAliasWarning(command, write = (message) => process.stderr.write(message)) {
|
|
43202
43374
|
const warning = aliasWarning(commandPath(command));
|
|
@@ -43302,8 +43474,8 @@ async function searchAttributions(query, runId) {
|
|
|
43302
43474
|
}
|
|
43303
43475
|
|
|
43304
43476
|
// src/cli.ts
|
|
43305
|
-
import * as
|
|
43306
|
-
import * as
|
|
43477
|
+
import * as fs50 from "fs";
|
|
43478
|
+
import * as path59 from "path";
|
|
43307
43479
|
|
|
43308
43480
|
// src/runs/enforcement.ts
|
|
43309
43481
|
import { z as z45 } from "zod";
|
|
@@ -44411,7 +44583,7 @@ function createRunManager(baseDirOrOptions) {
|
|
|
44411
44583
|
|
|
44412
44584
|
// src/runs/coordinated-manager.ts
|
|
44413
44585
|
import { existsSync as existsSync24, readFileSync as readFileSync32, renameSync as renameSync3, writeFileSync as writeFileSync19 } from "fs";
|
|
44414
|
-
import { join as
|
|
44586
|
+
import { join as join33 } from "path";
|
|
44415
44587
|
|
|
44416
44588
|
// src/runs/agent-work-supervisor.ts
|
|
44417
44589
|
import { z as z48 } from "zod";
|
|
@@ -44725,8 +44897,8 @@ async function executeAgentWorkPreparation(input) {
|
|
|
44725
44897
|
function passed(results, id) {
|
|
44726
44898
|
return results.some((result) => result.id === id && result.outcome === "passed");
|
|
44727
44899
|
}
|
|
44728
|
-
async function containedExistingDirectory(root,
|
|
44729
|
-
const candidate =
|
|
44900
|
+
async function containedExistingDirectory(root, relative5) {
|
|
44901
|
+
const candidate = relative5 ? path55.resolve(root, relative5) : root;
|
|
44730
44902
|
const resolved = await realpath6(candidate);
|
|
44731
44903
|
const relation = path55.relative(root, resolved);
|
|
44732
44904
|
if (relation === ".." || relation.startsWith(`..${path55.sep}`) || path55.isAbsolute(relation)) {
|
|
@@ -44809,7 +44981,7 @@ var workspaceFilesystemEntry = z49.discriminatedUnion("kind", [
|
|
|
44809
44981
|
}).strict()
|
|
44810
44982
|
]);
|
|
44811
44983
|
function requireStrictlyOrderedPaths(values, context, field) {
|
|
44812
|
-
if (values.some(({ path:
|
|
44984
|
+
if (values.some(({ path: path60 }, index) => index > 0 && path60 <= values[index - 1].path)) {
|
|
44813
44985
|
context.addIssue({
|
|
44814
44986
|
code: "custom",
|
|
44815
44987
|
path: [field],
|
|
@@ -44829,7 +45001,7 @@ var completeGitIdentity = z49.object({
|
|
|
44829
45001
|
kind: z49.enum(["absent", "present"]),
|
|
44830
45002
|
paths: z49.array(boundedRelativePath).max(4096)
|
|
44831
45003
|
}).strict().superRefine((identity, context) => {
|
|
44832
|
-
if (identity.paths.some((
|
|
45004
|
+
if (identity.paths.some((path60, index) => index > 0 && path60 <= identity.paths[index - 1]) || identity.kind === "absent" && identity.paths.length !== 0 || identity.kind === "present" && identity.paths.length === 0) {
|
|
44833
45005
|
context.addIssue({
|
|
44834
45006
|
code: "custom",
|
|
44835
45007
|
path: ["paths"],
|
|
@@ -45139,7 +45311,7 @@ var GovernedWorkspaceMutationRecoveryReceipt_v1 = z49.object({
|
|
|
45139
45311
|
});
|
|
45140
45312
|
}
|
|
45141
45313
|
if (receipt.changed_paths.some(
|
|
45142
|
-
(
|
|
45314
|
+
(path60, index) => index > 0 && path60 <= receipt.changed_paths[index - 1]
|
|
45143
45315
|
)) {
|
|
45144
45316
|
context.addIssue({
|
|
45145
45317
|
code: "custom",
|
|
@@ -45974,15 +46146,15 @@ var AttemptAwaitableSupervisor = class {
|
|
|
45974
46146
|
0,
|
|
45975
46147
|
Date.parse(record.observer_lease.expires_at) - Date.parse(this.now()) + 1
|
|
45976
46148
|
);
|
|
45977
|
-
let
|
|
46149
|
+
let resolve16;
|
|
45978
46150
|
const completion = new Promise((resolvePromise) => {
|
|
45979
|
-
|
|
46151
|
+
resolve16 = resolvePromise;
|
|
45980
46152
|
});
|
|
45981
46153
|
const timer = setTimeout(() => {
|
|
45982
46154
|
this.leaseExpiryWakeups.delete(record.awaitable_id);
|
|
45983
|
-
void this.attach(record.awaitable_id).finally(
|
|
46155
|
+
void this.attach(record.awaitable_id).finally(resolve16);
|
|
45984
46156
|
}, delayMs);
|
|
45985
|
-
this.leaseExpiryWakeups.set(record.awaitable_id, { timer, completion, resolve:
|
|
46157
|
+
this.leaseExpiryWakeups.set(record.awaitable_id, { timer, completion, resolve: resolve16 });
|
|
45986
46158
|
}
|
|
45987
46159
|
clearLeaseExpiryWakeup(awaitableId) {
|
|
45988
46160
|
const wakeup = this.leaseExpiryWakeups.get(awaitableId);
|
|
@@ -46087,14 +46259,14 @@ function normalizeRetryDelay(value, name) {
|
|
|
46087
46259
|
}
|
|
46088
46260
|
function waitForRetry(delayMs, signal) {
|
|
46089
46261
|
if (signal.aborted) return Promise.resolve(false);
|
|
46090
|
-
return new Promise((
|
|
46262
|
+
return new Promise((resolve16) => {
|
|
46091
46263
|
const timer = setTimeout(() => {
|
|
46092
46264
|
signal.removeEventListener("abort", onAbort);
|
|
46093
|
-
|
|
46265
|
+
resolve16(true);
|
|
46094
46266
|
}, delayMs);
|
|
46095
46267
|
const onAbort = () => {
|
|
46096
46268
|
clearTimeout(timer);
|
|
46097
|
-
|
|
46269
|
+
resolve16(false);
|
|
46098
46270
|
};
|
|
46099
46271
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
46100
46272
|
});
|
|
@@ -49611,8 +49783,135 @@ function normalizeInstant8(value) {
|
|
|
49611
49783
|
// src/application/plan-artifact-service.ts
|
|
49612
49784
|
import * as fs48 from "fs";
|
|
49613
49785
|
import * as path57 from "path";
|
|
49614
|
-
|
|
49615
|
-
|
|
49786
|
+
import { isDeepStrictEqual } from "util";
|
|
49787
|
+
|
|
49788
|
+
// src/application/execution-plan-artifact.ts
|
|
49789
|
+
import { createHash as createHash13 } from "crypto";
|
|
49790
|
+
import { z as z54 } from "zod";
|
|
49791
|
+
var EXECUTION_PLAN_ARTIFACT_CONTRACT = "lexrunner.execution-plan-artifact.v1";
|
|
49792
|
+
var PLAN_ARTIFACT_REFERENCE_CONTRACT = "lexrunner.plan-artifact-reference.v1";
|
|
49793
|
+
var EXECUTION_PLAN_CANONICALIZATION_PROFILE = "lexrunner.execution-plan.canonical-json.v1";
|
|
49794
|
+
var EXECUTION_PLAN_HASH_PROFILE = "lexrunner.execution-plan-artifact.sha256.v1";
|
|
49795
|
+
var EXECUTION_PLAN_HASH_DOMAIN = "lexrunner:execution-plan-artifact:v1\0";
|
|
49796
|
+
var MAX_PLAN_ARTIFACT_BYTES = 4 * 1024 * 1024;
|
|
49797
|
+
var MAX_PLAN_RETRIEVAL_REFERENCE_BYTES = 4096;
|
|
49798
|
+
var MAX_SCOPE_LABEL_BYTES = 512;
|
|
49799
|
+
var Sha256Digest = z54.string().regex(/^sha256:[a-f0-9]{64}$/);
|
|
49800
|
+
var BoundedScopeLabel = z54.string().min(1).refine((value) => Buffer.byteLength(value, "utf8") <= MAX_SCOPE_LABEL_BYTES, {
|
|
49801
|
+
message: "Scope label exceeds the transport limit"
|
|
49802
|
+
});
|
|
49803
|
+
var BoundedIdentityLabel = z54.string().min(1).refine((value) => Buffer.byteLength(value, "utf8") <= MAX_SCOPE_LABEL_BYTES, {
|
|
49804
|
+
message: "Identity label exceeds the transport limit"
|
|
49805
|
+
});
|
|
49806
|
+
var PlanArtifactScope_v1Schema = z54.object({
|
|
49807
|
+
tenant: BoundedScopeLabel,
|
|
49808
|
+
workspace: BoundedScopeLabel,
|
|
49809
|
+
repository: BoundedScopeLabel,
|
|
49810
|
+
refNamespace: BoundedScopeLabel,
|
|
49811
|
+
policy: BoundedScopeLabel
|
|
49812
|
+
}).strict();
|
|
49813
|
+
var ExecutionPlanArtifactIdentity_v1Schema = z54.object({
|
|
49814
|
+
contract: z54.literal(EXECUTION_PLAN_ARTIFACT_CONTRACT),
|
|
49815
|
+
kind: z54.literal("execution-plan"),
|
|
49816
|
+
planSchema: z54.literal("lexrunner.execution-plan"),
|
|
49817
|
+
planSchemaVersion: BoundedIdentityLabel,
|
|
49818
|
+
canonicalizationProfile: z54.literal(EXECUTION_PLAN_CANONICALIZATION_PROFILE),
|
|
49819
|
+
hashProfile: z54.literal(EXECUTION_PLAN_HASH_PROFILE),
|
|
49820
|
+
digestAlgorithm: z54.literal("sha256"),
|
|
49821
|
+
digest: Sha256Digest,
|
|
49822
|
+
canonicalByteLength: z54.number().int().nonnegative().max(MAX_PLAN_ARTIFACT_BYTES),
|
|
49823
|
+
target: BoundedIdentityLabel,
|
|
49824
|
+
summary: z54.object({
|
|
49825
|
+
itemCount: z54.number().int().nonnegative().max(256),
|
|
49826
|
+
gateCount: z54.number().int().nonnegative().max(256 * 64)
|
|
49827
|
+
}).strict()
|
|
49828
|
+
}).strict();
|
|
49829
|
+
var ExecutionPlanArtifact_v1Schema = z54.object({
|
|
49830
|
+
identity: ExecutionPlanArtifactIdentity_v1Schema,
|
|
49831
|
+
canonicalBytes: z54.string()
|
|
49832
|
+
}).strict().superRefine((artifact, context) => {
|
|
49833
|
+
const byteLength = Buffer.byteLength(artifact.canonicalBytes, "utf8");
|
|
49834
|
+
if (byteLength > MAX_PLAN_ARTIFACT_BYTES) {
|
|
49835
|
+
context.addIssue({
|
|
49836
|
+
code: "custom",
|
|
49837
|
+
path: ["canonicalBytes"],
|
|
49838
|
+
message: "Canonical plan bytes exceed the artifact limit"
|
|
49839
|
+
});
|
|
49840
|
+
}
|
|
49841
|
+
if (byteLength !== artifact.identity.canonicalByteLength) {
|
|
49842
|
+
context.addIssue({
|
|
49843
|
+
code: "custom",
|
|
49844
|
+
path: ["identity", "canonicalByteLength"],
|
|
49845
|
+
message: "Canonical plan byte length does not match the artifact identity"
|
|
49846
|
+
});
|
|
49847
|
+
}
|
|
49848
|
+
if (computeExecutionPlanArtifactDigest(artifact.canonicalBytes) !== artifact.identity.digest) {
|
|
49849
|
+
context.addIssue({
|
|
49850
|
+
code: "custom",
|
|
49851
|
+
path: ["identity", "digest"],
|
|
49852
|
+
message: "Canonical plan digest does not match the artifact identity"
|
|
49853
|
+
});
|
|
49854
|
+
}
|
|
49855
|
+
try {
|
|
49856
|
+
const plan = loadPlan(artifact.canonicalBytes);
|
|
49857
|
+
if (canonicalJSONStringify(plan) !== artifact.canonicalBytes) {
|
|
49858
|
+
context.addIssue({
|
|
49859
|
+
code: "custom",
|
|
49860
|
+
path: ["canonicalBytes"],
|
|
49861
|
+
message: "Plan bytes are not in the declared canonical form"
|
|
49862
|
+
});
|
|
49863
|
+
}
|
|
49864
|
+
const gateCount = plan.items.reduce((count, item) => count + item.gates.length, 0);
|
|
49865
|
+
if (artifact.identity.planSchemaVersion !== plan.schemaVersion || artifact.identity.target !== plan.target || artifact.identity.summary.itemCount !== plan.items.length || artifact.identity.summary.gateCount !== gateCount) {
|
|
49866
|
+
context.addIssue({
|
|
49867
|
+
code: "custom",
|
|
49868
|
+
path: ["identity"],
|
|
49869
|
+
message: "Plan semantics do not match the artifact identity"
|
|
49870
|
+
});
|
|
49871
|
+
}
|
|
49872
|
+
} catch {
|
|
49873
|
+
context.addIssue({
|
|
49874
|
+
code: "custom",
|
|
49875
|
+
path: ["canonicalBytes"],
|
|
49876
|
+
message: "Canonical bytes do not contain a valid execution plan"
|
|
49877
|
+
});
|
|
49878
|
+
}
|
|
49879
|
+
});
|
|
49880
|
+
var PlanArtifactReference_v1Schema = z54.object({
|
|
49881
|
+
contract: z54.literal(PLAN_ARTIFACT_REFERENCE_CONTRACT),
|
|
49882
|
+
artifact: ExecutionPlanArtifactIdentity_v1Schema,
|
|
49883
|
+
expectedDigest: Sha256Digest,
|
|
49884
|
+
expectedCanonicalByteLength: z54.number().int().nonnegative().max(MAX_PLAN_ARTIFACT_BYTES),
|
|
49885
|
+
retrieval: z54.object({
|
|
49886
|
+
kind: z54.enum(["file", "registered"]),
|
|
49887
|
+
reference: z54.string().min(1).refine(
|
|
49888
|
+
(value) => !value.includes("\0") && Buffer.byteLength(value, "utf8") <= MAX_PLAN_RETRIEVAL_REFERENCE_BYTES,
|
|
49889
|
+
{ message: "Retrieval reference is invalid or exceeds the transport limit" }
|
|
49890
|
+
)
|
|
49891
|
+
}).strict(),
|
|
49892
|
+
scope: PlanArtifactScope_v1Schema.optional()
|
|
49893
|
+
}).strict().superRefine((reference, context) => {
|
|
49894
|
+
if (reference.expectedDigest !== reference.artifact.digest) {
|
|
49895
|
+
context.addIssue({
|
|
49896
|
+
code: "custom",
|
|
49897
|
+
path: ["expectedDigest"],
|
|
49898
|
+
message: "Expected digest does not match the embedded artifact identity"
|
|
49899
|
+
});
|
|
49900
|
+
}
|
|
49901
|
+
if (reference.expectedCanonicalByteLength !== reference.artifact.canonicalByteLength) {
|
|
49902
|
+
context.addIssue({
|
|
49903
|
+
code: "custom",
|
|
49904
|
+
path: ["expectedCanonicalByteLength"],
|
|
49905
|
+
message: "Expected byte length does not match the embedded artifact identity"
|
|
49906
|
+
});
|
|
49907
|
+
}
|
|
49908
|
+
});
|
|
49909
|
+
function computeExecutionPlanArtifactDigest(canonicalBytes2) {
|
|
49910
|
+
const digest = createHash13("sha256").update(EXECUTION_PLAN_HASH_DOMAIN, "utf8").update(canonicalBytes2, "utf8").digest("hex");
|
|
49911
|
+
return `sha256:${digest}`;
|
|
49912
|
+
}
|
|
49913
|
+
|
|
49914
|
+
// src/application/plan-artifact-service.ts
|
|
49616
49915
|
var MAX_PLAN_ITEMS = 256;
|
|
49617
49916
|
var MAX_GATES_PER_ITEM2 = 64;
|
|
49618
49917
|
var MAX_IDENTITY_LABEL_BYTES = 512;
|
|
@@ -49624,16 +49923,41 @@ var PlanArtifactServiceError = class extends Error {
|
|
|
49624
49923
|
this.name = "PlanArtifactServiceError";
|
|
49625
49924
|
}
|
|
49626
49925
|
};
|
|
49926
|
+
var _hooks;
|
|
49627
49927
|
var PlanArtifactService = class {
|
|
49928
|
+
constructor(options = {}) {
|
|
49929
|
+
__privateAdd(this, _hooks);
|
|
49930
|
+
__privateSet(this, _hooks, options.importHooks ?? {});
|
|
49931
|
+
}
|
|
49628
49932
|
resolve(input = {}) {
|
|
49629
49933
|
const workingDir = path57.resolve(input.workingDir ?? process.cwd());
|
|
49934
|
+
const scope = parseScope(input.scope);
|
|
49935
|
+
if (input.planReference !== void 0 && input.planFile !== void 0) {
|
|
49936
|
+
throw new PlanArtifactServiceError(
|
|
49937
|
+
"PLAN_REFERENCE_INVALID",
|
|
49938
|
+
"Provide either an immutable plan reference or an explicit plan path, not both",
|
|
49939
|
+
"explicit"
|
|
49940
|
+
);
|
|
49941
|
+
}
|
|
49942
|
+
if (input.planReference !== void 0 && input.scope !== void 0) {
|
|
49943
|
+
throw new PlanArtifactServiceError(
|
|
49944
|
+
"PLAN_REFERENCE_INVALID",
|
|
49945
|
+
"A separately supplied scope cannot override an immutable plan reference",
|
|
49946
|
+
"explicit"
|
|
49947
|
+
);
|
|
49948
|
+
}
|
|
49949
|
+
if (input.planReference !== void 0) {
|
|
49950
|
+
const reference = parseReference(input.planReference);
|
|
49951
|
+
const explicitPath = resolveExplicitReference(reference.retrieval.reference, workingDir);
|
|
49952
|
+
return readArtifact(explicitPath, "explicit", __privateGet(this, _hooks), reference);
|
|
49953
|
+
}
|
|
49630
49954
|
if (input.planFile !== void 0) {
|
|
49631
49955
|
const explicitPath = resolveExplicitReference(input.planFile, workingDir);
|
|
49632
|
-
return readArtifact(explicitPath, "explicit");
|
|
49956
|
+
return readArtifact(explicitPath, "explicit", __privateGet(this, _hooks), void 0, scope);
|
|
49633
49957
|
}
|
|
49634
49958
|
const repositoryPlan = path57.join(workingDir, "plan.json");
|
|
49635
|
-
if (
|
|
49636
|
-
return readArtifact(repositoryPlan, "repository-root");
|
|
49959
|
+
if (pathEntryExists(repositoryPlan)) {
|
|
49960
|
+
return readArtifact(repositoryPlan, "repository-root", __privateGet(this, _hooks), void 0, scope);
|
|
49637
49961
|
}
|
|
49638
49962
|
let profilePlan;
|
|
49639
49963
|
try {
|
|
@@ -49641,8 +49965,8 @@ var PlanArtifactService = class {
|
|
|
49641
49965
|
profilePlan = path57.join(profile.path, "runner", "plan.json");
|
|
49642
49966
|
} catch {
|
|
49643
49967
|
}
|
|
49644
|
-
if (profilePlan &&
|
|
49645
|
-
return readArtifact(profilePlan, "profile-runner");
|
|
49968
|
+
if (profilePlan && pathEntryExists(profilePlan)) {
|
|
49969
|
+
return readArtifact(profilePlan, "profile-runner", __privateGet(this, _hooks), void 0, scope);
|
|
49646
49970
|
}
|
|
49647
49971
|
throw new PlanArtifactServiceError(
|
|
49648
49972
|
"PLAN_NOT_FOUND",
|
|
@@ -49650,46 +49974,85 @@ var PlanArtifactService = class {
|
|
|
49650
49974
|
);
|
|
49651
49975
|
}
|
|
49652
49976
|
};
|
|
49653
|
-
|
|
49654
|
-
|
|
49977
|
+
_hooks = new WeakMap();
|
|
49978
|
+
function parseReference(reference) {
|
|
49979
|
+
const parsed = PlanArtifactReference_v1Schema.safeParse(reference);
|
|
49980
|
+
if (!parsed.success) {
|
|
49655
49981
|
throw new PlanArtifactServiceError(
|
|
49656
49982
|
"PLAN_REFERENCE_INVALID",
|
|
49657
|
-
"The
|
|
49983
|
+
"The immutable plan reference does not satisfy the bounded transport contract",
|
|
49658
49984
|
"explicit"
|
|
49659
49985
|
);
|
|
49660
49986
|
}
|
|
49661
|
-
return
|
|
49987
|
+
return parsed.data;
|
|
49662
49988
|
}
|
|
49663
|
-
function
|
|
49664
|
-
|
|
49665
|
-
|
|
49666
|
-
|
|
49667
|
-
} catch {
|
|
49989
|
+
function parseScope(scope) {
|
|
49990
|
+
if (scope === void 0) return void 0;
|
|
49991
|
+
const parsed = PlanArtifactScope_v1Schema.safeParse(scope);
|
|
49992
|
+
if (!parsed.success) {
|
|
49668
49993
|
throw new PlanArtifactServiceError(
|
|
49669
|
-
"
|
|
49670
|
-
"The
|
|
49671
|
-
|
|
49994
|
+
"PLAN_REFERENCE_INVALID",
|
|
49995
|
+
"The plan scope does not satisfy the bounded transport contract",
|
|
49996
|
+
"explicit"
|
|
49672
49997
|
);
|
|
49673
49998
|
}
|
|
49674
|
-
|
|
49999
|
+
return parsed.data;
|
|
50000
|
+
}
|
|
50001
|
+
function resolveExplicitReference(reference, workingDir) {
|
|
50002
|
+
if (reference.length === 0 || reference.includes("\0") || Buffer.byteLength(reference, "utf8") > MAX_PLAN_RETRIEVAL_REFERENCE_BYTES) {
|
|
49675
50003
|
throw new PlanArtifactServiceError(
|
|
49676
|
-
"
|
|
49677
|
-
"The
|
|
50004
|
+
"PLAN_REFERENCE_INVALID",
|
|
50005
|
+
"The explicit plan reference is empty, overlong, or contains an invalid character",
|
|
50006
|
+
"explicit"
|
|
50007
|
+
);
|
|
50008
|
+
}
|
|
50009
|
+
return path57.isAbsolute(reference) ? path57.normalize(reference) : path57.resolve(workingDir, reference);
|
|
50010
|
+
}
|
|
50011
|
+
function readArtifact(filePath, source, hooks, expected, scope) {
|
|
50012
|
+
const content = readPortableRaceDetectedFile(filePath, source, hooks);
|
|
50013
|
+
const plan = loadPlan(content);
|
|
50014
|
+
assertBoundedArtifact(plan, source);
|
|
50015
|
+
const canonicalBytes2 = canonicalJSONStringify(plan);
|
|
50016
|
+
const canonicalByteLength = Buffer.byteLength(canonicalBytes2, "utf8");
|
|
50017
|
+
if (canonicalByteLength > MAX_PLAN_ARTIFACT_BYTES) {
|
|
50018
|
+
throw new PlanArtifactServiceError(
|
|
50019
|
+
"PLAN_ARTIFACT_LIMIT_EXCEEDED",
|
|
50020
|
+
"The canonical integration plan exceeds the artifact byte limit",
|
|
49678
50021
|
source
|
|
49679
50022
|
);
|
|
49680
50023
|
}
|
|
49681
|
-
|
|
49682
|
-
|
|
49683
|
-
|
|
49684
|
-
|
|
50024
|
+
const artifactIdentity = {
|
|
50025
|
+
contract: EXECUTION_PLAN_ARTIFACT_CONTRACT,
|
|
50026
|
+
kind: "execution-plan",
|
|
50027
|
+
planSchema: "lexrunner.execution-plan",
|
|
50028
|
+
planSchemaVersion: plan.schemaVersion,
|
|
50029
|
+
canonicalizationProfile: EXECUTION_PLAN_CANONICALIZATION_PROFILE,
|
|
50030
|
+
hashProfile: EXECUTION_PLAN_HASH_PROFILE,
|
|
50031
|
+
digestAlgorithm: "sha256",
|
|
50032
|
+
digest: computeExecutionPlanArtifactDigest(canonicalBytes2),
|
|
50033
|
+
canonicalByteLength,
|
|
50034
|
+
target: plan.target,
|
|
50035
|
+
summary: {
|
|
50036
|
+
itemCount: plan.items.length,
|
|
50037
|
+
gateCount: plan.items.reduce((count, item) => count + item.gates.length, 0)
|
|
50038
|
+
}
|
|
50039
|
+
};
|
|
50040
|
+
const artifact = { identity: artifactIdentity, canonicalBytes: canonicalBytes2 };
|
|
50041
|
+
if (expected && !isDeepStrictEqual(expected.artifact, artifactIdentity)) {
|
|
49685
50042
|
throw new PlanArtifactServiceError(
|
|
49686
|
-
"
|
|
49687
|
-
"The
|
|
50043
|
+
"PLAN_REFERENCE_MISMATCH",
|
|
50044
|
+
"The retrieved integration plan does not match the immutable reference",
|
|
49688
50045
|
source
|
|
49689
50046
|
);
|
|
49690
50047
|
}
|
|
49691
|
-
const
|
|
49692
|
-
|
|
50048
|
+
const reference = expected ?? parseReference({
|
|
50049
|
+
contract: PLAN_ARTIFACT_REFERENCE_CONTRACT,
|
|
50050
|
+
artifact: artifactIdentity,
|
|
50051
|
+
expectedDigest: artifactIdentity.digest,
|
|
50052
|
+
expectedCanonicalByteLength: artifactIdentity.canonicalByteLength,
|
|
50053
|
+
retrieval: { kind: "file", reference: filePath },
|
|
50054
|
+
...scope ? { scope } : {}
|
|
50055
|
+
});
|
|
49693
50056
|
return {
|
|
49694
50057
|
plan,
|
|
49695
50058
|
identity: {
|
|
@@ -49701,10 +50064,167 @@ function readArtifact(filePath, source) {
|
|
|
49701
50064
|
target: plan.target,
|
|
49702
50065
|
itemCount: plan.items.length
|
|
49703
50066
|
},
|
|
50067
|
+
artifact,
|
|
50068
|
+
reference,
|
|
50069
|
+
acquisition: {
|
|
50070
|
+
contract: "lexrunner.plan-artifact-acquisition.v1",
|
|
50071
|
+
assurance: "portable-race-detection",
|
|
50072
|
+
authority: "unverified"
|
|
50073
|
+
},
|
|
49704
50074
|
source,
|
|
49705
50075
|
filePath
|
|
49706
50076
|
};
|
|
49707
50077
|
}
|
|
50078
|
+
function readPortableRaceDetectedFile(filePath, source, hooks) {
|
|
50079
|
+
const initialPath = snapshotPath(filePath, source);
|
|
50080
|
+
hooks.afterInitialPathSnapshot?.();
|
|
50081
|
+
const noFollow = typeof fs48.constants.O_NOFOLLOW === "number" ? fs48.constants.O_NOFOLLOW : 0;
|
|
50082
|
+
let descriptor;
|
|
50083
|
+
try {
|
|
50084
|
+
descriptor = fs48.openSync(filePath, fs48.constants.O_RDONLY | noFollow);
|
|
50085
|
+
} catch (error) {
|
|
50086
|
+
throw importError(error, source);
|
|
50087
|
+
}
|
|
50088
|
+
let bytes;
|
|
50089
|
+
try {
|
|
50090
|
+
const before = fs48.fstatSync(descriptor, { bigint: true });
|
|
50091
|
+
assertOpenedIdentity(initialPath[initialPath.length - 1].stats, before, source);
|
|
50092
|
+
hooks.afterOpen?.();
|
|
50093
|
+
if (before.size > BigInt(MAX_PLAN_ARTIFACT_BYTES)) {
|
|
50094
|
+
throw new PlanArtifactServiceError(
|
|
50095
|
+
"PLAN_ARTIFACT_LIMIT_EXCEEDED",
|
|
50096
|
+
"The referenced integration plan exceeds the artifact byte limit",
|
|
50097
|
+
source
|
|
50098
|
+
);
|
|
50099
|
+
}
|
|
50100
|
+
bytes = readAtMost(descriptor, MAX_PLAN_ARTIFACT_BYTES + 1);
|
|
50101
|
+
hooks.afterRead?.();
|
|
50102
|
+
const after = fs48.fstatSync(descriptor, { bigint: true });
|
|
50103
|
+
assertStableOpenedFile(before, after, bytes.length, source);
|
|
50104
|
+
} finally {
|
|
50105
|
+
fs48.closeSync(descriptor);
|
|
50106
|
+
}
|
|
50107
|
+
hooks.beforeFinalPathSnapshot?.();
|
|
50108
|
+
const finalPath = snapshotPath(filePath, source);
|
|
50109
|
+
assertStablePath(initialPath, finalPath, source);
|
|
50110
|
+
try {
|
|
50111
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
50112
|
+
} catch {
|
|
50113
|
+
throw new PlanArtifactServiceError(
|
|
50114
|
+
"PLAN_UNREADABLE",
|
|
50115
|
+
"The referenced integration plan is not valid UTF-8",
|
|
50116
|
+
source
|
|
50117
|
+
);
|
|
50118
|
+
}
|
|
50119
|
+
}
|
|
50120
|
+
function snapshotPath(filePath, source) {
|
|
50121
|
+
const absolute = path57.resolve(filePath);
|
|
50122
|
+
const root = path57.parse(absolute).root;
|
|
50123
|
+
const relative5 = path57.relative(root, absolute);
|
|
50124
|
+
const segments = relative5.length === 0 ? [] : relative5.split(path57.sep);
|
|
50125
|
+
const candidates = [root];
|
|
50126
|
+
let current = root;
|
|
50127
|
+
for (const segment of segments) {
|
|
50128
|
+
current = path57.join(current, segment);
|
|
50129
|
+
candidates.push(current);
|
|
50130
|
+
}
|
|
50131
|
+
return candidates.map((candidate, index) => {
|
|
50132
|
+
let stats;
|
|
50133
|
+
try {
|
|
50134
|
+
stats = fs48.lstatSync(candidate, { bigint: true });
|
|
50135
|
+
} catch (error) {
|
|
50136
|
+
throw importError(error, source);
|
|
50137
|
+
}
|
|
50138
|
+
const leaf = index === candidates.length - 1;
|
|
50139
|
+
if (stats.isSymbolicLink()) {
|
|
50140
|
+
throw new PlanArtifactServiceError(
|
|
50141
|
+
"PLAN_FILESYSTEM_UNSAFE",
|
|
50142
|
+
"The integration plan path contains an unsafe filesystem object",
|
|
50143
|
+
source
|
|
50144
|
+
);
|
|
50145
|
+
}
|
|
50146
|
+
if (leaf ? !stats.isFile() : !stats.isDirectory()) {
|
|
50147
|
+
throw new PlanArtifactServiceError(
|
|
50148
|
+
"PLAN_UNREADABLE",
|
|
50149
|
+
"The referenced integration plan is not a readable bounded file",
|
|
50150
|
+
source
|
|
50151
|
+
);
|
|
50152
|
+
}
|
|
50153
|
+
if (leaf && stats.nlink !== 1n) {
|
|
50154
|
+
throw new PlanArtifactServiceError(
|
|
50155
|
+
"PLAN_FILESYSTEM_UNSAFE",
|
|
50156
|
+
"The integration plan file has an ambiguous filesystem identity",
|
|
50157
|
+
source
|
|
50158
|
+
);
|
|
50159
|
+
}
|
|
50160
|
+
return { stats, leaf };
|
|
50161
|
+
});
|
|
50162
|
+
}
|
|
50163
|
+
function assertOpenedIdentity(pathStats, openedStats, source) {
|
|
50164
|
+
if (!openedStats.isFile() || openedStats.nlink !== 1n || !sameObject(pathStats, openedStats) || pathStats.size !== openedStats.size || pathStats.mtimeNs !== openedStats.mtimeNs || pathStats.ctimeNs !== openedStats.ctimeNs) {
|
|
50165
|
+
throw new PlanArtifactServiceError(
|
|
50166
|
+
"PLAN_FILESYSTEM_UNSAFE",
|
|
50167
|
+
"The integration plan filesystem identity changed during acquisition",
|
|
50168
|
+
source
|
|
50169
|
+
);
|
|
50170
|
+
}
|
|
50171
|
+
}
|
|
50172
|
+
function assertStableOpenedFile(before, after, bytesRead, source) {
|
|
50173
|
+
if (bytesRead > MAX_PLAN_ARTIFACT_BYTES) {
|
|
50174
|
+
throw new PlanArtifactServiceError(
|
|
50175
|
+
"PLAN_ARTIFACT_LIMIT_EXCEEDED",
|
|
50176
|
+
"The referenced integration plan exceeds the artifact byte limit",
|
|
50177
|
+
source
|
|
50178
|
+
);
|
|
50179
|
+
}
|
|
50180
|
+
if (!after.isFile() || after.nlink !== 1n || !sameObject(before, after) || before.size !== after.size || before.mtimeNs !== after.mtimeNs || before.ctimeNs !== after.ctimeNs || BigInt(bytesRead) !== before.size) {
|
|
50181
|
+
throw new PlanArtifactServiceError(
|
|
50182
|
+
"PLAN_FILESYSTEM_UNSAFE",
|
|
50183
|
+
"The integration plan changed while its bytes were being acquired",
|
|
50184
|
+
source
|
|
50185
|
+
);
|
|
50186
|
+
}
|
|
50187
|
+
}
|
|
50188
|
+
function assertStablePath(before, after, source) {
|
|
50189
|
+
if (before.length !== after.length || before.some((entry, index) => {
|
|
50190
|
+
const current = after[index];
|
|
50191
|
+
return !current || entry.leaf !== current.leaf || !sameObject(entry.stats, current.stats) || entry.leaf && (entry.stats.size !== current.stats.size || entry.stats.mtimeNs !== current.stats.mtimeNs || entry.stats.ctimeNs !== current.stats.ctimeNs || current.stats.nlink !== 1n);
|
|
50192
|
+
})) {
|
|
50193
|
+
throw new PlanArtifactServiceError(
|
|
50194
|
+
"PLAN_FILESYSTEM_UNSAFE",
|
|
50195
|
+
"The integration plan path changed while its bytes were being acquired",
|
|
50196
|
+
source
|
|
50197
|
+
);
|
|
50198
|
+
}
|
|
50199
|
+
}
|
|
50200
|
+
function sameObject(left, right) {
|
|
50201
|
+
return left.dev === right.dev && left.ino === right.ino && left.mode === right.mode;
|
|
50202
|
+
}
|
|
50203
|
+
function readAtMost(descriptor, maximumBytes) {
|
|
50204
|
+
const buffer = Buffer.allocUnsafe(maximumBytes);
|
|
50205
|
+
let offset = 0;
|
|
50206
|
+
while (offset < maximumBytes) {
|
|
50207
|
+
const count = fs48.readSync(descriptor, buffer, offset, maximumBytes - offset, null);
|
|
50208
|
+
if (count === 0) break;
|
|
50209
|
+
offset += count;
|
|
50210
|
+
}
|
|
50211
|
+
return buffer.subarray(0, offset);
|
|
50212
|
+
}
|
|
50213
|
+
function importError(error, source) {
|
|
50214
|
+
const code = error?.code;
|
|
50215
|
+
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
50216
|
+
return new PlanArtifactServiceError(
|
|
50217
|
+
"PLAN_NOT_FOUND",
|
|
50218
|
+
"The referenced integration plan does not exist",
|
|
50219
|
+
source
|
|
50220
|
+
);
|
|
50221
|
+
}
|
|
50222
|
+
return new PlanArtifactServiceError(
|
|
50223
|
+
"PLAN_UNREADABLE",
|
|
50224
|
+
"The referenced integration plan could not be safely read",
|
|
50225
|
+
source
|
|
50226
|
+
);
|
|
50227
|
+
}
|
|
49708
50228
|
function assertBoundedArtifact(plan, source) {
|
|
49709
50229
|
const labels = [
|
|
49710
50230
|
plan.schemaVersion,
|
|
@@ -49719,11 +50239,277 @@ function assertBoundedArtifact(plan, source) {
|
|
|
49719
50239
|
);
|
|
49720
50240
|
}
|
|
49721
50241
|
}
|
|
49722
|
-
function
|
|
50242
|
+
function pathEntryExists(filePath) {
|
|
49723
50243
|
try {
|
|
49724
|
-
|
|
49725
|
-
|
|
49726
|
-
|
|
50244
|
+
fs48.lstatSync(filePath);
|
|
50245
|
+
return true;
|
|
50246
|
+
} catch (error) {
|
|
50247
|
+
const code = error?.code;
|
|
50248
|
+
if (code === "ENOENT" || code === "ENOTDIR") return false;
|
|
50249
|
+
return true;
|
|
50250
|
+
}
|
|
50251
|
+
}
|
|
50252
|
+
|
|
50253
|
+
// src/application/plan-artifact-registration-service.ts
|
|
50254
|
+
import * as fs49 from "fs";
|
|
50255
|
+
import * as path58 from "path";
|
|
50256
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
50257
|
+
var PlanArtifactRegistrationError = class extends Error {
|
|
50258
|
+
constructor(code, message) {
|
|
50259
|
+
super(message);
|
|
50260
|
+
this.code = code;
|
|
50261
|
+
this.name = "PlanArtifactRegistrationError";
|
|
50262
|
+
}
|
|
50263
|
+
};
|
|
50264
|
+
var _PlanArtifactRegistrationService_instances, verifyExisting_fn;
|
|
50265
|
+
var PlanArtifactRegistrationService = class {
|
|
50266
|
+
constructor() {
|
|
50267
|
+
__privateAdd(this, _PlanArtifactRegistrationService_instances);
|
|
50268
|
+
}
|
|
50269
|
+
register(input) {
|
|
50270
|
+
const parsed = ExecutionPlanArtifact_v1Schema.safeParse(input.artifact);
|
|
50271
|
+
if (!parsed.success) {
|
|
50272
|
+
throw new PlanArtifactRegistrationError(
|
|
50273
|
+
"PLAN_REGISTRATION_INVALID",
|
|
50274
|
+
"The plan artifact does not satisfy the immutable artifact contract"
|
|
50275
|
+
);
|
|
50276
|
+
}
|
|
50277
|
+
const artifact = parsed.data;
|
|
50278
|
+
const scope = parseScope2(input.scope);
|
|
50279
|
+
const storeDirectory = validateStoreReference(input.storeDirectory);
|
|
50280
|
+
prepareControlledStore(storeDirectory);
|
|
50281
|
+
const digestName = `${artifact.identity.digest.slice("sha256:".length)}.json`;
|
|
50282
|
+
const artifactPath = path58.join(storeDirectory, digestName);
|
|
50283
|
+
const reference = createRegisteredReference(artifact, artifactPath, scope);
|
|
50284
|
+
if (pathEntryExists2(artifactPath)) {
|
|
50285
|
+
return __privateMethod(this, _PlanArtifactRegistrationService_instances, verifyExisting_fn).call(this, artifact, reference, false);
|
|
50286
|
+
}
|
|
50287
|
+
const temporaryPath = path58.join(storeDirectory, `.plan-${randomUUID9()}.tmp`);
|
|
50288
|
+
let temporaryCreated = false;
|
|
50289
|
+
try {
|
|
50290
|
+
const descriptor = fs49.openSync(
|
|
50291
|
+
temporaryPath,
|
|
50292
|
+
fs49.constants.O_WRONLY | fs49.constants.O_CREAT | fs49.constants.O_EXCL,
|
|
50293
|
+
384
|
|
50294
|
+
);
|
|
50295
|
+
temporaryCreated = true;
|
|
50296
|
+
try {
|
|
50297
|
+
writeAll(descriptor, Buffer.from(artifact.canonicalBytes, "utf8"));
|
|
50298
|
+
fs49.fsyncSync(descriptor);
|
|
50299
|
+
} finally {
|
|
50300
|
+
fs49.closeSync(descriptor);
|
|
50301
|
+
}
|
|
50302
|
+
try {
|
|
50303
|
+
fs49.linkSync(temporaryPath, artifactPath);
|
|
50304
|
+
} catch (error) {
|
|
50305
|
+
if (!pathEntryExists2(artifactPath)) throw error;
|
|
50306
|
+
return __privateMethod(this, _PlanArtifactRegistrationService_instances, verifyExisting_fn).call(this, artifact, reference, false);
|
|
50307
|
+
}
|
|
50308
|
+
try {
|
|
50309
|
+
fs49.unlinkSync(temporaryPath);
|
|
50310
|
+
} catch (error) {
|
|
50311
|
+
if (error.code !== "ENOENT") throw error;
|
|
50312
|
+
}
|
|
50313
|
+
temporaryCreated = false;
|
|
50314
|
+
flushDirectoryWhenSupported(storeDirectory);
|
|
50315
|
+
assertStoreDirectory(storeDirectory);
|
|
50316
|
+
return __privateMethod(this, _PlanArtifactRegistrationService_instances, verifyExisting_fn).call(this, artifact, reference, true);
|
|
50317
|
+
} catch (error) {
|
|
50318
|
+
if (error instanceof PlanArtifactRegistrationError) throw error;
|
|
50319
|
+
throw new PlanArtifactRegistrationError(
|
|
50320
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50321
|
+
"The plan artifact could not be published without replacing existing bytes"
|
|
50322
|
+
);
|
|
50323
|
+
} finally {
|
|
50324
|
+
if (temporaryCreated) {
|
|
50325
|
+
try {
|
|
50326
|
+
fs49.unlinkSync(temporaryPath);
|
|
50327
|
+
} catch {
|
|
50328
|
+
}
|
|
50329
|
+
}
|
|
50330
|
+
}
|
|
50331
|
+
}
|
|
50332
|
+
};
|
|
50333
|
+
_PlanArtifactRegistrationService_instances = new WeakSet();
|
|
50334
|
+
verifyExisting_fn = function(artifact, reference, created) {
|
|
50335
|
+
try {
|
|
50336
|
+
waitForConcurrentPublisher(reference.retrieval.reference);
|
|
50337
|
+
const resolved = new PlanArtifactService().resolve({ planReference: reference });
|
|
50338
|
+
if (resolved.artifact.canonicalBytes !== artifact.canonicalBytes) {
|
|
50339
|
+
throw new PlanArtifactRegistrationError(
|
|
50340
|
+
"PLAN_REGISTRATION_CONFLICT",
|
|
50341
|
+
"The content-addressed plan object conflicts with the requested artifact"
|
|
50342
|
+
);
|
|
50343
|
+
}
|
|
50344
|
+
return {
|
|
50345
|
+
artifact: resolved.artifact,
|
|
50346
|
+
reference,
|
|
50347
|
+
created,
|
|
50348
|
+
storage: { assurance: "service-no-replace-verified", authority: "unverified" }
|
|
50349
|
+
};
|
|
50350
|
+
} catch (error) {
|
|
50351
|
+
if (error instanceof PlanArtifactRegistrationError) throw error;
|
|
50352
|
+
if (error instanceof PlanArtifactServiceError && error.code === "PLAN_REFERENCE_MISMATCH") {
|
|
50353
|
+
throw new PlanArtifactRegistrationError(
|
|
50354
|
+
"PLAN_REGISTRATION_CONFLICT",
|
|
50355
|
+
"The content-addressed plan object conflicts with the requested artifact"
|
|
50356
|
+
);
|
|
50357
|
+
}
|
|
50358
|
+
throw new PlanArtifactRegistrationError(
|
|
50359
|
+
"PLAN_REGISTRATION_VERIFY_FAILED",
|
|
50360
|
+
"The persisted plan artifact could not be reread and verified"
|
|
50361
|
+
);
|
|
50362
|
+
}
|
|
50363
|
+
};
|
|
50364
|
+
function createRegisteredReference(artifact, artifactPath, scope) {
|
|
50365
|
+
if (Buffer.byteLength(artifactPath, "utf8") > 4096) {
|
|
50366
|
+
throw new PlanArtifactRegistrationError(
|
|
50367
|
+
"PLAN_REGISTRATION_INVALID",
|
|
50368
|
+
"The artifact store cannot produce a bounded retrieval reference"
|
|
50369
|
+
);
|
|
50370
|
+
}
|
|
50371
|
+
const reference = {
|
|
50372
|
+
contract: PLAN_ARTIFACT_REFERENCE_CONTRACT,
|
|
50373
|
+
artifact: artifact.identity,
|
|
50374
|
+
expectedDigest: artifact.identity.digest,
|
|
50375
|
+
expectedCanonicalByteLength: artifact.identity.canonicalByteLength,
|
|
50376
|
+
retrieval: { kind: "registered", reference: artifactPath },
|
|
50377
|
+
...scope ? { scope } : {}
|
|
50378
|
+
};
|
|
50379
|
+
const parsed = PlanArtifactReference_v1Schema.safeParse(reference);
|
|
50380
|
+
if (!parsed.success) {
|
|
50381
|
+
throw new PlanArtifactRegistrationError(
|
|
50382
|
+
"PLAN_REGISTRATION_INVALID",
|
|
50383
|
+
"The registered artifact reference does not satisfy the bounded transport contract"
|
|
50384
|
+
);
|
|
50385
|
+
}
|
|
50386
|
+
return parsed.data;
|
|
50387
|
+
}
|
|
50388
|
+
function parseScope2(scope) {
|
|
50389
|
+
if (scope === void 0) return void 0;
|
|
50390
|
+
const parsed = PlanArtifactScope_v1Schema.safeParse(scope);
|
|
50391
|
+
if (!parsed.success) {
|
|
50392
|
+
throw new PlanArtifactRegistrationError(
|
|
50393
|
+
"PLAN_REGISTRATION_INVALID",
|
|
50394
|
+
"The plan scope does not satisfy the bounded transport contract"
|
|
50395
|
+
);
|
|
50396
|
+
}
|
|
50397
|
+
return parsed.data;
|
|
50398
|
+
}
|
|
50399
|
+
function validateStoreReference(reference) {
|
|
50400
|
+
if (reference.length === 0 || reference.includes("\0") || Buffer.byteLength(reference, "utf8") > 4096) {
|
|
50401
|
+
throw new PlanArtifactRegistrationError(
|
|
50402
|
+
"PLAN_REGISTRATION_INVALID",
|
|
50403
|
+
"The artifact store reference is invalid or exceeds its bound"
|
|
50404
|
+
);
|
|
50405
|
+
}
|
|
50406
|
+
return path58.resolve(reference);
|
|
50407
|
+
}
|
|
50408
|
+
function prepareControlledStore(storeDirectory) {
|
|
50409
|
+
const root = path58.parse(storeDirectory).root;
|
|
50410
|
+
const segments = path58.relative(root, storeDirectory).split(path58.sep).filter(Boolean);
|
|
50411
|
+
let current = root;
|
|
50412
|
+
for (const segment of segments) {
|
|
50413
|
+
current = path58.join(current, segment);
|
|
50414
|
+
try {
|
|
50415
|
+
const stats = fs49.lstatSync(current);
|
|
50416
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
50417
|
+
throw new PlanArtifactRegistrationError(
|
|
50418
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50419
|
+
"The artifact store contains an unsafe filesystem object"
|
|
50420
|
+
);
|
|
50421
|
+
}
|
|
50422
|
+
} catch (error) {
|
|
50423
|
+
if (error instanceof PlanArtifactRegistrationError) throw error;
|
|
50424
|
+
if (error.code !== "ENOENT") {
|
|
50425
|
+
throw new PlanArtifactRegistrationError(
|
|
50426
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50427
|
+
"The artifact store identity is unavailable"
|
|
50428
|
+
);
|
|
50429
|
+
}
|
|
50430
|
+
try {
|
|
50431
|
+
fs49.mkdirSync(current, { mode: 448 });
|
|
50432
|
+
} catch (mkdirError) {
|
|
50433
|
+
if (mkdirError.code !== "EEXIST") {
|
|
50434
|
+
throw new PlanArtifactRegistrationError(
|
|
50435
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50436
|
+
"The artifact store could not be prepared"
|
|
50437
|
+
);
|
|
50438
|
+
}
|
|
50439
|
+
}
|
|
50440
|
+
const created = fs49.lstatSync(current);
|
|
50441
|
+
if (created.isSymbolicLink() || !created.isDirectory()) {
|
|
50442
|
+
throw new PlanArtifactRegistrationError(
|
|
50443
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50444
|
+
"The artifact store contains an unsafe filesystem object"
|
|
50445
|
+
);
|
|
50446
|
+
}
|
|
50447
|
+
}
|
|
50448
|
+
}
|
|
50449
|
+
assertStoreDirectory(storeDirectory);
|
|
50450
|
+
}
|
|
50451
|
+
function assertStoreDirectory(storeDirectory) {
|
|
50452
|
+
const root = path58.parse(storeDirectory).root;
|
|
50453
|
+
const segments = path58.relative(root, storeDirectory).split(path58.sep).filter(Boolean);
|
|
50454
|
+
let current = root;
|
|
50455
|
+
for (const segment of segments) {
|
|
50456
|
+
current = path58.join(current, segment);
|
|
50457
|
+
let stats;
|
|
50458
|
+
try {
|
|
50459
|
+
stats = fs49.lstatSync(current);
|
|
50460
|
+
} catch {
|
|
50461
|
+
throw new PlanArtifactRegistrationError(
|
|
50462
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50463
|
+
"The artifact store identity is unavailable"
|
|
50464
|
+
);
|
|
50465
|
+
}
|
|
50466
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
50467
|
+
throw new PlanArtifactRegistrationError(
|
|
50468
|
+
"PLAN_REGISTRATION_UNSAFE",
|
|
50469
|
+
"The artifact store contains an unsafe filesystem object"
|
|
50470
|
+
);
|
|
50471
|
+
}
|
|
50472
|
+
}
|
|
50473
|
+
}
|
|
50474
|
+
function writeAll(descriptor, bytes) {
|
|
50475
|
+
let offset = 0;
|
|
50476
|
+
while (offset < bytes.length) {
|
|
50477
|
+
offset += fs49.writeSync(descriptor, bytes, offset, bytes.length - offset, null);
|
|
50478
|
+
}
|
|
50479
|
+
}
|
|
50480
|
+
function flushDirectoryWhenSupported(directory) {
|
|
50481
|
+
let descriptor;
|
|
50482
|
+
try {
|
|
50483
|
+
descriptor = fs49.openSync(directory, fs49.constants.O_RDONLY);
|
|
50484
|
+
fs49.fsyncSync(descriptor);
|
|
50485
|
+
} catch (error) {
|
|
50486
|
+
const code = error?.code;
|
|
50487
|
+
if (process.platform !== "win32" || code !== "EISDIR" && code !== "EPERM") throw error;
|
|
50488
|
+
} finally {
|
|
50489
|
+
if (descriptor !== void 0) fs49.closeSync(descriptor);
|
|
50490
|
+
}
|
|
50491
|
+
}
|
|
50492
|
+
function pathEntryExists2(filePath) {
|
|
50493
|
+
try {
|
|
50494
|
+
fs49.lstatSync(filePath);
|
|
50495
|
+
return true;
|
|
50496
|
+
} catch (error) {
|
|
50497
|
+
const code = error?.code;
|
|
50498
|
+
return code !== "ENOENT" && code !== "ENOTDIR";
|
|
50499
|
+
}
|
|
50500
|
+
}
|
|
50501
|
+
function waitForConcurrentPublisher(artifactPath) {
|
|
50502
|
+
const deadline = Date.now() + 500;
|
|
50503
|
+
const signal = new Int32Array(new SharedArrayBuffer(4));
|
|
50504
|
+
while (Date.now() < deadline) {
|
|
50505
|
+
let stats;
|
|
50506
|
+
try {
|
|
50507
|
+
stats = fs49.lstatSync(artifactPath);
|
|
50508
|
+
} catch {
|
|
50509
|
+
return;
|
|
50510
|
+
}
|
|
50511
|
+
if (!stats.isFile() || stats.isSymbolicLink() || stats.nlink <= 1) return;
|
|
50512
|
+
Atomics.wait(signal, 0, 0, 10);
|
|
49727
50513
|
}
|
|
49728
50514
|
}
|
|
49729
50515
|
|
|
@@ -50282,7 +51068,7 @@ workspaceCmd.command("init").description("Initialize lexrunner workspace with in
|
|
|
50282
51068
|
force: opts.force
|
|
50283
51069
|
});
|
|
50284
51070
|
if (isJsonMode) {
|
|
50285
|
-
const { writeSuccessEnvelope } = await import("./jsonEnvelope-
|
|
51071
|
+
const { writeSuccessEnvelope } = await import("./jsonEnvelope-MXJM5ZQH.js");
|
|
50286
51072
|
writeSuccessEnvelope("lex-pr workspace init", initialized);
|
|
50287
51073
|
} else {
|
|
50288
51074
|
console.log(
|
|
@@ -50302,7 +51088,7 @@ workspaceCmd.command("init").description("Initialize lexrunner workspace with in
|
|
|
50302
51088
|
policyTemplate: opts.policyTemplate
|
|
50303
51089
|
});
|
|
50304
51090
|
if (isJsonMode) {
|
|
50305
|
-
const { writeSuccessEnvelope, writeErrorEnvelope } = await import("./jsonEnvelope-
|
|
51091
|
+
const { writeSuccessEnvelope, writeErrorEnvelope } = await import("./jsonEnvelope-MXJM5ZQH.js");
|
|
50306
51092
|
if (result.success) {
|
|
50307
51093
|
writeSuccessEnvelope("lex-pr workspace init", {
|
|
50308
51094
|
profileDir: result.profileDir,
|
|
@@ -50330,7 +51116,7 @@ workspaceCmd.command("init").description("Initialize lexrunner workspace with in
|
|
|
50330
51116
|
throw error;
|
|
50331
51117
|
}
|
|
50332
51118
|
if (isJsonMode) {
|
|
50333
|
-
const { writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-
|
|
51119
|
+
const { writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-MXJM5ZQH.js");
|
|
50334
51120
|
if (error instanceof WorkspaceConfigServiceError) {
|
|
50335
51121
|
writeErrorEnvelope("lex-pr workspace init", {
|
|
50336
51122
|
code: error.code,
|
|
@@ -50427,7 +51213,7 @@ program.command("init").description("Initialize lexrunner workspace with interac
|
|
|
50427
51213
|
jsonMode: isJsonMode
|
|
50428
51214
|
});
|
|
50429
51215
|
if (isJsonMode) {
|
|
50430
|
-
const { writeSuccessEnvelope, writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-
|
|
51216
|
+
const { writeSuccessEnvelope, writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-MXJM5ZQH.js");
|
|
50431
51217
|
if (result.success) {
|
|
50432
51218
|
writeSuccessEnvelope("lex-pr init", {
|
|
50433
51219
|
profileDir: result.profileDir,
|
|
@@ -50455,7 +51241,7 @@ program.command("init").description("Initialize lexrunner workspace with interac
|
|
|
50455
51241
|
throw error;
|
|
50456
51242
|
}
|
|
50457
51243
|
if (isJsonMode) {
|
|
50458
|
-
const { writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-
|
|
51244
|
+
const { writeErrorEnvelope, errorToJsonError } = await import("./jsonEnvelope-MXJM5ZQH.js");
|
|
50459
51245
|
if (error instanceof WriteProtectionError) {
|
|
50460
51246
|
writeErrorEnvelope("lex-pr init", {
|
|
50461
51247
|
code: "EWRITE_PROTECTED",
|
|
@@ -50651,8 +51437,8 @@ program.command("view").description("Interactive plan viewer with navigation and
|
|
|
50651
51437
|
throwExit(1);
|
|
50652
51438
|
}
|
|
50653
51439
|
try {
|
|
50654
|
-
const { InteractivePlanViewer } = await import("./planViewer-
|
|
50655
|
-
const planContent =
|
|
51440
|
+
const { InteractivePlanViewer } = await import("./planViewer-WOV6A2HZ.js");
|
|
51441
|
+
const planContent = fs50.readFileSync(planFile, "utf-8");
|
|
50656
51442
|
const plan = loadPlan(planContent);
|
|
50657
51443
|
const viewer = new InteractivePlanViewer(plan, {
|
|
50658
51444
|
filter: opts.filter,
|
|
@@ -50668,7 +51454,7 @@ program.command("view").description("Interactive plan viewer with navigation and
|
|
|
50668
51454
|
program.command("deliverables:list").description("List all autopilot deliverables with metadata").option("--profile-dir <dir>", "Profile directory (default: .smartergpt)").option("--json", "Output JSON format").action(async (opts) => {
|
|
50669
51455
|
try {
|
|
50670
51456
|
const profile = resolveProfile(opts.profileDir);
|
|
50671
|
-
const { DeliverablesManager } = await import("./autopilot-
|
|
51457
|
+
const { DeliverablesManager } = await import("./autopilot-7PX6YG55.js");
|
|
50672
51458
|
const manager = new DeliverablesManager(profile.path);
|
|
50673
51459
|
const deliverables = await manager.listDeliverables();
|
|
50674
51460
|
if (opts.json) {
|
|
@@ -50694,7 +51480,7 @@ program.command("deliverables:list").description("List all autopilot deliverable
|
|
|
50694
51480
|
});
|
|
50695
51481
|
const latest = manager.getLatestPath();
|
|
50696
51482
|
if (latest) {
|
|
50697
|
-
console.log(`\u{1F4CD} Latest: ${
|
|
51483
|
+
console.log(`\u{1F4CD} Latest: ${path59.basename(latest)}`);
|
|
50698
51484
|
}
|
|
50699
51485
|
}
|
|
50700
51486
|
} catch (error) {
|
|
@@ -50707,7 +51493,7 @@ program.command("deliverables:list").description("List all autopilot deliverable
|
|
|
50707
51493
|
program.command("deliverables:cleanup").description("Clean up old deliverables based on retention policy").option("--profile-dir <dir>", "Profile directory (default: .smartergpt)").option("--max-age <days>", "Maximum age in days (deletes older deliverables)").option("--max-count <count>", "Maximum number of deliverables to keep").option("--keep-latest", "Always keep the latest deliverables (default: true)", true).option("--dry-run", "Preview cleanup without deleting").option("--json", "Output JSON format").action(async (opts) => {
|
|
50708
51494
|
try {
|
|
50709
51495
|
const profile = resolveProfile(opts.profileDir);
|
|
50710
|
-
const { DeliverablesManager } = await import("./autopilot-
|
|
51496
|
+
const { DeliverablesManager } = await import("./autopilot-7PX6YG55.js");
|
|
50711
51497
|
const manager = new DeliverablesManager(profile.path);
|
|
50712
51498
|
const policy = {
|
|
50713
51499
|
maxAge: opts.maxAge ? parseInt(opts.maxAge) : void 0,
|
|
@@ -50768,8 +51554,8 @@ program.command("deliverables:cleanup").description("Clean up old deliverables b
|
|
|
50768
51554
|
console.log(`Freed space: ${(result.freedSpace / 1024).toFixed(2)} KB`);
|
|
50769
51555
|
if (result.removed.length > 0) {
|
|
50770
51556
|
console.log("\nRemoved:");
|
|
50771
|
-
result.removed.forEach((
|
|
50772
|
-
console.log(` - ${
|
|
51557
|
+
result.removed.forEach((path60) => {
|
|
51558
|
+
console.log(` - ${path60}`);
|
|
50773
51559
|
});
|
|
50774
51560
|
}
|
|
50775
51561
|
}
|
|
@@ -50840,8 +51626,8 @@ var isDirectExec = (() => {
|
|
|
50840
51626
|
try {
|
|
50841
51627
|
if (typeof import.meta === "undefined") return false;
|
|
50842
51628
|
if (!process.argv[1] || !import.meta.url) return false;
|
|
50843
|
-
const invokedPath =
|
|
50844
|
-
const modulePath =
|
|
51629
|
+
const invokedPath = fs50.realpathSync(resolve15(process.argv[1]));
|
|
51630
|
+
const modulePath = fs50.realpathSync(fileURLToPath6(import.meta.url));
|
|
50845
51631
|
return invokedPath === modulePath;
|
|
50846
51632
|
} catch {
|
|
50847
51633
|
return false;
|
|
@@ -50911,11 +51697,17 @@ export {
|
|
|
50911
51697
|
ConfigurationQueryService,
|
|
50912
51698
|
ControllerLease_v1,
|
|
50913
51699
|
DiscoveryQueryService,
|
|
51700
|
+
EXECUTION_PLAN_ARTIFACT_CONTRACT,
|
|
51701
|
+
EXECUTION_PLAN_CANONICALIZATION_PROFILE,
|
|
51702
|
+
EXECUTION_PLAN_HASH_DOMAIN,
|
|
51703
|
+
EXECUTION_PLAN_HASH_PROFILE,
|
|
50914
51704
|
EngineVerificationCheckSource_v2,
|
|
50915
51705
|
EngineVerificationDeterminism_v2,
|
|
50916
51706
|
EngineVerificationTrustGapReason_v2,
|
|
50917
51707
|
ExecutionEnvelope_v1,
|
|
50918
51708
|
ExecutionEnvironmentOS,
|
|
51709
|
+
ExecutionPlanArtifactIdentity_v1Schema,
|
|
51710
|
+
ExecutionPlanArtifact_v1Schema,
|
|
50919
51711
|
ExecutionState,
|
|
50920
51712
|
ExternalAwaitOutcome_v1,
|
|
50921
51713
|
ExternalAwaitableDescriptor_v1,
|
|
@@ -50971,6 +51763,11 @@ export {
|
|
|
50971
51763
|
NativeWslProjectionSelection_v1,
|
|
50972
51764
|
NativeWslProjectionStatusRequestJsonSchema,
|
|
50973
51765
|
NativeWslSourceObservation_v1,
|
|
51766
|
+
PLAN_ARTIFACT_REFERENCE_CONTRACT,
|
|
51767
|
+
PlanArtifactReference_v1Schema,
|
|
51768
|
+
PlanArtifactRegistrationError,
|
|
51769
|
+
PlanArtifactRegistrationService,
|
|
51770
|
+
PlanArtifactScope_v1Schema,
|
|
50974
51771
|
PlanArtifactService,
|
|
50975
51772
|
PlanArtifactServiceError,
|
|
50976
51773
|
PlanCreationService,
|
|
@@ -51000,6 +51797,7 @@ export {
|
|
|
51000
51797
|
completionForAttemptAwaitable,
|
|
51001
51798
|
computeAgentEngineVerificationV2Hash,
|
|
51002
51799
|
computeAgentTaskPacketHash,
|
|
51800
|
+
computeExecutionPlanArtifactDigest,
|
|
51003
51801
|
computeFanInEvidenceSetHash,
|
|
51004
51802
|
computeMergeOrder,
|
|
51005
51803
|
containsAttemptAwaitableCredentialValue,
|