loki-mode 11.81.1 → 11.83.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/telemetry-schema.json +1 -1
- package/autonomy/telemetry.sh +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +1397 -1380
- package/loki-ts/package.json +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +818 -566
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-Vc1xmG5S.js → AdminPage-DpWNKWhs.js} +1 -1
- package/web-app/dist/assets/{Avatar-DpDwMCRf.js → Avatar-BjGfE5Z2.js} +1 -1
- package/web-app/dist/assets/{Badge-Db74zT9q.js → Badge-BZzQgc5L.js} +1 -1
- package/web-app/dist/assets/{Button-GehhhJSq.js → Button-B4UFBoKo.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BGdBtPaF.js → CockpitPage-HrjOxPcp.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DpnZuvk5.js → ComparePage-rDB52mbC.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DzEqEovi.js → ErrorBoundary-BnGTHBD5.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-Cw7HQjzr.js → EvidenceReceiptPanel-EWQ-AUvr.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-Cxpn_s6S.js → GitHubIssuesPanel-COCm9cnv.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-DCdf7lvR.js → GitHubPRsPanel-ZYNmFQAR.js} +1 -1
- package/web-app/dist/assets/{HomePage-DnVetpJ_.js → HomePage-CJXtxNhl.js} +2 -2
- package/web-app/dist/assets/{LoginPage-8VjdvfM3.js → LoginPage-CXG5HrnH.js} +1 -1
- package/web-app/dist/assets/{MagicPage-CP5dgazx.js → MagicPage-D_1k-qFR.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DOpoS7e3.js → MetricsPage-Bh2OOgQW.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-COzCrnS6.js → NotFoundPage-DYtJqd7q.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-DO4l10Ay.js → ProjectPage-C0_lqGnI.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C0tYUwpA.js → ProjectsPage-C3ZDOF-i.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CocOl0Br.js → SettingsPage-DNLBBiFb.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-D1JXy7Uh.js → ShowcasePage-jxMrHvDJ.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-J2oNgHg2.js → SystemSettingsPage-C2ZPx8uP.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-CcE2AFtg.js → TeamsPage-CmSWv2WS.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DYXxELhl.js → TemplatesPage-Cqcz3jC1.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DNQJnu5M.js → TerminalOutput-Cfy74R8E.js} +1 -1
- package/web-app/dist/assets/{activity-BZxgQZSK.js → activity-DvB2Cewz.js} +1 -1
- package/web-app/dist/assets/{bell-BgmfzWCz.js → bell-DFPKTgoZ.js} +1 -1
- package/web-app/dist/assets/{bot-BGir-bWC.js → bot-Bf5xNfiN.js} +1 -1
- package/web-app/dist/assets/{check-CveMRLRE.js → check-BdqIiGKJ.js} +1 -1
- package/web-app/dist/assets/{chevron-left-Dxd2H6to.js → chevron-left-Q2RMHGjD.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CBmik7wR.js → circle-alert-CSsLxjNX.js} +1 -1
- package/web-app/dist/assets/{clock-BOKNTHCd.js → clock-SUq-A-Pc.js} +1 -1
- package/web-app/dist/assets/{cloud-CQy11uYO.js → cloud-1Qu-bH4o.js} +1 -1
- package/web-app/dist/assets/{code-xml-G-3Gc_8h.js → code-xml-B8tVFMMA.js} +1 -1
- package/web-app/dist/assets/{database-DgDzuYJ_.js → database-BqqcDq2C.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-Lp9JyaRP.js → dollar-sign-D3Q2UCG0.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BO2cQzOV.js → file-code-corner-CRIBFOW5.js} +1 -1
- package/web-app/dist/assets/{file-plus-DH7lzils.js → file-plus-Bv-fZPBA.js} +1 -1
- package/web-app/dist/assets/{globe-BfSvGNE3.js → globe-C4B7SAB9.js} +1 -1
- package/web-app/dist/assets/{hammer-DnCBfcc3.js → hammer-y0Ikysax.js} +1 -1
- package/web-app/dist/assets/{index-BQo5YwJS.js → index-dNruR__0.js} +3 -3
- package/web-app/dist/assets/{layers-BrW-wRnL.js → layers-EgGWmhHw.js} +1 -1
- package/web-app/dist/assets/{loader-circle-BMGt1Kfa.js → loader-circle-Bt5dIF0I.js} +1 -1
- package/web-app/dist/assets/{lock-65KUUGOn.js → lock-BGuyekU7.js} +1 -1
- package/web-app/dist/assets/{package-BuhQfrbf.js → package-BkYbeAX3.js} +1 -1
- package/web-app/dist/assets/{plus-CCqniqNu.js → plus-BzcgCbLN.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CaTVoaT8.js → refresh-cw-Dm5Jp3fH.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-G73Ulpkj.js → rotate-ccw-BwCcLLQd.js} +1 -1
- package/web-app/dist/assets/{scroll-text-Bl6ByvVU.js → scroll-text-ZdYcnYoT.js} +1 -1
- package/web-app/dist/assets/{server-UW4cgj8y.js → server-BKLLV1vh.js} +1 -1
- package/web-app/dist/assets/{shield-alert-C0FwCrI5.js → shield-alert-BmdJ5RUP.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-ApOqvOwV.js → thumbs-up-BkgThloL.js} +1 -1
- package/web-app/dist/assets/{trash-2-BsQzJxqd.js → trash-2-CEGx8Si2.js} +1 -1
- package/web-app/dist/assets/{trending-down-mfvmwkOt.js → trending-down-bDEP2c-J.js} +1 -1
- package/web-app/dist/assets/{trending-up-DAE5_Gqc.js → trending-up-BTZtHq6z.js} +1 -1
- package/web-app/dist/assets/{upload-Ci5-pITX.js → upload-CU4BNteU.js} +1 -1
- package/web-app/dist/assets/{usePolling-DdLg3S71.js → usePolling-uzQ6JTcy.js} +1 -1
- package/web-app/dist/assets/{user-vdRHG5fO.js → user-Bz1t2qnf.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -258,7 +258,7 @@ var ASSIGNMENT, RULES, QUERY_SEGMENT, SECRET_PARAM, redactQuery = (s) => s.repla
|
|
|
258
258
|
if (!keep || !data || typeof data !== "object" || Array.isArray(data))
|
|
259
259
|
return redactDeep(data);
|
|
260
260
|
return Object.fromEntries(Object.entries(data).map(([k, v]) => typeof v === "string" && keep.get(k)?.test(v) ? [k, v] : [redactSecrets(k), redactDeep(v)]));
|
|
261
|
-
}, redactEnvelope = (e) => Object.fromEntries(Object.entries(e).map(([k, v]) => [redactSecrets(k), k === "data" ? redactEventData(e.type, v) : redactDeep(v)]));
|
|
261
|
+
}, redactEnvelope = (e) => Object.fromEntries(Object.entries(e).map(([k, v]) => [redactSecrets(k), k === "data" ? redactEventData(e.type, v) : redactDeep(v)])), UNSAFE_TERMINAL_CHARS_RE;
|
|
262
262
|
var init_redact = __esm(() => {
|
|
263
263
|
ASSIGNMENT = /((?<![A-Za-z0-9_.-])[_.-]*(?:[A-Za-z0-9]+[_.-]+)*(?:password|passwd|secret|token|api[_-]?key|apikey)["']?\s*[:=]\s*)((?:"(?!\[REDACTED)(?:\\.|[^"\\\n])+")|(?:'(?!\[REDACTED)(?:\\.|[^'\\\n])+')|(?!["']|\[REDACTED)[^\s"',;&]+)/gi;
|
|
264
264
|
RULES = [
|
|
@@ -300,6 +300,7 @@ var init_redact = __esm(() => {
|
|
|
300
300
|
["log.sealed", new Map([["kid", B64(43)], ["sig", B64(86)], ["events_sha256", HEX64]])],
|
|
301
301
|
["receipt.sealed", new Map([["kid", B64(43)], ["receipt_sha256", HEX64], ["events_sha256", HEX64]])]
|
|
302
302
|
]);
|
|
303
|
+
UNSAFE_TERMINAL_CHARS_RE = /[\x00-\x1f\x7f-\x9f\u00ad\u061c\u200b-\u200f\u2028-\u202e\u2060-\u2064\u2066-\u2069\ufeff]/g;
|
|
303
304
|
});
|
|
304
305
|
|
|
305
306
|
// ../../loki-ts/src/util/credential_env.ts
|
|
@@ -55777,6 +55778,7 @@ var init_test_file_text = __esm(() => {
|
|
|
55777
55778
|
var exports_testmap = {};
|
|
55778
55779
|
__export(exports_testmap, {
|
|
55779
55780
|
projectInterpreter: () => projectInterpreter,
|
|
55781
|
+
missingJavaTool: () => missingJavaTool,
|
|
55780
55782
|
isTestFile: () => isTestFile,
|
|
55781
55783
|
impactedRefs: () => impactedRefs,
|
|
55782
55784
|
harnessRunners: () => harnessRunners,
|
|
@@ -55796,6 +55798,10 @@ function pytestPython(root) {
|
|
|
55796
55798
|
}
|
|
55797
55799
|
return "python";
|
|
55798
55800
|
}
|
|
55801
|
+
function missingJavaTool(files, env = process.env, root) {
|
|
55802
|
+
const want = files.some((f) => /(?:^|\/)pom\.xml$/.test(f)) ? "maven" : files.some((f) => /(?:^|\/)(?:build|settings)\.gradle(?:\.kts)?$|(?:^|\/)gradlew$/.test(f)) ? "gradle" : files.some((f) => /\.java$/.test(f)) ? "javac" : null;
|
|
55803
|
+
return want && !javaToolOk(want, env, root) ? JAVA_TOOLS[want].tool : null;
|
|
55804
|
+
}
|
|
55799
55805
|
function guessRunner(fileName, runners, relPath) {
|
|
55800
55806
|
if (fileName.endsWith(".py"))
|
|
55801
55807
|
return runners.includes("unittest") && !runners.includes("pytest") ? "unittest" : "pytest";
|
|
@@ -55803,6 +55809,8 @@ function guessRunner(fileName, runners, relPath) {
|
|
|
55803
55809
|
return "go";
|
|
55804
55810
|
if (fileName.endsWith(".rs"))
|
|
55805
55811
|
return runners.includes("cargo") && relPath !== undefined && CARGO_TEST_FILE_RE.test(relPath) ? "cargo" : null;
|
|
55812
|
+
if (fileName.endsWith(".java"))
|
|
55813
|
+
return ["maven", "gradle", "javac"].find((r) => runners.includes(r)) ?? null;
|
|
55806
55814
|
return /\.[cm]?[jt]sx?$/.test(fileName) ? ["vitest", "jest", "bun", "node"].find((r) => runners.includes(r)) ?? null : null;
|
|
55807
55815
|
}
|
|
55808
55816
|
function projectInterpreter(root) {
|
|
@@ -55851,6 +55859,10 @@ function buildTestMap(root) {
|
|
|
55851
55859
|
mark("go", rel);
|
|
55852
55860
|
else if (name === "Cargo.toml")
|
|
55853
55861
|
mark("cargo", rel);
|
|
55862
|
+
else if (name === "pom.xml")
|
|
55863
|
+
mark("maven", rel);
|
|
55864
|
+
else if (/^(?:build|settings)\.gradle(?:\.kts)?$/.test(name) || name === "gradlew")
|
|
55865
|
+
mark("gradle", rel);
|
|
55854
55866
|
}
|
|
55855
55867
|
const jsRunner = evidence["vitest"] ? "vitest" : evidence["jest"] ? "jest" : evidence["bun"] ? "bun" : evidence["node"] ? "node" : null;
|
|
55856
55868
|
const tests = [];
|
|
@@ -55919,7 +55931,10 @@ class RealTestMapProvider {
|
|
|
55919
55931
|
return impactedRefs(map, changedFiles);
|
|
55920
55932
|
}
|
|
55921
55933
|
}
|
|
55922
|
-
var RUNNER_ORDER, COMMANDS, STDLIB_RUNNERS, FOREIGN_SOURCE_RE,
|
|
55934
|
+
var RUNNER_ORDER, COMMANDS, STDLIB_RUNNERS, FOREIGN_SOURCE_RE, JAVA_TOOLS, javaToolOk = (r, env, root) => {
|
|
55935
|
+
const t = JAVA_TOOLS[r];
|
|
55936
|
+
return !t || !!Bun.which(t.tool, { PATH: env.PATH ?? "" }) || !!t.wrapper && !!root && existsSync36(join53(root, t.wrapper));
|
|
55937
|
+
}, harnessRunners = (runners, files = [], env = process.env, root, focus2 = []) => pickHarnessRunners(runners, files, env, root, focus2).filter((r) => javaToolOk(r, env, root)), pickHarnessRunners = (runners, files, env, root, focus2) => {
|
|
55923
55938
|
const onPath = (tool) => !!Bun.which(tool, { PATH: env.PATH ?? "" }), w = languageBytes(root, files, (f) => STDLIB_RUNNERS.find((r) => r.ext.test(f))?.runner ?? (/\.[cm]?[jt]sx?$/i.test(f) ? "js" : FOREIGN_SOURCE_RE.test(f) ? "other" : null)), at2 = (k3) => w.get(k3) ?? 0, js = at2("js"), top = STDLIB_RUNNERS.reduce((a, r) => at2(r.runner) > at2(a.runner) ? r : a), bun = env.LOKI_WALL_HARNESS_RUNNER !== "0" && onPath("bun") ? ["bun"] : toolchainRunner(files, focus2);
|
|
55924
55939
|
const t = at2(top.runner), o = at2("other");
|
|
55925
55940
|
return runners.length > 0 ? runners : js >= t && js >= o ? js === 0 && w.size > 0 ? [] : bun : t > o ? onPath(top.tool) ? [top.runner] : toolchainRunner(files, focus2) : [];
|
|
@@ -55939,7 +55954,7 @@ var init_testmap = __esm(() => {
|
|
|
55939
55954
|
init_linguist();
|
|
55940
55955
|
init_scope();
|
|
55941
55956
|
init_test_file_text();
|
|
55942
|
-
RUNNER_ORDER = ["pytest", "vitest", "jest", "bun", "node", "npm", "go", "cargo"];
|
|
55957
|
+
RUNNER_ORDER = ["pytest", "vitest", "jest", "bun", "node", "npm", "go", "cargo", "maven", "gradle", "javac"];
|
|
55943
55958
|
COMMANDS = {
|
|
55944
55959
|
pytest: { cmd: "python -m pytest -q <files>", coarse: false },
|
|
55945
55960
|
unittest: { cmd: "python3 -m unittest <files>", coarse: false },
|
|
@@ -55949,11 +55964,15 @@ var init_testmap = __esm(() => {
|
|
|
55949
55964
|
node: { cmd: "node --test <files>", coarse: false },
|
|
55950
55965
|
npm: { cmd: "npm test --silent", coarse: true },
|
|
55951
55966
|
go: { cmd: "go test ./<pkg dirs>", coarse: false },
|
|
55952
|
-
cargo: { cmd: "cargo test", coarse: true }
|
|
55967
|
+
cargo: { cmd: "cargo test", coarse: true },
|
|
55968
|
+
maven: { cmd: "mvn test -Dtest=<class>", coarse: false },
|
|
55969
|
+
gradle: { cmd: "gradle cleanTest test --tests <class>", coarse: false },
|
|
55970
|
+
javac: { cmd: "javac + java <test class>", coarse: false }
|
|
55953
55971
|
};
|
|
55954
|
-
STDLIB_RUNNERS = [{ ext: /\.py$/, runner: "unittest", tool: "python3" }, { ext: /\.go$/, runner: "go", tool: "go" }, { ext: /\.rs$/, runner: "cargo", tool: "cargo" }];
|
|
55972
|
+
STDLIB_RUNNERS = [{ ext: /\.py$/, runner: "unittest", tool: "python3" }, { ext: /\.go$/, runner: "go", tool: "go" }, { ext: /\.rs$/, runner: "cargo", tool: "cargo" }, { ext: /\.java$/, runner: "javac", tool: "javac" }];
|
|
55955
55973
|
FOREIGN_SOURCE_RE = /\.(?:py|go|rs|java|kt|kts|scala|rb|php|cs|c|cc|cpp|cxx|h|hpp|swift|m|mm|ex|exs|erl|hs|clj|lua|pl|dart|r|jl|zig)$/i;
|
|
55956
|
-
|
|
55974
|
+
JAVA_TOOLS = { maven: { tool: "mvn", wrapper: "mvnw" }, gradle: { tool: "gradle", wrapper: "gradlew" }, javac: { tool: "javac" } };
|
|
55975
|
+
TOOLCHAINS = [[/(?:^|\/)package\.json$/, "node", /\.[cm]?[jt]sx?$/], [/(?:^|\/)go\.mod$/, "go", /\.go$/], [/(?:^|\/)Cargo\.toml$/, "cargo", /\.rs$/], [/(?:^|\/)pom\.xml$/, "maven", /\.java$/], [/(?:^|\/)(?:build|settings)\.gradle(?:\.kts)?$|(?:^|\/)gradlew$/, "gradle", /\.java$/], [/(?:^|\/)(?:pyproject\.toml|setup\.py|setup\.cfg|requirements(?:[-_.][\w.-]+)?\.txt|tox\.ini|pytest\.ini)$/, "pytest", /\.py$/]];
|
|
55957
55976
|
CARGO_TEST_FILE_RE = /(?:^|\/)tests\/[^/]+\.rs$/;
|
|
55958
55977
|
});
|
|
55959
55978
|
|
|
@@ -56129,6 +56148,50 @@ function skipped(raw2) {
|
|
|
56129
56148
|
return stripAnsi(raw2).split(`
|
|
56130
56149
|
`).filter((l) => /^(?:=+ )?\d+ \w+.* in [\d.]+s|^\s*Tests?:?\s+\d|^(?:#|\u2139) skipped \d/.test(l.trim())).reduce((t, l) => t + [...l.matchAll(/(\d+) (?:skipped|deselected|xfailed)|skipped (\d+)/g)].reduce((u10, m) => u10 + +(m[1] ?? m[2]), 0), 0);
|
|
56131
56150
|
}
|
|
56151
|
+
function javaSummary(raw2) {
|
|
56152
|
+
const ls2 = stripAnsi(raw2).split(`
|
|
56153
|
+
`).map((l) => l.trimEnd()), tail2 = ls2.filter((l) => l.trim()).slice(-40), ok2 = (re2) => {
|
|
56154
|
+
const m = tail2.map((l) => re2.exec(l)).filter(Boolean).pop();
|
|
56155
|
+
return m ? m[1] === "SUCCESS" || m[1] === "SUCCESSFUL" : null;
|
|
56156
|
+
};
|
|
56157
|
+
const wrap = ls2.filter((l) => l.trim()).slice(-1)[0]?.match(/^LOKI_JAVA_TESTS: (\d+) run, (\d+) failed$/);
|
|
56158
|
+
if (wrap) {
|
|
56159
|
+
const ids = ls2.flatMap((l) => l.match(/^FAIL (.+)$/)?.[1] ?? []), failed2 = +wrap[2];
|
|
56160
|
+
return +wrap[1] > 0 && ids.length === failed2 && ls2.filter((l) => /^(?:PASS|FAIL) /.test(l)).length === +wrap[1] ? { executed: +wrap[1], failed: failed2, ids } : null;
|
|
56161
|
+
}
|
|
56162
|
+
const mv2 = ok2(/^\[(?:INFO|ERROR)\] BUILD (SUCCESS|FAILURE)$/), gr2 = ok2(/^BUILD (SUCCESSFUL|FAILED)\b/);
|
|
56163
|
+
if (mv2 !== null) {
|
|
56164
|
+
let executed = 0, failed2 = 0, seen = false;
|
|
56165
|
+
ls2.forEach((l, i) => {
|
|
56166
|
+
if (/^\[(?:INFO|ERROR)\] Results:$/.test(l)) {
|
|
56167
|
+
const m = ls2.slice(i + 1, i + 40).map((x3) => /^\[(?:INFO|WARNING|ERROR)\] Tests run: (\d+), Failures: (\d+), Errors: (\d+), Skipped: (\d+)$/.exec(x3)).find(Boolean);
|
|
56168
|
+
if (m) {
|
|
56169
|
+
seen = true;
|
|
56170
|
+
executed += +m[1] - +m[4];
|
|
56171
|
+
failed2 += +m[2] + +m[3];
|
|
56172
|
+
}
|
|
56173
|
+
}
|
|
56174
|
+
});
|
|
56175
|
+
const ids = [...new Set(ls2.flatMap((l) => {
|
|
56176
|
+
const m = /^\[ERROR\] (?:(\S+)\(([\w.$]+)\)|([\w.$]+\.[\w$]+)(?:\[[^\]]*\])?) .*<<< (?:FAILURE|ERROR)!$/.exec(l);
|
|
56177
|
+
return m ? [m[3] ?? `${m[2]}.${m[1]}`] : [];
|
|
56178
|
+
}))];
|
|
56179
|
+
return seen && executed > 0 && (mv2 ? failed2 === 0 : failed2 > 0) ? { executed, failed: failed2, ids } : null;
|
|
56180
|
+
}
|
|
56181
|
+
if (gr2 !== null) {
|
|
56182
|
+
const ev2 = ls2.flatMap((l) => {
|
|
56183
|
+
const m = /^\s*(\S.*?) > (\S.*?) (PASSED|FAILED|SKIPPED)$/.exec(l);
|
|
56184
|
+
return m ? [{ id: `${m[1]}.${m[2]}`, s: m[3] }] : [];
|
|
56185
|
+
}), bad = ev2.filter((e10) => e10.s === "FAILED");
|
|
56186
|
+
const executed = ev2.filter((e10) => e10.s !== "SKIPPED").length;
|
|
56187
|
+
return executed > 0 && (gr2 ? bad.length === 0 : bad.length > 0) ? { executed, failed: bad.length, ids: [...new Set(bad.map((e10) => e10.id))] } : null;
|
|
56188
|
+
}
|
|
56189
|
+
return null;
|
|
56190
|
+
}
|
|
56191
|
+
function javaTestClass(path) {
|
|
56192
|
+
const m = /^(.*?)\/?src\/test\/java\/(.+)\.java$/.exec(path), cls = (m ? m[2] : basename12(path, ".java")).split("/").join(".");
|
|
56193
|
+
return { root: m?.[1] || ".", cls, rel: m ? `src/test/java/${m[2]}.java` : path };
|
|
56194
|
+
}
|
|
56132
56195
|
function testCount(raw2, path, ok2) {
|
|
56133
56196
|
const out3 = stripAnsi(raw2);
|
|
56134
56197
|
const bu2 = bunCount(out3), ut = unittestCount(out3, ok2);
|
|
@@ -56136,6 +56199,9 @@ function testCount(raw2, path, ok2) {
|
|
|
56136
56199
|
return bu2;
|
|
56137
56200
|
if (ut !== null)
|
|
56138
56201
|
return ut;
|
|
56202
|
+
const jv = javaSummary(out3);
|
|
56203
|
+
if (jv)
|
|
56204
|
+
return jv.executed;
|
|
56139
56205
|
if (/^\s*(?:Test Files\s+0\b|No test files found)/m.test(out3) && !/^\s*Tests?\s+\d/m.test(out3))
|
|
56140
56206
|
return 0;
|
|
56141
56207
|
const r = ran(out3, path, ok2);
|
|
@@ -56202,6 +56268,9 @@ function classifyCheck(i) {
|
|
|
56202
56268
|
return { result: "fail", ...n10 !== null ? { n: n10 } : {} };
|
|
56203
56269
|
if (n10 === null)
|
|
56204
56270
|
return { result: "not_run", reason: UNMEASURED_REASON };
|
|
56271
|
+
const jv = javaSummary(text3);
|
|
56272
|
+
if (jv && jv.failed > 0)
|
|
56273
|
+
return { result: "fail", n: n10 };
|
|
56205
56274
|
return { result: "pass", n: n10 };
|
|
56206
56275
|
}
|
|
56207
56276
|
function checkProvenance(name, ctx) {
|
|
@@ -56715,6 +56784,10 @@ function classify(f, status, output, repoDir, interpreter) {
|
|
|
56715
56784
|
return status === 1 ? pytestExit1IsRed(output) ? "fail" : "not_run" : status === 2 ? pytestCollectionIsRed(output, repoDir) ? "fail" : "not_run" : "not_run";
|
|
56716
56785
|
if (f.runner === "jest" || f.runner === "vitest" || f.runner === "bun")
|
|
56717
56786
|
return parsedFailCount(f.runner, output) > 0 ? "fail" : "not_run";
|
|
56787
|
+
if (f.runner === "maven" || f.runner === "gradle" || f.runner === "javac") {
|
|
56788
|
+
const j10 = javaSummary(output);
|
|
56789
|
+
return j10 && j10.failed > 0 ? "fail" : "not_run";
|
|
56790
|
+
}
|
|
56718
56791
|
return f.runner === "node" && nodeIsRed(f, output) ? "fail" : "not_run";
|
|
56719
56792
|
}
|
|
56720
56793
|
function baseJobs() {
|
|
@@ -56809,11 +56882,27 @@ function runnerCmd(t, repoDir) {
|
|
|
56809
56882
|
const names = goTestNames(join54(repoDir, t.path));
|
|
56810
56883
|
return ["go", ["test", "-json", ...names.length ? ["-run", `^(${names.join("|")})$`] : [], `./${dirname23(t.path)}`]];
|
|
56811
56884
|
}
|
|
56885
|
+
case "maven": {
|
|
56886
|
+
const j10 = javaTestClass(t.path);
|
|
56887
|
+
return [wrapperOr(repoDir, "mvnw", "mvn"), ["-B", "test", `-Dtest=${j10.cls.split(".").pop()}`, "-Dsurefire.failIfNoSpecifiedTests=false", "-DfailIfNoTests=false"]];
|
|
56888
|
+
}
|
|
56889
|
+
case "gradle": {
|
|
56890
|
+
const j10 = javaTestClass(t.path);
|
|
56891
|
+
return [wrapperOr(repoDir, "gradlew", "gradle"), ["cleanTest", "test", "--tests", j10.cls, "-i", "--console=plain"]];
|
|
56892
|
+
}
|
|
56893
|
+
case "javac": {
|
|
56894
|
+
const j10 = javaTestClass(t.path);
|
|
56895
|
+
return ["bash", ["-c", JAVAC_WRAPPER, "loki-javac", j10.root, j10.cls, j10.rel]];
|
|
56896
|
+
}
|
|
56812
56897
|
case "cargo":
|
|
56813
56898
|
return CARGO_TEST_FILE_RE.test(t.path) ? ["cargo", ["test", "--test", basename12(t.path, ".rs")]] : ["cargo", ["test"]];
|
|
56814
56899
|
}
|
|
56815
56900
|
}
|
|
56816
56901
|
function fullSuiteCmd(runner, repoDir) {
|
|
56902
|
+
if (runner === "maven" || runner === "gradle") {
|
|
56903
|
+
const s = FULL_SUITE_STATIC[runner];
|
|
56904
|
+
return { ...s, cmd: wrapperOr(repoDir, runner === "maven" ? "mvnw" : "gradlew", s.cmd) };
|
|
56905
|
+
}
|
|
56817
56906
|
if (runner !== "pytest" && runner !== "unittest")
|
|
56818
56907
|
return FULL_SUITE_STATIC[runner];
|
|
56819
56908
|
const [cmd, interpreter, pre2] = resolveTool(repoDir, "python", "python3", "python");
|
|
@@ -56896,7 +56985,23 @@ function firstFileLineAnchor(desc2) {
|
|
|
56896
56985
|
}
|
|
56897
56986
|
var NO_TESTS_REASON = "no tests executed", NO_RUNNER_REASON = "no runner of this repo runs this file", harnessSkipCode = (env = process.env) => env.LOKI_WALL_HARNESS_RUNNER === "0" ? "harness_runner_disabled" : Bun.which("bun", { PATH: env.PATH ?? "" }) ? "no_toolchain" : "bun_not_on_path", GO_EXIT0_REASON = "test count could not be confirmed: go test output is produced by the code under test and cannot confirm execution (a Go exit 0 is never a pass)", UNCONFIRMED_REASON = "test count could not be confirmed", FAIL_EVIDENCE, GO_FAIL_EVIDENCE, UNMEASURED_REASON = "executed count unmeasured (Loki could not parse the runner summary, harness-owned)", stripAnsi = (s) => s.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, "").replace(/(?:\u001b\[|\u009b)[0-9;?]*[ -\/]*[@-~]/g, "").replace(/\r\n?/g, `
|
|
56898
56987
|
`), tailLines = (out3) => out3.split(`
|
|
56899
|
-
`).filter((x3) => x3.trim()).slice(-12), GO_PKG_RE,
|
|
56988
|
+
`).filter((x3) => x3.trim()).slice(-12), GO_PKG_RE, JAVAC_WRAPPER = `set -u
|
|
56989
|
+
root="$1"; cls="$2"; shift 2; cd "$root" || exit 70
|
|
56990
|
+
if [ "$cls" = "-" ]; then
|
|
56991
|
+
set -- $(find src/test/java -name '*Test.java' 2>/dev/null | sort); cls=""
|
|
56992
|
+
for f in "$@"; do c="\${f#src/test/java/}"; c="\${c%.java}"; cls="$cls \${c//\\//.}"; done
|
|
56993
|
+
fi
|
|
56994
|
+
out="$(mktemp -d "\${TMPDIR:-/tmp}/loki-javac.XXXXXX")" || exit 70
|
|
56995
|
+
trap 'rm -rf -- "\${out:?}"' EXIT
|
|
56996
|
+
find src/main/java -name '*.java' 2>/dev/null > "$out/srcs"
|
|
56997
|
+
javac -nowarn -d "$out" @"$out/srcs" "$@" || exit 1
|
|
56998
|
+
st=0; : > "$out/run.log"
|
|
56999
|
+
for c in $cls; do java -cp "$out" "$c" >> "$out/run.log" 2>&1 || st=$?; done
|
|
57000
|
+
cat "$out/run.log"
|
|
57001
|
+
p=$(grep -c '^PASS ' "$out/run.log"); f=$(grep -c '^FAIL ' "$out/run.log")
|
|
57002
|
+
echo "LOKI_JAVA_TESTS: $((p + f)) run, $f failed"
|
|
57003
|
+
[ "$f" -gt 0 ] && st=1
|
|
57004
|
+
exit $st`, wrapperOr = (repoDir, w, bare) => existsSync37(join54(repoDir, w)) ? `./${w}` : bare, EXIT_CODED_COUNT = "n/a (exit-coded check, not a test runner)", FRAMEWORK_RE, SCRIPT_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, normPath = (p) => p.replace(/^(?:\.\/)+/, ""), hasExogenousProof = (checks, ctx) => checks.some((c) => isExecutedProof(c) && ((p) => p !== "agent_authored" && p !== "llm_judge")(checkProvenance(c.name ?? "", ctx))), CODE_FILE_EXT, DECL_RE, VAR_DECL_RE, stripComments = (src) => src.replace(/\/\*[\s\S]*?\*\//g, " ").split(`
|
|
56900
57005
|
`).map((l) => /^\s*\*/.test(l) ? "" : l.replace(/\/\/.*$/, "").replace(/(^|\s)#.*$/, "$1")).join(`
|
|
56901
57006
|
`), GO_METHOD_RE, METHOD_RE, NOT_A_NAME, declNames = (line2) => {
|
|
56902
57007
|
const out3 = [];
|
|
@@ -56911,7 +57016,7 @@ var NO_TESTS_REASON = "no tests executed", NO_RUNNER_REASON = "no runner of this
|
|
|
56911
57016
|
if (m)
|
|
56912
57017
|
out3.push(m[1]);
|
|
56913
57018
|
return out3.filter((n10) => !NOT_A_NAME.has(n10));
|
|
56914
|
-
}, printable = (s) => s.replace(
|
|
57019
|
+
}, printable = (s) => s.replace(UNSAFE_TERMINAL_CHARS_RE, "?"), SENSITIVE, API, TEST_CFG, RANK3, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, REVIEWER_ITEM = "one reviewer", PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), DEEP_ITEMS, NOT_SELECTED = "not selected by risk tier: ", MANIFEST_LOCKS, dirOf = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "", PKG_DEP_KEYS, PYPROJECT_NONDEP, SEM_RULES, DOC_FILE, readOr = (p) => {
|
|
56915
57020
|
try {
|
|
56916
57021
|
return readFileSync49(p, "utf8");
|
|
56917
57022
|
} catch {
|
|
@@ -56990,7 +57095,10 @@ var init_check_result = __esm(() => {
|
|
|
56990
57095
|
node: { cmd: "node", args: ["--test"] },
|
|
56991
57096
|
npm: { cmd: "npm", args: ["test", "--silent"] },
|
|
56992
57097
|
go: { cmd: "go", args: ["test", "-json", "./..."] },
|
|
56993
|
-
cargo: { cmd: "cargo", args: ["test"] }
|
|
57098
|
+
cargo: { cmd: "cargo", args: ["test"] },
|
|
57099
|
+
maven: { cmd: "mvn", args: ["-B", "test"] },
|
|
57100
|
+
gradle: { cmd: "gradle", args: ["cleanTest", "test", "-i", "--console=plain"] },
|
|
57101
|
+
javac: { cmd: "bash", args: ["-c", JAVAC_WRAPPER, "loki-javac", ".", "-"] }
|
|
56994
57102
|
};
|
|
56995
57103
|
URL_RE = /\b[a-z][a-z0-9+.-]{0,63}:\/\/\S+/gi;
|
|
56996
57104
|
ANCHOR_RE = /(?<![\w./@-])([\w./@-]{1,512})[`'"]?(?::L?|#L|\s*\(line\s+)([1-9]\d*)(?!\d)/g;
|
|
@@ -59186,6 +59294,9 @@ function failIds(raw2) {
|
|
|
59186
59294
|
const output = stripAnsi(raw2), gc2 = goCargoIds(output);
|
|
59187
59295
|
if (gc2)
|
|
59188
59296
|
return gc2;
|
|
59297
|
+
const jv = javaSummary(output);
|
|
59298
|
+
if (jv)
|
|
59299
|
+
return jv.failed > 0 && jv.ids.length >= jv.failed ? jv.ids : [];
|
|
59189
59300
|
const ids = [...new Set(output.split(`
|
|
59190
59301
|
`).map((l) => ID_LINE.exec(l.trim())).flatMap((m) => m ? [(m.slice(1).find(Boolean) ?? "").trim()] : []).filter(Boolean))];
|
|
59191
59302
|
const c = failCount(output);
|
|
@@ -64503,7 +64614,10 @@ class TestName(unittest.TestCase):
|
|
|
64503
64614
|
def test_it(self): self.assertEqual(fn(1), 2)
|
|
64504
64615
|
Run: python3 -m unittest <file>.`,
|
|
64505
64616
|
go: `${COMMANDS.go.cmd.replace(" ./<pkg dirs>", "")}. Write a _test.go file in the package under test. Example: func TestName(t *testing.T) { if got := Fn(1); got != 2 { t.Fatalf("got %v", got) } } Run: ${COMMANDS.go.cmd.replace("<pkg dirs>", "<dir>")}.`,
|
|
64506
|
-
cargo: `${COMMANDS.cargo.cmd}. Write an integration test file directly under tests/ that calls the crate's public API. Example: #[test] fn name() { assert_eq!(my_crate::f(1), 2); } Run: ${COMMANDS.cargo.cmd} --test <stem
|
|
64617
|
+
cargo: `${COMMANDS.cargo.cmd}. Write an integration test file directly under tests/ that calls the crate's public API. Example: #[test] fn name() { assert_eq!(my_crate::f(1), 2); } Run: ${COMMANDS.cargo.cmd} --test <stem>.`,
|
|
64618
|
+
maven: `Maven + JUnit (use the JUnit version already declared in the build file). Put the file in src/test/java/ (add a package line only if the code under test is in a package). The file name must end in Test.java and the public class name must equal the file name without .java, so surefire picks it up. Example: import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class loki_wall_LeapTest { @Test void leap() { assertTrue(Leap.is(2000)); } } Run: ${COMMANDS.maven.cmd.replace("<class>", "<ClassName>")}.`,
|
|
64619
|
+
gradle: `Gradle + JUnit (use the JUnit version already declared in the build file). Put the file in src/test/java/. The public class name must equal the file name without .java and the file name must end in Test.java. Example: import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class loki_wall_LeapTest { @Test void leap() { assertTrue(Leap.is(2000)); } } Run: ${COMMANDS.gradle.cmd.replace("<class>", "<ClassName>")}.`,
|
|
64620
|
+
javac: 'Plain Java 8+ with NO test framework and NO build tool (do not import org.junit). Put the file in src/test/java/. The file name must end in Test.java and the public class name must equal the file name without .java. The class has public static void main. For every check print exactly one line, `PASS <name>` or `FAIL <name>` (name on the same line), and at the end System.exit(1) if any check failed. Catch exceptions per check so one failure does not hide the rest. Example: static void check(String n, boolean ok) { System.out.println((ok ? "PASS " : "FAIL ") + n); if (!ok) failed = true; } Run: javac the sources under src/main/java plus the file, then java <ClassName>.'
|
|
64507
64621
|
};
|
|
64508
64622
|
});
|
|
64509
64623
|
|
|
@@ -65318,27 +65432,102 @@ var init_select = __esm(() => {
|
|
|
65318
65432
|
RANK_LABELS = ["wallPasses", "deterministicFails", "passesInS", "flakyInS", "lintFails", "diffLines", "index"];
|
|
65319
65433
|
});
|
|
65320
65434
|
|
|
65435
|
+
// ../../loki-ts/src/features/dependents.ts
|
|
65436
|
+
import { readFileSync as readFileSync73 } from "fs";
|
|
65437
|
+
import { dirname as dirname33, join as join82, normalize as normalize5 } from "path";
|
|
65438
|
+
function importTargets(rel, text3) {
|
|
65439
|
+
const out3 = [], dir = dirname33(rel);
|
|
65440
|
+
if (JS2.test(rel))
|
|
65441
|
+
for (const m of text3.matchAll(JS_SPEC_RE)) {
|
|
65442
|
+
const spec = m[1] ?? "";
|
|
65443
|
+
if (!spec.startsWith("."))
|
|
65444
|
+
continue;
|
|
65445
|
+
const p = posix3(join82(dir, spec)), stem = p.replace(/\.[cm]?[jt]sx?$/, "");
|
|
65446
|
+
out3.push(p, ...JS_EXT2.flatMap((e10) => [stem + e10, `${p}/index${e10}`]));
|
|
65447
|
+
}
|
|
65448
|
+
else if (PY3.test(rel)) {
|
|
65449
|
+
const add3 = (dots, mod, names) => {
|
|
65450
|
+
const up2 = dots > 0 ? join82(dir, ...Array(dots - 1).fill("..")) : "", roots = dots > 0 ? [up2] : [".", dir], path = mod.split(".").filter(Boolean).join("/");
|
|
65451
|
+
for (const r of roots) {
|
|
65452
|
+
const b = join82(r, path);
|
|
65453
|
+
if (path)
|
|
65454
|
+
out3.push(...pyMod(posix3(b)).map(posix3));
|
|
65455
|
+
for (const n10 of names)
|
|
65456
|
+
out3.push(...pyMod(posix3(join82(b, n10))));
|
|
65457
|
+
}
|
|
65458
|
+
};
|
|
65459
|
+
for (const m of text3.matchAll(PY_FROM)) {
|
|
65460
|
+
const dots = /^\.*/.exec(m[1])[0].length;
|
|
65461
|
+
add3(dots, m[1].slice(dots), m[2].replace(/[()]/g, "").split(",").map((s) => s.trim().split(/\s+as\s+/)[0]).filter((s) => /^\w+$/.test(s)));
|
|
65462
|
+
}
|
|
65463
|
+
for (const m of text3.matchAll(PY_IMP))
|
|
65464
|
+
for (const part of m[1].split(","))
|
|
65465
|
+
add3(0, part.trim().split(/\s+as\s+/)[0], []);
|
|
65466
|
+
}
|
|
65467
|
+
return out3;
|
|
65468
|
+
}
|
|
65469
|
+
function dependentTests(repoDir, map, changed, already) {
|
|
65470
|
+
const chg = new Set(changed.map(posix3).filter((f) => JS2.test(f) || PY3.test(f))), none = { tests: [], dropped: 0, truncated: false };
|
|
65471
|
+
if (chg.size === 0)
|
|
65472
|
+
return none;
|
|
65473
|
+
const isTest = new Set(map.tests.map((t) => t.path)), have = new Set(already.map((t) => t.path)), t02 = Date.now();
|
|
65474
|
+
let bytes = 0, truncated = false;
|
|
65475
|
+
const deps = new Set;
|
|
65476
|
+
for (const rel of listProjectFiles(repoDir)) {
|
|
65477
|
+
if (!(JS2.test(rel) || PY3.test(rel)) || isTest.has(rel) || chg.has(rel))
|
|
65478
|
+
continue;
|
|
65479
|
+
if (bytes > SCAN_MAX_BYTES || Date.now() - t02 > SCAN_MAX_MS) {
|
|
65480
|
+
truncated = true;
|
|
65481
|
+
break;
|
|
65482
|
+
}
|
|
65483
|
+
const text3 = read2(repoDir, rel);
|
|
65484
|
+
bytes += text3.length;
|
|
65485
|
+
if (importsAny(text3, rel, chg))
|
|
65486
|
+
deps.add(rel);
|
|
65487
|
+
}
|
|
65488
|
+
if (deps.size === 0)
|
|
65489
|
+
return { ...none, truncated };
|
|
65490
|
+
const all = map.tests.filter((t) => !have.has(t.path) && importsAny(read2(repoDir, t.path), t.path, deps)).sort((a, b) => a.path.localeCompare(b.path));
|
|
65491
|
+
return { tests: all.slice(0, MAX_DEPENDENT_TESTS), dropped: Math.max(0, all.length - MAX_DEPENDENT_TESTS), truncated };
|
|
65492
|
+
}
|
|
65493
|
+
var MAX_DEPENDENT_TESTS = 20, SCAN_MAX_BYTES = 48000000, SCAN_MAX_MS = 4000, FILE_MAX_BYTES = 256000, JS2, PY3, JS_EXT2, PY_FROM, PY_IMP, posix3 = (p) => normalize5(p).split("\\").join("/").replace(/^\.\//, ""), pyMod = (base) => [`${base}.py`, `${base}/__init__.py`], read2 = (repoDir, rel) => {
|
|
65494
|
+
try {
|
|
65495
|
+
return readFileSync73(join82(repoDir, rel), "utf8").slice(0, FILE_MAX_BYTES);
|
|
65496
|
+
} catch {
|
|
65497
|
+
return "";
|
|
65498
|
+
}
|
|
65499
|
+
}, importsAny = (text3, rel, set) => importTargets(rel, text3).some((t) => set.has(t)), dependentNotes = (d) => [...d.truncated ? ["reverse-dependent scan hit its byte or time bound: some importers of changed files may not have been tested"] : [], ...d.dropped ? [`reverse-dependent tests dropped by the ${MAX_DEPENDENT_TESTS}-file cap: ${d.dropped}`] : []];
|
|
65500
|
+
var init_dependents = __esm(() => {
|
|
65501
|
+
init_safe_git();
|
|
65502
|
+
init_test_file_text();
|
|
65503
|
+
JS2 = /\.(?:[cm]?[jt]sx?)$/;
|
|
65504
|
+
PY3 = /\.py$/;
|
|
65505
|
+
JS_EXT2 = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
65506
|
+
PY_FROM = /^[ \t]*from[ \t]+(\.*[\w.]*)[ \t]+import[ \t]+(\([^)]*\)|[^\n#]+)/gm;
|
|
65507
|
+
PY_IMP = /^[ \t]*import[ \t]+([\w., \t]+)/gm;
|
|
65508
|
+
});
|
|
65509
|
+
|
|
65321
65510
|
// ../../loki-ts/src/util/app_probe.ts
|
|
65322
65511
|
import { spawnSync as spawnSync9 } from "child_process";
|
|
65323
|
-
import { existsSync as existsSync56, mkdirSync as mkdirSync40, readFileSync as
|
|
65324
|
-
import { join as
|
|
65512
|
+
import { existsSync as existsSync56, mkdirSync as mkdirSync40, readFileSync as readFileSync74, renameSync as renameSync18, writeFileSync as writeFileSync38 } from "fs";
|
|
65513
|
+
import { join as join83 } from "path";
|
|
65325
65514
|
function readJson5(p) {
|
|
65326
65515
|
try {
|
|
65327
|
-
const v3 = JSON.parse(
|
|
65516
|
+
const v3 = JSON.parse(readFileSync74(p, "utf8"));
|
|
65328
65517
|
return v3 && typeof v3 === "object" ? v3 : null;
|
|
65329
65518
|
} catch {
|
|
65330
65519
|
return null;
|
|
65331
65520
|
}
|
|
65332
65521
|
}
|
|
65333
65522
|
function stopApp(repoDir, opts = {}) {
|
|
65334
|
-
const runner = opts.runnerPath ??
|
|
65335
|
-
if (!existsSync56(runner) || !existsSync56(
|
|
65523
|
+
const runner = opts.runnerPath ?? join83(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
65524
|
+
if (!existsSync56(runner) || !existsSync56(join83(repoDir, ".loki", "app-runner", "app.pid")))
|
|
65336
65525
|
return;
|
|
65337
65526
|
spawnSync9("bash", ["-c", STOP, "app-probe", repoDir, runner], { cwd: repoDir, env: plainTestEnv(), timeout: opts.timeoutMs ?? 60000, killSignal: "SIGKILL", stdio: "ignore" });
|
|
65338
65527
|
}
|
|
65339
65528
|
async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
65340
|
-
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ??
|
|
65341
|
-
const dir =
|
|
65529
|
+
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ?? join83(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
65530
|
+
const dir = join83(repoDir, ".loki", "app-runner"), checks = [];
|
|
65342
65531
|
const t02 = Date.now();
|
|
65343
65532
|
const mk3 = (name, result, reason) => ({ name, cmd: "autonomy/app-runner.sh", result, duration_s: (Date.now() - t02) / 1000, reason });
|
|
65344
65533
|
const sh3 = (script) => {
|
|
@@ -65356,9 +65545,9 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65356
65545
|
return { checks, pid, url };
|
|
65357
65546
|
}
|
|
65358
65547
|
const ir2 = Number(m[1]), sr2 = Number(m[2]), hr = Number(m[3]), noApp = m[4] === "1";
|
|
65359
|
-
const pidTxt = existsSync56(
|
|
65548
|
+
const pidTxt = existsSync56(join83(dir, "app.pid")) ? readFileSync74(join83(dir, "app.pid"), "utf8").trim() : "";
|
|
65360
65549
|
pid = /^\d+$/.test(pidTxt) && sr2 >= 0 ? Number(pidTxt) : null;
|
|
65361
|
-
const st2 = readJson5(
|
|
65550
|
+
const st2 = readJson5(join83(dir, "state.json"));
|
|
65362
65551
|
url = typeof st2?.["url"] === "string" ? st2["url"] : null;
|
|
65363
65552
|
if (sr2 < 0) {
|
|
65364
65553
|
checks.push(noApp ? mk3("app boot", "n/a", "app-runner detected no app") : mk3("app boot", "not_run", ir2 === 0 ? "app-runner detected no app" : "no runnable app detected or runtime missing"), mk3("http probe", noApp ? "n/a" : "not_run", "app not booted"));
|
|
@@ -65369,7 +65558,7 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65369
65558
|
return { checks, pid, url };
|
|
65370
65559
|
}
|
|
65371
65560
|
checks.push(mk3("app boot", "pass", "app process started"));
|
|
65372
|
-
const health = readJson5(
|
|
65561
|
+
const health = readJson5(join83(dir, "health.json"));
|
|
65373
65562
|
checks.push(hr === 0 && health?.["ok"] === true ? mk3("http probe", "pass", "health.json ok") : mk3("http probe", "fail", "app-runner health check failed"));
|
|
65374
65563
|
if (opts.specText !== undefined && checks[1]?.result === "pass" && url)
|
|
65375
65564
|
checks.push(await functionalVerify(opts, url, dir, lokiDir2, timeoutMs));
|
|
@@ -65382,10 +65571,10 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65382
65571
|
async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
65383
65572
|
const t02 = Date.now();
|
|
65384
65573
|
const res = (result, reason) => ({ name: "functional verify", cmd: "autonomy/lib/functional-verify.py", result, duration_s: (Date.now() - t02) / 1000, reason });
|
|
65385
|
-
const py2 = await findPython3(), script = opts.verifyPath ??
|
|
65574
|
+
const py2 = await findPython3(), script = opts.verifyPath ?? join83(REPO_ROOT, "autonomy", "lib", "functional-verify.py");
|
|
65386
65575
|
if (!py2 || !existsSync56(script))
|
|
65387
65576
|
return res("not_run", "python3 or functional-verify.py unavailable");
|
|
65388
|
-
const specFile =
|
|
65577
|
+
const specFile = join83(dir, "spec.txt");
|
|
65389
65578
|
writeFileSync38(specFile, opts.specText ?? "");
|
|
65390
65579
|
const r = spawnSync9(py2, ["-I", script, specFile, url], { env: plainTestEnv(), encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
|
|
65391
65580
|
let out3 = null;
|
|
@@ -65397,11 +65586,11 @@ async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
|
65397
65586
|
}
|
|
65398
65587
|
if (!out3 || r.status !== 0)
|
|
65399
65588
|
return res("not_run", "functional harness produced no result");
|
|
65400
|
-
const q10 =
|
|
65589
|
+
const q10 = join83(lokiDir2, "quality");
|
|
65401
65590
|
mkdirSync40(q10, { recursive: true });
|
|
65402
|
-
const tmp =
|
|
65591
|
+
const tmp = join83(q10, `functional-results.json.tmp.${process.pid}`);
|
|
65403
65592
|
writeFileSync38(tmp, JSON.stringify(out3, null, 2));
|
|
65404
|
-
renameSync18(tmp,
|
|
65593
|
+
renameSync18(tmp, join83(q10, "functional-results.json"));
|
|
65405
65594
|
const s = String(out3["functional_status"] ?? "inconclusive");
|
|
65406
65595
|
return res(s === "verified" ? "pass" : s === "failed" ? "fail" : "not_run", `functional_status ${s}`);
|
|
65407
65596
|
}
|
|
@@ -65433,15 +65622,15 @@ app_runner_stop >/dev/null 2>&1
|
|
|
65433
65622
|
});
|
|
65434
65623
|
|
|
65435
65624
|
// ../../loki-ts/src/util/secure_scan.ts
|
|
65436
|
-
import { copyFileSync as copyFileSync5, existsSync as existsSync57, lstatSync as lstatSync23, mkdirSync as mkdirSync41, mkdtempSync as mkdtempSync9, readFileSync as
|
|
65625
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync57, lstatSync as lstatSync23, mkdirSync as mkdirSync41, mkdtempSync as mkdtempSync9, readFileSync as readFileSync75, realpathSync as realpathSync26, rmSync as rmSync21, statSync as statSync25, writeFileSync as writeFileSync39 } from "fs";
|
|
65437
65626
|
import { randomBytes as randomBytes6 } from "crypto";
|
|
65438
65627
|
import { tmpdir as tmpdir12 } from "os";
|
|
65439
|
-
import { basename as basename22, dirname as
|
|
65628
|
+
import { basename as basename22, dirname as dirname34, join as join84, resolve as resolve28, sep as sep17 } from "path";
|
|
65440
65629
|
function fail(error) {
|
|
65441
65630
|
return { ok: false, findings: [], error };
|
|
65442
65631
|
}
|
|
65443
65632
|
async function runSecureScan(targetDir, opts = {}) {
|
|
65444
|
-
const script = opts.scriptPath ??
|
|
65633
|
+
const script = opts.scriptPath ?? join84(REPO_ROOT, "autonomy", "lib", "secure-scan.py");
|
|
65445
65634
|
if (!existsSync57(script))
|
|
65446
65635
|
return fail(`secure-scan script not found: ${script}`);
|
|
65447
65636
|
const py2 = await findPython3();
|
|
@@ -65485,12 +65674,12 @@ async function runSecureScan(targetDir, opts = {}) {
|
|
|
65485
65674
|
return fail(`secure-scan failed (exit ${res.exitCode}): ${tail2}`);
|
|
65486
65675
|
}
|
|
65487
65676
|
async function secureScanChanged(repoDir, changed, scriptPath) {
|
|
65488
|
-
const dir = mkdtempSync9(
|
|
65677
|
+
const dir = mkdtempSync9(join84(tmpdir12(), "loki-deep-secure-"));
|
|
65489
65678
|
try {
|
|
65490
65679
|
for (const f of changed)
|
|
65491
|
-
if (existsSync57(
|
|
65492
|
-
mkdirSync41(
|
|
65493
|
-
copyFileSync5(
|
|
65680
|
+
if (existsSync57(join84(repoDir, f)) && lstatSync23(join84(repoDir, f)).isFile()) {
|
|
65681
|
+
mkdirSync41(dirname34(join84(dir, f)), { recursive: true });
|
|
65682
|
+
copyFileSync5(join84(repoDir, f), join84(dir, f));
|
|
65494
65683
|
}
|
|
65495
65684
|
return await runSecureScan(dir, { ...scriptPath ? { scriptPath } : {}, timeoutMs: 60000 });
|
|
65496
65685
|
} finally {
|
|
@@ -65624,7 +65813,7 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65624
65813
|
const skipped2 = [];
|
|
65625
65814
|
for (const p of untracked2.split("\x00").filter(Boolean)) {
|
|
65626
65815
|
try {
|
|
65627
|
-
const st2 = statSync25(
|
|
65816
|
+
const st2 = statSync25(join84(repoDir, p));
|
|
65628
65817
|
if (!st2.isFile())
|
|
65629
65818
|
continue;
|
|
65630
65819
|
if (st2.size > MAX_ADDED_FILE_BYTES) {
|
|
@@ -65639,14 +65828,14 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65639
65828
|
continue;
|
|
65640
65829
|
}
|
|
65641
65830
|
const lines2 = new Map;
|
|
65642
|
-
|
|
65831
|
+
readFileSync75(join84(repoDir, p), "utf8").split(`
|
|
65643
65832
|
`).forEach((t, i) => lines2.set(i + 1, t));
|
|
65644
65833
|
added.set(p, lines2);
|
|
65645
65834
|
} catch {}
|
|
65646
65835
|
}
|
|
65647
65836
|
if (added.size === 0)
|
|
65648
65837
|
return { ok: true, findings: skipped2 };
|
|
65649
|
-
const mirror = mkdtempSync9(
|
|
65838
|
+
const mirror = mkdtempSync9(join84(tmpdir12(), "loki-secure-added-"));
|
|
65650
65839
|
try {
|
|
65651
65840
|
const root = resolve28(mirror) + sep17;
|
|
65652
65841
|
const chunkMap = new Map;
|
|
@@ -65692,12 +65881,12 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65692
65881
|
chunks.push(cur);
|
|
65693
65882
|
const whole = chunks.length === 1;
|
|
65694
65883
|
for (const c of chunks) {
|
|
65695
|
-
const rel = whole ? p :
|
|
65884
|
+
const rel = whole ? p : join84(chunkRoot, String(chunkSeq++), basename22(p));
|
|
65696
65885
|
const out3 = whole ? dest : resolve28(mirror, rel);
|
|
65697
65886
|
if (!out3.startsWith(root))
|
|
65698
65887
|
break;
|
|
65699
65888
|
chunkMap.set(rel, { file: p, lines: c.orig });
|
|
65700
|
-
mkdirSync41(
|
|
65889
|
+
mkdirSync41(dirname34(out3), { recursive: true });
|
|
65701
65890
|
writeFileSync39(out3, c.body.join(`
|
|
65702
65891
|
`) + `
|
|
65703
65892
|
`);
|
|
@@ -65744,14 +65933,14 @@ var init_secure_scan = __esm(() => {
|
|
|
65744
65933
|
});
|
|
65745
65934
|
|
|
65746
65935
|
// ../../loki-ts/src/util/run_control.ts
|
|
65747
|
-
import { existsSync as existsSync58, readFileSync as
|
|
65748
|
-
import { join as
|
|
65936
|
+
import { existsSync as existsSync58, readFileSync as readFileSync76, renameSync as renameSync19, writeFileSync as writeFileSync40 } from "fs";
|
|
65937
|
+
import { join as join85 } from "path";
|
|
65749
65938
|
function readRunControl(runDir) {
|
|
65750
|
-
const p =
|
|
65939
|
+
const p = join85(runDir, RUN_CONTROL_FILE);
|
|
65751
65940
|
if (!existsSync58(p))
|
|
65752
65941
|
return null;
|
|
65753
65942
|
try {
|
|
65754
|
-
const a = JSON.parse(
|
|
65943
|
+
const a = JSON.parse(readFileSync76(p, "utf8")).action;
|
|
65755
65944
|
return typeof a === "string" && ACTIONS2.has(a) ? a : null;
|
|
65756
65945
|
} catch {
|
|
65757
65946
|
return null;
|
|
@@ -65809,8 +65998,8 @@ var init_run_control = __esm(() => {
|
|
|
65809
65998
|
});
|
|
65810
65999
|
|
|
65811
66000
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
65812
|
-
import { existsSync as existsSync59, readdirSync as readdirSync27, readFileSync as
|
|
65813
|
-
import { basename as basename23, dirname as
|
|
66001
|
+
import { existsSync as existsSync59, readdirSync as readdirSync27, readFileSync as readFileSync77 } from "fs";
|
|
66002
|
+
import { basename as basename23, dirname as dirname35, isAbsolute as isAbsolute15, join as join86, relative as relative16, resolve as resolve29 } from "path";
|
|
65814
66003
|
function parseJsonc(text3) {
|
|
65815
66004
|
let out3 = "", i = 0;
|
|
65816
66005
|
while (i < text3.length) {
|
|
@@ -65845,7 +66034,7 @@ function moduleOf(file, depth = 0) {
|
|
|
65845
66034
|
const ext = typeof j10.extends === "string" ? j10.extends : null;
|
|
65846
66035
|
if (!ext || !ext.startsWith("."))
|
|
65847
66036
|
return null;
|
|
65848
|
-
const next =
|
|
66037
|
+
const next = join86(dirname35(file), ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
65849
66038
|
return existsSync59(next) ? moduleOf(next, depth + 1) : null;
|
|
65850
66039
|
}
|
|
65851
66040
|
function readPackageConventions(pkgDir, runner = null) {
|
|
@@ -65857,13 +66046,13 @@ function readPackageConventions(pkgDir, runner = null) {
|
|
|
65857
66046
|
}
|
|
65858
66047
|
let packageType = null, tsModule = null;
|
|
65859
66048
|
for (const n10 of names) {
|
|
65860
|
-
const j10 = readJson6(
|
|
66049
|
+
const j10 = readJson6(join86(pkgDir, n10));
|
|
65861
66050
|
if (!j10)
|
|
65862
66051
|
continue;
|
|
65863
66052
|
if (packageType === null && typeof j10.type === "string" && typeof j10.name === "string")
|
|
65864
66053
|
packageType = j10.type;
|
|
65865
66054
|
if (tsModule === null && j10.compilerOptions !== undefined)
|
|
65866
|
-
tsModule = moduleOf(
|
|
66055
|
+
tsModule = moduleOf(join86(pkgDir, n10));
|
|
65867
66056
|
}
|
|
65868
66057
|
if (packageType === null && tsModule === null)
|
|
65869
66058
|
return null;
|
|
@@ -65969,13 +66158,13 @@ function vacuousCheck(fileName, content) {
|
|
|
65969
66158
|
function nearestPackageRoot(testDir, repoDir, fileName) {
|
|
65970
66159
|
const api = loadProjectApi(repoDir);
|
|
65971
66160
|
if (api)
|
|
65972
|
-
return siteFor(api, repoDir, relative16(repoDir,
|
|
66161
|
+
return siteFor(api, repoDir, relative16(repoDir, join86(testDir, fileName)))?.cwd ?? repoDir;
|
|
65973
66162
|
const shaped = (d) => {
|
|
65974
66163
|
try {
|
|
65975
66164
|
return readdirSync27(d).some((f) => {
|
|
65976
66165
|
if (!f.endsWith(".json"))
|
|
65977
66166
|
return false;
|
|
65978
|
-
const j10 = readJson6(
|
|
66167
|
+
const j10 = readJson6(join86(d, f));
|
|
65979
66168
|
return !!j10 && typeof j10.name === "string" && Object.keys(j10).length > 1;
|
|
65980
66169
|
});
|
|
65981
66170
|
} catch {
|
|
@@ -65983,8 +66172,8 @@ function nearestPackageRoot(testDir, repoDir, fileName) {
|
|
|
65983
66172
|
}
|
|
65984
66173
|
};
|
|
65985
66174
|
let pkg = testDir;
|
|
65986
|
-
while (pkg !== repoDir && pkg !==
|
|
65987
|
-
pkg =
|
|
66175
|
+
while (pkg !== repoDir && pkg !== dirname35(pkg) && !shaped(pkg))
|
|
66176
|
+
pkg = dirname35(pkg);
|
|
65988
66177
|
return pkg;
|
|
65989
66178
|
}
|
|
65990
66179
|
function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
@@ -66036,7 +66225,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66036
66225
|
};
|
|
66037
66226
|
const strayInTestDir = (out3) => {
|
|
66038
66227
|
const first = relative16(testDir, out3).split("/")[0];
|
|
66039
|
-
return !!first && first !== "__self__" && !existsSync59(
|
|
66228
|
+
return !!first && first !== "__self__" && !existsSync59(join86(testDir, first)) && [pkg, repoDir].some((d) => d !== testDir && existsSync59(join86(d, first)));
|
|
66040
66229
|
};
|
|
66041
66230
|
const scan = (cwd) => {
|
|
66042
66231
|
const vars = new Map, walk = new Set, taint = new Set, reports = new Map, created = [];
|
|
@@ -66051,7 +66240,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66051
66240
|
if (env)
|
|
66052
66241
|
return ev2(env[1], report);
|
|
66053
66242
|
if (e10 === "fileURLToPath(import.meta.url)" || e10 === "__filename")
|
|
66054
|
-
return
|
|
66243
|
+
return join86(testDir, "__self__");
|
|
66055
66244
|
const url = /^fileURLToPath\(new URL\((["'])([^"']*)\1\s*,\s*import\.meta\.url\)\)$/.exec(e10);
|
|
66056
66245
|
if (url)
|
|
66057
66246
|
return resolve29(testDir, url[2]);
|
|
@@ -66067,11 +66256,11 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66067
66256
|
if (args.some((a) => a === null))
|
|
66068
66257
|
return null;
|
|
66069
66258
|
if (call[1] === "dirname")
|
|
66070
|
-
return
|
|
66259
|
+
return dirname35(args[0]);
|
|
66071
66260
|
const out3 = resolve29(...args);
|
|
66072
|
-
const first = parts.slice(1).map((a) => /^\s*["'`]([^"'`]*)["'`]\s*$/.exec(a)?.[1]).find((x3) => x3), viaWalk = !!first && walk.has(parts[0].trim()) && [pkg, repoDir].some((d) => existsSync59(
|
|
66261
|
+
const first = parts.slice(1).map((a) => /^\s*["'`]([^"'`]*)["'`]\s*$/.exec(a)?.[1]).find((x3) => x3), viaWalk = !!first && walk.has(parts[0].trim()) && [pkg, repoDir].some((d) => existsSync59(join86(d, first.split("/").filter(Boolean)[0] ?? "\x00")));
|
|
66073
66262
|
if (report && (viaWalk || !parts.some((a) => walk.has(a.trim()) || taint.has(a.trim())) && (relative16(testDir, out3).startsWith("..") || strayInTestDir(out3))) && parts.some((a) => /^\s*["'`]/.test(a)))
|
|
66074
|
-
reports.set(`${ln2}|${e10}`, { out: out3, rel: relative16(repoDir, out3), tail: viaWalk ?
|
|
66263
|
+
reports.set(`${ln2}|${e10}`, { out: out3, rel: relative16(repoDir, out3), tail: viaWalk ? join86(...args.slice(1)) : undefined });
|
|
66075
66264
|
return out3;
|
|
66076
66265
|
};
|
|
66077
66266
|
for (const line2 of walkCode.split(`
|
|
@@ -66119,7 +66308,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66119
66308
|
const runs2 = [...new Set([pkg, repoDir])].map(scan);
|
|
66120
66309
|
const planned = (rel) => !!planText && rel.split("/").some((_, i, a) => {
|
|
66121
66310
|
const pre2 = a.slice(0, i + 1).join("/");
|
|
66122
|
-
return (i > 0 || a.length === 1) && !existsSync59(
|
|
66311
|
+
return (i > 0 || a.length === 1) && !existsSync59(join86(repoDir, pre2)) && new RegExp(`(?<![\\w-])${pre2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(planText);
|
|
66123
66312
|
});
|
|
66124
66313
|
const phantom = (r, created) => {
|
|
66125
66314
|
const rel = r.rel;
|
|
@@ -66129,11 +66318,11 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66129
66318
|
const seen = (from) => {
|
|
66130
66319
|
let d = from;
|
|
66131
66320
|
for (let i = 0;i < 64; i++) {
|
|
66132
|
-
if (existsSync59(
|
|
66321
|
+
if (existsSync59(join86(d, r.tail)))
|
|
66133
66322
|
return true;
|
|
66134
|
-
if (d === repoDir || d ===
|
|
66323
|
+
if (d === repoDir || d === dirname35(d))
|
|
66135
66324
|
return false;
|
|
66136
|
-
d =
|
|
66325
|
+
d = dirname35(d);
|
|
66137
66326
|
}
|
|
66138
66327
|
return false;
|
|
66139
66328
|
};
|
|
@@ -66171,7 +66360,7 @@ function phantomReason(miss, repoFiles, testDir = "", pkgRoot = "") {
|
|
|
66171
66360
|
}
|
|
66172
66361
|
var readJson6 = (p) => {
|
|
66173
66362
|
try {
|
|
66174
|
-
const v3 = parseJsonc(
|
|
66363
|
+
const v3 = parseJsonc(readFileSync77(p, "utf8"));
|
|
66175
66364
|
return v3 && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
66176
66365
|
} catch {
|
|
66177
66366
|
return null;
|
|
@@ -66180,8 +66369,8 @@ var readJson6 = (p) => {
|
|
|
66180
66369
|
${bad.map((b) => `- ${b.name}: ${b.why}`).join(`
|
|
66181
66370
|
`)}`, `Point every reference at the repository code with repo-relative paths (for example join(import.meta.dir, "..", "<repo path>") or the equivalent for this runner). Do not read the home directory, $HOME or an environment variable that falls back to one. Write nothing else.`].join(`
|
|
66182
66371
|
|
|
66183
|
-
`), outOfRepoTests = (repoDir, changed) => changed.filter((f) => /(^|[\/._-])(test|spec)s?[\/._-]|_test\./i.test(f) && existsSync59(
|
|
66184
|
-
const why = outOfRepoTarget(
|
|
66372
|
+
`), outOfRepoTests = (repoDir, changed) => changed.filter((f) => /(^|[\/._-])(test|spec)s?[\/._-]|_test\./i.test(f) && existsSync59(join86(repoDir, f))).flatMap((name) => {
|
|
66373
|
+
const why = outOfRepoTarget(readFileSync77(join86(repoDir, name), "utf8"));
|
|
66185
66374
|
return why ? [{ name, why }] : [];
|
|
66186
66375
|
}), CREATORS;
|
|
66187
66376
|
var init_conventions = __esm(() => {
|
|
@@ -66191,16 +66380,16 @@ var init_conventions = __esm(() => {
|
|
|
66191
66380
|
});
|
|
66192
66381
|
|
|
66193
66382
|
// ../../loki-ts/src/util/pr_lessons.ts
|
|
66194
|
-
import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync10, readFileSync as
|
|
66383
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync10, readFileSync as readFileSync78, rmSync as rmSync22, writeFileSync as writeFileSync41 } from "fs";
|
|
66195
66384
|
import { homedir as homedir10, tmpdir as tmpdir13 } from "os";
|
|
66196
|
-
import { dirname as
|
|
66385
|
+
import { dirname as dirname36, join as join87 } from "path";
|
|
66197
66386
|
import { createHash as createHash26 } from "crypto";
|
|
66198
66387
|
function loadLessons(repoDir) {
|
|
66199
66388
|
const p = lessonsPath(repoDir);
|
|
66200
66389
|
if (!existsSync60(p))
|
|
66201
66390
|
return [];
|
|
66202
66391
|
try {
|
|
66203
|
-
const j10 = JSON.parse(
|
|
66392
|
+
const j10 = JSON.parse(readFileSync78(p, "utf-8"));
|
|
66204
66393
|
return Array.isArray(j10.lessons) ? j10.lessons : [];
|
|
66205
66394
|
} catch {
|
|
66206
66395
|
return [];
|
|
@@ -66208,12 +66397,12 @@ function loadLessons(repoDir) {
|
|
|
66208
66397
|
}
|
|
66209
66398
|
function save3(repoDir, lessons) {
|
|
66210
66399
|
const p = lessonsPath(repoDir);
|
|
66211
|
-
mkdirSync42(
|
|
66400
|
+
mkdirSync42(dirname36(p), { recursive: true });
|
|
66212
66401
|
atomicWriteJson(p, { version: 2, lessons });
|
|
66213
66402
|
}
|
|
66214
66403
|
function loadPromoted() {
|
|
66215
66404
|
try {
|
|
66216
|
-
const j10 = JSON.parse(
|
|
66405
|
+
const j10 = JSON.parse(readFileSync78(promotedPath(), "utf-8"));
|
|
66217
66406
|
return Array.isArray(j10.lessons) ? j10.lessons : [];
|
|
66218
66407
|
} catch {
|
|
66219
66408
|
return [];
|
|
@@ -66324,7 +66513,7 @@ ${body}
|
|
|
66324
66513
|
function learningsBlock(repoDir, limit = 5) {
|
|
66325
66514
|
let items2 = [];
|
|
66326
66515
|
try {
|
|
66327
|
-
const parsed = JSON.parse(
|
|
66516
|
+
const parsed = JSON.parse(readFileSync78(join87(repoDir, ".loki", "state", "relevant-learnings.json"), "utf-8"));
|
|
66328
66517
|
if (Array.isArray(parsed.learnings))
|
|
66329
66518
|
items2 = parsed.learnings;
|
|
66330
66519
|
} catch {
|
|
@@ -66354,7 +66543,7 @@ ${lines2.join(`
|
|
|
66354
66543
|
</untrusted-learnings>
|
|
66355
66544
|
`;
|
|
66356
66545
|
}
|
|
66357
|
-
var lessonsPath = (repoDir) =>
|
|
66546
|
+
var lessonsPath = (repoDir) => join87(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), promotedPath = () => join87(process.env["LOKI_PROMOTED_DIR"] || join87(homedir10(), ".loki"), "memory", "semantic", "promoted-lessons.json"), DEMOTE_AFTER = 3, demoteOn = () => process.env["LOKI_PR_LESSON_DEMOTE"] !== "0", HEX642, KINDS, VERDICT_BASE, words = (s) => new Set(s.toLowerCase().match(/[a-z0-9_]{4,}/g) ?? []), fence = (s) => s.replace(/[<>]/g, "");
|
|
66358
66547
|
var init_pr_lessons = __esm(() => {
|
|
66359
66548
|
init_redact();
|
|
66360
66549
|
init_atomic();
|
|
@@ -66374,7 +66563,7 @@ import {
|
|
|
66374
66563
|
lstatSync as lstatSync24,
|
|
66375
66564
|
mkdirSync as mkdirSync43,
|
|
66376
66565
|
openSync as openSync13,
|
|
66377
|
-
readFileSync as
|
|
66566
|
+
readFileSync as readFileSync79,
|
|
66378
66567
|
readlinkSync as readlinkSync5,
|
|
66379
66568
|
realpathSync as realpathSync27,
|
|
66380
66569
|
rmSync as rmSync23,
|
|
@@ -66382,7 +66571,7 @@ import {
|
|
|
66382
66571
|
unlinkSync as unlinkSync8,
|
|
66383
66572
|
writeFileSync as writeFileSync42
|
|
66384
66573
|
} from "fs";
|
|
66385
|
-
import { dirname as
|
|
66574
|
+
import { dirname as dirname37, isAbsolute as isAbsolute16, join as join88, relative as relative17, resolve as resolve30, sep as sep18 } from "path";
|
|
66386
66575
|
function git8(root, args) {
|
|
66387
66576
|
return safeGit(root, args);
|
|
66388
66577
|
}
|
|
@@ -66422,7 +66611,7 @@ function safeJoin(root, relPath) {
|
|
|
66422
66611
|
const segment = segments[i];
|
|
66423
66612
|
if (segment === undefined)
|
|
66424
66613
|
continue;
|
|
66425
|
-
cur =
|
|
66614
|
+
cur = join88(cur, segment);
|
|
66426
66615
|
if (i < segments.length - 1) {
|
|
66427
66616
|
let st2;
|
|
66428
66617
|
try {
|
|
@@ -66439,7 +66628,7 @@ function safeJoin(root, relPath) {
|
|
|
66439
66628
|
function assertSymlinkWithinRoot(root, relPath, target) {
|
|
66440
66629
|
if (isAbsolute16(target))
|
|
66441
66630
|
throw new TreeSwapUnsafePathError(`symlink ${relPath} has an absolute target`);
|
|
66442
|
-
const resolvedTarget = resolve30(
|
|
66631
|
+
const resolvedTarget = resolve30(dirname37(join88(resolve30(root), relPath)), target);
|
|
66443
66632
|
const rel = relative17(resolve30(root), resolvedTarget);
|
|
66444
66633
|
if (rel === ".." || rel.startsWith(`..${"/"}`) || isAbsolute16(rel)) {
|
|
66445
66634
|
throw new TreeSwapUnsafePathError(`symlink ${relPath} escapes tree root`);
|
|
@@ -66458,7 +66647,7 @@ function readEntry(root, relPath) {
|
|
|
66458
66647
|
}
|
|
66459
66648
|
const fd2 = openSync13(abs, fsc.O_RDONLY | fsc.O_NOFOLLOW);
|
|
66460
66649
|
try {
|
|
66461
|
-
return { content:
|
|
66650
|
+
return { content: readFileSync79(fd2), mode: st2.mode & 511 };
|
|
66462
66651
|
} finally {
|
|
66463
66652
|
closeSync13(fd2);
|
|
66464
66653
|
}
|
|
@@ -66477,7 +66666,7 @@ function writeEntry(root, relPath, entry2) {
|
|
|
66477
66666
|
assertSymlinkWithinRoot(root, relPath, entry2.symlinkTarget);
|
|
66478
66667
|
}
|
|
66479
66668
|
const abs = safeJoin(root, relPath);
|
|
66480
|
-
mkdirSync43(
|
|
66669
|
+
mkdirSync43(dirname37(abs), { recursive: true });
|
|
66481
66670
|
removeEntry(root, relPath);
|
|
66482
66671
|
if (entry2.symlinkTarget !== undefined) {
|
|
66483
66672
|
symlinkSync4(entry2.symlinkTarget, abs);
|
|
@@ -66600,7 +66789,7 @@ function swapLocked(opts, excludes) {
|
|
|
66600
66789
|
pre2.push({ path, kind: "file", content: e10.content, mode: e10.mode, symlinkTarget: e10.symlinkTarget });
|
|
66601
66790
|
}
|
|
66602
66791
|
mkdirSync43(opts.runDir, { recursive: true });
|
|
66603
|
-
const undoPath =
|
|
66792
|
+
const undoPath = join88(opts.runDir, UNDO_FILE);
|
|
66604
66793
|
const enc = (l) => l.map((e10) => ({ ...e10, content: e10.content?.toString("base64") }));
|
|
66605
66794
|
let fd2;
|
|
66606
66795
|
try {
|
|
@@ -66640,7 +66829,7 @@ function removeLenient(root, relPath) {
|
|
|
66640
66829
|
}
|
|
66641
66830
|
}
|
|
66642
66831
|
function restoreFromUndo(primaryRoot, runDir, excludes = DEFAULT_EXCLUDES) {
|
|
66643
|
-
const rec2 = JSON.parse(
|
|
66832
|
+
const rec2 = JSON.parse(readFileSync79(join88(runDir, UNDO_FILE), "utf8"));
|
|
66644
66833
|
const dec = (l) => l.map((e10) => ({ ...e10, content: e10.content === undefined ? undefined : Buffer.from(e10.content, "base64") }));
|
|
66645
66834
|
const entries = dec(rec2.entries);
|
|
66646
66835
|
const errors2 = [];
|
|
@@ -66660,7 +66849,7 @@ function restoreFromUndo(primaryRoot, runDir, excludes = DEFAULT_EXCLUDES) {
|
|
|
66660
66849
|
throw new AggregateError(errors2, "treeswap: rollback incomplete");
|
|
66661
66850
|
}
|
|
66662
66851
|
function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
66663
|
-
const attemptsRoot =
|
|
66852
|
+
const attemptsRoot = join88(realpathSync27(resolve30(runDir)), "attempts");
|
|
66664
66853
|
let attemptsLst;
|
|
66665
66854
|
try {
|
|
66666
66855
|
attemptsLst = lstatSync24(attemptsRoot);
|
|
@@ -66677,17 +66866,17 @@ function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
|
66677
66866
|
if (isPrimaryOrAncestor(realpathSync27(attemptsRoot)))
|
|
66678
66867
|
throw new TreeSwapUnsafePathError(`attempts dir ${attemptsRoot} resolves to the primary tree`);
|
|
66679
66868
|
const lexical = resolve30(attemptDir);
|
|
66680
|
-
const parent =
|
|
66869
|
+
const parent = dirname37(lexical);
|
|
66681
66870
|
let real3;
|
|
66682
66871
|
try {
|
|
66683
|
-
real3 =
|
|
66872
|
+
real3 = join88(realpathSync27(parent), lexical.slice(parent.length + 1));
|
|
66684
66873
|
lstatSync24(real3);
|
|
66685
66874
|
} catch (err) {
|
|
66686
66875
|
if (err.code === "ENOENT")
|
|
66687
66876
|
return;
|
|
66688
66877
|
throw err;
|
|
66689
66878
|
}
|
|
66690
|
-
if (
|
|
66879
|
+
if (dirname37(real3) !== attemptsRoot)
|
|
66691
66880
|
throw new TreeSwapUnsafePathError(`${attemptDir} is not a direct child of ${attemptsRoot}`);
|
|
66692
66881
|
if (isPrimaryOrAncestor(real3))
|
|
66693
66882
|
throw new TreeSwapUnsafePathError(`${attemptDir} is or contains the primary tree`);
|
|
@@ -66698,7 +66887,7 @@ function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
|
66698
66887
|
throw new TreeSwapUnsafePathError(`${attemptDir} is not a directory`);
|
|
66699
66888
|
if (process.getuid && lst.uid !== process.getuid())
|
|
66700
66889
|
throw new TreeSwapUnsafePathError(`refusing to remove ${attemptDir}: not owned by the current user`);
|
|
66701
|
-
const gitFile =
|
|
66890
|
+
const gitFile = join88(real3, ".git");
|
|
66702
66891
|
let isLinkedWorktree = false;
|
|
66703
66892
|
try {
|
|
66704
66893
|
isLinkedWorktree = lstatSync24(gitFile).isFile();
|
|
@@ -66725,8 +66914,8 @@ var init_treeswap = __esm(() => {
|
|
|
66725
66914
|
});
|
|
66726
66915
|
|
|
66727
66916
|
// ../../loki-ts/src/features/attempts.ts
|
|
66728
|
-
import { existsSync as existsSync61, mkdirSync as mkdirSync44, readFileSync as
|
|
66729
|
-
import { join as
|
|
66917
|
+
import { existsSync as existsSync61, mkdirSync as mkdirSync44, readFileSync as readFileSync80 } from "fs";
|
|
66918
|
+
import { join as join89 } from "path";
|
|
66730
66919
|
function assertScrubbedEnv(env) {
|
|
66731
66920
|
for (const v3 of GITHUB_TOKEN_VARS) {
|
|
66732
66921
|
const val = env[v3] ?? "";
|
|
@@ -66777,19 +66966,19 @@ async function runTwoAttempts(ops, S, wall, signal, env = process.env) {
|
|
|
66777
66966
|
}
|
|
66778
66967
|
}
|
|
66779
66968
|
function treeswapOps(a) {
|
|
66780
|
-
const attemptsDir =
|
|
66969
|
+
const attemptsDir = join89(a.runDir, "attempts"), bDir = join89(attemptsDir, "B");
|
|
66781
66970
|
mkdirSync44(attemptsDir, { recursive: true });
|
|
66782
66971
|
safeGit(a.primary, ["worktree", "add", "--detach", bDir, a.base]);
|
|
66783
66972
|
const pre2 = new Set(untracked2(a.primary));
|
|
66784
66973
|
let snapA = null;
|
|
66785
66974
|
const wallWeakened = (root, isPrimary, p, touched) => {
|
|
66786
|
-
const sealed = a.wallContent?.get(p), f =
|
|
66975
|
+
const sealed = a.wallContent?.get(p), f = join89(root, p);
|
|
66787
66976
|
if (!existsSync61(f))
|
|
66788
66977
|
return isPrimary ? sealed !== undefined || touched.has(p) : false;
|
|
66789
66978
|
if (sealed === undefined)
|
|
66790
66979
|
return touched.has(p);
|
|
66791
66980
|
try {
|
|
66792
|
-
return
|
|
66981
|
+
return readFileSync80(f, "utf8") !== sealed;
|
|
66793
66982
|
} catch {
|
|
66794
66983
|
return true;
|
|
66795
66984
|
}
|
|
@@ -66867,8 +67056,8 @@ var init_attempts = __esm(() => {
|
|
|
66867
67056
|
});
|
|
66868
67057
|
|
|
66869
67058
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
66870
|
-
import { existsSync as existsSync62, lstatSync as lstatSync25, mkdirSync as mkdirSync45, readFileSync as
|
|
66871
|
-
import { join as
|
|
67059
|
+
import { existsSync as existsSync62, lstatSync as lstatSync25, mkdirSync as mkdirSync45, readFileSync as readFileSync81, writeFileSync as writeFileSync43 } from "fs";
|
|
67060
|
+
import { join as join90 } from "path";
|
|
66872
67061
|
function buildRouteRecord(i) {
|
|
66873
67062
|
const notProven = [...i.notProven, ...i.planModelNote ? [`plan model: NOT PROVEN (owner provider): ${i.planModelNote}`] : []];
|
|
66874
67063
|
const base = { plan_model: i.planModel, shape_key: i.shapeKey, route_not_proven: notProven, applied: PER_UNIT_EXECUTORS_APPLIED };
|
|
@@ -66889,16 +67078,16 @@ function buildRouteRecord(i) {
|
|
|
66889
67078
|
function writeRouteRecord(runDir, record) {
|
|
66890
67079
|
try {
|
|
66891
67080
|
mkdirSync45(runDir, { recursive: true });
|
|
66892
|
-
writeFileSync43(
|
|
67081
|
+
writeFileSync43(join90(runDir, ROUTE_RECORD_FILE), `${JSON.stringify(record, null, 2)}
|
|
66893
67082
|
`);
|
|
66894
67083
|
} catch {}
|
|
66895
67084
|
}
|
|
66896
67085
|
function loadRouteRecord(runDir) {
|
|
66897
67086
|
try {
|
|
66898
|
-
const p =
|
|
67087
|
+
const p = join90(runDir, ROUTE_RECORD_FILE);
|
|
66899
67088
|
if (!existsSync62(p) || !lstatSync25(p).isFile())
|
|
66900
67089
|
return;
|
|
66901
|
-
const v3 = JSON.parse(
|
|
67090
|
+
const v3 = JSON.parse(readFileSync81(p, "utf8"));
|
|
66902
67091
|
return typeof v3 === "object" && v3 !== null && !Array.isArray(v3) ? v3 : undefined;
|
|
66903
67092
|
} catch {
|
|
66904
67093
|
return;
|
|
@@ -66973,10 +67162,10 @@ __export(exports_plan, {
|
|
|
66973
67162
|
planStage: () => planStage,
|
|
66974
67163
|
buildPlanBrief: () => buildPlanBrief
|
|
66975
67164
|
});
|
|
66976
|
-
import { existsSync as existsSync63, mkdirSync as mkdirSync46, readFileSync as
|
|
66977
|
-
import { join as
|
|
67165
|
+
import { existsSync as existsSync63, mkdirSync as mkdirSync46, readFileSync as readFileSync82, writeFileSync as writeFileSync44 } from "fs";
|
|
67166
|
+
import { join as join91 } from "path";
|
|
66978
67167
|
function planOutputPath(runDir) {
|
|
66979
|
-
return
|
|
67168
|
+
return join91(runDir, PLAN_OUTPUT_FILENAME);
|
|
66980
67169
|
}
|
|
66981
67170
|
function truncatePlan(raw2, max = MAX_PLAN_LINES) {
|
|
66982
67171
|
const lines2 = raw2.split(`
|
|
@@ -67046,7 +67235,7 @@ var init_plan = __esm(() => {
|
|
|
67046
67235
|
const cardOn = intentCardEnabled(process.env);
|
|
67047
67236
|
const runPlan = (onSonnet) => ctx.sessions.run({
|
|
67048
67237
|
stage: "plan",
|
|
67049
|
-
brief: buildPlanBrief(task, relevantFiles, outputPath,
|
|
67238
|
+
brief: buildPlanBrief(task, relevantFiles, outputPath, join91(ctx.runDir, PLAN_SCOPE_FILE), pr2.routed, cardOn, mutationStrict(), reviewerBriefEnabled()),
|
|
67050
67239
|
tier: "fast",
|
|
67051
67240
|
iterationId,
|
|
67052
67241
|
limitS: planStage.limitS,
|
|
@@ -67065,11 +67254,11 @@ var init_plan = __esm(() => {
|
|
|
67065
67254
|
if (!session.killed && session.exit !== 0) {
|
|
67066
67255
|
pr2.record({ planModel, planModelNote, skipReason: `plan session failed (exit ${session.exit})` });
|
|
67067
67256
|
mkdirSync46(ctx.runDir, { recursive: true });
|
|
67068
|
-
const stderrPath =
|
|
67257
|
+
const stderrPath = join91(ctx.runDir, `${iterationId}.stderr.log`);
|
|
67069
67258
|
writeFileSync44(stderrPath, session.stderrTail ?? "", "utf8");
|
|
67070
67259
|
return { status: "failed", reason: classifyExitCause(session.exit, false), data: { iteration_ids: [iterationId], duration_s: session.durationS, stderr_path: stderrPath } };
|
|
67071
67260
|
}
|
|
67072
|
-
const rawPlan = existsSync63(outputPath) ?
|
|
67261
|
+
const rawPlan = existsSync63(outputPath) ? readFileSync82(outputPath, "utf8") : "";
|
|
67073
67262
|
const ic2 = await applyIntent(rawPlan, cardOn, ctx.runDir, (d) => ctx.emit("variant", "plan", d));
|
|
67074
67263
|
const plan = truncatePlan(ic2.rest);
|
|
67075
67264
|
const route_record = pr2.record({ planModel, planModelNote }), oor = planOutOfRepo(ctx.runDir);
|
|
@@ -67094,9 +67283,9 @@ var init_plan = __esm(() => {
|
|
|
67094
67283
|
|
|
67095
67284
|
// ../../loki-ts/src/util/conflict_resume.ts
|
|
67096
67285
|
import { createHash as createHash27 } from "crypto";
|
|
67097
|
-
import { existsSync as existsSync64, mkdtempSync as mkdtempSync11, readFileSync as
|
|
67286
|
+
import { existsSync as existsSync64, mkdtempSync as mkdtempSync11, readFileSync as readFileSync83, rmSync as rmSync24, writeFileSync as writeFileSync45 } from "fs";
|
|
67098
67287
|
import { tmpdir as tmpdir14 } from "os";
|
|
67099
|
-
import { basename as basename24, join as
|
|
67288
|
+
import { basename as basename24, join as join92, relative as relative18 } from "path";
|
|
67100
67289
|
async function resumeAfterConflict(ctx, first, firstSession) {
|
|
67101
67290
|
if ((ctx.implementLeftS?.() ?? Infinity) < RESUME_MIN_LEFT_S)
|
|
67102
67291
|
return { session: firstSession, iterationId: first.iterationId };
|
|
@@ -67120,9 +67309,9 @@ async function adjudicateWallConflict(ctx, first, firstSession, wall) {
|
|
|
67120
67309
|
const reason = firstSession.markers.specConflict, rels = wall.map((f10) => relative18(ctx.repoDir, f10.path)), a = reason ? wallAnchor(reason, rels) : null;
|
|
67121
67310
|
if (!reason || !a)
|
|
67122
67311
|
return null;
|
|
67123
|
-
const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync11(
|
|
67312
|
+
const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync11(join92(tmpdir14(), "loki-e15-wall-")), name = basename24(f.path);
|
|
67124
67313
|
try {
|
|
67125
|
-
writeFileSync45(
|
|
67314
|
+
writeFileSync45(join92(cwd, name), f.content, "utf8");
|
|
67126
67315
|
const id2 = `${first.iterationId}-wa`;
|
|
67127
67316
|
ids.push(id2);
|
|
67128
67317
|
const au2 = await ctx.sessions.run({
|
|
@@ -67142,7 +67331,7 @@ async function adjudicateWallConflict(ctx, first, firstSession, wall) {
|
|
|
67142
67331
|
|
|
67143
67332
|
`)
|
|
67144
67333
|
});
|
|
67145
|
-
const next = !au2.killed && au2.exit === 0 && existsSync64(
|
|
67334
|
+
const next = !au2.killed && au2.exit === 0 && existsSync64(join92(cwd, name)) ? readFileSync83(join92(cwd, name), "utf8") : "";
|
|
67146
67335
|
const rewritten = next.trim() !== "" && next !== f.content;
|
|
67147
67336
|
if (rewritten) {
|
|
67148
67337
|
f.content = next;
|
|
@@ -67237,8 +67426,8 @@ __export(exports_implement, {
|
|
|
67237
67426
|
briefCtx: () => briefCtx,
|
|
67238
67427
|
applyExternalPatch: () => applyExternalPatch
|
|
67239
67428
|
});
|
|
67240
|
-
import { existsSync as existsSync65, mkdirSync as mkdirSync47, readFileSync as
|
|
67241
|
-
import { join as
|
|
67429
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync47, readFileSync as readFileSync84, rmSync as rmSync25, writeFileSync as writeFileSync46 } from "fs";
|
|
67430
|
+
import { join as join93, relative as relative19 } from "path";
|
|
67242
67431
|
function impactedTests(ctx) {
|
|
67243
67432
|
const o = ctx.outputs();
|
|
67244
67433
|
const map = o.intake?.testmap;
|
|
@@ -67266,7 +67455,7 @@ ${plan}` : "No separate plan was made: plan the change yourself in this session,
|
|
|
67266
67455
|
function restoreReadOnly(files) {
|
|
67267
67456
|
const reverted = [];
|
|
67268
67457
|
for (const f of files) {
|
|
67269
|
-
const current = existsSync65(f.path) ?
|
|
67458
|
+
const current = existsSync65(f.path) ? readFileSync84(f.path, "utf8") : null;
|
|
67270
67459
|
if (current !== f.content) {
|
|
67271
67460
|
writeFileSync46(f.path, f.content, "utf8");
|
|
67272
67461
|
reverted.push(f.path);
|
|
@@ -67285,7 +67474,7 @@ function specFor(ctx) {
|
|
|
67285
67474
|
if (!process.env.LOKI_E10_SPEC_SHA256)
|
|
67286
67475
|
return null;
|
|
67287
67476
|
try {
|
|
67288
|
-
return loadSpecFile(
|
|
67477
|
+
return loadSpecFile(join93(ctx.runDir, "spec.snapshot.md"));
|
|
67289
67478
|
} catch {
|
|
67290
67479
|
return null;
|
|
67291
67480
|
}
|
|
@@ -67298,7 +67487,7 @@ function applyExternalPatch(ctx, patchPath) {
|
|
|
67298
67487
|
`)[0]}` };
|
|
67299
67488
|
}
|
|
67300
67489
|
const testsReverted = restoreReadOnly(ctx.outputs().wall?.readOnlyFiles ?? []);
|
|
67301
|
-
return { status: "completed", data: { exit: "external", external: true, patch_sha256: sha2562(
|
|
67490
|
+
return { status: "completed", data: { exit: "external", external: true, patch_sha256: sha2562(readFileSync84(patchPath, "utf8")), tests_reverted: testsReverted, impacted_tests: impactedTests(ctx), iteration_ids: [] } };
|
|
67302
67491
|
}
|
|
67303
67492
|
var briefCtx = (ctx) => briefContext(ctx, { select: selectRelevantFiles, cmd: (t, repoDir) => {
|
|
67304
67493
|
const c = commandFor(t, repoDir, loadProjectApi(repoDir));
|
|
@@ -67330,7 +67519,7 @@ var init_implement = __esm(() => {
|
|
|
67330
67519
|
targetS: 180,
|
|
67331
67520
|
limitS: 480,
|
|
67332
67521
|
async run(ctx, signal) {
|
|
67333
|
-
rmSync25(
|
|
67522
|
+
rmSync25(join93(ctx.repoDir, ".loki", "supply-declared.json"), { force: true });
|
|
67334
67523
|
if (ctx.externalPatch)
|
|
67335
67524
|
return applyExternalPatch(ctx, ctx.externalPatch);
|
|
67336
67525
|
const prior = ctx.outputs();
|
|
@@ -67459,7 +67648,7 @@ var init_implement = __esm(() => {
|
|
|
67459
67648
|
return { status: "completed", data };
|
|
67460
67649
|
const stderrTail = session.stderrTail ?? "";
|
|
67461
67650
|
mkdirSync47(ctx.runDir, { recursive: true });
|
|
67462
|
-
const stderrPath =
|
|
67651
|
+
const stderrPath = join93(ctx.runDir, `${iterationId}.stderr.log`);
|
|
67463
67652
|
writeFileSync46(stderrPath, stderrTail, "utf8");
|
|
67464
67653
|
data.stderr_path = stderrPath;
|
|
67465
67654
|
return { status: "failed", reason: classifyExitCause(session.exit, false), data };
|
|
@@ -67470,17 +67659,17 @@ var init_implement = __esm(() => {
|
|
|
67470
67659
|
|
|
67471
67660
|
// ../../loki-ts/src/engine10/machine.ts
|
|
67472
67661
|
import { existsSync as existsSync66, mkdirSync as mkdirSync48, rmSync as rmSync26, writeFileSync as writeFileSync47 } from "fs";
|
|
67473
|
-
import { isAbsolute as isAbsolute17, join as
|
|
67662
|
+
import { isAbsolute as isAbsolute17, join as join94, relative as relative20 } from "path";
|
|
67474
67663
|
async function optional(path) {
|
|
67475
|
-
const abs = isAbsolute17(path) ? path :
|
|
67664
|
+
const abs = isAbsolute17(path) ? path : join94(import.meta.dir, path);
|
|
67476
67665
|
if (!existsSync66(abs))
|
|
67477
67666
|
return null;
|
|
67478
67667
|
return await import(abs);
|
|
67479
67668
|
}
|
|
67480
67669
|
function defaultLoader(dir) {
|
|
67481
67670
|
return async (name) => {
|
|
67482
|
-
const reg = dir ===
|
|
67483
|
-
const mod = reg ? await reg() : await optional(
|
|
67671
|
+
const reg = dir === join94(import.meta.dir, "stages") ? REGISTRY[`./stages/${name}.ts`] : undefined;
|
|
67672
|
+
const mod = reg ? await reg() : await optional(join94(dir, `${name}.ts`));
|
|
67484
67673
|
return mod ? mod.stage ?? mod.default ?? null : null;
|
|
67485
67674
|
};
|
|
67486
67675
|
}
|
|
@@ -67489,7 +67678,7 @@ function softCapS(capS) {
|
|
|
67489
67678
|
return Math.max(0, Math.min(plain2, budget));
|
|
67490
67679
|
}
|
|
67491
67680
|
async function runMachine(ctx, opts = {}) {
|
|
67492
|
-
const load = opts.load ?? defaultLoader(opts.stagesDir ??
|
|
67681
|
+
const load = opts.load ?? defaultLoader(opts.stagesDir ?? join94(import.meta.dir, "stages"));
|
|
67493
67682
|
const outputs = {};
|
|
67494
67683
|
let capHit = false, fatal = null;
|
|
67495
67684
|
if (opts.restored)
|
|
@@ -67705,9 +67894,9 @@ ${timeBudgetNote(limitS)}`;
|
|
|
67705
67894
|
else
|
|
67706
67895
|
try {
|
|
67707
67896
|
const w = a;
|
|
67708
|
-
mkdirSync48(
|
|
67897
|
+
mkdirSync48(join94(base, relative20(ctx.repoDir, w.targetDir)), { recursive: true });
|
|
67709
67898
|
for (const [n10, c] of w.contents)
|
|
67710
|
-
writeFileSync47(
|
|
67899
|
+
writeFileSync47(join94(base, relative20(ctx.repoDir, w.targetDir), n10), c, "utf8");
|
|
67711
67900
|
r = j10.split.install(sctx, a, base);
|
|
67712
67901
|
const changed = hooks.wall.changedSinceBase(ctx.repoDir, ctx.baseSha);
|
|
67713
67902
|
if (r.status === "completed") {
|
|
@@ -68014,8 +68203,8 @@ __export(exports_worker, {
|
|
|
68014
68203
|
main: () => main2,
|
|
68015
68204
|
assertWorkerEnv: () => assertWorkerEnv
|
|
68016
68205
|
});
|
|
68017
|
-
import { readFileSync as
|
|
68018
|
-
import { join as
|
|
68206
|
+
import { readFileSync as readFileSync85 } from "fs";
|
|
68207
|
+
import { join as join95 } from "path";
|
|
68019
68208
|
function assertWorkerEnv(env = process.env) {
|
|
68020
68209
|
if (env.LOKI_ALLOW_AGENT_GITHUB_TOKEN === "1")
|
|
68021
68210
|
return;
|
|
@@ -68045,7 +68234,7 @@ async function main2(args) {
|
|
|
68045
68234
|
return 2;
|
|
68046
68235
|
}
|
|
68047
68236
|
const repoDir = process.cwd();
|
|
68048
|
-
const lokiRoot =
|
|
68237
|
+
const lokiRoot = join95(repoDir, ".loki");
|
|
68049
68238
|
const deep = mode === "deep";
|
|
68050
68239
|
globalThis[Symbol.for("loki.ownsStopSignals")] = true;
|
|
68051
68240
|
for (const sig of ["SIGTERM", "SIGINT"])
|
|
@@ -68073,7 +68262,7 @@ async function main2(args) {
|
|
|
68073
68262
|
externalPatch,
|
|
68074
68263
|
runId,
|
|
68075
68264
|
repoDir,
|
|
68076
|
-
runDir:
|
|
68265
|
+
runDir: join95(lokiRoot, "runs", runId),
|
|
68077
68266
|
branch: `loki/${runId}`,
|
|
68078
68267
|
provider,
|
|
68079
68268
|
model,
|
|
@@ -68087,7 +68276,7 @@ async function main2(args) {
|
|
|
68087
68276
|
tests: new RealTestMapProvider,
|
|
68088
68277
|
cost: {
|
|
68089
68278
|
read(dir, ids) {
|
|
68090
|
-
const c = sumResultCosts(
|
|
68279
|
+
const c = sumResultCosts(join95(dir, ".loki"), liveArchivedCosts(join95(dir, ".loki"), ids, UNMETERED));
|
|
68091
68280
|
return costTotalsOf(c);
|
|
68092
68281
|
}
|
|
68093
68282
|
},
|
|
@@ -68097,7 +68286,7 @@ async function main2(args) {
|
|
|
68097
68286
|
const resize = deep ? undefined : () => resizeCap(ctx.runDir, loadProjectApi(repoDir), !(Number(parseCapUsd(process.env.LOKI_E10_MAX_COST_USD)) > 0), Number(process.env.LOKI_E10_CAP_FIXED_S) || undefined);
|
|
68098
68287
|
let flow = FLOW.filter((s) => s !== "pr"), restored;
|
|
68099
68288
|
if (process.env.LOKI_E10_RESUME === "1") {
|
|
68100
|
-
const p =
|
|
68289
|
+
const p = join95(repoDir, eventsRelPath(runId)), r = (await Promise.resolve().then(() => (init_run_outputs(), exports_run_outputs))).resumeMachineOpts(ctx, readEvents(p), readFileSync85(p, "utf8"), flow);
|
|
68101
68290
|
if (!r.ok) {
|
|
68102
68291
|
emit("escalated", null, { stop: `resume refused: ${r.reason}` });
|
|
68103
68292
|
return;
|
|
@@ -68145,12 +68334,12 @@ __export(exports_deep, {
|
|
|
68145
68334
|
});
|
|
68146
68335
|
import { existsSync as existsSync67, mkdirSync as mkdirSync49, mkdtempSync as mkdtempSync12, rmSync as rmSync27, writeFileSync as writeFileSync48 } from "fs";
|
|
68147
68336
|
import { tmpdir as tmpdir15 } from "os";
|
|
68148
|
-
import { join as
|
|
68337
|
+
import { join as join96 } from "path";
|
|
68149
68338
|
function sessionCouncil(sessions) {
|
|
68150
68339
|
return { async run(input, signal) {
|
|
68151
|
-
const cwd = mkdtempSync12(
|
|
68340
|
+
const cwd = mkdtempSync12(join96(tmpdir15(), "loki-deep-council-"));
|
|
68152
68341
|
try {
|
|
68153
|
-
writeFileSync48(
|
|
68342
|
+
writeFileSync48(join96(cwd, "diff.patch"), input.diff, "utf8");
|
|
68154
68343
|
const r = await sessions.run({
|
|
68155
68344
|
stage: "deep",
|
|
68156
68345
|
tier: "development",
|
|
@@ -68220,7 +68409,7 @@ ${r.stderr}`), lr2 = r.exitCode === 0 ? undefined : await harnessLoadReason({ re
|
|
|
68220
68409
|
async function runAppBoot(ctx, opts, checks, notProven) {
|
|
68221
68410
|
let r;
|
|
68222
68411
|
try {
|
|
68223
|
-
r = await (opts.appProbe ?? appProbe)(ctx.repoDir,
|
|
68412
|
+
r = await (opts.appProbe ?? appProbe)(ctx.repoDir, join96(ctx.repoDir, ".loki"));
|
|
68224
68413
|
} catch (err) {
|
|
68225
68414
|
r = { checks: [{ name: "app boot", cmd: "autonomy/app-runner.sh", result: "not_run", duration_s: 0, reason: `app probe threw: ${err.message}` }], pid: null, url: null };
|
|
68226
68415
|
}
|
|
@@ -68278,7 +68467,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
|
68278
68467
|
}
|
|
68279
68468
|
const inline = 'script="$1"; shift; . "$script" || exit 3; hit=0; for f in "$@"; do if _commit_scan_secret_file "$f" || _commit_path_looks_secret "$f"; then printf "%s\\n" "$f"; hit=1; fi; done; exit "$hit"';
|
|
68280
68469
|
const started = Date.now();
|
|
68281
|
-
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) =>
|
|
68470
|
+
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join96(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
|
|
68282
68471
|
const sec = await secureScanChanged(ctx.repoDir, changed, opts.secureScanPath), gaps = [], reasons = [];
|
|
68283
68472
|
const hits = r.exitCode === 3 ? [] : r.stdout.split(`
|
|
68284
68473
|
`).map((l) => l.trim()).filter(Boolean), high = sec.findings.filter((f) => String(f.severity).toUpperCase() === "HIGH");
|
|
@@ -68331,7 +68520,7 @@ async function runDeep(ctx, signal, opts = {}) {
|
|
|
68331
68520
|
const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
|
|
68332
68521
|
const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
68333
68522
|
mkdirSync49(ctx.runDir, { recursive: true });
|
|
68334
|
-
writeFileSync48(
|
|
68523
|
+
writeFileSync48(join96(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
|
|
68335
68524
|
`);
|
|
68336
68525
|
const headSha = (await safeGitRun(ctx.repoDir, ["rev-parse", "HEAD"], { timeoutMs: 1e4 })).stdout.trim();
|
|
68337
68526
|
const pushNotProven = await postDeepResults({
|
|
@@ -68357,11 +68546,11 @@ async function deepWorker(args, deps = {}) {
|
|
|
68357
68546
|
`);
|
|
68358
68547
|
return 2;
|
|
68359
68548
|
}
|
|
68360
|
-
const repoDir = process.cwd(), lokiRoot =
|
|
68549
|
+
const repoDir = process.cwd(), lokiRoot = join96(repoDir, ".loki"), runDir = join96(lokiRoot, "runs", runId);
|
|
68361
68550
|
const { readEvents: readEvents2 } = await Promise.resolve().then(() => (init_events(), exports_events)), { eventsRelPath: eventsRelPath2 } = await Promise.resolve().then(() => (init_engine_origin(), exports_engine_origin)), { outputsFromEvents: outputsFromEvents2 } = await Promise.resolve().then(() => (init_run_outputs(), exports_run_outputs));
|
|
68362
68551
|
let outputs;
|
|
68363
68552
|
try {
|
|
68364
|
-
outputs = outputsFromEvents2(readEvents2(
|
|
68553
|
+
outputs = outputsFromEvents2(readEvents2(join96(repoDir, eventsRelPath2(runId))));
|
|
68365
68554
|
} catch (err) {
|
|
68366
68555
|
process.stderr.write(`engine10 deep-worker: cannot read run events: ${err.message}
|
|
68367
68556
|
`);
|
|
@@ -68451,9 +68640,9 @@ __export(exports_verify, {
|
|
|
68451
68640
|
commandFor: () => commandFor,
|
|
68452
68641
|
changedFiles: () => changedFiles
|
|
68453
68642
|
});
|
|
68454
|
-
import { existsSync as existsSync68, mkdtempSync as mkdtempSync13, readFileSync as
|
|
68643
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync13, readFileSync as readFileSync86, rmSync as rmSync28 } from "fs";
|
|
68455
68644
|
import { tmpdir as tmpdir16 } from "os";
|
|
68456
|
-
import { basename as basename25, isAbsolute as isAbsolute18, join as
|
|
68645
|
+
import { basename as basename25, isAbsolute as isAbsolute18, join as join97, relative as relative21 } from "path";
|
|
68457
68646
|
async function runOnce3(cmd, args, cwd, signal, opts) {
|
|
68458
68647
|
if (!Bun.which(cmd, { PATH: opts.path ?? process.env["PATH"] ?? "" }))
|
|
68459
68648
|
return { ok: false, missing: true, cut: false, out: "" };
|
|
@@ -68535,7 +68724,7 @@ async function probeZeroChecks(repoDir, tests, signal, budgetS = 120, cap = 300)
|
|
|
68535
68724
|
rmNewUntracked(repoDir, before);
|
|
68536
68725
|
return { measured: measured.sort(), zero: zero.sort() };
|
|
68537
68726
|
}
|
|
68538
|
-
async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true, zeroIntake = new Set) {
|
|
68727
|
+
async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true, zeroIntake = new Set, dep = new Set) {
|
|
68539
68728
|
const out3 = { ids: [], names: [], weak: [], zero: [], cnt: {} };
|
|
68540
68729
|
const pairs = checks.flatMap((c) => {
|
|
68541
68730
|
const t = tests.find((x3) => testCheckName(x3) === c.name);
|
|
@@ -68546,7 +68735,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68546
68735
|
const zc2 = zeroOk ? un2.filter(({ c, t }) => c.result === "not_run" && !c.owner && (c.reason ?? "").startsWith(NO_TESTS_REASON) && !wall.has(c.name) && !isHoldoutCheck(c.name) && !changed.includes(t.path) && zeroIntake.has(c.name)) : [];
|
|
68547
68736
|
if (!(un2.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length || zc2.length) || signal.aborted)
|
|
68548
68737
|
return out3;
|
|
68549
|
-
const dir = mkdtempSync13(
|
|
68738
|
+
const dir = mkdtempSync13(join97(tmpdir16(), "e10-base-"));
|
|
68550
68739
|
const git9 = (args) => {
|
|
68551
68740
|
safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
|
|
68552
68741
|
};
|
|
@@ -68565,9 +68754,9 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68565
68754
|
out3.cnt[c.name] = { b: { run: base.get(c).n, skipped: base.get(c).sk }, h: { run: c.n ?? 0, skipped: c.sk ?? 0 } };
|
|
68566
68755
|
}
|
|
68567
68756
|
const progress = checks.some((c) => wall.has(c.name) && c.result === "pass") || sus.some(({ c }) => !out3.weak.includes(c.name) && base.get(c).red.length > 0 && (c.n ?? 0) >= base.get(c).n);
|
|
68568
|
-
|
|
68757
|
+
{
|
|
68569
68758
|
for (const { c } of un2) {
|
|
68570
|
-
if (!rel.has(c.name) && c.result === "fail" && c.ids?.length && c.ids.every((i) => base.get(c).red.includes(i))) {
|
|
68759
|
+
if ((progress || dep.has(c.name)) && !rel.has(c.name) && c.result === "fail" && c.ids?.length && c.ids.every((i) => base.get(c).red.includes(i))) {
|
|
68571
68760
|
out3.names.push(c.name);
|
|
68572
68761
|
out3.ids.push(...c.ids);
|
|
68573
68762
|
}
|
|
@@ -68585,15 +68774,15 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68585
68774
|
return out3;
|
|
68586
68775
|
}
|
|
68587
68776
|
function isLokiModeRepo(repoDir) {
|
|
68588
|
-
return existsSync68(
|
|
68777
|
+
return existsSync68(join97(repoDir, "scripts", "select-tests.sh"));
|
|
68589
68778
|
}
|
|
68590
68779
|
function projectDeclaresRuff(repoDir) {
|
|
68591
|
-
if (["ruff.toml", ".ruff.toml"].some((f) => existsSync68(
|
|
68780
|
+
if (["ruff.toml", ".ruff.toml"].some((f) => existsSync68(join97(repoDir, f))))
|
|
68592
68781
|
return true;
|
|
68593
68782
|
const files = ["pyproject.toml", "setup.cfg", "tox.ini", ".pre-commit-config.yaml", "Pipfile", "requirements.txt", "requirements-dev.txt", "dev-requirements.txt"];
|
|
68594
68783
|
return files.some((f) => {
|
|
68595
68784
|
try {
|
|
68596
|
-
return /\bruff\b/i.test(
|
|
68785
|
+
return /\bruff\b/i.test(readFileSync86(join97(repoDir, f), "utf8"));
|
|
68597
68786
|
} catch {
|
|
68598
68787
|
return false;
|
|
68599
68788
|
}
|
|
@@ -68619,9 +68808,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
68619
68808
|
}
|
|
68620
68809
|
for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
|
|
68621
68810
|
const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
|
|
68622
|
-
if (existsSync68(
|
|
68811
|
+
if (existsSync68(join97(g.cwd, "tsconfig.json")))
|
|
68623
68812
|
await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["--no-install", "tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
|
|
68624
|
-
if (ESLINT_CONFIGS.some((f) => existsSync68(
|
|
68813
|
+
if (ESLINT_CONFIGS.some((f) => existsSync68(join97(g.cwd, f)))) {
|
|
68625
68814
|
const c = await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["--no-install", "eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
|
|
68626
68815
|
if (await excuseLint(ctx, signal, c, "eslint", "npx", ["--no-install", "eslint"], g.cwd, g.rel, co))
|
|
68627
68816
|
pre2.push(c.name);
|
|
@@ -68636,7 +68825,7 @@ var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name),
|
|
|
68636
68825
|
return r.missing || r.cut ? null : r;
|
|
68637
68826
|
}, base: (f) => {
|
|
68638
68827
|
try {
|
|
68639
|
-
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative21(ctx.repoDir,
|
|
68828
|
+
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative21(ctx.repoDir, join97(cwd, f))}`], { stdio: ["ignore", "pipe", "ignore"] });
|
|
68640
68829
|
} catch {
|
|
68641
68830
|
return null;
|
|
68642
68831
|
}
|
|
@@ -68648,6 +68837,7 @@ var init_verify = __esm(() => {
|
|
|
68648
68837
|
init_assert_delta();
|
|
68649
68838
|
init_failures();
|
|
68650
68839
|
init_select();
|
|
68840
|
+
init_dependents();
|
|
68651
68841
|
init_load_owner();
|
|
68652
68842
|
init_sizing();
|
|
68653
68843
|
init_testmap();
|
|
@@ -68711,7 +68901,8 @@ var init_verify = __esm(() => {
|
|
|
68711
68901
|
const runner = rec2 ?? guessRunner(basename25(p), map.runners, p);
|
|
68712
68902
|
return runner && (runner !== "bun" || map.runners.includes("bun") || /[._](?:test|spec)\.[cm]?[jt]sx?$/.test(p)) ? [{ runner, path: p }] : [];
|
|
68713
68903
|
});
|
|
68714
|
-
const
|
|
68904
|
+
const dep = dependentTests(ctx.repoDir, map, changed, [...impacted, ...changedTestFiles, ...wallTests, ...relevant2]), depNames = new Set(dep.tests.map(testCheckName));
|
|
68905
|
+
const tests = failedFirst(dedupeTests([...impacted, ...dep.tests, ...changedTestFiles, ...wallTests, ...relevant2]), ctx.outputs().verify?.checks);
|
|
68715
68906
|
const scopedOut = scopedOutOf(map);
|
|
68716
68907
|
if (scopedOut.length)
|
|
68717
68908
|
ctx.emit("test.scoped_out", "verify", { tests: scopedOut });
|
|
@@ -68740,7 +68931,7 @@ var init_verify = __esm(() => {
|
|
|
68740
68931
|
}
|
|
68741
68932
|
const targetNames = new Set([...[...wallTests, ...relevant2].map(testCheckName), ...checks.filter(isHold).map((c) => c.name)]);
|
|
68742
68933
|
const cfgChanged = testConfigChanged(ctx.repoDir, ctx.baseSha, changed);
|
|
68743
|
-
const preRed = await subtractBase(ctx, api, checks, tests, changed, new Set(wallTests.map(testCheckName)), new Set(relevant2.map(testCheckName)), signal, cfgChanged.length === 0, new Set(ctx.outputs().intake?.zero_baseline?.zero ?? []));
|
|
68934
|
+
const preRed = await subtractBase(ctx, api, checks, tests, changed, new Set(wallTests.map(testCheckName)), new Set(relevant2.map(testCheckName)), signal, cfgChanged.length === 0, new Set(ctx.outputs().intake?.zero_baseline?.zero ?? []), depNames);
|
|
68744
68935
|
const attr = attribute(ctx.repoDir, ctx.baseSha, checks.filter((c) => c.result === "fail" && !preRed.names.includes(c.name)).map((c) => ({ name: c.name, ids: c.ids, eligible: !targetNames.has(c.name) && !changed.includes(c.name.slice(c.name.indexOf(":") + 1)) })));
|
|
68745
68936
|
attr.introducedChecks = [...new Set(attr.introducedChecks.map((n10) => isHoldoutCheck(n10) ? "holdout" : n10))];
|
|
68746
68937
|
preRed.names.push(...attr.preExistingChecks);
|
|
@@ -68808,11 +68999,11 @@ ${x3}` : c.cmd };
|
|
|
68808
68999
|
return [`weakened test: ${t.path}`, ...assertDeltaNotes(ctx.repoDir, ctx.baseSha, null, t.path, intake?.task ?? "", k3?.b, k3?.h) ?? []];
|
|
68809
69000
|
});
|
|
68810
69001
|
const weakened = [...modifiedRel, ...cfgChanged.map((f) => `test configuration changed: ${f}`), ...preRed.weak.map((n10) => `skipped or fewer tests than base: ${n10}`)];
|
|
68811
|
-
const notProven = [...weakened, ...intake?.deps_not_proven ?? [], ...pub.filter((c) => c.name === "holdout" && c.result !== "pass").map((c) => c.result === "not_run" ? "holdout not executed" : "holdout check failed"), ...[...fullNotProven].filter((n10) => !naNote(n10)), ...pub.filter((c) => c.owner === "harness" && c.name !== "holdout").map((c) => `${c.reason} (${c.name}; harness-owned, no fix rounds)`), ...new Set(checks.filter((c) => c.interpreter === "system" && c.result !== "not_run").map((c) => c.name.startsWith("lint:") ? "lint ran on the system ruff" : "tests ran on the system interpreter"))];
|
|
69002
|
+
const notProven = [...weakened, ...dependentNotes(dep), ...intake?.deps_not_proven ?? [], ...pub.filter((c) => c.name === "holdout" && c.result !== "pass").map((c) => c.result === "not_run" ? "holdout not executed" : "holdout check failed"), ...[...fullNotProven].filter((n10) => !naNote(n10)), ...pub.filter((c) => c.owner === "harness" && c.name !== "holdout").map((c) => `${c.reason} (${c.name}; harness-owned, no fix rounds)`), ...new Set(checks.filter((c) => c.interpreter === "system" && c.result !== "not_run").map((c) => c.name.startsWith("lint:") ? "lint ran on the system ruff" : "tests ran on the system interpreter"))];
|
|
68812
69003
|
const wallDropped2 = [...wallPaths].filter((p) => !wallTests.some((t) => t.path === p));
|
|
68813
69004
|
notProven.push(...wallDropped2.map((p) => `Wall test not executed: ${p}: ${NO_RUNNER_REASON}`));
|
|
68814
69005
|
const wallNames = new Set(wallTests.map(testCheckName)), wallRun = checks.filter((c) => wallNames.has(c.name) || isHold(c)), wallPassed = wallRun.some((c) => c.result === "fail") ? false : wallRun.length > 0 && wallDropped2.length === 0 && wallRun.every((c) => c.result === "pass") ? true : undefined;
|
|
68815
|
-
return { status: "completed", data: { checks: pub, flaky, ...wallPassed === undefined ? {} : { wall_passed: wallPassed }, failures_grouped: failuresGrouped, holdout_failed: holdoutFailed, changed_files: changed, not_proven: notProven, ...fullNotProven.size ? { not_applicable: [...fullNotProven].filter(naNote).map(naText) } : {}, pre_red: preRed.ids, pre_red_checks: preRed.names, skipped_on_base: preRed.zero, ...attr.line ? { baseline_line: attr.line, introduced_checks: attr.introducedChecks } : {}, test_counts: testCounts, uncovered_changed: uncoveredChanged, target_checks: checks.filter((c) => c.result === "pass" && targetNames.has(c.name)).map((c) => isHold(c) ? "holdout" : c.name), risk } };
|
|
69006
|
+
return { status: "completed", data: { checks: pub, flaky, ...wallPassed === undefined ? {} : { wall_passed: wallPassed }, failures_grouped: failuresGrouped, holdout_failed: holdoutFailed, changed_files: changed, ...depNames.size ? { dependent_checks: [...depNames] } : {}, not_proven: notProven, ...fullNotProven.size ? { not_applicable: [...fullNotProven].filter(naNote).map(naText) } : {}, pre_red: preRed.ids, pre_red_checks: preRed.names, skipped_on_base: preRed.zero, ...attr.line ? { baseline_line: attr.line, introduced_checks: attr.introducedChecks } : {}, test_counts: testCounts, uncovered_changed: uncoveredChanged, target_checks: checks.filter((c) => c.result === "pass" && targetNames.has(c.name)).map((c) => isHold(c) ? "holdout" : c.name), risk } };
|
|
68816
69007
|
}
|
|
68817
69008
|
};
|
|
68818
69009
|
stage5 = verifyStage;
|
|
@@ -68843,9 +69034,9 @@ __export(exports_wall, {
|
|
|
68843
69034
|
BASE_RUN_TIMEOUT_MS: () => BASE_RUN_TIMEOUT_MS
|
|
68844
69035
|
});
|
|
68845
69036
|
import { spawnSync as spawnSync10 } from "child_process";
|
|
68846
|
-
import { existsSync as existsSync69, mkdirSync as mkdirSync50, mkdtempSync as mkdtempSync14, readFileSync as
|
|
69037
|
+
import { existsSync as existsSync69, mkdirSync as mkdirSync50, mkdtempSync as mkdtempSync14, readFileSync as readFileSync87, readdirSync as readdirSync28, rmSync as rmSync29, writeFileSync as writeFileSync49 } from "fs";
|
|
68847
69038
|
import { tmpdir as tmpdir17 } from "os";
|
|
68848
|
-
import { dirname as
|
|
69039
|
+
import { dirname as dirname39, join as join98, relative as relative22 } from "path";
|
|
68849
69040
|
|
|
68850
69041
|
class RealBaseTestRunner {
|
|
68851
69042
|
api;
|
|
@@ -68911,10 +69102,10 @@ ${acceptance2.map((a) => `Acceptance: ${a}`).join(`
|
|
|
68911
69102
|
function loadTaskText(ctx, fromPrior) {
|
|
68912
69103
|
if (fromPrior)
|
|
68913
69104
|
return fromPrior;
|
|
68914
|
-
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ??
|
|
69105
|
+
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join98(ctx.runDir, "issue.json");
|
|
68915
69106
|
if (existsSync69(issueJsonPath)) {
|
|
68916
69107
|
try {
|
|
68917
|
-
const issue = JSON.parse(
|
|
69108
|
+
const issue = JSON.parse(readFileSync87(issueJsonPath, "utf8"));
|
|
68918
69109
|
const text3 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
|
|
68919
69110
|
|
|
68920
69111
|
`);
|
|
@@ -68924,9 +69115,11 @@ function loadTaskText(ctx, fromPrior) {
|
|
|
68924
69115
|
}
|
|
68925
69116
|
return process.env.LOKI_E10_TASK_TEXT ?? "";
|
|
68926
69117
|
}
|
|
68927
|
-
function wallTargetDir(repoDir, existingTests) {
|
|
69118
|
+
function wallTargetDir(repoDir, existingTests, runners = []) {
|
|
68928
69119
|
const first = existingTests[0];
|
|
68929
|
-
|
|
69120
|
+
if (!first && runners.some((r) => r === "maven" || r === "gradle" || r === "javac"))
|
|
69121
|
+
return join98(repoDir, "src", "test", "java");
|
|
69122
|
+
return first ? join98(repoDir, dirname39(first.path)) : join98(repoDir, "tests");
|
|
68930
69123
|
}
|
|
68931
69124
|
async function wallAuthor(ctx, signal, retry) {
|
|
68932
69125
|
const done = (result) => ({ kind: "done", result });
|
|
@@ -68945,18 +69138,20 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
68945
69138
|
if (!ctx.externalPatch && planMode() !== "always" && smallTaskPath(sz2.size, hasRelevantTests(task, repoMap, testMap, ctx.tests.impacted)) === "lean") {
|
|
68946
69139
|
return done({ status: "skipped", data: { size: sz2.size }, reason: "small task with a relevant test: cascade skips Wall" });
|
|
68947
69140
|
}
|
|
68948
|
-
if (testMap && runners.length === 0)
|
|
68949
|
-
|
|
69141
|
+
if (testMap && runners.length === 0) {
|
|
69142
|
+
const miss = missingJavaTool(repoMap?.files ?? [], process.env, ctx.repoDir);
|
|
69143
|
+
return done({ status: "skipped", data: { size: sz2.size, files: [], no_runner: true, skip_code: harnessSkipCode(), not_proven: [miss ? `Wall not run: ${miss} is not installed on this machine, so this Java repo could not be tested (harness-owned)` : "Wall skipped: no runnable test command for this stack"] }, reason: miss ? `${miss} is not installed: the Wall cannot run Java tests (harness-owned, not proven)` : "no runnable test command detected: the Wall cannot write a runnable check" });
|
|
69144
|
+
}
|
|
68950
69145
|
if (testMap && runners.every((r) => r === "pytest") && projectInterpreter(ctx.repoDir) === "system" && wallHoldoutRatio() === 0)
|
|
68951
69146
|
return done({ status: "skipped", data: { size: sz2.size, files: [], no_interpreter: true, not_proven: ["Wall skipped: no project test interpreter"] }, reason: "Wall skipped: no project test interpreter" });
|
|
68952
69147
|
const tree = prior.intake?.tree;
|
|
68953
69148
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
68954
|
-
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative22(ctx.repoDir, targetDir)}/x`);
|
|
68955
|
-
const conv2 = readPackageConventions(
|
|
68956
|
-
const cwd = mkdtempSync14(
|
|
69149
|
+
const targetDir = wallTargetDir(ctx.repoDir, existingTests, runners), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative22(ctx.repoDir, targetDir)}/x`);
|
|
69150
|
+
const conv2 = readPackageConventions(join98(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
69151
|
+
const cwd = mkdtempSync14(join98(tmpdir17(), "loki-e15-wall-"));
|
|
68957
69152
|
const wm2 = wallManifestFor(ctx.repoDir, tree, task);
|
|
68958
69153
|
for (const [n10, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm2 ? [["wall_manifest.txt", wm2.text]] : []])
|
|
68959
|
-
writeFileSync49(
|
|
69154
|
+
writeFileSync49(join98(cwd, n10), c, "utf8");
|
|
68960
69155
|
const clauseSet = extractClauses(task);
|
|
68961
69156
|
const model = retry?.model ?? wallFirstModel(sz2.size), iterationId = `${ctx.runId}-wall${retry?.suffix ?? ""}`;
|
|
68962
69157
|
const session = await ctx.sessions.run({
|
|
@@ -68975,21 +69170,21 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
68975
69170
|
}
|
|
68976
69171
|
const planText = typeof prior.plan?.plan === "string" ? prior.plan.plan : null, repoFiles = repoMap?.files ?? [];
|
|
68977
69172
|
const oor = () => readdirSync28(cwd).filter((f) => f.startsWith(WALL_PREFIX)).flatMap((name) => {
|
|
68978
|
-
const text3 =
|
|
69173
|
+
const text3 = readFileSync87(join98(cwd, name), "utf8"), why = outOfRepoTarget(text3) ?? vacuousCheck(name, text3) ?? phantomReason(phantomRepoPaths(text3, name, targetDir, ctx.repoDir, planText), repoFiles, relative22(ctx.repoDir, targetDir), pkg?.root ?? "");
|
|
68979
69174
|
return why ? [{ name, why }] : [];
|
|
68980
69175
|
});
|
|
68981
69176
|
const bad1 = oor();
|
|
68982
69177
|
if (bad1.length > 0 && !signal.aborted && !ctx.overCap?.())
|
|
68983
69178
|
await ctx.sessions.run({ stage: "wall", brief: withStagePrefix(outOfRepoReask("Rewrite these Wall files in place, keeping the same names and acceptance coverage.", bad1)), tier: "development", model, iterationId: `${iterationId}-oor`, limitS: wallLimitS(sz2.size), signal, cwd });
|
|
68984
|
-
const oorBad = new Map(oor().map((b) => [b.name, b.why])), all = readdirSync28(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n10) => !oorBad.has(n10) && !conventionViolation(conv2, n10,
|
|
68985
|
-
const sealedDir =
|
|
69179
|
+
const oorBad = new Map(oor().map((b) => [b.name, b.why])), all = readdirSync28(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n10) => !oorBad.has(n10) && !conventionViolation(conv2, n10, readFileSync87(join98(cwd, n10), "utf8"))), runnerOf: (n10) => guessRunner(n10, runners) }), generated = all.filter((n10) => !held?.names.has(n10));
|
|
69180
|
+
const sealedDir = join98(ctx.runDir, "wall");
|
|
68986
69181
|
if (generated.length > 0)
|
|
68987
69182
|
mkdirSync50(sealedDir, { recursive: true });
|
|
68988
69183
|
const contents = new Map;
|
|
68989
69184
|
const discarded = [];
|
|
68990
69185
|
for (const name of generated) {
|
|
68991
|
-
const content =
|
|
68992
|
-
writeFileSync49(
|
|
69186
|
+
const content = readFileSync87(join98(cwd, name), "utf8"), oorWhy = oorBad.get(name), bad = oorWhy ?? conventionViolation(conv2, name, content);
|
|
69187
|
+
writeFileSync49(join98(sealedDir, name), content, "utf8");
|
|
68993
69188
|
if (oorWhy)
|
|
68994
69189
|
discarded.push({ file: name, reason: `${oorWhy}; wall test discarded after one rewrite request` });
|
|
68995
69190
|
else if (bad)
|
|
@@ -69018,7 +69213,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
69018
69213
|
const content = contents.get(name);
|
|
69019
69214
|
if (content === undefined)
|
|
69020
69215
|
continue;
|
|
69021
|
-
const dest =
|
|
69216
|
+
const dest = join98(targetDir, name), runner = guessRunner(name, runners, relative22(ctx.repoDir, dest));
|
|
69022
69217
|
writeFileSync49(dest, content, "utf8");
|
|
69023
69218
|
sealedFiles.push({ path: dest, sha256: sha2562(content), ...runner ? { runner } : {} });
|
|
69024
69219
|
readOnlyFiles.push({ path: dest, content });
|
|
@@ -69035,7 +69230,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
69035
69230
|
}
|
|
69036
69231
|
const each = yield { runner: baseRunner, tests: wallTests };
|
|
69037
69232
|
for (const [i, t] of wallTests.entries()) {
|
|
69038
|
-
const e10 = each?.[i], r = e10 ?? baseRunner.run(baseDir, [t]), abs =
|
|
69233
|
+
const e10 = each?.[i], r = e10 ?? baseRunner.run(baseDir, [t]), abs = join98(ctx.repoDir, t.path);
|
|
69039
69234
|
baseRun.pass += r.pass;
|
|
69040
69235
|
baseRun.fail += r.fail;
|
|
69041
69236
|
baseRun.not_run += r.not_run ?? 0;
|
|
@@ -69078,7 +69273,7 @@ async function runWall(ctx, signal, opts = {}) {
|
|
|
69078
69273
|
if (a.kind === "authored") {
|
|
69079
69274
|
for (const f of first.data.files ?? [])
|
|
69080
69275
|
rmSync29(f.path, { force: true });
|
|
69081
|
-
rmSync29(
|
|
69276
|
+
rmSync29(join98(ctx.runDir, "wall"), { recursive: true, force: true });
|
|
69082
69277
|
ctx.wallSealed = false;
|
|
69083
69278
|
}
|
|
69084
69279
|
removeHoldout(ctx.runId, ctx.repoDir);
|
|
@@ -69118,15 +69313,15 @@ var init_wall = __esm(() => {
|
|
|
69118
69313
|
});
|
|
69119
69314
|
|
|
69120
69315
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
69121
|
-
import { chmodSync as chmodSync6, closeSync as closeSync14, lstatSync as lstatSync26, mkdirSync as mkdirSync51, openSync as openSync14, readFileSync as
|
|
69122
|
-
import { dirname as
|
|
69316
|
+
import { chmodSync as chmodSync6, closeSync as closeSync14, lstatSync as lstatSync26, mkdirSync as mkdirSync51, openSync as openSync14, readFileSync as readFileSync88, realpathSync as realpathSync29, rmdirSync, unlinkSync as unlinkSync9, writeFileSync as writeFileSync50 } from "fs";
|
|
69317
|
+
import { dirname as dirname40, join as join99, relative as relative23, sep as sep19 } from "path";
|
|
69123
69318
|
function safeRestore(repoDir, f, want, mode) {
|
|
69124
|
-
const root = realpathSync29(repoDir), fp2 =
|
|
69319
|
+
const root = realpathSync29(repoDir), fp2 = join99(root, f), rel = relative23(root, dirname40(fp2));
|
|
69125
69320
|
if (rel.startsWith(".."))
|
|
69126
69321
|
throw new Error("outside repo");
|
|
69127
69322
|
let cur = root;
|
|
69128
69323
|
for (const part of rel === "" ? [] : rel.split(sep19)) {
|
|
69129
|
-
cur =
|
|
69324
|
+
cur = join99(cur, part);
|
|
69130
69325
|
let st3;
|
|
69131
69326
|
try {
|
|
69132
69327
|
st3 = lstatSync26(cur);
|
|
@@ -69143,7 +69338,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
69143
69338
|
} catch {
|
|
69144
69339
|
st2 = null;
|
|
69145
69340
|
}
|
|
69146
|
-
if (st2?.isFile() &&
|
|
69341
|
+
if (st2?.isFile() && readFileSync88(fp2).equals(want)) {
|
|
69147
69342
|
chmodSync6(fp2, mode);
|
|
69148
69343
|
return;
|
|
69149
69344
|
}
|
|
@@ -69180,7 +69375,7 @@ async function discardIfSatisfied(git9, base, o, staged, keep, repoDir) {
|
|
|
69180
69375
|
return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
|
|
69181
69376
|
const notProven = [];
|
|
69182
69377
|
for (const [f, v3] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
|
|
69183
|
-
const fp2 =
|
|
69378
|
+
const fp2 = join99(repoDir, f);
|
|
69184
69379
|
try {
|
|
69185
69380
|
if (v3.startsWith("!")) {
|
|
69186
69381
|
const st2 = lstatSync26(fp2);
|
|
@@ -69199,7 +69394,7 @@ async function discardIfSatisfied(git9, base, o, staged, keep, repoDir) {
|
|
|
69199
69394
|
try {
|
|
69200
69395
|
let m = 420;
|
|
69201
69396
|
try {
|
|
69202
|
-
const l = lstatSync26(
|
|
69397
|
+
const l = lstatSync26(join99(repoDir, f));
|
|
69203
69398
|
if (l.isFile())
|
|
69204
69399
|
m = l.mode & 511;
|
|
69205
69400
|
} catch {}
|
|
@@ -69215,7 +69410,7 @@ var init_discard = __esm(() => {
|
|
|
69215
69410
|
});
|
|
69216
69411
|
|
|
69217
69412
|
// ../../loki-ts/src/e10ext/scope.ts
|
|
69218
|
-
import { basename as basename26, dirname as
|
|
69413
|
+
import { basename as basename26, dirname as dirname41 } from "path";
|
|
69219
69414
|
function contractText(o) {
|
|
69220
69415
|
const c = o.intake?.contract_snapshot?.contract;
|
|
69221
69416
|
return Array.isArray(c?.criteria) ? c.criteria.map((x3) => typeof x3?.text === "string" ? x3.text : "").join(`
|
|
@@ -69229,8 +69424,8 @@ function outsideScope(o, staged) {
|
|
|
69229
69424
|
const text3 = `${plan}
|
|
69230
69425
|
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
69231
69426
|
${contractText(o)}`, pre2 = o.intake?.preexisting_dirty ?? {};
|
|
69232
|
-
const toks = surfaceTokens(text3), plannedDirs = new Set(rel.map((r) =>
|
|
69233
|
-
return staged.filter(({ st: st2, f }) => st2 !== "A" && !isTestFile(f) && !Object.hasOwn(pre2, f) && !rel.includes(f) && !mentions(text3, f) && !mentions(text3, basename26(f)) && !plannedDirs.has(
|
|
69427
|
+
const toks = surfaceTokens(text3), plannedDirs = new Set(rel.map((r) => dirname41(r)).filter((d) => d !== "."));
|
|
69428
|
+
return staged.filter(({ st: st2, f }) => st2 !== "A" && !isTestFile(f) && !Object.hasOwn(pre2, f) && !rel.includes(f) && !mentions(text3, f) && !mentions(text3, basename26(f)) && !plannedDirs.has(dirname41(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
|
|
69234
69429
|
}
|
|
69235
69430
|
function flagOutsideScope(o, staged) {
|
|
69236
69431
|
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
@@ -69245,14 +69440,14 @@ var init_scope2 = __esm(() => {
|
|
|
69245
69440
|
});
|
|
69246
69441
|
|
|
69247
69442
|
// ../../loki-ts/src/council/role_agents.ts
|
|
69248
|
-
import { existsSync as existsSync70, readdirSync as readdirSync29, readFileSync as
|
|
69443
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, readFileSync as readFileSync89 } from "fs";
|
|
69249
69444
|
import { homedir as homedir11 } from "os";
|
|
69250
|
-
import { join as
|
|
69445
|
+
import { join as join100 } from "path";
|
|
69251
69446
|
function agentDirs(repoDir, env = process.env) {
|
|
69252
|
-
return [env["LOKI_AGENTS_PROJECT_DIR"] ||
|
|
69447
|
+
return [env["LOKI_AGENTS_PROJECT_DIR"] || join100(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join100(env["XDG_CONFIG_HOME"] || join100(homedir11(), ".config"), "loki", "agents")];
|
|
69253
69448
|
}
|
|
69254
69449
|
function parseAgent(file, stem2) {
|
|
69255
|
-
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(
|
|
69450
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync89(file, "utf8"));
|
|
69256
69451
|
if (!m)
|
|
69257
69452
|
return null;
|
|
69258
69453
|
const body = m[2].trim();
|
|
@@ -69277,7 +69472,7 @@ function loadRoleAgent(repoDir, role, env = process.env) {
|
|
|
69277
69472
|
const ordered = [...names.filter((n10) => n10 === `${role}.md`), ...names.filter((n10) => n10 !== `${role}.md`)];
|
|
69278
69473
|
for (const n10 of ordered) {
|
|
69279
69474
|
try {
|
|
69280
|
-
const a = parseAgent(
|
|
69475
|
+
const a = parseAgent(join100(d, n10), n10.slice(0, -3));
|
|
69281
69476
|
if (a && a.role === role)
|
|
69282
69477
|
return a;
|
|
69283
69478
|
} catch {}
|
|
@@ -69296,11 +69491,11 @@ function explicitReview(repoDir, env) {
|
|
|
69296
69491
|
if (flag && isOff(ev2))
|
|
69297
69492
|
return "off";
|
|
69298
69493
|
for (const f of ["loki.yaml", "loki.yml"]) {
|
|
69299
|
-
const p =
|
|
69494
|
+
const p = join100(repoDir, f);
|
|
69300
69495
|
if (!existsSync70(p))
|
|
69301
69496
|
continue;
|
|
69302
69497
|
try {
|
|
69303
|
-
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(
|
|
69498
|
+
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync89(p, "utf8"));
|
|
69304
69499
|
const v3 = asProvider(m?.[1]);
|
|
69305
69500
|
if (v3)
|
|
69306
69501
|
return v3;
|
|
@@ -69333,7 +69528,7 @@ var init_role_agents = __esm(() => {
|
|
|
69333
69528
|
|
|
69334
69529
|
// ../../loki-ts/src/util/child_ledger.ts
|
|
69335
69530
|
import { appendFileSync as appendFileSync10, mkdirSync as mkdirSync52 } from "fs";
|
|
69336
|
-
import { join as
|
|
69531
|
+
import { join as join101 } from "path";
|
|
69337
69532
|
function unmeasuredRecord(phase, model, source) {
|
|
69338
69533
|
return { phase, model, input_tokens: 0, output_tokens: 0, cache_creation_tokens: 0, cache_read_tokens: 0, source, cost_status: "unmeasured" };
|
|
69339
69534
|
}
|
|
@@ -69358,9 +69553,9 @@ function recordFromClaudeResult(phase, payload, source = "claude-json") {
|
|
|
69358
69553
|
}
|
|
69359
69554
|
function appendChildLedger(lokiDir2, rec2) {
|
|
69360
69555
|
try {
|
|
69361
|
-
const dir =
|
|
69556
|
+
const dir = join101(lokiDir2, "metrics");
|
|
69362
69557
|
mkdirSync52(dir, { recursive: true });
|
|
69363
|
-
appendFileSync10(
|
|
69558
|
+
appendFileSync10(join101(dir, "child-sessions.jsonl"), `${JSON.stringify(rec2)}
|
|
69364
69559
|
`);
|
|
69365
69560
|
return true;
|
|
69366
69561
|
} catch {
|
|
@@ -69390,7 +69585,7 @@ var init_child_ledger = __esm(() => {
|
|
|
69390
69585
|
});
|
|
69391
69586
|
|
|
69392
69587
|
// ../../loki-ts/src/engine10/stages/xreview.ts
|
|
69393
|
-
import { join as
|
|
69588
|
+
import { join as join102 } from "path";
|
|
69394
69589
|
function minVerdict(verdict, review) {
|
|
69395
69590
|
const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
|
|
69396
69591
|
return RANK4[ceiling] < RANK4[verdict] ? ceiling : verdict;
|
|
@@ -69488,9 +69683,9 @@ Review ONLY the diff below. Do not modify files.` : "You are an independent code
|
|
|
69488
69683
|
try {
|
|
69489
69684
|
if (p === "claude")
|
|
69490
69685
|
await ensureClaudeHelpCache();
|
|
69491
|
-
const r = await withChildLedger(run,
|
|
69686
|
+
const r = await withChildLedger(run, join102(ctx.repoDir, ".loki"), "xreview")(reviewArgv(p, prompt, process.env, p === "claude" ? agent?.model || pin : undefined), { cwd: ctx.repoDir, timeoutMs: boxFor(ctx) * 1000, group: true, signal });
|
|
69492
69687
|
const costId = `${ctx.runId}-xreview-${p}`;
|
|
69493
|
-
writeReviewerCost(
|
|
69688
|
+
writeReviewerCost(join102(ctx.repoDir, ".loki"), costId, { reviewer: `xreview-${p}`, provider: p, model: p === "claude" ? agent?.model || pin : undefined, stdout: r.stdout, stderr: r.stderr });
|
|
69494
69689
|
if (r.exitCode !== 0)
|
|
69495
69690
|
return { ...tag({ provider: p, level: "not_run", notes: [`cross-review not run: ${p} exited ${r.exitCode}`] }), cost_iteration: costId };
|
|
69496
69691
|
return { ...tag(parseReview(p, r.stdout)), cost_iteration: costId };
|
|
@@ -69671,9 +69866,9 @@ __export(exports_contract, {
|
|
|
69671
69866
|
MAX_CONTRACT_BYTES: () => MAX_CONTRACT_BYTES,
|
|
69672
69867
|
CONSTRAINT_KINDS: () => CONSTRAINT_KINDS
|
|
69673
69868
|
});
|
|
69674
|
-
import { existsSync as existsSync71, lstatSync as lstatSync27, mkdirSync as mkdirSync53, readFileSync as
|
|
69869
|
+
import { existsSync as existsSync71, lstatSync as lstatSync27, mkdirSync as mkdirSync53, readFileSync as readFileSync90, rmSync as rmSync30, writeFileSync as writeFileSync51 } from "fs";
|
|
69675
69870
|
import { spawnSync as spawnSync11 } from "child_process";
|
|
69676
|
-
import { dirname as
|
|
69871
|
+
import { dirname as dirname42, join as join103 } from "path";
|
|
69677
69872
|
import { createHash as createHash28 } from "crypto";
|
|
69678
69873
|
function contractEnabled(env = process.env) {
|
|
69679
69874
|
return env["LOKI_CONTRACT"] !== "0";
|
|
@@ -69740,7 +69935,7 @@ function assignCriteria(units, criteria2) {
|
|
|
69740
69935
|
return { units: out3, orphans: criteria2.filter((c) => !owned.has(c.id)) };
|
|
69741
69936
|
}
|
|
69742
69937
|
function groupContractPath(repoDir, groupId) {
|
|
69743
|
-
return
|
|
69938
|
+
return join103(repoDir, ".loki", "groups", groupId.replace(/[^A-Za-z0-9._-]/g, "_"), "contract.json");
|
|
69744
69939
|
}
|
|
69745
69940
|
function freezeGroupContract(repoDir, groupId, units, contract) {
|
|
69746
69941
|
const a = assignCriteria(units, contract.criteria);
|
|
@@ -69748,7 +69943,7 @@ function freezeGroupContract(repoDir, groupId, units, contract) {
|
|
|
69748
69943
|
return { ok: false, reason: `NOT PROVEN: group contract has ${a.orphans.length} criterion owned by no unit: ${a.orphans.map((o) => `${sanitizeCriterion(o.id)} ${sanitizeCriterion(o.text)}`).join("; ")}`, orphans: a.orphans };
|
|
69749
69944
|
const gc2 = { group: groupId, units: a.units, orphans: [] };
|
|
69750
69945
|
const path = groupContractPath(repoDir, groupId);
|
|
69751
|
-
mkdirSync53(
|
|
69946
|
+
mkdirSync53(dirname42(path), { recursive: true });
|
|
69752
69947
|
atomicWriteJson(path, gc2);
|
|
69753
69948
|
return { ok: true, path, contract: gc2 };
|
|
69754
69949
|
}
|
|
@@ -69805,7 +70000,7 @@ function untracedLines(trace) {
|
|
|
69805
70000
|
return trace.criteria.filter((c) => c.status === "no_match").map((c) => `contract ${sanitizeCriterion(c.id)} untraced (no keyword match in changed files): ${sanitizeCriterion(c.text)}`);
|
|
69806
70001
|
}
|
|
69807
70002
|
function contractPath(repoDir) {
|
|
69808
|
-
return
|
|
70003
|
+
return join103(repoDir, ".loki", "contract.json");
|
|
69809
70004
|
}
|
|
69810
70005
|
function readContract(repoDir) {
|
|
69811
70006
|
const p = contractPath(repoDir);
|
|
@@ -69821,7 +70016,7 @@ function readContract(repoDir) {
|
|
|
69821
70016
|
return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
|
|
69822
70017
|
let raw2;
|
|
69823
70018
|
try {
|
|
69824
|
-
raw2 =
|
|
70019
|
+
raw2 = readFileSync90(p);
|
|
69825
70020
|
} catch {
|
|
69826
70021
|
return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
|
|
69827
70022
|
}
|
|
@@ -69893,9 +70088,9 @@ function main3(args) {
|
|
|
69893
70088
|
`);
|
|
69894
70089
|
return 2;
|
|
69895
70090
|
}
|
|
69896
|
-
const contract = parseContract(
|
|
70091
|
+
const contract = parseContract(readFileSync90(file, "utf8"), file);
|
|
69897
70092
|
const out3 = contractPath(repoRoot(process.cwd()));
|
|
69898
|
-
mkdirSync53(
|
|
70093
|
+
mkdirSync53(dirname42(out3), { recursive: true });
|
|
69899
70094
|
writeFileSync51(out3, JSON.stringify(contract, null, 2) + `
|
|
69900
70095
|
`);
|
|
69901
70096
|
process.stdout.write(renderContract(contract));
|
|
@@ -69952,7 +70147,7 @@ function fromSpecText(raw2) {
|
|
|
69952
70147
|
}
|
|
69953
70148
|
}
|
|
69954
70149
|
function fromPrdText(text3, python = "python3") {
|
|
69955
|
-
const script =
|
|
70150
|
+
const script = join103(REPO_ROOT, "autonomy", "lib", "requirements_contract.py");
|
|
69956
70151
|
if (!existsSync71(script))
|
|
69957
70152
|
return null;
|
|
69958
70153
|
const code = `import sys,json,importlib.util as u
|
|
@@ -69995,12 +70190,12 @@ function mapRequirements(reqs, ran2, revision) {
|
|
|
69995
70190
|
return { version: 1, revision, requirements: out3 };
|
|
69996
70191
|
}
|
|
69997
70192
|
function fromChecklist(lokiDir2) {
|
|
69998
|
-
const p =
|
|
70193
|
+
const p = join103(lokiDir2, "checklist", "checklist.json");
|
|
69999
70194
|
if (!existsSync71(p))
|
|
70000
70195
|
return null;
|
|
70001
70196
|
let doc;
|
|
70002
70197
|
try {
|
|
70003
|
-
doc = JSON.parse(
|
|
70198
|
+
doc = JSON.parse(readFileSync90(p, "utf8"));
|
|
70004
70199
|
} catch {
|
|
70005
70200
|
return null;
|
|
70006
70201
|
}
|
|
@@ -70032,7 +70227,7 @@ function writeRequirementsMap(repoDir, lokiDir2, reqs, ran2) {
|
|
|
70032
70227
|
if (!reqs || reqs.length === 0)
|
|
70033
70228
|
return null;
|
|
70034
70229
|
const m = mapRequirements(reqs, ran2, currentRevision(repoDir));
|
|
70035
|
-
atomicWriteJson(
|
|
70230
|
+
atomicWriteJson(join103(lokiDir2, "state", "requirements-map.json"), m);
|
|
70036
70231
|
return m;
|
|
70037
70232
|
} catch {
|
|
70038
70233
|
return null;
|
|
@@ -70044,17 +70239,17 @@ function writeFromChecklist(repoDir, lokiDir2) {
|
|
|
70044
70239
|
}
|
|
70045
70240
|
function writeFromEngine10(repoDir, lokiDir2, runDir, task, events2) {
|
|
70046
70241
|
let reqs = null;
|
|
70047
|
-
const snap =
|
|
70242
|
+
const snap = join103(runDir, "spec.snapshot.md");
|
|
70048
70243
|
if (existsSync71(snap)) {
|
|
70049
70244
|
try {
|
|
70050
|
-
reqs = fromSpecText(
|
|
70245
|
+
reqs = fromSpecText(readFileSync90(snap, "utf8"));
|
|
70051
70246
|
} catch {
|
|
70052
70247
|
reqs = null;
|
|
70053
70248
|
}
|
|
70054
70249
|
}
|
|
70055
70250
|
if (!reqs && task)
|
|
70056
70251
|
reqs = fromPrdText(task);
|
|
70057
|
-
const mapPath =
|
|
70252
|
+
const mapPath = join103(lokiDir2, "state", "requirements-map.json");
|
|
70058
70253
|
if (!reqs || reqs.length === 0) {
|
|
70059
70254
|
try {
|
|
70060
70255
|
rmSync30(mapPath, { force: true });
|
|
@@ -70080,7 +70275,7 @@ function uncoveredCount(m) {
|
|
|
70080
70275
|
}
|
|
70081
70276
|
function readRequirementsMap(lokiDir2) {
|
|
70082
70277
|
try {
|
|
70083
|
-
const m = JSON.parse(
|
|
70278
|
+
const m = JSON.parse(readFileSync90(join103(lokiDir2, "state", "requirements-map.json"), "utf8"));
|
|
70084
70279
|
return m.version === 1 && Array.isArray(m.requirements) ? m : null;
|
|
70085
70280
|
} catch {
|
|
70086
70281
|
return null;
|
|
@@ -70108,17 +70303,17 @@ var init_contract = __esm(() => {
|
|
|
70108
70303
|
BULLET = /^\s*(?:[-*+]|\d+[.)])\s+(.+)$/;
|
|
70109
70304
|
STOP3 = new Set(["the", "and", "for", "with", "that", "this", "must", "should", "shall", "when", "then", "are", "was", "all", "any", "can", "not", "has", "have", "from", "into", "each", "user", "users"]);
|
|
70110
70305
|
MAX_CONTRACT_BYTES = 1024 * 1024;
|
|
70111
|
-
REQ_MAP_REL =
|
|
70306
|
+
REQ_MAP_REL = join103(".loki", "state", "requirements-map.json");
|
|
70112
70307
|
REQ_STOP = new Set(["with", "that", "this", "from", "have", "will", "should", "must", "when", "then", "into", "each", "every", "user", "users", "page", "able", "allow", "support", "ensure", "using", "their", "there", "which", "shall"]);
|
|
70113
70308
|
LINK_RE = /\s*\[checks?:\s*([^\]]+)\]\s*$/i;
|
|
70114
70309
|
});
|
|
70115
70310
|
|
|
70116
70311
|
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
70117
70312
|
import { createHash as createHash29 } from "crypto";
|
|
70118
|
-
import { existsSync as existsSync72, mkdirSync as mkdirSync54, readdirSync as readdirSync30, readFileSync as
|
|
70119
|
-
import { dirname as
|
|
70313
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync54, readdirSync as readdirSync30, readFileSync as readFileSync91, renameSync as renameSync20, statSync as statSync26, writeFileSync as writeFileSync52 } from "fs";
|
|
70314
|
+
import { dirname as dirname43, join as join104 } from "path";
|
|
70120
70315
|
function sealGroup(runDir, rh) {
|
|
70121
|
-
const manifestPath =
|
|
70316
|
+
const manifestPath = join104(runDir, "group", "manifest.json");
|
|
70122
70317
|
if (!existsSync72(manifestPath))
|
|
70123
70318
|
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
70124
70319
|
const notProven = [];
|
|
@@ -70143,10 +70338,10 @@ function sealGroup(runDir, rh) {
|
|
|
70143
70338
|
return fail2(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
70144
70339
|
seen.add(id2);
|
|
70145
70340
|
seenLower.add(id2.toLowerCase());
|
|
70146
|
-
const dir =
|
|
70341
|
+
const dir = join104(unitsDir(runDir), id2), rp = join104(dir, "receipt.json"), ep2 = join104(dir, "events.jsonl");
|
|
70147
70342
|
let bytes;
|
|
70148
70343
|
try {
|
|
70149
|
-
bytes =
|
|
70344
|
+
bytes = readFileSync91(rp);
|
|
70150
70345
|
} catch {
|
|
70151
70346
|
return fail2(`unit ${id2} sub-receipt missing`);
|
|
70152
70347
|
}
|
|
@@ -70165,7 +70360,7 @@ function sealGroup(runDir, rh) {
|
|
|
70165
70360
|
unit_id: id2,
|
|
70166
70361
|
sub_receipt_sha256: sha4(bytes),
|
|
70167
70362
|
receipt_sha256: sub["receipt_sha256"],
|
|
70168
|
-
events_file_sha256: existsSync72(ep2) ? sha4(
|
|
70363
|
+
events_file_sha256: existsSync72(ep2) ? sha4(readFileSync91(ep2)) : null,
|
|
70169
70364
|
verdict,
|
|
70170
70365
|
goal: text3(u10["goal"], 200),
|
|
70171
70366
|
files: (Array.isArray(u10["files"]) ? u10["files"] : []).map((f) => text3(f, 200)).filter(Boolean).slice(0, 50),
|
|
@@ -70185,12 +70380,12 @@ function capGroupVerdict(v3, g) {
|
|
|
70185
70380
|
return !g.allUnitsPass && (v3 === "VERIFIED" || v3 === "ALREADY_SATISFIED") ? "PARTIAL" : v3;
|
|
70186
70381
|
}
|
|
70187
70382
|
async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
70188
|
-
const runDir =
|
|
70383
|
+
const runDir = dirname43(receiptPath);
|
|
70189
70384
|
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
70190
70385
|
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
70191
70386
|
const g = receipt["group"];
|
|
70192
70387
|
if (g === undefined)
|
|
70193
|
-
return existsSync72(
|
|
70388
|
+
return existsSync72(join104(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
70194
70389
|
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
70195
70390
|
return bad("group section malformed");
|
|
70196
70391
|
const entries = g["units"];
|
|
@@ -70202,20 +70397,20 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
70202
70397
|
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
70203
70398
|
let unchecked = null;
|
|
70204
70399
|
for (let i = 0;i < entries.length; i++) {
|
|
70205
|
-
const e10 = entries[i], id2 = ids[i], dir =
|
|
70400
|
+
const e10 = entries[i], id2 = ids[i], dir = join104(unitsDir(runDir), id2), rp = join104(dir, "receipt.json"), ep2 = join104(dir, "events.jsonl");
|
|
70206
70401
|
if (e10["index"] !== i)
|
|
70207
70402
|
return bad(`unit ${id2} is out of order (index ${String(e10["index"])} at position ${i})`);
|
|
70208
70403
|
let bytes;
|
|
70209
70404
|
try {
|
|
70210
70405
|
if (!statSync26(dir).isDirectory())
|
|
70211
70406
|
return bad(`unit ${id2} is not a directory`);
|
|
70212
|
-
bytes =
|
|
70407
|
+
bytes = readFileSync91(rp);
|
|
70213
70408
|
} catch {
|
|
70214
70409
|
return bad(`unit ${id2} sub-receipt missing`);
|
|
70215
70410
|
}
|
|
70216
70411
|
if (sha4(bytes) !== e10["sub_receipt_sha256"])
|
|
70217
70412
|
return bad(`unit ${id2} sub-receipt does not match its recorded hash`);
|
|
70218
|
-
const evSha = existsSync72(ep2) ? sha4(
|
|
70413
|
+
const evSha = existsSync72(ep2) ? sha4(readFileSync91(ep2)) : null;
|
|
70219
70414
|
if (evSha !== (e10["events_file_sha256"] ?? null))
|
|
70220
70415
|
return bad(`unit ${id2} events.jsonl does not match its recorded hash`);
|
|
70221
70416
|
const sub = readJson7(rp);
|
|
@@ -70244,7 +70439,7 @@ function composeGroupReceipt(groupDir, rh, o) {
|
|
|
70244
70439
|
const body = { schema: GROUP_SCHEMA, run_id: gid, verdict, base_sha: o.baseRef, head_sha: o.head, not_proven: seal.notProven, group: seal.section };
|
|
70245
70440
|
const hash = rh(body), sig = signReceipt(gid, hash);
|
|
70246
70441
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
70247
|
-
const path =
|
|
70442
|
+
const path = join104(groupDir, "receipt.json"), tmp = `${path}.${process.pid}.tmp`;
|
|
70248
70443
|
mkdirSync54(groupDir, { recursive: true });
|
|
70249
70444
|
writeFileSync52(tmp, JSON.stringify(receipt, null, 2) + `
|
|
70250
70445
|
`);
|
|
@@ -70256,9 +70451,9 @@ function compositeVerdict(childVerdicts) {
|
|
|
70256
70451
|
const failed2 = childVerdicts.filter((v3) => v3 === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v3)).length;
|
|
70257
70452
|
return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v3) => PASSING.has(v3)) });
|
|
70258
70453
|
}
|
|
70259
|
-
var ID_RE, PASSING, sha4 = (b) => createHash29("sha256").update(b).digest("hex"), isObj10 = (v3) => v3 !== null && typeof v3 === "object" && !Array.isArray(v3), text3 = (v3, cap) => typeof v3 === "string" ? v3.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v3) => typeof v3 === "number" && Number.isFinite(v3) && v3 >= 0 ? v3 : 0, unitsDir = (runDir) =>
|
|
70454
|
+
var ID_RE, PASSING, sha4 = (b) => createHash29("sha256").update(b).digest("hex"), isObj10 = (v3) => v3 !== null && typeof v3 === "object" && !Array.isArray(v3), text3 = (v3, cap) => typeof v3 === "string" ? v3.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v3) => typeof v3 === "number" && Number.isFinite(v3) && v3 >= 0 ? v3 : 0, unitsDir = (runDir) => join104(runDir, "group", "units"), readJson7 = (p) => {
|
|
70260
70455
|
try {
|
|
70261
|
-
return JSON.parse(
|
|
70456
|
+
return JSON.parse(readFileSync91(p, "utf8"));
|
|
70262
70457
|
} catch {
|
|
70263
70458
|
return;
|
|
70264
70459
|
}
|
|
@@ -70276,8 +70471,8 @@ var init_seal_group = __esm(() => {
|
|
|
70276
70471
|
});
|
|
70277
70472
|
|
|
70278
70473
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
70279
|
-
import { existsSync as existsSync73, readFileSync as
|
|
70280
|
-
import { basename as basename27, join as
|
|
70474
|
+
import { existsSync as existsSync73, readFileSync as readFileSync92, statSync as statSync27 } from "fs";
|
|
70475
|
+
import { basename as basename27, join as join105 } from "path";
|
|
70281
70476
|
function supplyEnabled(env) {
|
|
70282
70477
|
return env["LOKI_SUPPLY_GUARD"] !== "0";
|
|
70283
70478
|
}
|
|
@@ -70292,13 +70487,13 @@ function isManifestPath(path) {
|
|
|
70292
70487
|
return MANIFESTS2.test(basename27(path));
|
|
70293
70488
|
}
|
|
70294
70489
|
function readDeclared(repoDir) {
|
|
70295
|
-
const p =
|
|
70490
|
+
const p = join105(repoDir, ".loki", DECLARED_FILE);
|
|
70296
70491
|
if (!existsSync73(p))
|
|
70297
70492
|
return { deps: [], problem: null };
|
|
70298
70493
|
try {
|
|
70299
70494
|
if (statSync27(p).size > MAX_FILE_BYTES)
|
|
70300
70495
|
return { deps: [], problem: "declaration file too large" };
|
|
70301
|
-
const j10 = JSON.parse(
|
|
70496
|
+
const j10 = JSON.parse(readFileSync92(p, "utf8"));
|
|
70302
70497
|
if (!Array.isArray(j10))
|
|
70303
70498
|
return { deps: [], problem: "declaration is not a JSON array" };
|
|
70304
70499
|
const deps = [];
|
|
@@ -70318,11 +70513,11 @@ function readDeclared(repoDir) {
|
|
|
70318
70513
|
}
|
|
70319
70514
|
}
|
|
70320
70515
|
function readAllowlist(repoDir) {
|
|
70321
|
-
const p =
|
|
70516
|
+
const p = join105(repoDir, ".loki", "supply-allowlist");
|
|
70322
70517
|
if (!existsSync73(p))
|
|
70323
70518
|
return new Set;
|
|
70324
70519
|
try {
|
|
70325
|
-
return new Set(
|
|
70520
|
+
return new Set(readFileSync92(p, "utf8").split(`
|
|
70326
70521
|
`).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
|
|
70327
70522
|
} catch {
|
|
70328
70523
|
return new Set;
|
|
@@ -70363,7 +70558,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70363
70558
|
if (eco === "npm") {
|
|
70364
70559
|
if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
|
|
70365
70560
|
return true;
|
|
70366
|
-
return files(
|
|
70561
|
+
return files(join105(repoDir, ".npmrc"), home ? join105(home, ".npmrc") : "").some((t) => t.split(`
|
|
70367
70562
|
`).some((l) => {
|
|
70368
70563
|
const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
|
|
70369
70564
|
return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
|
|
@@ -70372,7 +70567,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70372
70567
|
if (eco === "pypi") {
|
|
70373
70568
|
if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
|
|
70374
70569
|
return true;
|
|
70375
|
-
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ?
|
|
70570
|
+
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join105(home, ".config", "pip", "pip.conf") : "", home ? join105(home, ".pip", "pip.conf") : "", join105(repoDir, "pip.conf")];
|
|
70376
70571
|
return files(...cfg).some((t) => t.split(`
|
|
70377
70572
|
`).some((l) => {
|
|
70378
70573
|
const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
|
|
@@ -70382,7 +70577,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70382
70577
|
if (eco === "cargo") {
|
|
70383
70578
|
if (Object.keys(env).some((k3) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k3) || /^CARGO_SOURCE_/.test(k3)))
|
|
70384
70579
|
return true;
|
|
70385
|
-
return files(
|
|
70580
|
+
return files(join105(repoDir, ".cargo", "config.toml"), join105(repoDir, ".cargo", "config"), home ? join105(home, ".cargo", "config.toml") : "", home ? join105(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
|
|
70386
70581
|
}
|
|
70387
70582
|
if (eco === "go") {
|
|
70388
70583
|
const gp2 = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
|
|
@@ -70505,7 +70700,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
|
|
|
70505
70700
|
}
|
|
70506
70701
|
}, PUBLIC_HOSTS, hostOf = (u10) => u10.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//, "").replace(/^www\./, "").split(/[/?#\s]/)[0].replace(/^[^@]*@/, "").replace(/:\d+$/, ""), privateUrl = (u10) => /[a-z0-9]/i.test(u10) && !PUBLIC_HOSTS.has(hostOf(u10)), readSmall = (p) => {
|
|
70507
70702
|
try {
|
|
70508
|
-
return statSync27(p).size <= MAX_FILE_BYTES ?
|
|
70703
|
+
return statSync27(p).size <= MAX_FILE_BYTES ? readFileSync92(p, "utf8") : "";
|
|
70509
70704
|
} catch {
|
|
70510
70705
|
return "";
|
|
70511
70706
|
}
|
|
@@ -70544,8 +70739,8 @@ __export(exports_seal, {
|
|
|
70544
70739
|
AGENT_ONLY_REASON: () => AGENT_ONLY_REASON
|
|
70545
70740
|
});
|
|
70546
70741
|
import { createHash as createHash30 } from "crypto";
|
|
70547
|
-
import { existsSync as existsSync74, readdirSync as readdirSync31, mkdirSync as mkdirSync55, readFileSync as
|
|
70548
|
-
import { basename as basename28, isAbsolute as isAbsolute20, join as
|
|
70742
|
+
import { existsSync as existsSync74, readdirSync as readdirSync31, mkdirSync as mkdirSync55, readFileSync as readFileSync93 } from "fs";
|
|
70743
|
+
import { basename as basename28, isAbsolute as isAbsolute20, join as join106, relative as relative24 } from "path";
|
|
70549
70744
|
async function leanSymbolGap(ctx, o, rawDiff, head, vraw) {
|
|
70550
70745
|
if (externalRun(o) || Array.isArray(o.wall?.files) && o.wall.files.length > 0 || o.intake?.already_satisfied === true || o.implement?.exit === "already_done")
|
|
70551
70746
|
return [];
|
|
@@ -70566,7 +70761,7 @@ async function leanSymbolGap(ctx, o, rawDiff, head, vraw) {
|
|
|
70566
70761
|
const n11 = String(c.name ?? ""), p = n11.slice(n11.indexOf(":") + 1);
|
|
70567
70762
|
if (n11.includes(":") && isTestFile(p))
|
|
70568
70763
|
try {
|
|
70569
|
-
sources2.push(
|
|
70764
|
+
sources2.push(readFileSync93(join106(ctx.repoDir, p), "utf8"));
|
|
70570
70765
|
} catch {}
|
|
70571
70766
|
}
|
|
70572
70767
|
return symbolGap(changedSymbols(d.stdout), sources2);
|
|
@@ -70649,7 +70844,7 @@ function renderReceiptMd(r) {
|
|
|
70649
70844
|
`);
|
|
70650
70845
|
}
|
|
70651
70846
|
var SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", WALL_GREEN_ON_BASE_REASON = "Wall green on base: no Wall test discriminates the change", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash30("sha256").update(s).digest("hex"), str3 = (v3) => typeof v3 === "string" && v3 !== "" ? v3 : null, EXTERNAL_MODEL_LABEL = "external (no Loki implement session)", EXTERNAL_DIFF_NOT_ISOLATED = "Wall author not filesystem-isolated from the external diff", EXTERNAL_NO_WALL = "external diff sealed with no Wall file that ran; the only checks are the repo's existing tests", externalRun = (o) => o.implement?.exit === "external", LEAN_NO_SYMBOL = "no passing check references a changed symbol and no Wall file ran", strs2 = (v3) => Array.isArray(v3) ? v3.filter((x3) => typeof x3 === "string" && x3 !== "") : [], g = (ctx) => (a) => git9(ctx, a), receiptRel = (ctx) => {
|
|
70652
|
-
const r = relative24(ctx.repoDir,
|
|
70847
|
+
const r = relative24(ctx.repoDir, join106(ctx.runDir, "receipt.json"));
|
|
70653
70848
|
return r.startsWith("..") || isAbsolute20(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
70654
70849
|
}, commitStage, wallGreenOnBaseOf = (o) => {
|
|
70655
70850
|
const b = o.wall?.base_run ?? {};
|
|
@@ -70791,7 +70986,7 @@ var init_seal = __esm(() => {
|
|
|
70791
70986
|
if (wallNotRun > 0) {
|
|
70792
70987
|
try {
|
|
70793
70988
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename28(String(f.path))));
|
|
70794
|
-
for (const n11 of readdirSync31(
|
|
70989
|
+
for (const n11 of readdirSync31(join106(ctx.runDir, "wall")).sort())
|
|
70795
70990
|
if (!kept.has(n11))
|
|
70796
70991
|
notProven.add(`wall test discarded: ${n11} (not_run)`);
|
|
70797
70992
|
} catch {}
|
|
@@ -70862,19 +71057,19 @@ var init_seal = __esm(() => {
|
|
|
70862
71057
|
for (const [s, d] of Object.entries(o))
|
|
70863
71058
|
if (typeof d?.duration_s === "number")
|
|
70864
71059
|
stages[s] = d.duration_s;
|
|
70865
|
-
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(
|
|
71060
|
+
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join106(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
|
|
70866
71061
|
const iterIds = [...new Set([...Object.values(o).flatMap((d) => [...strs2(d?.iteration_ids), ...strs2([d?.iteration_id])]), ...ctx.sessionIds?.() ?? [], ...xr2?.cost_iteration ? [xr2.cost_iteration] : []])];
|
|
70867
71062
|
if (iterIds.length === 0)
|
|
70868
71063
|
notProven.add("cost not measured (no iteration ids recorded)");
|
|
70869
71064
|
const cost = ctx.cost.read(ctx.repoDir, iterIds);
|
|
70870
71065
|
if (cost.unmetered)
|
|
70871
71066
|
notProven.add("cost unmetered (CLI invoker; recorded as 0)");
|
|
70872
|
-
const eventsPath =
|
|
71067
|
+
const eventsPath = join106(ctx.runDir, "events.jsonl");
|
|
70873
71068
|
const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
|
|
70874
71069
|
const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
|
|
70875
71070
|
if (wallFiles.length > 0 && wallPassed === null)
|
|
70876
71071
|
notProven.add("wall result not recorded by verify");
|
|
70877
|
-
const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(
|
|
71072
|
+
const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(join106(ctx.repoDir, ".loki"), liveArchivedCosts(join106(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
|
|
70878
71073
|
if (routeBlock)
|
|
70879
71074
|
for (const l of routeNotProven(routeBlock))
|
|
70880
71075
|
notProven.add(l);
|
|
@@ -70917,7 +71112,7 @@ var init_seal = __esm(() => {
|
|
|
70917
71112
|
model: externalRun(o) ? EXTERNAL_MODEL_LABEL : ctx.model,
|
|
70918
71113
|
...externalRun(o) ? { implement: { exit: "external", patch_sha256: str3(o.implement?.patch_sha256) ?? "" } } : {},
|
|
70919
71114
|
resumed: o.intake?.resumed === true,
|
|
70920
|
-
events_sha256: sha2562(existsSync74(eventsPath) ?
|
|
71115
|
+
events_sha256: sha2562(existsSync74(eventsPath) ? readFileSync93(eventsPath) : ""),
|
|
70921
71116
|
...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
|
|
70922
71117
|
log_seal: true,
|
|
70923
71118
|
toolchain: collectToolchain(),
|
|
@@ -70945,10 +71140,10 @@ var init_seal = __esm(() => {
|
|
|
70945
71140
|
}
|
|
70946
71141
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
70947
71142
|
mkdirSync55(ctx.runDir, { recursive: true });
|
|
70948
|
-
const path =
|
|
71143
|
+
const path = join106(ctx.runDir, "receipt.json");
|
|
70949
71144
|
atomicWriteText(path, JSON.stringify(receipt, null, 2) + `
|
|
70950
71145
|
`);
|
|
70951
|
-
atomicWriteText(
|
|
71146
|
+
atomicWriteText(join106(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
70952
71147
|
recordRun(process.env, ctx.repoDir, ranModel(o.implement, ctx.model, o.fix), verdict, cost.usd, cost.unmetered === true, totalS);
|
|
70953
71148
|
try {
|
|
70954
71149
|
hooks.sealed?.(ctx.runDir, JSON.parse(JSON.stringify(receipt), (_k2, v3) => v3 && typeof v3 === "object" ? Object.freeze(v3) : v3));
|
|
@@ -71022,7 +71217,7 @@ var init_github_token = __esm(() => {
|
|
|
71022
71217
|
// ../../loki-ts/src/engine10/fetch_issue.ts
|
|
71023
71218
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
71024
71219
|
import { writeFileSync as writeFileSync54 } from "fs";
|
|
71025
|
-
import { join as
|
|
71220
|
+
import { join as join107 } from "path";
|
|
71026
71221
|
function defaultExec(cmd, args) {
|
|
71027
71222
|
const ms = Number(process.env.LOKI_FETCH_ISSUE_TIMEOUT_MS) || 60000;
|
|
71028
71223
|
return execFileSync7(cmd, args, { encoding: "utf8", env: process.env, timeout: ms, killSignal: "SIGKILL" });
|
|
@@ -71049,7 +71244,7 @@ function fetchIssueToFile(ref, outFile, exec = defaultExec) {
|
|
|
71049
71244
|
var ISSUE_PROVIDERS_SH;
|
|
71050
71245
|
var init_fetch_issue = __esm(() => {
|
|
71051
71246
|
init_paths();
|
|
71052
|
-
ISSUE_PROVIDERS_SH =
|
|
71247
|
+
ISSUE_PROVIDERS_SH = join107(REPO_ROOT, "autonomy/issue-providers.sh");
|
|
71053
71248
|
if (false) {}
|
|
71054
71249
|
});
|
|
71055
71250
|
|
|
@@ -71582,9 +71777,21 @@ var init_provider = __esm(() => {
|
|
|
71582
71777
|
});
|
|
71583
71778
|
|
|
71584
71779
|
// ../../loki-ts/src/util/funnel.ts
|
|
71780
|
+
function blockerOf(v3) {
|
|
71781
|
+
return typeof v3 === "string" && PREFLIGHT_BLOCKERS.includes(v3) ? v3 : null;
|
|
71782
|
+
}
|
|
71783
|
+
function noteRefusal(b) {
|
|
71784
|
+
if (b)
|
|
71785
|
+
refusal = b;
|
|
71786
|
+
}
|
|
71787
|
+
function noteRefusalFromEvents(events2) {
|
|
71788
|
+
noteRefusal(blockerOf(events2.find((e10) => e10.type === "stage.failed" && e10.stage === "intake")?.data["blocker"]));
|
|
71789
|
+
}
|
|
71790
|
+
var PREFLIGHT_BLOCKERS, refusal = null;
|
|
71585
71791
|
var init_funnel = __esm(() => {
|
|
71586
71792
|
init_paths();
|
|
71587
71793
|
init_safe_git();
|
|
71794
|
+
PREFLIGHT_BLOCKERS = ["not_a_repo", "git_identity", "dirty_tracked_tree", "no_provider", "not_logged_in", "prd_missing", "unsupported_flag", "disk", "other"];
|
|
71588
71795
|
});
|
|
71589
71796
|
|
|
71590
71797
|
// ../../loki-ts/src/cockpit/capability.ts
|
|
@@ -71597,14 +71804,14 @@ var init_capability = __esm(() => {
|
|
|
71597
71804
|
var init_raster = () => {};
|
|
71598
71805
|
|
|
71599
71806
|
// ../../loki-ts/src/commands/doctor.ts
|
|
71600
|
-
import { appendFileSync as appendFileSync11, writeFileSync as writeFileSync56, mkdirSync as mkdirSync56, accessSync as accessSync2, constants as fsConstants2, existsSync as existsSync75, lstatSync as lstatSync28, readdirSync as readdirSync32, readFileSync as
|
|
71807
|
+
import { appendFileSync as appendFileSync11, writeFileSync as writeFileSync56, mkdirSync as mkdirSync56, accessSync as accessSync2, constants as fsConstants2, existsSync as existsSync75, lstatSync as lstatSync28, readdirSync as readdirSync32, readFileSync as readFileSync94, readlinkSync as readlinkSync6, realpathSync as realpathSync31, statSync as statSync29, statfsSync } from "fs";
|
|
71601
71808
|
import { spawnSync as spawnSync12 } from "child_process";
|
|
71602
71809
|
import { homedir as homedir12, tmpdir as tmpdir18 } from "os";
|
|
71603
|
-
import { join as
|
|
71810
|
+
import { join as join108, resolve as resolve31 } from "path";
|
|
71604
71811
|
function loadRequirements(file = REQUIREMENTS_FILE) {
|
|
71605
71812
|
if (file === REQUIREMENTS_FILE && cached)
|
|
71606
71813
|
return cached;
|
|
71607
|
-
const t = JSON.parse(
|
|
71814
|
+
const t = JSON.parse(readFileSync94(file, "utf8"));
|
|
71608
71815
|
if (file === REQUIREMENTS_FILE)
|
|
71609
71816
|
cached = t;
|
|
71610
71817
|
return t;
|
|
@@ -71635,7 +71842,7 @@ function providerLoginIssue(provider, cli, env) {
|
|
|
71635
71842
|
const said = `${r.stdout}${r.stderr}`;
|
|
71636
71843
|
return /not logged in/i.test(said) || classifyFailure(said).reason === "auth" ? { fatal: "codex is not logged in; run: codex login (or set OPENAI_API_KEY)" } : { warn: "could not confirm the Codex login (codex login status gave no answer); continuing" };
|
|
71637
71844
|
}
|
|
71638
|
-
if (PROVIDER_API_KEY_VARS.some(key) || provider === "opencode" && existsSync75(
|
|
71845
|
+
if (PROVIDER_API_KEY_VARS.some(key) || provider === "opencode" && existsSync75(join108(env.XDG_DATA_HOME || join108(home, ".local", "share"), "opencode", "auth.json")) || provider === "cline" && existsSync75(join108(home, ".cline")))
|
|
71639
71846
|
return null;
|
|
71640
71847
|
return provider === "aider" || provider === "opencode" || provider === "cline" ? { warn: `no ${provider} login or API key found (set a provider API key such as ANTHROPIC_API_KEY or OPENAI_API_KEY${provider === "opencode" ? ", or run: opencode auth login" : ""}); continuing` } : null;
|
|
71641
71848
|
}
|
|
@@ -71646,9 +71853,9 @@ function providerAuthPath(provider, env) {
|
|
|
71646
71853
|
const v3 = own.find(set);
|
|
71647
71854
|
if (v3)
|
|
71648
71855
|
return `${v3 === "CLAUDE_CODE_OAUTH_TOKEN" ? "oauth_token" : "api_key"}:${v3}`;
|
|
71649
|
-
if (provider === "opencode" && existsSync75(
|
|
71856
|
+
if (provider === "opencode" && existsSync75(join108(env.XDG_DATA_HOME || join108(home, ".local", "share"), "opencode", "auth.json")))
|
|
71650
71857
|
return "cli_login:opencode";
|
|
71651
|
-
if (provider === "cline" && existsSync75(
|
|
71858
|
+
if (provider === "cline" && existsSync75(join108(home, ".cline")))
|
|
71652
71859
|
return "cli_login:cline";
|
|
71653
71860
|
return provider === "claude" || provider === "codex" ? `cli_login:${provider}` : "none";
|
|
71654
71861
|
}
|
|
@@ -71673,9 +71880,9 @@ function claudeAuthStatusLoggedIn(cli = "claude", env = process.env) {
|
|
|
71673
71880
|
}
|
|
71674
71881
|
}
|
|
71675
71882
|
function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
71676
|
-
const file =
|
|
71883
|
+
const file = join108(env.HOME || homedir12(), ".loki", "claude-login-ok.json");
|
|
71677
71884
|
try {
|
|
71678
|
-
const c = JSON.parse(
|
|
71885
|
+
const c = JSON.parse(readFileSync94(file, "utf8"));
|
|
71679
71886
|
if (c?.cli === cli && typeof c.at === "number" && now2 - c.at >= 0 && now2 - c.at < CLAUDE_LOGIN_TTL_MS)
|
|
71680
71887
|
return "yes";
|
|
71681
71888
|
} catch {}
|
|
@@ -71684,7 +71891,7 @@ function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
|
71684
71891
|
li2 = claudeAuthStatusLoggedIn(cli, env);
|
|
71685
71892
|
if (li2 === "yes") {
|
|
71686
71893
|
try {
|
|
71687
|
-
mkdirSync56(
|
|
71894
|
+
mkdirSync56(join108(file, ".."), { recursive: true });
|
|
71688
71895
|
writeFileSync56(file, JSON.stringify({ cli, at: now2 }));
|
|
71689
71896
|
} catch {}
|
|
71690
71897
|
}
|
|
@@ -71693,16 +71900,16 @@ function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
|
71693
71900
|
async function ghAuthProbeCached(env, probe, now2 = Date.now()) {
|
|
71694
71901
|
const bin = "gh";
|
|
71695
71902
|
const gh = Bun.which(bin, { PATH: env.PATH ?? process.env.PATH ?? "" }) ?? bin;
|
|
71696
|
-
const file =
|
|
71903
|
+
const file = join108(env.HOME || homedir12(), ".loki", "gh-auth-ok.json");
|
|
71697
71904
|
try {
|
|
71698
|
-
const c = JSON.parse(
|
|
71905
|
+
const c = JSON.parse(readFileSync94(file, "utf8"));
|
|
71699
71906
|
if (c?.gh === gh && typeof c.at === "number" && now2 - c.at >= 0 && now2 - c.at < CLAUDE_LOGIN_TTL_MS)
|
|
71700
71907
|
return true;
|
|
71701
71908
|
} catch {}
|
|
71702
71909
|
const ok3 = await probe();
|
|
71703
71910
|
if (ok3) {
|
|
71704
71911
|
try {
|
|
71705
|
-
mkdirSync56(
|
|
71912
|
+
mkdirSync56(join108(file, ".."), { recursive: true });
|
|
71706
71913
|
writeFileSync56(file, JSON.stringify({ gh, at: now2 }));
|
|
71707
71914
|
} catch {}
|
|
71708
71915
|
}
|
|
@@ -71777,7 +71984,7 @@ var init_first_run_repo = __esm(() => {
|
|
|
71777
71984
|
|
|
71778
71985
|
// ../../loki-ts/src/engine10/preflight.ts
|
|
71779
71986
|
import { accessSync as accessSync3, constants as fsc2, mkdirSync as mkdirSync57, statfsSync as statfsSync2, writeFileSync as writeFileSync57 } from "fs";
|
|
71780
|
-
import { join as
|
|
71987
|
+
import { join as join109 } from "path";
|
|
71781
71988
|
async function sh3(argv, opts) {
|
|
71782
71989
|
try {
|
|
71783
71990
|
return await run(argv, opts);
|
|
@@ -71819,18 +72026,19 @@ async function checkPreflight(o) {
|
|
|
71819
72026
|
pinErr = `${e10.message}; set a valid value or unset it (the run would otherwise drop the pin and use the provider default model)`;
|
|
71820
72027
|
}
|
|
71821
72028
|
}
|
|
71822
|
-
const
|
|
71823
|
-
|
|
71824
|
-
|
|
72029
|
+
const refuse = (b, f) => [b, f];
|
|
72030
|
+
const hit = wt.exitCode !== 0 || wt.stdout.trim() !== "true" ? refuse("not_a_repo", initFatal ?? NOT_A_REPO(o.repoDir)) : !name.stdout.trim() || !email.stdout.trim() ? refuse("git_identity", `git identity is not set; run: git config user.name "you" && git config user.email "you@example.com"`) : !envVar ? refuse("unsupported_flag", `the v10 engine has no ${o.provider} invoker yet`) : o.provider !== "claude" && truthy(env["LOKI_HOST_GUARD"]) ? refuse("other", `LOKI_HOST_GUARD=1 is set but provider '${o.provider}' has no enforced PreToolUse hook; unset LOKI_HOST_GUARD or use --provider claude`) : pinErr ? refuse("other", pinErr) : !cliOk ? refuse("no_provider", `provider CLI '${cli}' is not on PATH; install it or set ${envVar} to its path${requirementFix(o.provider) ? `. Fix: ${requirementFix(o.provider)}` : ""}`) : head.exitCode !== 0 ? refuse("other", "repository has no commits; run: git add . && git commit -m init") : null;
|
|
72031
|
+
if (hit)
|
|
72032
|
+
return { fatal: hit[1], warnings, blocker: hit[0] };
|
|
71825
72033
|
try {
|
|
71826
72034
|
accessSync3(o.repoDir, fsc2.W_OK);
|
|
71827
72035
|
} catch {
|
|
71828
|
-
return { fatal: `${o.repoDir} is not writable; run: chmod u+w "${o.repoDir}" (or run loki from a writable checkout)`, warnings };
|
|
72036
|
+
return { fatal: `${o.repoDir} is not writable; run: chmod u+w "${o.repoDir}" (or run loki from a writable checkout)`, warnings, blocker: "other" };
|
|
71829
72037
|
}
|
|
71830
72038
|
const free = freeMb(o.repoDir, o.statfs ?? statfsSync2);
|
|
71831
72039
|
const minMb = Number(env["LOKI_MIN_FREE_MB"]) > 0 ? Number(env["LOKI_MIN_FREE_MB"]) : 200;
|
|
71832
72040
|
if (free !== null && free < minMb)
|
|
71833
|
-
return { fatal: `only ${Math.floor(free)} MB free on the volume holding ${o.repoDir} (need ${minMb} MB); free disk space, or lower LOKI_MIN_FREE_MB`, warnings };
|
|
72041
|
+
return { fatal: `only ${Math.floor(free)} MB free on the volume holding ${o.repoDir} (need ${minMb} MB); free disk space, or lower LOKI_MIN_FREE_MB`, warnings, blocker: "disk" };
|
|
71834
72042
|
if (free !== null && free < Math.max(2048, minMb))
|
|
71835
72043
|
warnings.push(`low disk: ${Math.floor(free)} MB free on the volume holding ${o.repoDir}; a long run may fail mid-way (warns under 2 GB)`);
|
|
71836
72044
|
const auth_path = providerAuthPath(o.provider, env);
|
|
@@ -71861,16 +72069,16 @@ async function checkPreflight(o) {
|
|
|
71861
72069
|
if (o.runDir) {
|
|
71862
72070
|
try {
|
|
71863
72071
|
mkdirSync57(o.runDir, { recursive: true });
|
|
71864
|
-
writeFileSync57(
|
|
72072
|
+
writeFileSync57(join109(o.runDir, "preflight.json"), JSON.stringify({ provider: o.provider, auth_path, probe }) + `
|
|
71865
72073
|
`);
|
|
71866
72074
|
} catch {}
|
|
71867
72075
|
}
|
|
71868
72076
|
if (authFatal)
|
|
71869
|
-
return { fatal: authFatal, warnings };
|
|
72077
|
+
return { fatal: authFatal, warnings, blocker: "not_logged_in" };
|
|
71870
72078
|
if (o.pr && GITHUB_ORIGIN_RE.test((await git10(["config", "--get", "remote.origin.url"])).stdout.trim())) {
|
|
71871
72079
|
const ghOk = await ghAuthProbeCached(env, async () => (await sh3(["gh", "--version"], { env, timeoutMs: 5000 })).exitCode === 0 && (await sh3(["gh", "auth", "status"], { env, timeoutMs: 1e4 })).exitCode === 0);
|
|
71872
72080
|
if (!ghOk)
|
|
71873
|
-
return { fatal: `gh (GitHub CLI) is missing or not authenticated; run gh auth login, or pass --no-pr`, warnings };
|
|
72081
|
+
return { fatal: `gh (GitHub CLI) is missing or not authenticated; run gh auth login, or pass --no-pr`, warnings, blocker: "other" };
|
|
71874
72082
|
const plan = await probePublish((await git10(["config", "--get", "remote.origin.url"])).stdout.trim(), env);
|
|
71875
72083
|
if (plan) {
|
|
71876
72084
|
if (plan.warning)
|
|
@@ -71887,7 +72095,7 @@ async function assertPreflight(o) {
|
|
|
71887
72095
|
process.stderr.write(`${w}
|
|
71888
72096
|
`);
|
|
71889
72097
|
if (r.fatal)
|
|
71890
|
-
throw new PreflightError(r.fatal);
|
|
72098
|
+
throw new PreflightError(r.fatal, r.blocker);
|
|
71891
72099
|
}
|
|
71892
72100
|
var CLI_ENV_VAR, GITHUB_ORIGIN_RE, PreflightError;
|
|
71893
72101
|
var init_preflight = __esm(() => {
|
|
@@ -71898,9 +72106,15 @@ var init_preflight = __esm(() => {
|
|
|
71898
72106
|
init_first_run_repo();
|
|
71899
72107
|
init_engine_origin();
|
|
71900
72108
|
init_shell();
|
|
72109
|
+
init_funnel();
|
|
71901
72110
|
CLI_ENV_VAR = { claude: "LOKI_CLAUDE_CLI", codex: "LOKI_CODEX_CLI", cline: "LOKI_CLINE_CLI", aider: "LOKI_AIDER_CLI", opencode: "LOKI_OPENCODE_CLI" };
|
|
71902
72111
|
GITHUB_ORIGIN_RE = /^(?:https:\/\/(?:[^@/]+@)?github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)/;
|
|
71903
72112
|
PreflightError = class PreflightError extends Error {
|
|
72113
|
+
blocker;
|
|
72114
|
+
constructor(message, blocker = "other") {
|
|
72115
|
+
super(message);
|
|
72116
|
+
this.blocker = blocker;
|
|
72117
|
+
}
|
|
71904
72118
|
};
|
|
71905
72119
|
});
|
|
71906
72120
|
|
|
@@ -71909,7 +72123,7 @@ var exports_ship_hook = {};
|
|
|
71909
72123
|
__export(exports_ship_hook, {
|
|
71910
72124
|
startShip: () => startShip
|
|
71911
72125
|
});
|
|
71912
|
-
import { dirname as
|
|
72126
|
+
import { dirname as dirname45 } from "path";
|
|
71913
72127
|
async function startShip(repoDir, eventsPath, env) {
|
|
71914
72128
|
let url = shipEnabled(env);
|
|
71915
72129
|
if (!url) {
|
|
@@ -71919,7 +72133,7 @@ async function startShip(repoDir, eventsPath, env) {
|
|
|
71919
72133
|
}
|
|
71920
72134
|
if (!url)
|
|
71921
72135
|
return;
|
|
71922
|
-
startShipLoop({ runDir:
|
|
72136
|
+
startShipLoop({ runDir: dirname45(eventsPath), url, source: sourceId(repoDir), token: env.LOKI_CONTROL_TOKEN });
|
|
71923
72137
|
}
|
|
71924
72138
|
var init_ship_hook = __esm(() => {
|
|
71925
72139
|
init_discover();
|
|
@@ -72526,10 +72740,10 @@ __export(exports_run_group, {
|
|
|
72526
72740
|
groupCostLine: () => groupCostLine,
|
|
72527
72741
|
NOT_PROVEN: () => NOT_PROVEN
|
|
72528
72742
|
});
|
|
72529
|
-
import { cpSync as cpSync2, existsSync as existsSync76, mkdirSync as mkdirSync58, readdirSync as readdirSync34, readFileSync as
|
|
72743
|
+
import { cpSync as cpSync2, existsSync as existsSync76, mkdirSync as mkdirSync58, readdirSync as readdirSync34, readFileSync as readFileSync95, rmSync as rmSync32, statSync as statSync30 } from "fs";
|
|
72530
72744
|
import { createHash as createHash31 } from "crypto";
|
|
72531
72745
|
import { spawn as spawn12 } from "child_process";
|
|
72532
|
-
import { join as
|
|
72746
|
+
import { join as join110, resolve as resolve32 } from "path";
|
|
72533
72747
|
function scopedEnv(env) {
|
|
72534
72748
|
const out3 = {};
|
|
72535
72749
|
for (const [k3, v3] of Object.entries(env))
|
|
@@ -72566,7 +72780,7 @@ function groupCostLine(costs, provider = "claude") {
|
|
|
72566
72780
|
`;
|
|
72567
72781
|
}
|
|
72568
72782
|
function writeGroupCostRecord(repoDir, name, costs, provider) {
|
|
72569
|
-
const dir =
|
|
72783
|
+
const dir = join110(repoDir, ".loki", "metrics", "efficiency");
|
|
72570
72784
|
const timestamp = new Date().toISOString();
|
|
72571
72785
|
try {
|
|
72572
72786
|
const base = { phase: "implement", provider, status: "group", kind: "group_cost", timestamp };
|
|
@@ -72580,7 +72794,7 @@ function writeGroupCostRecord(repoDir, name, costs, provider) {
|
|
|
72580
72794
|
if (recs.length === 0)
|
|
72581
72795
|
return;
|
|
72582
72796
|
mkdirSync58(dir, { recursive: true });
|
|
72583
|
-
recs.forEach((r, k3) => atomicWriteJson(
|
|
72797
|
+
recs.forEach((r, k3) => atomicWriteJson(join110(dir, `iteration-group-${name}-${String(k3).padStart(3, "0")}.json`), r));
|
|
72584
72798
|
} catch {}
|
|
72585
72799
|
}
|
|
72586
72800
|
function testCommand(repoDir, env) {
|
|
@@ -72593,7 +72807,7 @@ function testCommand(repoDir, env) {
|
|
|
72593
72807
|
return [];
|
|
72594
72808
|
}
|
|
72595
72809
|
function findResumable(repoDir, specSha, unitIds) {
|
|
72596
|
-
const root =
|
|
72810
|
+
const root = join110(repoDir, ".loki", "groups");
|
|
72597
72811
|
let names = [];
|
|
72598
72812
|
try {
|
|
72599
72813
|
names = readdirSync34(root);
|
|
@@ -72604,7 +72818,7 @@ function findResumable(repoDir, specSha, unitIds) {
|
|
|
72604
72818
|
for (const gid of names) {
|
|
72605
72819
|
if (!GID_RE.test(gid))
|
|
72606
72820
|
continue;
|
|
72607
|
-
const p =
|
|
72821
|
+
const p = join110(root, gid, "dag.json"), d = readJson8(p);
|
|
72608
72822
|
if (!d || (unitIds ? JSON.stringify((Array.isArray(d["units"]) ? d["units"] : []).filter((u10) => !u10.fixKind).map((u10) => u10.id)) !== JSON.stringify(unitIds) : d["spec_sha256"] !== specSha) || typeof d["base_ref"] !== "string" || !Array.isArray(d["units"]))
|
|
72609
72823
|
continue;
|
|
72610
72824
|
let at2 = 0;
|
|
@@ -72621,7 +72835,7 @@ function findResumable(repoDir, specSha, unitIds) {
|
|
|
72621
72835
|
async function unitDone(verifyReceipt, repoDir, gid, n11, id2) {
|
|
72622
72836
|
if (!UNIT_ID_RE.test(id2))
|
|
72623
72837
|
return false;
|
|
72624
|
-
const rp =
|
|
72838
|
+
const rp = join110(repoDir, ".loki", "groups", gid, "group", "units", id2, "receipt.json");
|
|
72625
72839
|
const rec2 = readJson8(rp);
|
|
72626
72840
|
if (!rec2 || rec2["verdict"] !== "VERIFIED")
|
|
72627
72841
|
return false;
|
|
@@ -72636,7 +72850,7 @@ async function adoptJournaled(verifyReceipt, repoDir, dir, key, gid, n11, id2, t
|
|
|
72636
72850
|
return false;
|
|
72637
72851
|
if (!await unitDone(verifyReceipt, repoDir, e10.gid, e10.n, id2))
|
|
72638
72852
|
return false;
|
|
72639
|
-
const signed = readJson8(
|
|
72853
|
+
const signed = readJson8(join110(repoDir, ".loki", "groups", e10.gid, "group", "units", id2, "receipt.json"));
|
|
72640
72854
|
const signedTask = (signed?.["task"] ?? {}).sha256;
|
|
72641
72855
|
const signedSpec = (signed?.["unit_spec"] ?? {}).sha256;
|
|
72642
72856
|
if (typeof signedSpec !== "string" || signedSpec === "" || signedSpec !== specSha)
|
|
@@ -72646,9 +72860,9 @@ async function adoptJournaled(verifyReceipt, repoDir, dir, key, gid, n11, id2, t
|
|
|
72646
72860
|
const tip = git11(repoDir, ["rev-parse", "--verify", "--quiet", `refs/heads/loki/unit-${e10.gid}-${e10.n}`]);
|
|
72647
72861
|
if (tip === "" || tip !== e10.head)
|
|
72648
72862
|
return false;
|
|
72649
|
-
const dst =
|
|
72863
|
+
const dst = join110(repoDir, ".loki", "groups", gid, "group", "units", id2);
|
|
72650
72864
|
rmSync32(dst, { recursive: true, force: true });
|
|
72651
|
-
cpSync2(
|
|
72865
|
+
cpSync2(join110(repoDir, ".loki", "groups", e10.gid, "group", "units", id2), dst, { recursive: true });
|
|
72652
72866
|
if (safeGitSpawn(repoDir, ["update-ref", `refs/heads/loki/unit-${gid}-${n11}`, tip], { encoding: "utf8" }).status !== 0)
|
|
72653
72867
|
return false;
|
|
72654
72868
|
if (!await unitDone(verifyReceipt, repoDir, gid, n11, id2))
|
|
@@ -72683,8 +72897,8 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72683
72897
|
const revised = resumable !== null && exact === null;
|
|
72684
72898
|
const changed = new Set;
|
|
72685
72899
|
const groupId = resumable?.gid ?? `g${Date.now().toString(36)}`;
|
|
72686
|
-
const groupDir =
|
|
72687
|
-
const receiptPath =
|
|
72900
|
+
const groupDir = join110(repoDir, ".loki", "groups", groupId);
|
|
72901
|
+
const receiptPath = join110(groupDir, "receipt.json");
|
|
72688
72902
|
const slugOf = () => originSlug(repoDir);
|
|
72689
72903
|
let baseRef;
|
|
72690
72904
|
let startBranch = "";
|
|
@@ -72776,10 +72990,10 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72776
72990
|
const accOf = new Map;
|
|
72777
72991
|
for (const cu2 of Array.isArray(gc2?.["units"]) ? gc2["units"] : [])
|
|
72778
72992
|
accOf.set(cu2.id, cu2.criteria.map((c) => c.text));
|
|
72779
|
-
const specDir =
|
|
72993
|
+
const specDir = join110(groupDir, "unit_specs");
|
|
72780
72994
|
mkdirSync58(specDir, { recursive: true });
|
|
72781
72995
|
for (const u10 of units) {
|
|
72782
|
-
const spec =
|
|
72996
|
+
const spec = join110(specDir, `${u10.id}.json`);
|
|
72783
72997
|
const isFix = !!u10.fixKind;
|
|
72784
72998
|
if (!isFix)
|
|
72785
72999
|
u10.base = baseRef;
|
|
@@ -72805,19 +73019,19 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72805
73019
|
say(`loki: unit ${u10.id} skipped-unchanged
|
|
72806
73020
|
`);
|
|
72807
73021
|
} else if (resumable && UNIT_ID_RE.test(u10.id))
|
|
72808
|
-
rmSync32(
|
|
73022
|
+
rmSync32(join110(groupDir, "group", "units", u10.id), { recursive: true, force: true });
|
|
72809
73023
|
}
|
|
72810
73024
|
const cut2 = units.findIndex((u10) => u10.fixKind && !u10.done);
|
|
72811
73025
|
if (cut2 >= 0)
|
|
72812
73026
|
for (const u10 of units.splice(cut2)) {
|
|
72813
73027
|
if (u10.done)
|
|
72814
73028
|
doneCount--;
|
|
72815
|
-
rmSync32(
|
|
73029
|
+
rmSync32(join110(groupDir, "group", "units", u10.id), { recursive: true, force: true });
|
|
72816
73030
|
}
|
|
72817
73031
|
if (resumable)
|
|
72818
73032
|
say(`loki: resuming group ${groupId}: ${doneCount} of ${units.length} units already VERIFIED
|
|
72819
73033
|
`);
|
|
72820
|
-
const dagPath =
|
|
73034
|
+
const dagPath = join110(groupDir, "dag.json");
|
|
72821
73035
|
atomicWriteJson(dagPath, { group: groupId, spec_sha256: specSha, base_ref: baseRef, start_branch: startBranch, ...full, units });
|
|
72822
73036
|
try {
|
|
72823
73037
|
const chk = await checkDecomposable(full, { map: (() => {
|
|
@@ -72847,7 +73061,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72847
73061
|
const n11 = Math.min(slots, pending);
|
|
72848
73062
|
say(`loki: group ${groupId}: ${units.length} units, ${n11} parallel slot(s) (provider ${provider})
|
|
72849
73063
|
`);
|
|
72850
|
-
const backlog =
|
|
73064
|
+
const backlog = join110(REPO_ROOT, "autonomy", "lib", "backlog.py");
|
|
72851
73065
|
const feed = createGroupFeed(groupId, units, createGroupRenderer({ write: say, isTTY: false }));
|
|
72852
73066
|
const res = await run2([backlog, slug, "--dag", dagPath, "--group", groupId, "--slots", String(n11), "--provider", provider], scopedEnv({ ...env, LOKI_PROVIDER: provider }), repoDir, (c) => feed.feed(c));
|
|
72853
73067
|
launchCode = res.code;
|
|
@@ -72887,7 +73101,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72887
73101
|
const testCmd = testCommand(repoDir, env), fixes = units.filter((u10) => u10.fixKind);
|
|
72888
73102
|
const putDag = (us2) => atomicWriteJson(dagPath, { group: groupId, spec_sha256: specSha, base_ref: baseRef, start_branch: startBranch, ...full, units: us2 });
|
|
72889
73103
|
const launchFix = async (fix) => {
|
|
72890
|
-
const key = `unit-${groupId}-${units.length + 1}`, spec =
|
|
73104
|
+
const key = `unit-${groupId}-${units.length + 1}`, spec = join110(specDir, `${fix.id}.json`), slug = slugOf();
|
|
72891
73105
|
if (!slug)
|
|
72892
73106
|
return null;
|
|
72893
73107
|
atomicWriteJson(spec, { id: fix.id, writeSet: fix.writeSet, pack: fix.writeSet, tokenBudget: 1e9, acceptance: fix.acceptance });
|
|
@@ -72896,7 +73110,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72896
73110
|
fix.base = git11(repoDir, ["rev-parse", "HEAD"]);
|
|
72897
73111
|
units.push(fix);
|
|
72898
73112
|
putDag(units.map((u10) => u10 === fix ? u10 : { ...u10, done: true }));
|
|
72899
|
-
const res = await run2([
|
|
73113
|
+
const res = await run2([join110(REPO_ROOT, "autonomy", "lib", "backlog.py"), slug, "--dag", dagPath, "--group", groupId, "--slots", "1", "--provider", provider], scopedEnv({ ...env, LOKI_PROVIDER: provider }), repoDir);
|
|
72900
73114
|
costs.push(parseGroupCost(res.stdout));
|
|
72901
73115
|
if (res.code !== 0 || !new RegExp(`^backlog: ${key} (VERIFIED|PR \\S+)$`, "m").test(res.stdout)) {
|
|
72902
73116
|
units.pop();
|
|
@@ -72930,7 +73144,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72930
73144
|
return 1;
|
|
72931
73145
|
}
|
|
72932
73146
|
const order2 = units.map((u10) => ({ unit_id: u10.id, goal: u10.items.join("; "), files: u10.writeSet }));
|
|
72933
|
-
atomicWriteJson(
|
|
73147
|
+
atomicWriteJson(join110(groupDir, "group", "manifest.json"), { group_id: groupId, units: order2 });
|
|
72934
73148
|
const head = git11(repoDir, ["rev-parse", "--verify", `refs/heads/${r.branch}`]);
|
|
72935
73149
|
let verdict = "", unitVerdicts = [], why = "";
|
|
72936
73150
|
try {
|
|
@@ -72976,7 +73190,7 @@ var NOT_PROVEN = 4, ENV_KEEP, defaultLauncher = (argv, env, cwd, onOut) => new P
|
|
|
72976
73190
|
return r.status === 0 ? String(r.stdout).trim() : "";
|
|
72977
73191
|
}, SLUG_RE, originSlug = (repoDir) => SLUG_RE.exec(git11(repoDir, ["remote", "get-url", "origin"]))?.[1], sha2563 = (s) => createHash31("sha256").update(s).digest("hex"), UNIT_ID_RE, GID_RE, readJson8 = (p) => {
|
|
72978
73192
|
try {
|
|
72979
|
-
const v3 = JSON.parse(
|
|
73193
|
+
const v3 = JSON.parse(readFileSync95(p, "utf8"));
|
|
72980
73194
|
return v3 !== null && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
72981
73195
|
} catch {
|
|
72982
73196
|
return null;
|
|
@@ -73011,7 +73225,7 @@ __export(exports_route, {
|
|
|
73011
73225
|
MAX_SPEC_BYTES: () => MAX_SPEC_BYTES2,
|
|
73012
73226
|
MAX_SEQ_TASK_BYTES: () => MAX_SEQ_TASK_BYTES
|
|
73013
73227
|
});
|
|
73014
|
-
import { closeSync as closeSync15, constants as constants5, fstatSync as fstatSync8, openSync as openSync15, readFileSync as
|
|
73228
|
+
import { closeSync as closeSync15, constants as constants5, fstatSync as fstatSync8, openSync as openSync15, readFileSync as readFileSync96, realpathSync as realpathSync32 } from "fs";
|
|
73015
73229
|
import { isAbsolute as isAbsolute21, relative as relative25, resolve as resolve33 } from "path";
|
|
73016
73230
|
function providerSlots(env, provider) {
|
|
73017
73231
|
provider = (provider || env.LOKI_PROVIDER || "claude").toLowerCase();
|
|
@@ -73038,7 +73252,7 @@ function readSpec(task, repoDir, cwd) {
|
|
|
73038
73252
|
return { kind: "text" };
|
|
73039
73253
|
if (st2.size > MAX_SPEC_BYTES2)
|
|
73040
73254
|
return { kind: "reject", reason: `spec file over ${MAX_SPEC_BYTES2} bytes` };
|
|
73041
|
-
const buf =
|
|
73255
|
+
const buf = readFileSync96(fd2);
|
|
73042
73256
|
if (buf.length > MAX_SPEC_BYTES2)
|
|
73043
73257
|
return { kind: "reject", reason: `spec file over ${MAX_SPEC_BYTES2} bytes` };
|
|
73044
73258
|
if (buf.includes(0))
|
|
@@ -73157,15 +73371,15 @@ var init_route = __esm(() => {
|
|
|
73157
73371
|
});
|
|
73158
73372
|
|
|
73159
73373
|
// ../../loki-ts/src/contrib/forecast.ts
|
|
73160
|
-
import { appendFileSync as appendFileSync12, existsSync as existsSync77, mkdirSync as mkdirSync59, readFileSync as
|
|
73161
|
-
import { join as
|
|
73374
|
+
import { appendFileSync as appendFileSync12, existsSync as existsSync77, mkdirSync as mkdirSync59, readFileSync as readFileSync97 } from "fs";
|
|
73375
|
+
import { join as join111 } from "path";
|
|
73162
73376
|
function readWindowDeltas(lokiDir2) {
|
|
73163
73377
|
const p = historyPath2(lokiDir2);
|
|
73164
73378
|
if (!existsSync77(p))
|
|
73165
73379
|
return [];
|
|
73166
73380
|
const out3 = [];
|
|
73167
73381
|
try {
|
|
73168
|
-
for (const line2 of
|
|
73382
|
+
for (const line2 of readFileSync97(p, "utf8").split(`
|
|
73169
73383
|
`)) {
|
|
73170
73384
|
if (!line2.trim())
|
|
73171
73385
|
continue;
|
|
@@ -73216,17 +73430,17 @@ function forecastLine(reading, history, opts = {}) {
|
|
|
73216
73430
|
const w = range(history.map((h10) => h10.week));
|
|
73217
73431
|
return fit(`forecast: ~${s}% of session window, ~${w}% of week (basis: ${history.length} past runs; ${used})`, width);
|
|
73218
73432
|
}
|
|
73219
|
-
async function printForecast(lokiDir2,
|
|
73433
|
+
async function printForecast(lokiDir2, read3, write, env = process.env) {
|
|
73220
73434
|
if (!forecastOn(env))
|
|
73221
73435
|
return;
|
|
73222
73436
|
try {
|
|
73223
|
-
const line2 = forecastLine(await
|
|
73437
|
+
const line2 = forecastLine(await read3(), readWindowDeltas(lokiDir2), { env });
|
|
73224
73438
|
if (line2)
|
|
73225
73439
|
write(line2 + `
|
|
73226
73440
|
`);
|
|
73227
73441
|
} catch {}
|
|
73228
73442
|
}
|
|
73229
|
-
var MIN_FORECAST_RUNS = 3, KEEP_RUNS = 20, forecastOn = (env = process.env) => env["LOKI_FORECAST"] !== "0", finite = (v3) => typeof v3 === "number" && Number.isFinite(v3), historyPath2 = (lokiDir2) =>
|
|
73443
|
+
var MIN_FORECAST_RUNS = 3, KEEP_RUNS = 20, forecastOn = (env = process.env) => env["LOKI_FORECAST"] !== "0", finite = (v3) => typeof v3 === "number" && Number.isFinite(v3), historyPath2 = (lokiDir2) => join111(lokiDir2, "quota-runs.jsonl"), range = (xs2) => {
|
|
73230
73444
|
const lo = Math.floor(Math.min(...xs2)), hi2 = Math.ceil(Math.max(...xs2));
|
|
73231
73445
|
return lo === hi2 ? `${hi2}` : `${lo}-${hi2}`;
|
|
73232
73446
|
};
|
|
@@ -73235,8 +73449,8 @@ var init_forecast = __esm(() => {
|
|
|
73235
73449
|
});
|
|
73236
73450
|
|
|
73237
73451
|
// ../../loki-ts/src/commands/queue.ts
|
|
73238
|
-
import { existsSync as existsSync78, mkdirSync as mkdirSync60, readFileSync as
|
|
73239
|
-
import { join as
|
|
73452
|
+
import { existsSync as existsSync78, mkdirSync as mkdirSync60, readFileSync as readFileSync98, readdirSync as readdirSync35, renameSync as renameSync21, statSync as statSync31, writeFileSync as writeFileSync58 } from "fs";
|
|
73453
|
+
import { join as join112, resolve as resolve34 } from "path";
|
|
73240
73454
|
function normalizeRef(raw2) {
|
|
73241
73455
|
const m = URL_RE2.exec(raw2);
|
|
73242
73456
|
if (m)
|
|
@@ -73246,11 +73460,11 @@ function normalizeRef(raw2) {
|
|
|
73246
73460
|
return /^0+$/.test(raw2.replace(/^.*#/, "")) ? null : raw2;
|
|
73247
73461
|
}
|
|
73248
73462
|
function queuePath(lokiDir2) {
|
|
73249
|
-
return
|
|
73463
|
+
return join112(lokiDir2, "issue-queue.json");
|
|
73250
73464
|
}
|
|
73251
73465
|
function readQueue(lokiDir2) {
|
|
73252
73466
|
try {
|
|
73253
|
-
const d = JSON.parse(
|
|
73467
|
+
const d = JSON.parse(readFileSync98(queuePath(lokiDir2), "utf8"));
|
|
73254
73468
|
return Array.isArray(d.items) ? d.items.filter((i) => typeof i?.ref === "string") : [];
|
|
73255
73469
|
} catch {
|
|
73256
73470
|
return [];
|
|
@@ -73261,7 +73475,7 @@ function quarantineCorruptQueue(lokiDir2, now2, warn) {
|
|
|
73261
73475
|
if (!existsSync78(p))
|
|
73262
73476
|
return;
|
|
73263
73477
|
try {
|
|
73264
|
-
const d = JSON.parse(
|
|
73478
|
+
const d = JSON.parse(readFileSync98(p, "utf8"));
|
|
73265
73479
|
if (d !== null && typeof d === "object" && Array.isArray(d.items))
|
|
73266
73480
|
return;
|
|
73267
73481
|
} catch {}
|
|
@@ -73463,8 +73677,8 @@ ${QUEUE_USAGE}`);
|
|
|
73463
73677
|
try {
|
|
73464
73678
|
mkdirSync60(d.lokiDir, { recursive: true });
|
|
73465
73679
|
const stamp2 = finished.toISOString().replace(/[:.]/g, "-");
|
|
73466
|
-
writeFileSync58(
|
|
73467
|
-
writeFileSync58(
|
|
73680
|
+
writeFileSync58(join112(d.lokiDir, `queue-digest-${stamp2}.txt`), text4);
|
|
73681
|
+
writeFileSync58(join112(d.lokiDir, "queue-digest-latest.txt"), text4);
|
|
73468
73682
|
} catch (e10) {
|
|
73469
73683
|
d.err(`loki queue: could not write digest: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
73470
73684
|
`);
|
|
@@ -73474,11 +73688,11 @@ ${QUEUE_USAGE}`);
|
|
|
73474
73688
|
}
|
|
73475
73689
|
function newestRecord(lokiDir2, since) {
|
|
73476
73690
|
for (const [sub2, file] of [["runs", "receipt.json"], ["proofs", "proof.json"]]) {
|
|
73477
|
-
const dir =
|
|
73691
|
+
const dir = join112(lokiDir2, sub2);
|
|
73478
73692
|
let best = null;
|
|
73479
73693
|
try {
|
|
73480
73694
|
for (const name of readdirSync35(dir)) {
|
|
73481
|
-
const p =
|
|
73695
|
+
const p = join112(dir, name, file);
|
|
73482
73696
|
if (!existsSync78(p))
|
|
73483
73697
|
continue;
|
|
73484
73698
|
const t = statSync31(p).mtimeMs;
|
|
@@ -73487,7 +73701,7 @@ function newestRecord(lokiDir2, since) {
|
|
|
73487
73701
|
}
|
|
73488
73702
|
if (!best)
|
|
73489
73703
|
continue;
|
|
73490
|
-
const d = JSON.parse(
|
|
73704
|
+
const d = JSON.parse(readFileSync98(best.p, "utf8"));
|
|
73491
73705
|
const usd = d.cost?.usd;
|
|
73492
73706
|
const unmetered = d.cost?.source === "cli-invoker-unmetered";
|
|
73493
73707
|
return {
|
|
@@ -73521,7 +73735,7 @@ function makeDefaultRunner(lokiDir2) {
|
|
|
73521
73735
|
return async (ref, opts) => {
|
|
73522
73736
|
const since = Date.now();
|
|
73523
73737
|
const argv = [resolve34(REPO_ROOT, "bin", "loki"), ...queueStartArgs(ref, !!opts.pr)];
|
|
73524
|
-
const runLoki = opts.cwd ?
|
|
73738
|
+
const runLoki = opts.cwd ? join112(opts.cwd, ".loki") : lokiDir2;
|
|
73525
73739
|
const env = runnerEnv(opts, runLoki);
|
|
73526
73740
|
const proc = Bun.spawn(argv, { stdout: "pipe", stderr: "pipe", stdin: "ignore", env, ...opts.cwd ? { cwd: opts.cwd } : {} });
|
|
73527
73741
|
const mins2 = itemTimeoutMin(process.env["LOKI_QUEUE_ITEM_TIMEOUT_MIN"]);
|
|
@@ -73531,9 +73745,9 @@ function makeDefaultRunner(lokiDir2) {
|
|
|
73531
73745
|
clearTimeout(timer);
|
|
73532
73746
|
const output = so + se2;
|
|
73533
73747
|
try {
|
|
73534
|
-
const logDir =
|
|
73748
|
+
const logDir = join112(lokiDir2, "queue-logs");
|
|
73535
73749
|
mkdirSync60(logDir, { recursive: true });
|
|
73536
|
-
writeFileSync58(
|
|
73750
|
+
writeFileSync58(join112(logDir, `${(opts.logName ?? ref).replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 120)}.log`), output);
|
|
73537
73751
|
} catch {}
|
|
73538
73752
|
const proof = newestRecord(runLoki, since);
|
|
73539
73753
|
return { rc: rc2, output, verdict: proof.verdict, costUsd: proof.costUsd, runId: proof.runId ?? null };
|
|
@@ -73713,13 +73927,13 @@ function renderEpicTree(n11, title, rows) {
|
|
|
73713
73927
|
}
|
|
73714
73928
|
function makeSessionDecompose(repoDir, lokiDir2, provider) {
|
|
73715
73929
|
return async (slug, issue, triageReason) => {
|
|
73716
|
-
const { mkdirSync: mkdirSync61, readFileSync:
|
|
73717
|
-
const { join:
|
|
73930
|
+
const { mkdirSync: mkdirSync61, readFileSync: readFileSync99, existsSync: existsSync79 } = await import("fs");
|
|
73931
|
+
const { join: join113 } = await import("path");
|
|
73718
73932
|
const { createSessionRunner: createSessionRunner2 } = await Promise.resolve().then(() => (init_session(), exports_session));
|
|
73719
73933
|
const { envOverride: envOverride2 } = await Promise.resolve().then(() => (init_decision(), exports_decision));
|
|
73720
|
-
const dir =
|
|
73934
|
+
const dir = join113(lokiDir2, "issues-run", "decompose");
|
|
73721
73935
|
mkdirSync61(dir, { recursive: true });
|
|
73722
|
-
const outPath =
|
|
73936
|
+
const outPath = join113(dir, `issue-${issue.number}-${Date.now()}.json`);
|
|
73723
73937
|
const runner = createSessionRunner2({ provider, lokiRoot: lokiDir2 });
|
|
73724
73938
|
const r = await runner.run({
|
|
73725
73939
|
stage: "plan",
|
|
@@ -73732,7 +73946,7 @@ function makeSessionDecompose(repoDir, lokiDir2, provider) {
|
|
|
73732
73946
|
...provider === "claude" && envOverride2(process.env) === null ? { model: "opus" } : {}
|
|
73733
73947
|
});
|
|
73734
73948
|
if (existsSync79(outPath))
|
|
73735
|
-
return
|
|
73949
|
+
return readFileSync99(outPath, "utf8");
|
|
73736
73950
|
return r.summary ?? "";
|
|
73737
73951
|
};
|
|
73738
73952
|
}
|
|
@@ -73759,7 +73973,7 @@ __export(exports_issues_run, {
|
|
|
73759
73973
|
import { spawnSync as spawnSync15 } from "child_process";
|
|
73760
73974
|
import { cpSync as cpSync3, existsSync as existsSync79, mkdirSync as mkdirSync61, mkdtempSync as mkdtempSync15, rmSync as rmSync33, writeFileSync as writeFileSync59 } from "fs";
|
|
73761
73975
|
import { tmpdir as tmpdir19 } from "os";
|
|
73762
|
-
import { join as
|
|
73976
|
+
import { join as join113, resolve as resolve35 } from "path";
|
|
73763
73977
|
import { createInterface as createInterface3 } from "readline";
|
|
73764
73978
|
function parseIssuesArgs(args) {
|
|
73765
73979
|
const a = { slug: null, label: null, milestone: null, limit: DEFAULT_LIMIT, parallel: 1, draft: false, dryRun: false, yes: false, comment: false, split: true, json: false };
|
|
@@ -74015,7 +74229,7 @@ ${USAGE}`);
|
|
|
74015
74229
|
}
|
|
74016
74230
|
}
|
|
74017
74231
|
const stamp2 = started.toISOString().replace(/[:.]/g, "-");
|
|
74018
|
-
const runDir =
|
|
74232
|
+
const runDir = join113(d.lokiDir, "issues-run", stamp2);
|
|
74019
74233
|
mkdirSync61(runDir, { recursive: true });
|
|
74020
74234
|
const byRef = new Map(actionable.map((i) => [`${slug}#${i.number}`, i]));
|
|
74021
74235
|
const sink = () => {};
|
|
@@ -74105,14 +74319,14 @@ ${USAGE}`);
|
|
|
74105
74319
|
${trees.join(`
|
|
74106
74320
|
`)}` : "");
|
|
74107
74321
|
try {
|
|
74108
|
-
writeFileSync59(
|
|
74322
|
+
writeFileSync59(join113(runDir, "digest.md"), text4);
|
|
74109
74323
|
} catch (e10) {
|
|
74110
74324
|
d.err(`loki issues run: could not write digest: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
74111
74325
|
`);
|
|
74112
74326
|
}
|
|
74113
74327
|
d.out(`
|
|
74114
74328
|
${text4}
|
|
74115
|
-
digest: ${
|
|
74329
|
+
digest: ${join113(runDir, "digest.md")}
|
|
74116
74330
|
`);
|
|
74117
74331
|
return 0;
|
|
74118
74332
|
}
|
|
@@ -74122,11 +74336,11 @@ function perRun(est) {
|
|
|
74122
74336
|
return est.prior ? { usd: est.prior.usd, tilde: "~", label: " (rough prior)" } : null;
|
|
74123
74337
|
}
|
|
74124
74338
|
function keepReceipt(wt, runId2, runDir, err) {
|
|
74125
|
-
const src =
|
|
74339
|
+
const src = join113(wt, ".loki", "runs", runId2);
|
|
74126
74340
|
if (!/^[A-Za-z0-9_.-]+$/.test(runId2) || !existsSync79(src))
|
|
74127
74341
|
return;
|
|
74128
74342
|
try {
|
|
74129
|
-
cpSync3(src,
|
|
74343
|
+
cpSync3(src, join113(runDir, "receipts", runId2), { recursive: true });
|
|
74130
74344
|
} catch (e10) {
|
|
74131
74345
|
err(`loki issues run: could not keep the receipt of ${runId2}: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
74132
74346
|
`);
|
|
@@ -74173,8 +74387,8 @@ function makeWorktrees(repoDir) {
|
|
|
74173
74387
|
let root = null;
|
|
74174
74388
|
return {
|
|
74175
74389
|
create: (name, base) => {
|
|
74176
|
-
root ??= mkdtempSync15(
|
|
74177
|
-
const p =
|
|
74390
|
+
root ??= mkdtempSync15(join113(tmpdir19(), "loki-issues-"));
|
|
74391
|
+
const p = join113(root, name);
|
|
74178
74392
|
safeGit(repoDir, ["worktree", "add", "-B", `loki/${name}`, p, base]);
|
|
74179
74393
|
return p;
|
|
74180
74394
|
},
|
|
@@ -74267,7 +74481,7 @@ __export(exports_satisfaction, {
|
|
|
74267
74481
|
});
|
|
74268
74482
|
import { appendFileSync as appendFileSync13, mkdirSync as mkdirSync62 } from "fs";
|
|
74269
74483
|
import { homedir as homedir13 } from "os";
|
|
74270
|
-
import { join as
|
|
74484
|
+
import { join as join114 } from "path";
|
|
74271
74485
|
import { createInterface as createInterface4 } from "readline";
|
|
74272
74486
|
function satisfactionEnabled(env, tty) {
|
|
74273
74487
|
if (!tty)
|
|
@@ -74287,9 +74501,9 @@ function parseScore(line2) {
|
|
|
74287
74501
|
return { score: Number(m[1]), again: m[2] ? m[2].toLowerCase() === "y" : null };
|
|
74288
74502
|
}
|
|
74289
74503
|
function recordSatisfaction(home, row) {
|
|
74290
|
-
const dir =
|
|
74504
|
+
const dir = join114(home, ".loki");
|
|
74291
74505
|
mkdirSync62(dir, { recursive: true, mode: 448 });
|
|
74292
|
-
appendFileSync13(
|
|
74506
|
+
appendFileSync13(join114(dir, "satisfaction.jsonl"), `${JSON.stringify(row)}
|
|
74293
74507
|
`, { mode: 384 });
|
|
74294
74508
|
}
|
|
74295
74509
|
async function maybeAsk(o) {
|
|
@@ -74360,8 +74574,8 @@ __export(exports_supervisor, {
|
|
|
74360
74574
|
});
|
|
74361
74575
|
import { spawn as spawn13, spawnSync as spawnSync16 } from "child_process";
|
|
74362
74576
|
import { createHash as createHash32, createPublicKey as createPublicKey3, sign as sign2 } from "crypto";
|
|
74363
|
-
import { existsSync as existsSync80, mkdirSync as mkdirSync63, readFileSync as
|
|
74364
|
-
import { join as
|
|
74577
|
+
import { existsSync as existsSync80, mkdirSync as mkdirSync63, readFileSync as readFileSync99, writeFileSync as writeFileSync60 } from "fs";
|
|
74578
|
+
import { join as join115, relative as relative26, resolve as resolve36 } from "path";
|
|
74365
74579
|
async function slackEvent(...a) {
|
|
74366
74580
|
try {
|
|
74367
74581
|
await (await Promise.resolve().then(() => (init_slack_events(), exports_slack_events))).notifyEvent(...a);
|
|
@@ -74390,7 +74604,7 @@ class SupervisorLog {
|
|
|
74390
74604
|
this.log = new EventLog(path, runId2);
|
|
74391
74605
|
this.hash = createHash32("sha256");
|
|
74392
74606
|
try {
|
|
74393
|
-
this.hash.update(
|
|
74607
|
+
this.hash.update(readFileSync99(path));
|
|
74394
74608
|
} catch {}
|
|
74395
74609
|
}
|
|
74396
74610
|
implementOpen = false;
|
|
@@ -74445,7 +74659,7 @@ class SupervisorLog {
|
|
|
74445
74659
|
const expected = this.hash.copy().digest("hex");
|
|
74446
74660
|
let actual = "";
|
|
74447
74661
|
try {
|
|
74448
|
-
actual = createHash32("sha256").update(
|
|
74662
|
+
actual = createHash32("sha256").update(readFileSync99(this.path)).digest("hex");
|
|
74449
74663
|
} catch {}
|
|
74450
74664
|
if (actual === expected)
|
|
74451
74665
|
return true;
|
|
@@ -74467,15 +74681,15 @@ async function runSupervisor(opts) {
|
|
|
74467
74681
|
const t02 = Date.now();
|
|
74468
74682
|
const startedProvider = opts.started?.["provider"];
|
|
74469
74683
|
const env = opts.env ?? process.env;
|
|
74470
|
-
await assertPreflight({ repoDir: opts.repoDir, provider: typeof startedProvider === "string" ? startedProvider : "claude", pr: opts.pr !== undefined, env, runDir:
|
|
74684
|
+
await assertPreflight({ repoDir: opts.repoDir, provider: typeof startedProvider === "string" ? startedProvider : "claude", pr: opts.pr !== undefined, env, runDir: join115(opts.repoDir, ".loki", "runs", opts.runId) });
|
|
74471
74685
|
writeEngineMarker(opts.repoDir, opts.runId);
|
|
74472
74686
|
const origin = readOriginUrl(opts.repoDir);
|
|
74473
|
-
const rmRunPid = writeRunPid(
|
|
74687
|
+
const rmRunPid = writeRunPid(join115(opts.repoDir, ".loki", "runs", opts.runId), opts.runId);
|
|
74474
74688
|
process.once("exit", rmRunPid);
|
|
74475
|
-
const log = new SupervisorLog(
|
|
74689
|
+
const log = new SupervisorLog(join115(opts.repoDir, eventsRelPath(opts.runId)), opts.runId);
|
|
74476
74690
|
if ((env.LOKI_CONTROL ?? process.env.LOKI_CONTROL) !== "0")
|
|
74477
74691
|
Promise.resolve().then(() => (init_ship_hook(), exports_ship_hook)).then((m) => m.startShip(opts.repoDir, log.path, env)).catch(() => {});
|
|
74478
|
-
const aliveDir =
|
|
74692
|
+
const aliveDir = join115(opts.repoDir, ".loki", "runs", opts.runId), lastAlive = opts.resume ? readAliveBeat(aliveDir) : null;
|
|
74479
74693
|
log.append(opts.resume ? "run.resumed" : "run.started", null, { ...opts.started, ...opts.resume ? { phase: "stage", ...lastAlive ? { last_alive_ts: new Date(lastAlive).toISOString() } : {} } : {}, origin_repo: githubRepoFromUrl(origin) });
|
|
74480
74694
|
if (!opts.resume)
|
|
74481
74695
|
Promise.resolve().then(() => (init_writeback(), exports_writeback)).then((m) => m.writeBack({ phase: "started", verdict: "", prUrl: null, receiptSha256: null, task: "" }, env));
|
|
@@ -74510,7 +74724,7 @@ async function runSupervisor(opts) {
|
|
|
74510
74724
|
if (e10?.type === "receipt.sealed")
|
|
74511
74725
|
sealed = e10.data;
|
|
74512
74726
|
if (e10?.type === "variant" && e10.data.intent_confirm === true && workerEnv.LOKI_INTENT_TTY === "1") {
|
|
74513
|
-
askIntent(String(e10.data.card ?? ""),
|
|
74727
|
+
askIntent(String(e10.data.card ?? ""), join115(opts.repoDir, ".loki", "runs", opts.runId));
|
|
74514
74728
|
}
|
|
74515
74729
|
}, (stopped) => {
|
|
74516
74730
|
for (const g10 of sessionGroups)
|
|
@@ -74609,8 +74823,8 @@ async function runSupervisor(opts) {
|
|
|
74609
74823
|
}
|
|
74610
74824
|
log.append("run.completed", null, { verdict, ...cancelled2 ? { cancelled: true, signal: cancelled2, outcome: "CANCELLED" } : {}, pr_url: prUrl, not_proven: notProven, cost_usd: costUsd, wall_s: wallS, pre_model: preModelTiming(allEvents, t02) });
|
|
74611
74825
|
log.sealLog();
|
|
74612
|
-
recordFingerprints(
|
|
74613
|
-
const stages = allEvents.filter((e10) => e10.type === "stage.completed" && typeof e10.data.duration_s === "number").map((e10) => ({ label: String(e10.stage), seconds: e10.data.duration_s })), pc2 = partialCost(allEvents, log.tampered), summary = { pr: prUrl ? { url: prUrl, draft: verdict !== "VERIFIED" } : null, verdict, outcome, notProven, flaky: recordFingerprints(
|
|
74826
|
+
recordFingerprints(join115(opts.repoDir, ".loki", "state"), opts.runId, "failed", failedCheckNames(folded.stages["verify"]?.data.checks, folded.stages["verify"]?.data.pre_red_checks), cleanTreeId(opts.repoDir));
|
|
74827
|
+
const stages = allEvents.filter((e10) => e10.type === "stage.completed" && typeof e10.data.duration_s === "number").map((e10) => ({ label: String(e10.stage), seconds: e10.data.duration_s })), pc2 = partialCost(allEvents, log.tampered), summary = { pr: prUrl ? { url: prUrl, draft: verdict !== "VERIFIED" } : null, verdict, outcome, notProven, flaky: recordFingerprints(join115(opts.repoDir, ".loki", "state"), opts.runId, "flaky", folded.stages["verify"]?.data.flaky, cleanTreeId(opts.repoDir)), wallS, stages, cost: { usd: costUsd, provider: String(opts.started?.provider ?? ""), tokens: summaryTokens(folded, allEvents.some((e10) => e10.type === "cost")), ...summaryCache(allEvents, log.tampered), partialUsd: pc2.usd, measuredSessions: pc2.measured, totalSessions: pc2.total, stageShares: log.tampered ? null : stageShareText(allEvents), capUsd: Number(opts.started?.["max_cost_usd"]) > 0 ? Number(opts.started?.["max_cost_usd"]) : undefined } };
|
|
74614
74828
|
await slackEvent(env, "finished", { summary: formatSummary(summary), outcome: String(outcome), cost: summary.cost.usd != null ? `$${summary.cost.usd.toFixed(2)}` : "not measured", time: `${Math.round(wallS)}s`, receipt: log.tampered ? "TAMPERED" : receiptVerdict ? verdict : undefined });
|
|
74615
74829
|
rmRunPid();
|
|
74616
74830
|
process.off("exit", rmRunPid);
|
|
@@ -74636,6 +74850,7 @@ async function main4(args) {
|
|
|
74636
74850
|
if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
|
|
74637
74851
|
process.stderr.write(`engine10: --max-cost needs a value
|
|
74638
74852
|
`);
|
|
74853
|
+
noteRefusal("unsupported_flag");
|
|
74639
74854
|
return 2;
|
|
74640
74855
|
}
|
|
74641
74856
|
maxCost = v3;
|
|
@@ -74647,6 +74862,7 @@ async function main4(args) {
|
|
|
74647
74862
|
if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
|
|
74648
74863
|
process.stderr.write(`engine10: --provider needs a value
|
|
74649
74864
|
`);
|
|
74865
|
+
noteRefusal("unsupported_flag");
|
|
74650
74866
|
return 2;
|
|
74651
74867
|
}
|
|
74652
74868
|
provider = v3;
|
|
@@ -74656,6 +74872,7 @@ async function main4(args) {
|
|
|
74656
74872
|
if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
|
|
74657
74873
|
process.stderr.write(`engine10: --spec needs a value
|
|
74658
74874
|
`);
|
|
74875
|
+
noteRefusal("unsupported_flag");
|
|
74659
74876
|
return 2;
|
|
74660
74877
|
}
|
|
74661
74878
|
specFile = v3;
|
|
@@ -74671,6 +74888,7 @@ async function main4(args) {
|
|
|
74671
74888
|
if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
|
|
74672
74889
|
process.stderr.write(`engine10: --seal-existing needs a patch file
|
|
74673
74890
|
`);
|
|
74891
|
+
noteRefusal("unsupported_flag");
|
|
74674
74892
|
return 2;
|
|
74675
74893
|
}
|
|
74676
74894
|
sealPatch = resolve36(v3);
|
|
@@ -74682,6 +74900,7 @@ async function main4(args) {
|
|
|
74682
74900
|
process.stderr.write(`engine10: unknown flag ${a}
|
|
74683
74901
|
usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-cost N] [--provider P] [--spec F] [--seal-existing PATCH] [--resume] [--fresh] [-- <task>]
|
|
74684
74902
|
`);
|
|
74903
|
+
noteRefusal("unsupported_flag");
|
|
74685
74904
|
return 2;
|
|
74686
74905
|
} else
|
|
74687
74906
|
words3.push(a);
|
|
@@ -74696,6 +74915,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74696
74915
|
} catch (e10) {
|
|
74697
74916
|
process.stderr.write(`engine10: ${e10.message}
|
|
74698
74917
|
`);
|
|
74918
|
+
noteRefusal("prd_missing");
|
|
74699
74919
|
return 2;
|
|
74700
74920
|
}
|
|
74701
74921
|
if (!task)
|
|
@@ -74712,6 +74932,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74712
74932
|
if (!task) {
|
|
74713
74933
|
process.stderr.write(`engine10: no task given
|
|
74714
74934
|
`);
|
|
74935
|
+
noteRefusal("prd_missing");
|
|
74715
74936
|
return 2;
|
|
74716
74937
|
}
|
|
74717
74938
|
let repoDir;
|
|
@@ -74722,6 +74943,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74722
74943
|
if (!i.notice) {
|
|
74723
74944
|
process.stderr.write(`engine10: ${i.fatal ?? "not inside a git repository"}
|
|
74724
74945
|
`);
|
|
74946
|
+
noteRefusal("not_a_repo");
|
|
74725
74947
|
return 2;
|
|
74726
74948
|
}
|
|
74727
74949
|
process.stderr.write(`engine10: ${i.notice}
|
|
@@ -74731,6 +74953,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74731
74953
|
} catch {
|
|
74732
74954
|
process.stderr.write(`engine10: not inside a git repository
|
|
74733
74955
|
`);
|
|
74956
|
+
noteRefusal("not_a_repo");
|
|
74734
74957
|
return 2;
|
|
74735
74958
|
}
|
|
74736
74959
|
}
|
|
@@ -74740,7 +74963,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74740
74963
|
return rec2;
|
|
74741
74964
|
}
|
|
74742
74965
|
const runId2 = `e10-${new Date().toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z")}-${Math.random().toString(16).slice(2, 6)}`;
|
|
74743
|
-
const runDir =
|
|
74966
|
+
const runDir = join115(repoDir, ".loki", "runs", runId2);
|
|
74744
74967
|
const cap = resolveCap(maxCost, repoDir);
|
|
74745
74968
|
if ("error" in cap) {
|
|
74746
74969
|
process.stderr.write(`engine10: ${cap.error}
|
|
@@ -74778,7 +75001,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74778
75001
|
}
|
|
74779
75002
|
if (spec) {
|
|
74780
75003
|
mkdirSync63(runDir, { recursive: true });
|
|
74781
|
-
writeFileSync60(
|
|
75004
|
+
writeFileSync60(join115(runDir, "spec.snapshot.md"), spec.raw);
|
|
74782
75005
|
for (const e10 of [env, process.env]) {
|
|
74783
75006
|
e10.LOKI_E10_SPEC_PATH = relative26(repoDir, spec.path);
|
|
74784
75007
|
e10.LOKI_E10_SPEC_SHA256 = spec.sha256;
|
|
@@ -74803,9 +75026,9 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74803
75026
|
mkdirSync63(runDir, { recursive: true });
|
|
74804
75027
|
try {
|
|
74805
75028
|
if (trackerRef)
|
|
74806
|
-
await fetchTrackerIssueToFile(trackerRef,
|
|
75029
|
+
await fetchTrackerIssueToFile(trackerRef, join115(runDir, "issue.json"));
|
|
74807
75030
|
else
|
|
74808
|
-
fetchIssueToFile(task,
|
|
75031
|
+
fetchIssueToFile(task, join115(runDir, "issue.json"));
|
|
74809
75032
|
} catch (err) {
|
|
74810
75033
|
process.stderr.write(`engine10: issue fetch failed: ${err.message.split(`
|
|
74811
75034
|
`)[0]}
|
|
@@ -74835,7 +75058,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74835
75058
|
process.stdout.write(`${capLine}
|
|
74836
75059
|
`);
|
|
74837
75060
|
const t02 = Date.now();
|
|
74838
|
-
const eventsPath =
|
|
75061
|
+
const eventsPath = join115(repoDir, eventsRelPath(runId2));
|
|
74839
75062
|
const live2 = (e10) => {
|
|
74840
75063
|
const clockS = (Date.parse(e10.ts) - t02) / 1000;
|
|
74841
75064
|
const d = e10.data;
|
|
@@ -74882,7 +75105,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74882
75105
|
const reqOnce = async (evs) => {
|
|
74883
75106
|
if (reqMap === undefined) {
|
|
74884
75107
|
const rq2 = await Promise.resolve().then(() => (init_contract(), exports_contract));
|
|
74885
|
-
reqMap = rq2.writeFromEngine10(repoDir,
|
|
75108
|
+
reqMap = rq2.writeFromEngine10(repoDir, join115(repoDir, ".loki"), runDir, isIssue ? null : task, evs);
|
|
74886
75109
|
}
|
|
74887
75110
|
return reqMap;
|
|
74888
75111
|
};
|
|
@@ -74892,6 +75115,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74892
75115
|
if (e10.type === "stage.completed" && e10.stage === "plan")
|
|
74893
75116
|
statusStep();
|
|
74894
75117
|
}, { intervalMs: 500 }) : () => {};
|
|
75118
|
+
let refusedAs = "other";
|
|
74895
75119
|
const res = await runSupervisor({
|
|
74896
75120
|
runId: runId2,
|
|
74897
75121
|
repoDir,
|
|
@@ -74945,7 +75169,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74945
75169
|
comment: noPr ? undefined : async ({ issueRef, reason, prUrl }) => {
|
|
74946
75170
|
const { DEFAULT_PUSH_SH: DEFAULT_PUSH_SH2 } = await Promise.resolve().then(() => (init_pr(), exports_pr));
|
|
74947
75171
|
mkdirSync63(runDir, { recursive: true });
|
|
74948
|
-
const bodyFile =
|
|
75172
|
+
const bodyFile = join115(runDir, "backstop-comment.md");
|
|
74949
75173
|
writeFileSync60(bodyFile, `<!-- loki-backstop -->
|
|
74950
75174
|
Loki 10 run ${runId2} ${prUrl ? `opened draft PR ${prUrl}` : "ended without a PR"}.
|
|
74951
75175
|
|
|
@@ -74960,6 +75184,7 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
|
|
|
74960
75184
|
throw e10;
|
|
74961
75185
|
process.stderr.write(`${e10.message}
|
|
74962
75186
|
`);
|
|
75187
|
+
refusedAs = e10.blocker;
|
|
74963
75188
|
return null;
|
|
74964
75189
|
});
|
|
74965
75190
|
clearInterval(tailTimer);
|
|
@@ -74967,12 +75192,14 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
|
|
|
74967
75192
|
if (!res) {
|
|
74968
75193
|
stopTail();
|
|
74969
75194
|
liveStop();
|
|
75195
|
+
noteRefusal(refusedAs);
|
|
74970
75196
|
return 2;
|
|
74971
75197
|
}
|
|
74972
75198
|
await new Promise((r) => setTimeout(r, 300));
|
|
74973
75199
|
stopTail();
|
|
74974
75200
|
liveStop();
|
|
74975
75201
|
const events2 = readEvents(eventsPath), f = fold(events2);
|
|
75202
|
+
noteRefusalFromEvents(events2);
|
|
74976
75203
|
const sawCost = events2.some((e10) => e10.type === "cost"), cli = process.env.LOKI_E10_INVOKER === "cli";
|
|
74977
75204
|
const { usd, pc: pc2 } = summaryCost(events2, res.tampered);
|
|
74978
75205
|
const out3 = json2 ? `${JSON.stringify({ ok: EXIT[res.outcome] === 0, outcome: res.outcome, stop: res.stop, run_id: runId2, receipt_sha256: res.receiptSha })}
|
|
@@ -75007,7 +75234,7 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
|
|
|
75007
75234
|
const rr2 = resultOf(res.outcome);
|
|
75008
75235
|
if (res.outcome === "BUDGET_STOP" && cap.usd > 0)
|
|
75009
75236
|
writeBudgetStop(repoDir, runId2, { task: task.trim(), cap_usd: cap.usd, spent_usd: seed + (usd ?? 0), source: cap.source });
|
|
75010
|
-
const ui2 = { result: rr2, filesChanged: ds2?.files ?? null, insertions: ds2?.ins, deletions: ds2?.del, costUsd: usd, elapsedS: Number(f.run.completed?.data.wall_s ?? (Date.now() - t02) / 1000), receiptPath: res.receiptSha ?
|
|
75237
|
+
const ui2 = { result: rr2, filesChanged: ds2?.files ?? null, insertions: ds2?.ins, deletions: ds2?.del, costUsd: usd, elapsedS: Number(f.run.completed?.data.wall_s ?? (Date.now() - t02) / 1000), receiptPath: res.receiptSha ? join115(runDir, "receipt.json") : null, next: res.outcome === "BUDGET_STOP" && cap.usd > 0 ? budgetNext(seed + (usd ?? 0), cap.usd) : nextOf(rr2, ds2?.files ?? null, reasonOf(events2, res.tampered, res.stop, res.outcome), provider, runId2), uncovered };
|
|
75011
75238
|
const rdy = events2.find((e10) => e10.type === "stage.completed" && e10.stage === "intake")?.data.readiness, foldTail = [handoffRef, typeof rdy === "string" ? rdy : ""].filter(Boolean).join("; ");
|
|
75012
75239
|
const riskLine = readRiskSummary(repoDir, t02);
|
|
75013
75240
|
process.stdout.write(json2 ? `${JSON.stringify({ ...JSON.parse(out3), summary: { ...summaryObject(ui2), ...riskLine ? { risk: riskLine } : {} } })}
|
|
@@ -75046,6 +75273,7 @@ var init_supervisor = __esm(() => {
|
|
|
75046
75273
|
init_worker_proc();
|
|
75047
75274
|
init_intent_card();
|
|
75048
75275
|
init_preflight();
|
|
75276
|
+
init_funnel();
|
|
75049
75277
|
init_session();
|
|
75050
75278
|
init_failure_memory();
|
|
75051
75279
|
init_model_downgrades();
|
|
@@ -75062,8 +75290,8 @@ var init_supervisor = __esm(() => {
|
|
|
75062
75290
|
});
|
|
75063
75291
|
|
|
75064
75292
|
// ../../loki-ts/src/e10ext/compound_match.ts
|
|
75065
|
-
import { readFileSync as
|
|
75066
|
-
import { basename as basename29, join as
|
|
75293
|
+
import { readFileSync as readFileSync100 } from "fs";
|
|
75294
|
+
import { basename as basename29, join as join116 } from "path";
|
|
75067
75295
|
function parts(s) {
|
|
75068
75296
|
return s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
75069
75297
|
}
|
|
@@ -75090,7 +75318,7 @@ function linkedHits(word, repoMap, testMap, repoDir) {
|
|
|
75090
75318
|
continue;
|
|
75091
75319
|
let body;
|
|
75092
75320
|
try {
|
|
75093
|
-
body = importLines(
|
|
75321
|
+
body = importLines(readFileSync100(join116(repoDir, t.path), "utf8"));
|
|
75094
75322
|
} catch {
|
|
75095
75323
|
continue;
|
|
75096
75324
|
}
|
|
@@ -75111,8 +75339,8 @@ var init_compound_match = __esm(() => {
|
|
|
75111
75339
|
});
|
|
75112
75340
|
|
|
75113
75341
|
// ../../loki-ts/src/util/already_done_evidence.ts
|
|
75114
|
-
import { existsSync as existsSync81, readFileSync as
|
|
75115
|
-
import { basename as basename30, join as
|
|
75342
|
+
import { existsSync as existsSync81, readFileSync as readFileSync101 } from "fs";
|
|
75343
|
+
import { basename as basename30, join as join117 } from "path";
|
|
75116
75344
|
function keywords2(task) {
|
|
75117
75345
|
const words3 = task.toLowerCase().match(/[a-z0-9_]+/g) ?? [];
|
|
75118
75346
|
return Array.from(new Set(words3.filter((w) => w.length > 2 && !STOP_WORDS.has(w))));
|
|
@@ -75144,7 +75372,7 @@ function docEvidence(words3, repoDir) {
|
|
|
75144
75372
|
for (const name of DOC_FILES) {
|
|
75145
75373
|
let text4;
|
|
75146
75374
|
try {
|
|
75147
|
-
text4 =
|
|
75375
|
+
text4 = readFileSync101(join117(repoDir, name), "utf8");
|
|
75148
75376
|
} catch {
|
|
75149
75377
|
continue;
|
|
75150
75378
|
}
|
|
@@ -75206,7 +75434,7 @@ function citesToken(text4, token) {
|
|
|
75206
75434
|
function citesRealHit(text4, hit, repoDir) {
|
|
75207
75435
|
if (hit.source === "changelog")
|
|
75208
75436
|
return false;
|
|
75209
|
-
return (citesToken(text4, hit.path) || citesToken(text4, basename30(hit.path))) && existsSync81(
|
|
75437
|
+
return (citesToken(text4, hit.path) || citesToken(text4, basename30(hit.path))) && existsSync81(join117(repoDir, hit.path));
|
|
75210
75438
|
}
|
|
75211
75439
|
function renderAlreadyDoneComment(evidence) {
|
|
75212
75440
|
return ["Loki 10: no change needed. This already appears to be implemented.", "", "Evidence:", ...evidence.map((e10) => `- ${e10}`), ""].join(`
|
|
@@ -75408,9 +75636,9 @@ __export(exports_warm, {
|
|
|
75408
75636
|
WarmEngine: () => WarmEngine
|
|
75409
75637
|
});
|
|
75410
75638
|
import { createHash as createHash33 } from "crypto";
|
|
75411
|
-
import { existsSync as existsSync82, mkdirSync as mkdirSync64, readFileSync as
|
|
75639
|
+
import { existsSync as existsSync82, mkdirSync as mkdirSync64, readFileSync as readFileSync102, statSync as statSync32, unlinkSync as unlinkSync11 } from "fs";
|
|
75412
75640
|
import { createServer as createServer2 } from "net";
|
|
75413
|
-
import { dirname as
|
|
75641
|
+
import { dirname as dirname46, resolve as resolve37 } from "path";
|
|
75414
75642
|
function speedEnabled() {
|
|
75415
75643
|
return process.env["LOKI_SPEED"] !== "0";
|
|
75416
75644
|
}
|
|
@@ -75438,7 +75666,7 @@ function dirtyHash(repoDir) {
|
|
|
75438
75666
|
try {
|
|
75439
75667
|
const p = resolve37(repoDir, rel);
|
|
75440
75668
|
if (existsSync82(p) && statSync32(p).isFile() && statSync32(p).size <= MAX_HASHED_BYTES)
|
|
75441
|
-
h10.update(
|
|
75669
|
+
h10.update(readFileSync102(p));
|
|
75442
75670
|
} catch {}
|
|
75443
75671
|
}
|
|
75444
75672
|
return h10.digest("hex");
|
|
@@ -75491,7 +75719,7 @@ function startWarmIfEnabled() {
|
|
|
75491
75719
|
}
|
|
75492
75720
|
}
|
|
75493
75721
|
function startWarmServer(path = warmSocketPath(), engine = new WarmEngine) {
|
|
75494
|
-
mkdirSync64(
|
|
75722
|
+
mkdirSync64(dirname46(path), { recursive: true });
|
|
75495
75723
|
try {
|
|
75496
75724
|
unlinkSync11(path);
|
|
75497
75725
|
} catch {}
|
|
@@ -75550,7 +75778,7 @@ var init_warm = __esm(() => {
|
|
|
75550
75778
|
import { execFile as execFile3 } from "child_process";
|
|
75551
75779
|
import { mkdirSync as mkdirSync65, mkdtempSync as mkdtempSync16, rmSync as rmSync34 } from "fs";
|
|
75552
75780
|
import { tmpdir as tmpdir20 } from "os";
|
|
75553
|
-
import { join as
|
|
75781
|
+
import { join as join118 } from "path";
|
|
75554
75782
|
function hitsUnchangedFromBase(repoDir, baseSha, paths) {
|
|
75555
75783
|
if (paths.length === 0 || !baseSha)
|
|
75556
75784
|
return false;
|
|
@@ -75588,23 +75816,23 @@ function dropRoot(root) {
|
|
|
75588
75816
|
function pinBaseTree(ctx, signal) {
|
|
75589
75817
|
let root;
|
|
75590
75818
|
try {
|
|
75591
|
-
root = mkdtempSync16(
|
|
75819
|
+
root = mkdtempSync16(join118(tmpdir20(), "loki-already-done-"));
|
|
75592
75820
|
} catch {
|
|
75593
75821
|
return Promise.resolve(null);
|
|
75594
75822
|
}
|
|
75595
75823
|
trackRoot(root);
|
|
75596
75824
|
try {
|
|
75597
|
-
mkdirSync65(
|
|
75825
|
+
mkdirSync65(join118(root, "tree"));
|
|
75598
75826
|
} catch {
|
|
75599
75827
|
dropRoot(root);
|
|
75600
75828
|
return Promise.resolve(null);
|
|
75601
75829
|
}
|
|
75602
|
-
const tarball =
|
|
75830
|
+
const tarball = join118(root, "base.tar");
|
|
75603
75831
|
const step = (cmd2, args, cwd) => new Promise((res) => {
|
|
75604
75832
|
execFile3(cmd2, args, { env: process.env, signal, cwd }, (err) => res(!err));
|
|
75605
75833
|
});
|
|
75606
75834
|
return (async () => {
|
|
75607
|
-
if (!ctx.baseSha || (await safeGitRun(ctx.repoDir, ["archive", "-o", tarball, ctx.baseSha], { signal })).exitCode !== 0 || !await step("tar", ["-x", "-f", tarball, "-C",
|
|
75835
|
+
if (!ctx.baseSha || (await safeGitRun(ctx.repoDir, ["archive", "-o", tarball, ctx.baseSha], { signal })).exitCode !== 0 || !await step("tar", ["-x", "-f", tarball, "-C", join118(root, "tree")], root)) {
|
|
75608
75836
|
dropRoot(root);
|
|
75609
75837
|
return null;
|
|
75610
75838
|
}
|
|
@@ -75662,7 +75890,7 @@ function deferAlreadyDone(ctx, signal, task, repoMap, testMap, apply) {
|
|
|
75662
75890
|
if (!root)
|
|
75663
75891
|
return;
|
|
75664
75892
|
try {
|
|
75665
|
-
const r = await checkAlreadyDone({ ...ctx, repoDir:
|
|
75893
|
+
const r = await checkAlreadyDone({ ...ctx, repoDir: join118(root, "tree"), sessions: inner }, check.signal, task, repoMap, testMap);
|
|
75666
75894
|
const ph = phase;
|
|
75667
75895
|
if (r && ph !== "done" && !check.signal.aborted) {
|
|
75668
75896
|
hit = r;
|
|
@@ -75688,8 +75916,8 @@ __export(exports_intake, {
|
|
|
75688
75916
|
stage: () => stage8,
|
|
75689
75917
|
runIntake: () => runIntake
|
|
75690
75918
|
});
|
|
75691
|
-
import { appendFileSync as appendFileSync14, existsSync as existsSync83, mkdirSync as mkdirSync66, readFileSync as
|
|
75692
|
-
import { dirname as
|
|
75919
|
+
import { appendFileSync as appendFileSync14, existsSync as existsSync83, mkdirSync as mkdirSync66, readFileSync as readFileSync103, writeFileSync as writeFileSync61 } from "fs";
|
|
75920
|
+
import { dirname as dirname47, join as join119, resolve as resolve38 } from "path";
|
|
75693
75921
|
function issueRefOf(raw2) {
|
|
75694
75922
|
return typeof raw2.repo === "string" && raw2.repo && typeof raw2.number === "number" ? `${raw2.repo}#${raw2.number}` : null;
|
|
75695
75923
|
}
|
|
@@ -75709,15 +75937,15 @@ function ensureBranch(repoDir, branch, from) {
|
|
|
75709
75937
|
}
|
|
75710
75938
|
}
|
|
75711
75939
|
function excludeLokiDir(repoDir) {
|
|
75712
|
-
let path =
|
|
75940
|
+
let path = join119(repoDir, ".git", "info", "exclude");
|
|
75713
75941
|
try {
|
|
75714
75942
|
path = resolve38(repoDir, git13(repoDir, ["rev-parse", "--git-path", "info/exclude"]));
|
|
75715
75943
|
} catch {}
|
|
75716
|
-
const existing = existsSync83(path) ?
|
|
75944
|
+
const existing = existsSync83(path) ? readFileSync103(path, "utf8") : "";
|
|
75717
75945
|
if (existing.split(`
|
|
75718
75946
|
`).some((l) => l.trim() === ".loki/"))
|
|
75719
75947
|
return;
|
|
75720
|
-
mkdirSync66(
|
|
75948
|
+
mkdirSync66(dirname47(path), { recursive: true });
|
|
75721
75949
|
const sep20 = existing.length > 0 && !existing.endsWith(`
|
|
75722
75950
|
`) ? `
|
|
75723
75951
|
` : "";
|
|
@@ -75725,7 +75953,7 @@ function excludeLokiDir(repoDir) {
|
|
|
75725
75953
|
`);
|
|
75726
75954
|
}
|
|
75727
75955
|
function loadIssue(path) {
|
|
75728
|
-
const raw2 = JSON.parse(
|
|
75956
|
+
const raw2 = JSON.parse(readFileSync103(path, "utf8"));
|
|
75729
75957
|
return { state: typeof raw2.state === "string" ? raw2.state.toLowerCase() : null, closed_by_merged_pr: raw2.closed_by_merged_pr === true };
|
|
75730
75958
|
}
|
|
75731
75959
|
function isAlreadyDone(issue) {
|
|
@@ -75756,7 +75984,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75756
75984
|
return { status: "failed", data: {}, reason: "aborted before intake started" };
|
|
75757
75985
|
const { blocking: dirty, preexisting } = splitDirty(ctx.repoDir, dirtyTrackedFiles(ctx.repoDir));
|
|
75758
75986
|
if (dirty.length > 0)
|
|
75759
|
-
return { status: "failed", data: {}, reason: `dirty tracked tree: ${dirty.join(", ")}` };
|
|
75987
|
+
return { status: "failed", data: { blocker: "dirty_tracked_tree" }, reason: `dirty tracked tree: ${dirty.join(", ")}` };
|
|
75760
75988
|
let baseSha = git13(ctx.repoDir, ["rev-parse", "HEAD"]);
|
|
75761
75989
|
const startBranch = git13(ctx.repoDir, ["symbolic-ref", "-q", "--short", "HEAD"]);
|
|
75762
75990
|
let stacked = stackedOnLokiRun(ctx.repoDir);
|
|
@@ -75775,7 +76003,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75775
76003
|
ensureBranch(ctx.repoDir, ctx.branch);
|
|
75776
76004
|
const tree = git13(ctx.repoDir, ["rev-parse", "HEAD^{tree}"]);
|
|
75777
76005
|
excludeLokiDir(ctx.repoDir);
|
|
75778
|
-
const issueJsonPath = opts.issueJsonPath ?? process.env.LOKI_E10_ISSUE_JSON ??
|
|
76006
|
+
const issueJsonPath = opts.issueJsonPath ?? process.env.LOKI_E10_ISSUE_JSON ?? join119(ctx.runDir, "issue.json");
|
|
75779
76007
|
const taskText = opts.taskText ?? process.env.LOKI_E10_TASK_TEXT;
|
|
75780
76008
|
let source;
|
|
75781
76009
|
let taskSha256;
|
|
@@ -75784,7 +76012,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75784
76012
|
let issueRef = null;
|
|
75785
76013
|
if (existsSync83(issueJsonPath)) {
|
|
75786
76014
|
source = "issue";
|
|
75787
|
-
const raw2 =
|
|
76015
|
+
const raw2 = readFileSync103(issueJsonPath, "utf8");
|
|
75788
76016
|
taskSha256 = sha2562(raw2);
|
|
75789
76017
|
const i = JSON.parse(raw2);
|
|
75790
76018
|
task = [i.title, i.body].filter((x3) => typeof x3 === "string" && x3 !== "").join(`
|
|
@@ -75805,7 +76033,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75805
76033
|
return { status: "completed", data: { ...common, task_sha256: taskSha256, source, base_sha: baseSha, tree, branch: ctx.branch, already_satisfied: true } };
|
|
75806
76034
|
}
|
|
75807
76035
|
mkdirSync66(ctx.runDir, { recursive: true });
|
|
75808
|
-
const repomapRef =
|
|
76036
|
+
const repomapRef = join119(ctx.runDir, "repomap.json");
|
|
75809
76037
|
const cacheDir = repoCacheDir(repoKey(null, ctx.repoDir));
|
|
75810
76038
|
const repoMap = cachedRepoMap(cacheDir, tree, () => buildRepoMap(ctx.repoDir));
|
|
75811
76039
|
writeFileSync61(repomapRef, JSON.stringify(repoMap));
|
|
@@ -75826,7 +76054,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75826
76054
|
const already = speedEnabled() ? null : await checkAlreadyDone(ctx, signal, task, repoMap, testmap);
|
|
75827
76055
|
const alreadyData = (already2) => {
|
|
75828
76056
|
const comment = renderAlreadyDoneComment(already2.evidence);
|
|
75829
|
-
const bodyFile =
|
|
76057
|
+
const bodyFile = join119(ctx.runDir, "already-done-comment.md");
|
|
75830
76058
|
writeFileSync61(bodyFile, comment, "utf8");
|
|
75831
76059
|
const commentArgv = source === "issue" && issueRef ? buildAlreadyDoneCommentArgv(ctx.runId, issueRef, bodyFile) : undefined;
|
|
75832
76060
|
return { already_satisfied: true, evidence: already2.evidence, iteration_ids: [`${ctx.runId}-already-done`], comment, ...commentArgv ? { comment_argv: commentArgv } : {} };
|
|
@@ -76020,7 +76248,7 @@ __export(exports_keys_cmd, {
|
|
|
76020
76248
|
takePubkey: () => takePubkey,
|
|
76021
76249
|
main: () => main5
|
|
76022
76250
|
});
|
|
76023
|
-
import { readFileSync as
|
|
76251
|
+
import { readFileSync as readFileSync104 } from "fs";
|
|
76024
76252
|
import { parseArgs } from "util";
|
|
76025
76253
|
import { createPublicKey as createPublicKey4 } from "crypto";
|
|
76026
76254
|
function takePubkey(args) {
|
|
@@ -76033,7 +76261,7 @@ function takePubkey(args) {
|
|
|
76033
76261
|
return { args: rest };
|
|
76034
76262
|
if (!(file = pubkey[0]))
|
|
76035
76263
|
throw new Error("--pubkey requires a file argument");
|
|
76036
|
-
const t =
|
|
76264
|
+
const t = readFileSync104(file, "utf8"), key = createPublicKey4(t.trim().startsWith("{") ? { key: JSON.parse(t), format: "jwk" } : t);
|
|
76037
76265
|
return key.asymmetricKeyType === "ed25519" ? { args: rest, pubkey: key } : { args: rest, error: `cannot read an Ed25519 public key from ${file}` };
|
|
76038
76266
|
} catch (e10) {
|
|
76039
76267
|
return { args: [], error: file ? `cannot read an Ed25519 public key from ${file}` : e10.message.replace(/^./, (c) => c.toLowerCase()) };
|
|
@@ -76291,7 +76519,7 @@ var groupRoute = async (repoDir, rawGroup) => {
|
|
|
76291
76519
|
};
|
|
76292
76520
|
|
|
76293
76521
|
// ../../loki-ts/src/engine10/modernize/types.ts
|
|
76294
|
-
import { join as
|
|
76522
|
+
import { join as join120 } from "path";
|
|
76295
76523
|
function makeModernizeId(now2 = new Date) {
|
|
76296
76524
|
const utc = now2.toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z");
|
|
76297
76525
|
const short = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0");
|
|
@@ -76301,13 +76529,13 @@ function isModernizeId(mid) {
|
|
|
76301
76529
|
return MID_RE.test(mid);
|
|
76302
76530
|
}
|
|
76303
76531
|
function modernizeRoot(repoDir, mid) {
|
|
76304
|
-
return
|
|
76532
|
+
return join120(repoDir, ".loki", "modernize", mid);
|
|
76305
76533
|
}
|
|
76306
76534
|
function modernizeEventsPath(repoDir, mid) {
|
|
76307
|
-
return
|
|
76535
|
+
return join120(modernizeRoot(repoDir, mid), "events.jsonl");
|
|
76308
76536
|
}
|
|
76309
76537
|
function planPath(repoDir, mid) {
|
|
76310
|
-
return
|
|
76538
|
+
return join120(modernizeRoot(repoDir, mid), "plan.json");
|
|
76311
76539
|
}
|
|
76312
76540
|
function isSafeUnitId(unit) {
|
|
76313
76541
|
return typeof unit === "string" && unit.length <= MAX_UNIT_ID && UNIT_ID_RE2.test(unit) && !unit.includes("..");
|
|
@@ -76318,13 +76546,13 @@ function encodeUnitId(unit) {
|
|
|
76318
76546
|
return unit.replace(/\//g, "%2F");
|
|
76319
76547
|
}
|
|
76320
76548
|
function oracleDir(repoDir, mid, unit) {
|
|
76321
|
-
return
|
|
76549
|
+
return join120(modernizeRoot(repoDir, mid), "oracle", encodeUnitId(unit));
|
|
76322
76550
|
}
|
|
76323
76551
|
function reportJsonPath(repoDir, mid) {
|
|
76324
|
-
return
|
|
76552
|
+
return join120(modernizeRoot(repoDir, mid), "report.json");
|
|
76325
76553
|
}
|
|
76326
76554
|
function reportMdPath(repoDir, mid) {
|
|
76327
|
-
return
|
|
76555
|
+
return join120(modernizeRoot(repoDir, mid), "report.md");
|
|
76328
76556
|
}
|
|
76329
76557
|
var MID_RE, UNIT_ID_SEGMENT = "[A-Za-z0-9][A-Za-z0-9_.-]*", UNIT_ID_RE2, MAX_UNIT_ID = 128;
|
|
76330
76558
|
var init_types2 = __esm(() => {
|
|
@@ -76364,9 +76592,9 @@ __export(exports_dashboard, {
|
|
|
76364
76592
|
listModernizeIds: () => listModernizeIds
|
|
76365
76593
|
});
|
|
76366
76594
|
import { existsSync as existsSync84, readdirSync as readdirSync36 } from "fs";
|
|
76367
|
-
import { join as
|
|
76595
|
+
import { join as join121 } from "path";
|
|
76368
76596
|
function modernizeDir(repoDir) {
|
|
76369
|
-
return
|
|
76597
|
+
return join121(repoDir, ".loki", "modernize");
|
|
76370
76598
|
}
|
|
76371
76599
|
function listModernizeIds(repoDir) {
|
|
76372
76600
|
const dir = modernizeDir(repoDir);
|
|
@@ -76701,11 +76929,11 @@ var init_engine10_dashboard = __esm(() => {
|
|
|
76701
76929
|
});
|
|
76702
76930
|
|
|
76703
76931
|
// ../../loki-ts/src/engine10/modernize/inventory.ts
|
|
76704
|
-
import { readFileSync as
|
|
76705
|
-
import { extname as extname4, join as
|
|
76932
|
+
import { readFileSync as readFileSync105 } from "fs";
|
|
76933
|
+
import { extname as extname4, join as join122 } from "path";
|
|
76706
76934
|
function readCapped2(absPath) {
|
|
76707
76935
|
try {
|
|
76708
|
-
return
|
|
76936
|
+
return readFileSync105(absPath, "utf8").slice(0, MAX_SCAN_BYTES2);
|
|
76709
76937
|
} catch {
|
|
76710
76938
|
return "";
|
|
76711
76939
|
}
|
|
@@ -76722,9 +76950,9 @@ function detectEntryPoints(repoDir, files) {
|
|
|
76722
76950
|
const out3 = [];
|
|
76723
76951
|
for (const rel of files) {
|
|
76724
76952
|
const ext = extname4(rel);
|
|
76725
|
-
if (ext === ".py" && PY_MAIN_RE.test(readCapped2(
|
|
76953
|
+
if (ext === ".py" && PY_MAIN_RE.test(readCapped2(join122(repoDir, rel))))
|
|
76726
76954
|
out3.push(rel);
|
|
76727
|
-
else if (ext === ".java" && JAVA_MAIN_RE.test(readCapped2(
|
|
76955
|
+
else if (ext === ".java" && JAVA_MAIN_RE.test(readCapped2(join122(repoDir, rel))))
|
|
76728
76956
|
out3.push(rel);
|
|
76729
76957
|
}
|
|
76730
76958
|
return out3;
|
|
@@ -76774,7 +77002,7 @@ var init_inventory = __esm(() => {
|
|
|
76774
77002
|
});
|
|
76775
77003
|
|
|
76776
77004
|
// ../../loki-ts/src/engine10/modernize/lang/python.ts
|
|
76777
|
-
import { join as
|
|
77005
|
+
import { join as join123 } from "path";
|
|
76778
77006
|
async function buildPythonGraph(repoDir, files, opts = {}) {
|
|
76779
77007
|
if (files.length === 0)
|
|
76780
77008
|
return { graph: { nodes: [], edges: [] }, unresolved: [] };
|
|
@@ -76813,7 +77041,7 @@ var init_python2 = __esm(() => {
|
|
|
76813
77041
|
init_paths();
|
|
76814
77042
|
init_python();
|
|
76815
77043
|
init_shell();
|
|
76816
|
-
SCRIPT =
|
|
77044
|
+
SCRIPT = join123(REPO_ROOT, "autonomy", "lib", "modernize", "py_imports.py");
|
|
76817
77045
|
});
|
|
76818
77046
|
|
|
76819
77047
|
// ../../loki-ts/src/engine10/modernize/cluster.ts
|
|
@@ -76992,8 +77220,8 @@ var init_codemod = __esm(() => {
|
|
|
76992
77220
|
|
|
76993
77221
|
// ../../loki-ts/src/engine10/modernize/oracle/seal.ts
|
|
76994
77222
|
import { createHash as createHash34 } from "crypto";
|
|
76995
|
-
import { existsSync as existsSync85, mkdirSync as mkdirSync67, readFileSync as
|
|
76996
|
-
import { join as
|
|
77223
|
+
import { existsSync as existsSync85, mkdirSync as mkdirSync67, readFileSync as readFileSync106, writeFileSync as writeFileSync62 } from "fs";
|
|
77224
|
+
import { join as join124 } from "path";
|
|
76997
77225
|
function normalizersSha(n11) {
|
|
76998
77226
|
return sha2564(JSON.stringify({
|
|
76999
77227
|
float_tolerance: n11.float_tolerance,
|
|
@@ -77055,9 +77283,9 @@ function alreadySealedInLog(repoDir, mid, unit) {
|
|
|
77055
77283
|
}
|
|
77056
77284
|
function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS) {
|
|
77057
77285
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77058
|
-
const casesPath =
|
|
77059
|
-
const coveragePath =
|
|
77060
|
-
const sealedPath =
|
|
77286
|
+
const casesPath = join124(dir, "cases.jsonl");
|
|
77287
|
+
const coveragePath = join124(dir, "coverage.json");
|
|
77288
|
+
const sealedPath = join124(dir, "sealed.json");
|
|
77061
77289
|
if (alreadySealedInLog(repoDir, mid, unit)) {
|
|
77062
77290
|
throw new Error(`oracle seal: ${unit} already has a sealing event in the modernize log; re-seal refused (seal is write-once)`);
|
|
77063
77291
|
}
|
|
@@ -77068,8 +77296,8 @@ function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS)
|
|
|
77068
77296
|
throw new Error(`oracle seal: missing ${casesPath}`);
|
|
77069
77297
|
if (!existsSync85(coveragePath))
|
|
77070
77298
|
throw new Error(`oracle seal: missing ${coveragePath}`);
|
|
77071
|
-
const casesRaw =
|
|
77072
|
-
const coverageRaw =
|
|
77299
|
+
const casesRaw = readFileSync106(casesPath, "utf8");
|
|
77300
|
+
const coverageRaw = readFileSync106(coveragePath, "utf8");
|
|
77073
77301
|
const normalizersHash = normalizersSha(normalizers);
|
|
77074
77302
|
const sealed = buildSealedOracle(unit, casesRaw, coverageRaw, normalizersHash);
|
|
77075
77303
|
mkdirSync67(dir, { recursive: true });
|
|
@@ -77088,9 +77316,9 @@ function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS)
|
|
|
77088
77316
|
}
|
|
77089
77317
|
function verifySeal(repoDir, mid, unit) {
|
|
77090
77318
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77091
|
-
const sealedPath =
|
|
77092
|
-
const casesPath =
|
|
77093
|
-
const coveragePath =
|
|
77319
|
+
const sealedPath = join124(dir, "sealed.json");
|
|
77320
|
+
const casesPath = join124(dir, "cases.jsonl");
|
|
77321
|
+
const coveragePath = join124(dir, "coverage.json");
|
|
77094
77322
|
if (!existsSync85(sealedPath))
|
|
77095
77323
|
return { ok: false, reason: "no sealed.json" };
|
|
77096
77324
|
if (!existsSync85(casesPath))
|
|
@@ -77101,11 +77329,11 @@ function verifySeal(repoDir, mid, unit) {
|
|
|
77101
77329
|
if (!sealEvent) {
|
|
77102
77330
|
return { ok: false, reason: "no sealing event for this unit in the modernize log; sealed.json is not anchored" };
|
|
77103
77331
|
}
|
|
77104
|
-
const casesRaw =
|
|
77332
|
+
const casesRaw = readFileSync106(casesPath, "utf8");
|
|
77105
77333
|
if (sha2564(casesRaw) !== sealEvent.data.cases_sha256) {
|
|
77106
77334
|
return { ok: false, reason: "cases.jsonl does not match the sealing event's hash (tampered or re-captured)" };
|
|
77107
77335
|
}
|
|
77108
|
-
const coverageRaw =
|
|
77336
|
+
const coverageRaw = readFileSync106(coveragePath, "utf8");
|
|
77109
77337
|
if (sha2564(coverageRaw) !== sealEvent.data.coverage_sha256) {
|
|
77110
77338
|
return { ok: false, reason: "coverage.json does not match the sealing event's hash (tampered or re-captured)" };
|
|
77111
77339
|
}
|
|
@@ -77121,7 +77349,7 @@ function verifySeal(repoDir, mid, unit) {
|
|
|
77121
77349
|
reason: `verdict does not match the sealing event (event type ${sealEvent.type}, recomputed verdict ${recomputed.verdict})`
|
|
77122
77350
|
};
|
|
77123
77351
|
}
|
|
77124
|
-
const sealed = JSON.parse(
|
|
77352
|
+
const sealed = JSON.parse(readFileSync106(sealedPath, "utf8"));
|
|
77125
77353
|
if (JSON.stringify(sealed) !== JSON.stringify(recomputed)) {
|
|
77126
77354
|
return { ok: false, reason: "sealed.json does not match the record recomputed from cases.jsonl and coverage.json (hand-edited)" };
|
|
77127
77355
|
}
|
|
@@ -77137,9 +77365,9 @@ var init_seal2 = __esm(() => {
|
|
|
77137
77365
|
|
|
77138
77366
|
// ../../loki-ts/src/engine10/modernize/oracle/search.ts
|
|
77139
77367
|
import { spawnSync as spawnSync18 } from "child_process";
|
|
77140
|
-
import { copyFileSync as copyFileSync6, existsSync as existsSync86, linkSync as linkSync4, mkdirSync as mkdirSync68, mkdtempSync as mkdtempSync17, readFileSync as
|
|
77368
|
+
import { copyFileSync as copyFileSync6, existsSync as existsSync86, linkSync as linkSync4, mkdirSync as mkdirSync68, mkdtempSync as mkdtempSync17, readFileSync as readFileSync107, renameSync as renameSync22, rmSync as rmSync35, rmdirSync as rmdirSync2, writeFileSync as writeFileSync63 } from "fs";
|
|
77141
77369
|
import { tmpdir as tmpdir21 } from "os";
|
|
77142
|
-
import { basename as basename31, dirname as
|
|
77370
|
+
import { basename as basename31, dirname as dirname48, join as join125 } from "path";
|
|
77143
77371
|
function search(unitSource, seedCases, propose, runCapture, opts = {}) {
|
|
77144
77372
|
const maxRounds = opts.maxRounds ?? 10;
|
|
77145
77373
|
const plateauLimit = opts.plateauRounds ?? 2;
|
|
@@ -77196,10 +77424,10 @@ function realCaptureRunner(unitPath, cases, outPath) {
|
|
|
77196
77424
|
return captureFailed("old runtime unavailable");
|
|
77197
77425
|
let dir = "";
|
|
77198
77426
|
try {
|
|
77199
|
-
dir = mkdtempSync17(
|
|
77200
|
-
const casesFile =
|
|
77201
|
-
const outFile =
|
|
77202
|
-
const covFile =
|
|
77427
|
+
dir = mkdtempSync17(join125(tmpdir21(), "m10-search-"));
|
|
77428
|
+
const casesFile = join125(dir, "cases.jsonl");
|
|
77429
|
+
const outFile = join125(dir, "out.jsonl");
|
|
77430
|
+
const covFile = join125(dir, "coverage.json");
|
|
77203
77431
|
const lines2 = cases.map((c) => JSON.stringify({ entry: c.entry, args: c.args, kwargs: c.kwargs }));
|
|
77204
77432
|
writeFileSync63(casesFile, lines2.length ? lines2.join(`
|
|
77205
77433
|
`) + `
|
|
@@ -77220,7 +77448,7 @@ function realCaptureRunner(unitPath, cases, outPath) {
|
|
|
77220
77448
|
`).find((l) => l.trim().length > 0) ?? "(no stderr)";
|
|
77221
77449
|
return captureFailed(`py_capture.py exit ${r.status}: ${firstErrLine}`);
|
|
77222
77450
|
}
|
|
77223
|
-
const raw2 = JSON.parse(
|
|
77451
|
+
const raw2 = JSON.parse(readFileSync107(covFile, "utf8"));
|
|
77224
77452
|
if (outPath)
|
|
77225
77453
|
copyFileSync6(outFile, outPath);
|
|
77226
77454
|
return {
|
|
@@ -77247,13 +77475,13 @@ function resolveOldRuntimeSync() {
|
|
|
77247
77475
|
}
|
|
77248
77476
|
function makeProposeInputs(session, cap = 20) {
|
|
77249
77477
|
return (unitPath, missing, round2) => {
|
|
77250
|
-
const cwd = mkdtempSync17(
|
|
77478
|
+
const cwd = mkdtempSync17(join125(tmpdir21(), "m27-propose-"));
|
|
77251
77479
|
try {
|
|
77252
|
-
const unitFile =
|
|
77480
|
+
const unitFile = join125(cwd, basename31(unitPath));
|
|
77253
77481
|
copyFileSync6(unitPath, unitFile);
|
|
77254
77482
|
session({ cwd, env: tokenFreeEnv(), unitFile, missing, round: round2 });
|
|
77255
77483
|
const out3 = [];
|
|
77256
|
-
for (const line2 of
|
|
77484
|
+
for (const line2 of readFileSync107(join125(cwd, "proposals.jsonl"), "utf8").split(`
|
|
77257
77485
|
`)) {
|
|
77258
77486
|
try {
|
|
77259
77487
|
const c = JSON.parse(line2);
|
|
@@ -77271,7 +77499,7 @@ function makeProposeInputs(session, cap = 20) {
|
|
|
77271
77499
|
}
|
|
77272
77500
|
function captureUnitOracle(a) {
|
|
77273
77501
|
const dir = oracleDir(a.repoDir, a.mid, a.unit);
|
|
77274
|
-
if (existsSync86(
|
|
77502
|
+
if (existsSync86(join125(dir, "cases.jsonl")) || alreadySealedInLog(a.repoDir, a.mid, a.unit)) {
|
|
77275
77503
|
return { ok: false, reason: "oracle already captured (write-once)" };
|
|
77276
77504
|
}
|
|
77277
77505
|
const run2 = a.runCapture ?? realCaptureRunner;
|
|
@@ -77291,21 +77519,21 @@ function captureUnitOracle(a) {
|
|
|
77291
77519
|
}
|
|
77292
77520
|
if (r.cases.length === 0)
|
|
77293
77521
|
return { ok: false, reason: "no cases captured" };
|
|
77294
|
-
const scratch = mkdtempSync17(
|
|
77295
|
-
const t12 =
|
|
77522
|
+
const scratch = mkdtempSync17(join125(tmpdir21(), "m27-replay-"));
|
|
77523
|
+
const t12 = join125(scratch, "cases"), t22 = join125(scratch, "replay");
|
|
77296
77524
|
const created = [];
|
|
77297
|
-
for (let p = dir;!existsSync86(p) && !created.includes(p); p =
|
|
77525
|
+
for (let p = dir;!existsSync86(p) && !created.includes(p); p = dirname48(p))
|
|
77298
77526
|
created.push(p);
|
|
77299
|
-
const
|
|
77527
|
+
const read3 = (p) => readFileSync107(p, "utf8").split(`
|
|
77300
77528
|
`).filter(Boolean).map((l) => JSON.parse(l));
|
|
77301
|
-
const tmpCases =
|
|
77302
|
-
const tmpCov =
|
|
77529
|
+
const tmpCases = join125(dir, `.cases.${process.pid}.tmp`);
|
|
77530
|
+
const tmpCov = join125(dir, `.coverage.${process.pid}.tmp`);
|
|
77303
77531
|
try {
|
|
77304
77532
|
const cov = run2(a.unitPath, r.cases, t12);
|
|
77305
77533
|
const cov2 = run2(a.unitPath, r.cases, t22);
|
|
77306
77534
|
if (cov.branchesTotal < 0 || cov2.branchesTotal < 0)
|
|
77307
77535
|
return { ok: false, reason: cov.error ?? cov2.error ?? "replay failed" };
|
|
77308
|
-
const recs =
|
|
77536
|
+
const recs = read3(t12), again = read3(t22);
|
|
77309
77537
|
if (recs.length !== r.cases.length || again.length !== recs.length)
|
|
77310
77538
|
return { ok: false, reason: "capture records missing" };
|
|
77311
77539
|
recs.forEach((rec2, i) => {
|
|
@@ -77327,10 +77555,10 @@ function captureUnitOracle(a) {
|
|
|
77327
77555
|
branch_pct: cov.branchPct,
|
|
77328
77556
|
missing: cov.missing
|
|
77329
77557
|
}));
|
|
77330
|
-
if (existsSync86(
|
|
77558
|
+
if (existsSync86(join125(dir, "cases.jsonl")))
|
|
77331
77559
|
return { ok: false, reason: "oracle already captured (write-once)" };
|
|
77332
|
-
renameSync22(tmpCov,
|
|
77333
|
-
(a.link ?? linkSync4)(tmpCases,
|
|
77560
|
+
renameSync22(tmpCov, join125(dir, "coverage.json"));
|
|
77561
|
+
(a.link ?? linkSync4)(tmpCases, join125(dir, "cases.jsonl"));
|
|
77334
77562
|
return { ok: true, cases: r.cases.length, branchPct: cov.branchPct, stoppedReason: r.stoppedReason };
|
|
77335
77563
|
} catch (e10) {
|
|
77336
77564
|
return { ok: false, reason: `capture error: ${e10 instanceof Error ? e10.message : String(e10)}` };
|
|
@@ -77338,8 +77566,8 @@ function captureUnitOracle(a) {
|
|
|
77338
77566
|
rmSync35(scratch, { recursive: true, force: true });
|
|
77339
77567
|
for (const t of [tmpCases, tmpCov])
|
|
77340
77568
|
rmSync35(t, { force: true });
|
|
77341
|
-
if (created[0] === dir && !existsSync86(
|
|
77342
|
-
rmSync35(
|
|
77569
|
+
if (created[0] === dir && !existsSync86(join125(dir, "cases.jsonl")))
|
|
77570
|
+
rmSync35(join125(dir, "coverage.json"), { force: true });
|
|
77343
77571
|
for (const p of created) {
|
|
77344
77572
|
try {
|
|
77345
77573
|
rmdirSync2(p);
|
|
@@ -77355,12 +77583,12 @@ var init_search = __esm(() => {
|
|
|
77355
77583
|
init_safe_git();
|
|
77356
77584
|
init_types2();
|
|
77357
77585
|
init_seal2();
|
|
77358
|
-
PY_CAPTURE_SCRIPT =
|
|
77586
|
+
PY_CAPTURE_SCRIPT = join125(REPO_ROOT, "autonomy", "lib", "modernize", "py_capture.py");
|
|
77359
77587
|
});
|
|
77360
77588
|
|
|
77361
77589
|
// ../../loki-ts/src/engine10/modernize/equiv.ts
|
|
77362
|
-
import { readFileSync as
|
|
77363
|
-
import { join as
|
|
77590
|
+
import { readFileSync as readFileSync108 } from "fs";
|
|
77591
|
+
import { join as join126 } from "path";
|
|
77364
77592
|
function parseCases(raw2) {
|
|
77365
77593
|
const out3 = [];
|
|
77366
77594
|
for (const line2 of raw2.split(`
|
|
@@ -77555,11 +77783,11 @@ function checkEquivalence(repoDir, mid, unit, newTreeDir, normalizers, runNew, l
|
|
|
77555
77783
|
return notProvenResult(unit, "normalizers invalid: skip_fields covers every field, nothing would be compared", log);
|
|
77556
77784
|
}
|
|
77557
77785
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77558
|
-
const sealed = JSON.parse(
|
|
77786
|
+
const sealed = JSON.parse(readFileSync108(join126(dir, "sealed.json"), "utf8"));
|
|
77559
77787
|
const normCheck = verifyNormalizersAgainstSeal(sealed, normalizers);
|
|
77560
77788
|
if (!normCheck.ok)
|
|
77561
77789
|
return notProvenResult(unit, `normalizers: ${normCheck.reason ?? "check failed"}`, log);
|
|
77562
|
-
const records = parseCases(
|
|
77790
|
+
const records = parseCases(readFileSync108(join126(dir, "cases.jsonl"), "utf8"));
|
|
77563
77791
|
const heldOutSet = new Set(sealed.held_out);
|
|
77564
77792
|
let pass = 0;
|
|
77565
77793
|
let fail2 = 0;
|
|
@@ -77750,7 +77978,7 @@ var init_reslice = __esm(() => {
|
|
|
77750
77978
|
});
|
|
77751
77979
|
|
|
77752
77980
|
// ../../loki-ts/src/engine10/modernize/scheduler.ts
|
|
77753
|
-
import { join as
|
|
77981
|
+
import { join as join127 } from "path";
|
|
77754
77982
|
function mergeOnce(unit, ops, log, completed, worktree) {
|
|
77755
77983
|
if (completed.has(unit))
|
|
77756
77984
|
return "already_completed";
|
|
@@ -77871,7 +78099,7 @@ async function schedule(plan, opts) {
|
|
|
77871
78099
|
reason = hit ? "budget stop" : "per-unit cost cap reached";
|
|
77872
78100
|
break;
|
|
77873
78101
|
}
|
|
77874
|
-
const path =
|
|
78102
|
+
const path = join127(modernizeRoot(opts.repoDir, opts.mid), "wt", variant === 0 ? encodeUnitId(unit.id) : `${encodeUnitId(unit.id)}${VARIANT_SEP}${variant}`);
|
|
77875
78103
|
let outcome;
|
|
77876
78104
|
attempts++;
|
|
77877
78105
|
let resumeRunId;
|
|
@@ -77980,21 +78208,21 @@ var init_scheduler = __esm(() => {
|
|
|
77980
78208
|
});
|
|
77981
78209
|
|
|
77982
78210
|
// ../../loki-ts/src/engine10/modernize/resume.ts
|
|
77983
|
-
import { existsSync as existsSync87, readFileSync as
|
|
78211
|
+
import { existsSync as existsSync87, readFileSync as readFileSync109 } from "fs";
|
|
77984
78212
|
function loadResumeState(repoDir, mid) {
|
|
77985
78213
|
const path = modernizeEventsPath(repoDir, mid);
|
|
77986
78214
|
if (!existsSync87(path))
|
|
77987
78215
|
return { ok: false, reason: `no modernize log at ${path}` };
|
|
77988
78216
|
let text4;
|
|
77989
78217
|
try {
|
|
77990
|
-
text4 =
|
|
78218
|
+
text4 = readFileSync109(path, "utf8");
|
|
77991
78219
|
} catch (e10) {
|
|
77992
78220
|
return { ok: false, reason: `modernize log unreadable: ${e10 instanceof Error ? e10.message : String(e10)}` };
|
|
77993
78221
|
}
|
|
77994
78222
|
const pj2 = planPath(repoDir, mid);
|
|
77995
78223
|
if (existsSync87(pj2)) {
|
|
77996
78224
|
try {
|
|
77997
|
-
JSON.parse(
|
|
78225
|
+
JSON.parse(readFileSync109(pj2, "utf8"));
|
|
77998
78226
|
} catch {
|
|
77999
78227
|
return { ok: false, reason: `plan.json is corrupt or partial: ${pj2}` };
|
|
78000
78228
|
}
|
|
@@ -78107,8 +78335,8 @@ var init_resume = __esm(() => {
|
|
|
78107
78335
|
});
|
|
78108
78336
|
|
|
78109
78337
|
// ../../loki-ts/src/engine10/modernize/report.ts
|
|
78110
|
-
import { mkdirSync as mkdirSync69, readFileSync as
|
|
78111
|
-
import { dirname as
|
|
78338
|
+
import { mkdirSync as mkdirSync69, readFileSync as readFileSync110, writeFileSync as writeFileSync64 } from "fs";
|
|
78339
|
+
import { dirname as dirname49 } from "path";
|
|
78112
78340
|
function buildReport(o) {
|
|
78113
78341
|
const units = o.units.map((x3) => ({ unit: x3.unit, verdict: x3.verdict, not_proven: [...x3.not_proven], rate: x3.rate, branchPct: x3.branchPct, receiptPath: x3.receiptPath, receiptSha256: x3.receiptSha256 }));
|
|
78114
78342
|
const waves = o.waves.map((w) => ({
|
|
@@ -78151,7 +78379,7 @@ function renderReportMd(r) {
|
|
|
78151
78379
|
function writeReport(o) {
|
|
78152
78380
|
const sealed = sealReport(buildReport(o), o.sign);
|
|
78153
78381
|
const jp2 = reportJsonPath(o.repoDir, o.mid);
|
|
78154
|
-
mkdirSync69(
|
|
78382
|
+
mkdirSync69(dirname49(jp2), { recursive: true });
|
|
78155
78383
|
writeFileSync64(jp2, JSON.stringify(sealed, null, 2) + `
|
|
78156
78384
|
`, "utf8");
|
|
78157
78385
|
writeFileSync64(reportMdPath(o.repoDir, o.mid), renderReportMd(sealed), "utf8");
|
|
@@ -78168,7 +78396,7 @@ var init_report = __esm(() => {
|
|
|
78168
78396
|
|
|
78169
78397
|
// ../../loki-ts/src/engine10/modernize/ship.ts
|
|
78170
78398
|
import { mkdirSync as mkdirSync70, writeFileSync as writeFileSync65 } from "fs";
|
|
78171
|
-
import { join as
|
|
78399
|
+
import { join as join128 } from "path";
|
|
78172
78400
|
function waveIsDraft(verdict, units) {
|
|
78173
78401
|
return verdict === null || verdict.verified !== true || units.length === 0 || units.some((x3) => x3.verdict !== "PROVEN");
|
|
78174
78402
|
}
|
|
@@ -78189,9 +78417,9 @@ function shipWave(o) {
|
|
|
78189
78417
|
return fail2("no pinned origin: refusing to push (Rule of Two)");
|
|
78190
78418
|
if (draft)
|
|
78191
78419
|
return fail2("wave not verified: branch stays local, not pushed");
|
|
78192
|
-
const dir =
|
|
78420
|
+
const dir = join128(o.repoDir, ".loki", "modernize", o.mid);
|
|
78193
78421
|
mkdirSync70(dir, { recursive: true });
|
|
78194
|
-
const bodyFile =
|
|
78422
|
+
const bodyFile = join128(dir, `wave-${o.wave}-pr-body.md`);
|
|
78195
78423
|
writeFileSync65(bodyFile, renderWaveBody(o.wave, o.verdict, o.units), "utf8");
|
|
78196
78424
|
const r = (o.push ?? runPushPr)({ repoDir: o.repoDir, branch: o.branch, title: `Loki modernize: wave ${o.wave}`, bodyFile, draft, pinnedOrigin });
|
|
78197
78425
|
if (!r.ok)
|
|
@@ -78211,8 +78439,8 @@ var init_ship2 = __esm(() => {
|
|
|
78211
78439
|
});
|
|
78212
78440
|
|
|
78213
78441
|
// ../../loki-ts/src/engine10/modernize/presealed_wall.ts
|
|
78214
|
-
import { existsSync as existsSync88, mkdirSync as mkdirSync71, readFileSync as
|
|
78215
|
-
import { join as
|
|
78442
|
+
import { existsSync as existsSync88, mkdirSync as mkdirSync71, readFileSync as readFileSync111, writeFileSync as writeFileSync66 } from "fs";
|
|
78443
|
+
import { join as join129 } from "path";
|
|
78216
78444
|
function isRealFailCount(n11) {
|
|
78217
78445
|
return typeof n11 === "number" && Number.isInteger(n11) && n11 >= 1;
|
|
78218
78446
|
}
|
|
@@ -78235,7 +78463,7 @@ function classifyBaseRun(o, repoDir) {
|
|
|
78235
78463
|
return "not_run";
|
|
78236
78464
|
}
|
|
78237
78465
|
function preSealedPath(repoDir, mid, unit) {
|
|
78238
|
-
return
|
|
78466
|
+
return join129(oracleDir(repoDir, mid, unit), "presealed_wall.json");
|
|
78239
78467
|
}
|
|
78240
78468
|
function alreadySealed(repoDir, mid, unit) {
|
|
78241
78469
|
return readModernizeEvents(repoDir, mid).some((e10) => e10.type === SEALED_EVENT && e10.data.unit === unit);
|
|
@@ -78249,7 +78477,7 @@ function sealPreSealedWall(repoDir, mid, unit, target, runConformance, log, base
|
|
|
78249
78477
|
if (!oracleCheck.ok)
|
|
78250
78478
|
return refuse(`oracle seal invalid: ${oracleCheck.reason ?? "unknown"}; presealed wall refused`);
|
|
78251
78479
|
const dir = oracleDir(repoDir, mid, unit);
|
|
78252
|
-
const oracleSealed = JSON.parse(
|
|
78480
|
+
const oracleSealed = JSON.parse(readFileSync111(join129(dir, "sealed.json"), "utf8"));
|
|
78253
78481
|
if (oracleSealed.verdict !== "PROVEN_ORACLE") {
|
|
78254
78482
|
return refuse(`oracle seal invalid: oracle is ${oracleSealed.verdict} (${oracleSealed.not_proven ?? "no reason recorded"}); presealed wall refused`);
|
|
78255
78483
|
}
|
|
@@ -78318,7 +78546,7 @@ function verifyPreSealedWall(repoDir, mid, unit) {
|
|
|
78318
78546
|
const expectedSha = event.data.sealed_sha256;
|
|
78319
78547
|
if (typeof expectedSha !== "string")
|
|
78320
78548
|
return { ok: false, reason: "sealing event has no sealed_sha256" };
|
|
78321
|
-
const sealedRaw =
|
|
78549
|
+
const sealedRaw = readFileSync111(sealedPath, "utf8");
|
|
78322
78550
|
const actualSha = sha2564(sealedRaw);
|
|
78323
78551
|
if (actualSha !== expectedSha) {
|
|
78324
78552
|
return { ok: false, reason: "presealed_wall.json does not match the sealing event's hash (tampered or rewritten)" };
|
|
@@ -78327,7 +78555,7 @@ function verifyPreSealedWall(repoDir, mid, unit) {
|
|
|
78327
78555
|
if (!oracleCheck.ok) {
|
|
78328
78556
|
return { ok: false, reason: `bound oracle seal is no longer valid: ${oracleCheck.reason ?? "unknown"}` };
|
|
78329
78557
|
}
|
|
78330
|
-
const oracleSealed = JSON.parse(
|
|
78558
|
+
const oracleSealed = JSON.parse(readFileSync111(join129(oracleDir(repoDir, mid, unit), "sealed.json"), "utf8"));
|
|
78331
78559
|
const carried = JSON.parse(sealedRaw);
|
|
78332
78560
|
if (carried.oracle_cases_sha256 !== oracleSealed.cases_sha256 || carried.oracle_coverage_sha256 !== oracleSealed.coverage_sha256 || typeof carried.oracle_normalizers_sha256 !== "string" || typeof oracleSealed.normalizers_sha256 !== "string" || carried.oracle_normalizers_sha256 !== oracleSealed.normalizers_sha256) {
|
|
78333
78561
|
return { ok: false, reason: "carried oracle hashes do not match the current oracle seal" };
|
|
@@ -78353,9 +78581,9 @@ var init_presealed_wall = __esm(() => {
|
|
|
78353
78581
|
// ../../loki-ts/src/engine10/modernize/unit.ts
|
|
78354
78582
|
import { spawnSync as spawnSync19 } from "child_process";
|
|
78355
78583
|
import { createHash as createHash35 } from "crypto";
|
|
78356
|
-
import { lstatSync as lstatSync29, readFileSync as
|
|
78584
|
+
import { lstatSync as lstatSync29, readFileSync as readFileSync112, readdirSync as readdirSync37, readlinkSync as readlinkSync7, realpathSync as realpathSync33, rmSync as rmSync36 } from "fs";
|
|
78357
78585
|
import { tmpdir as tmpdir22 } from "os";
|
|
78358
|
-
import { join as
|
|
78586
|
+
import { join as join130, sep as sep20 } from "path";
|
|
78359
78587
|
function isSealedName(rel) {
|
|
78360
78588
|
return TEST_FILE2.test(rel) || PYTEST_CFG.test(rel);
|
|
78361
78589
|
}
|
|
@@ -78370,7 +78598,7 @@ function purgePycache(dir) {
|
|
|
78370
78598
|
for (const e10 of ents) {
|
|
78371
78599
|
if (!e10.isDirectory())
|
|
78372
78600
|
continue;
|
|
78373
|
-
const full =
|
|
78601
|
+
const full = join130(d, e10.name);
|
|
78374
78602
|
if (e10.name === "__pycache__")
|
|
78375
78603
|
rmSync36(full, { recursive: true, force: true });
|
|
78376
78604
|
else if (!skipName(e10.name))
|
|
@@ -78425,13 +78653,13 @@ function outsideTargetDigest(dir, full) {
|
|
|
78425
78653
|
}
|
|
78426
78654
|
for (const n11 of names) {
|
|
78427
78655
|
h10.update("D" + n11);
|
|
78428
|
-
walk(
|
|
78656
|
+
walk(join130(p, n11));
|
|
78429
78657
|
}
|
|
78430
78658
|
return;
|
|
78431
78659
|
}
|
|
78432
78660
|
if (st2.isFile()) {
|
|
78433
78661
|
try {
|
|
78434
|
-
h10.update(
|
|
78662
|
+
h10.update(readFileSync112(p));
|
|
78435
78663
|
} catch {
|
|
78436
78664
|
h10.update("unreadable");
|
|
78437
78665
|
}
|
|
@@ -78446,7 +78674,7 @@ function conformanceHashes(dir) {
|
|
|
78446
78674
|
const walk = (sub2, inSkip) => {
|
|
78447
78675
|
let ents;
|
|
78448
78676
|
try {
|
|
78449
|
-
ents = readdirSync37(
|
|
78677
|
+
ents = readdirSync37(join130(dir, sub2), { withFileTypes: true });
|
|
78450
78678
|
} catch {
|
|
78451
78679
|
return;
|
|
78452
78680
|
}
|
|
@@ -78477,14 +78705,14 @@ function conformanceHashes(dir) {
|
|
|
78477
78705
|
for (const rel of rels) {
|
|
78478
78706
|
let data;
|
|
78479
78707
|
try {
|
|
78480
|
-
const st2 = lstatSync29(
|
|
78708
|
+
const st2 = lstatSync29(join130(dir, rel));
|
|
78481
78709
|
if (st2.isSymbolicLink()) {
|
|
78482
|
-
out3[rel] = `${LINK}${readlinkSync7(
|
|
78710
|
+
out3[rel] = `${LINK}${readlinkSync7(join130(dir, rel))}|${outsideTargetDigest(dir, join130(dir, rel))}`;
|
|
78483
78711
|
continue;
|
|
78484
78712
|
}
|
|
78485
78713
|
if (!st2.isFile())
|
|
78486
78714
|
continue;
|
|
78487
|
-
data =
|
|
78715
|
+
data = readFileSync112(join130(dir, rel));
|
|
78488
78716
|
} catch {
|
|
78489
78717
|
continue;
|
|
78490
78718
|
}
|
|
@@ -78543,7 +78771,7 @@ function notProvenUnitResult(unit, reason, oracle, wall) {
|
|
|
78543
78771
|
return { unit, verdict: "NOT_PROVEN", oracle, wall, equiv: null, not_proven: [reason], conformance: null };
|
|
78544
78772
|
}
|
|
78545
78773
|
function readOracleSealed(repoDir, mid, unit) {
|
|
78546
|
-
return JSON.parse(
|
|
78774
|
+
return JSON.parse(readFileSync112(join130(oracleDir(repoDir, mid, unit), "sealed.json"), "utf8"));
|
|
78547
78775
|
}
|
|
78548
78776
|
function runUnit(card, log, runConformance, implement, runNew, runStub, collect) {
|
|
78549
78777
|
const { repoDir, mid, unit } = card;
|
|
@@ -78654,8 +78882,8 @@ var init_unit = __esm(() => {
|
|
|
78654
78882
|
|
|
78655
78883
|
// ../../loki-ts/src/engine10/modernize/wave.ts
|
|
78656
78884
|
import { spawnSync as spawnSync20 } from "child_process";
|
|
78657
|
-
import { readFileSync as
|
|
78658
|
-
import { join as
|
|
78885
|
+
import { readFileSync as readFileSync113, statSync as statSync33 } from "fs";
|
|
78886
|
+
import { join as join131 } from "path";
|
|
78659
78887
|
function clampTimeout(ms) {
|
|
78660
78888
|
if (ms === undefined || !Number.isFinite(ms) || ms <= 0)
|
|
78661
78889
|
return DEFAULT_STEP_TIMEOUT_MS;
|
|
@@ -78724,7 +78952,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78724
78952
|
const none = { build: null, integration: null, original_suite: null };
|
|
78725
78953
|
const text4 = () => {
|
|
78726
78954
|
try {
|
|
78727
|
-
return
|
|
78955
|
+
return readFileSync113(join131(target, marker ?? ""), "utf8");
|
|
78728
78956
|
} catch {
|
|
78729
78957
|
return "";
|
|
78730
78958
|
}
|
|
@@ -78736,7 +78964,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78736
78964
|
if (system === "gradle") {
|
|
78737
78965
|
let gw2 = "gradle";
|
|
78738
78966
|
try {
|
|
78739
|
-
if (inv.files.includes("gradlew") && (statSync33(
|
|
78967
|
+
if (inv.files.includes("gradlew") && (statSync33(join131(target, "gradlew")).mode & 73) !== 0)
|
|
78740
78968
|
gw2 = "./gradlew";
|
|
78741
78969
|
} catch {}
|
|
78742
78970
|
return { build: { argv: [gw2, "assemble"] }, integration: text4().includes("integrationTest") ? { argv: [gw2, "integrationTest"] } : null, original_suite: { argv: [gw2, "test"] } };
|
|
@@ -78748,7 +78976,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78748
78976
|
let toxIni = "";
|
|
78749
78977
|
if (inv.files.includes("tox.ini")) {
|
|
78750
78978
|
try {
|
|
78751
|
-
toxIni =
|
|
78979
|
+
toxIni = readFileSync113(join131(target, "tox.ini"), "utf8");
|
|
78752
78980
|
} catch {}
|
|
78753
78981
|
}
|
|
78754
78982
|
const integration = toxIni.includes("[testenv:integration") ? { argv: ["tox", "-e", "integration"] } : itDir && pytest ? { argv: ["python3", "-m", "pytest", "-q", itDir] } : null;
|
|
@@ -78780,9 +79008,9 @@ var init_wave = __esm(() => {
|
|
|
78780
79008
|
|
|
78781
79009
|
// ../../loki-ts/src/util/modernize_unit.ts
|
|
78782
79010
|
import { spawnSync as spawnSync21 } from "child_process";
|
|
78783
|
-
import { existsSync as existsSync89, lstatSync as lstatSync30, mkdtempSync as mkdtempSync18, readFileSync as
|
|
79011
|
+
import { existsSync as existsSync89, lstatSync as lstatSync30, mkdtempSync as mkdtempSync18, readFileSync as readFileSync114, realpathSync as realpathSync34, rmSync as rmSync37, statSync as statSync34, writeFileSync as writeFileSync67 } from "fs";
|
|
78784
79012
|
import { tmpdir as tmpdir23 } from "os";
|
|
78785
|
-
import { join as
|
|
79013
|
+
import { join as join132, sep as sep21 } from "path";
|
|
78786
79014
|
function parseUnitArgs(args) {
|
|
78787
79015
|
const f = {};
|
|
78788
79016
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -78854,7 +79082,7 @@ function makeUnitRunners(o) {
|
|
|
78854
79082
|
}
|
|
78855
79083
|
function makeSessionRunner(o) {
|
|
78856
79084
|
const limitS = o.sessionLimitS ?? SESSION_LIMIT_S2;
|
|
78857
|
-
const cli = import.meta.path.endsWith("modernize_unit.ts") ?
|
|
79085
|
+
const cli = import.meta.path.endsWith("modernize_unit.ts") ? join132(import.meta.dir, "..", "cli.ts") : import.meta.path;
|
|
78858
79086
|
return o.session ?? ((_brief, cwd, env) => spawnSync21(process.execPath, [...SAFE_BUN_FLAGS, cli, "engine10", "session"], { cwd, env, stdio: ["ignore", "ignore", "pipe"], timeout: limitS * 1000 }));
|
|
78859
79087
|
}
|
|
78860
79088
|
function defaultUnitFile(unitId, newTreeDir) {
|
|
@@ -78862,7 +79090,7 @@ function defaultUnitFile(unitId, newTreeDir) {
|
|
|
78862
79090
|
return null;
|
|
78863
79091
|
try {
|
|
78864
79092
|
const root = realpathSync34(newTreeDir);
|
|
78865
|
-
const real3 = realpathSync34(
|
|
79093
|
+
const real3 = realpathSync34(join132(root, unitId));
|
|
78866
79094
|
return real3.startsWith(root + sep21) ? real3 : null;
|
|
78867
79095
|
} catch {
|
|
78868
79096
|
return null;
|
|
@@ -78899,16 +79127,16 @@ function runPythonCase(o, unitId, newTreeDir, rec2, stub) {
|
|
|
78899
79127
|
const src = o.unitFile ? o.unitFile(unitId, newTreeDir) : defaultUnitFile(unitId, newTreeDir);
|
|
78900
79128
|
if (!src || !src.endsWith(".py") || !existsSync89(src))
|
|
78901
79129
|
throw new Error(`cannot locate the source of unit ${unitId} in the new tree`);
|
|
78902
|
-
const dir = mkdtempSync18(
|
|
79130
|
+
const dir = mkdtempSync18(join132(tmpdir23(), "loki-newcase-"));
|
|
78903
79131
|
try {
|
|
78904
|
-
const cases =
|
|
79132
|
+
const cases = join132(dir, "in.jsonl"), out3 = join132(dir, "out.jsonl");
|
|
78905
79133
|
writeFileSync67(cases, JSON.stringify({ entry: rec2.entry, args: rec2.args, kwargs: rec2.kwargs, boundaries: boundariesFromCase(rec2) }) + `
|
|
78906
79134
|
`, "utf8");
|
|
78907
|
-
const r = spawnSync21(o.pythonBin ?? "python3", [
|
|
79135
|
+
const r = spawnSync21(o.pythonBin ?? "python3", [join132(REPO_ROOT, "autonomy", "lib", "modernize", "py_capture.py"), "--unit", src, "--cases", cases, "--out", out3, ...stub ? ["--stub"] : []], { cwd: newTreeDir, encoding: "utf8", timeout: CASE_TIMEOUT_MS, env: { ...tokenFreeEnv(), PYTHONDONTWRITEBYTECODE: "1" } });
|
|
78908
79136
|
if (r.status !== 0 || !existsSync89(out3))
|
|
78909
79137
|
throw new Error(`new-tree case runner failed (${r.status ?? r.signal ?? "no status"}): ${String(r.stderr ?? "").trim().split(`
|
|
78910
79138
|
`).pop() ?? ""}`);
|
|
78911
|
-
const line2 =
|
|
79139
|
+
const line2 = readFileSync114(out3, "utf8").split(`
|
|
78912
79140
|
`).find((l) => l.trim() !== "");
|
|
78913
79141
|
if (!line2)
|
|
78914
79142
|
throw new Error("new-tree case runner produced no record");
|
|
@@ -78934,7 +79162,7 @@ Usage: ${UNIT_USAGE}
|
|
|
78934
79162
|
const root = u10.tmpRoot ?? (runTmp !== "" && isRealDir(runTmp) ? runTmp : tmpdir23());
|
|
78935
79163
|
let repoDir;
|
|
78936
79164
|
try {
|
|
78937
|
-
repoDir = mkdtempSync18(
|
|
79165
|
+
repoDir = mkdtempSync18(join132(root, "loki-unit-"));
|
|
78938
79166
|
} catch (e10) {
|
|
78939
79167
|
process.stderr.write(`modernize unit: cannot create a temp checkout directory: ${e10.message}
|
|
78940
79168
|
`);
|
|
@@ -79030,11 +79258,11 @@ var init_modernize_unit = __esm(() => {
|
|
|
79030
79258
|
|
|
79031
79259
|
// ../../loki-ts/src/util/modernize_coordinator.ts
|
|
79032
79260
|
import { createHash as createHash36 } from "crypto";
|
|
79033
|
-
import { existsSync as existsSync90, mkdtempSync as mkdtempSync19, readFileSync as
|
|
79261
|
+
import { existsSync as existsSync90, mkdtempSync as mkdtempSync19, readFileSync as readFileSync115, rmSync as rmSync38 } from "fs";
|
|
79034
79262
|
import { tmpdir as tmpdir24 } from "os";
|
|
79035
|
-
import { join as
|
|
79263
|
+
import { join as join133 } from "path";
|
|
79036
79264
|
function shipUnitOf(d, unit, o) {
|
|
79037
|
-
const sealed =
|
|
79265
|
+
const sealed = join133(oracleDir(d.repoDir, d.mid, unit), "sealed.json");
|
|
79038
79266
|
const eq3 = o?.result?.equiv;
|
|
79039
79267
|
return {
|
|
79040
79268
|
unit,
|
|
@@ -79051,7 +79279,7 @@ function scopeBuildToWave(cmd2, repoDir, units) {
|
|
|
79051
79279
|
const x3 = cmd2?.argv.indexOf("-x") ?? -1;
|
|
79052
79280
|
if (!cmd2 || !cmd2.argv.includes("compileall") || x3 < 0)
|
|
79053
79281
|
return cmd2;
|
|
79054
|
-
const files = [...new Set(units.flatMap((u10) => u10.nodes))].filter((n11) => n11.endsWith(".py") && isSafeUnitId(n11) && existsSync90(
|
|
79282
|
+
const files = [...new Set(units.flatMap((u10) => u10.nodes))].filter((n11) => n11.endsWith(".py") && isSafeUnitId(n11) && existsSync90(join133(repoDir, n11)));
|
|
79055
79283
|
return files.length ? { ...cmd2, argv: [...cmd2.argv.slice(0, x3 + 2), ...files] } : cmd2;
|
|
79056
79284
|
}
|
|
79057
79285
|
async function runWaves(plan, d) {
|
|
@@ -79210,16 +79438,16 @@ function makeAttemptRunner(o) {
|
|
|
79210
79438
|
}
|
|
79211
79439
|
function makeUnitPrep(o) {
|
|
79212
79440
|
const runtimeOk = o.runtimeOk ?? (() => {
|
|
79213
|
-
const dir = mkdtempSync19(
|
|
79441
|
+
const dir = mkdtempSync19(join133(tmpdir24(), "loki-probe-"));
|
|
79214
79442
|
try {
|
|
79215
|
-
return realCaptureRunner(
|
|
79443
|
+
return realCaptureRunner(join133(dir, "probe.py"), []).error !== "old runtime unavailable";
|
|
79216
79444
|
} finally {
|
|
79217
79445
|
rmSync38(dir, { recursive: true, force: true });
|
|
79218
79446
|
}
|
|
79219
79447
|
});
|
|
79220
79448
|
let runtime = null;
|
|
79221
79449
|
return (unit) => {
|
|
79222
|
-
if (existsSync90(
|
|
79450
|
+
if (existsSync90(join133(oracleDir(o.repoDir, o.mid, unit.id), "cases.jsonl")) || alreadySealedInLog(o.repoDir, o.mid, unit.id))
|
|
79223
79451
|
return null;
|
|
79224
79452
|
runtime ??= runtimeOk();
|
|
79225
79453
|
if (!runtime)
|
|
@@ -79227,7 +79455,7 @@ function makeUnitPrep(o) {
|
|
|
79227
79455
|
const node = unit.nodes.length === 1 ? unit.nodes[0] : "";
|
|
79228
79456
|
if (!node.endsWith(".py") || !isSafeUnitId(node))
|
|
79229
79457
|
return MULTI_FILE_REASON;
|
|
79230
|
-
const r = (o.capture ?? captureUnitOracle)({ repoDir: o.repoDir, mid: o.mid, unit: unit.id, unitPath:
|
|
79458
|
+
const r = (o.capture ?? captureUnitOracle)({ repoDir: o.repoDir, mid: o.mid, unit: unit.id, unitPath: join133(o.repoDir, node), propose: o.propose });
|
|
79231
79459
|
return r.ok ? null : r.reason;
|
|
79232
79460
|
};
|
|
79233
79461
|
}
|
|
@@ -79286,7 +79514,7 @@ function productionWaveDeps(o) {
|
|
|
79286
79514
|
}
|
|
79287
79515
|
};
|
|
79288
79516
|
}
|
|
79289
|
-
var productionReslice, sha2565 = (p) => existsSync90(p) ? createHash36("sha256").update(
|
|
79517
|
+
var productionReslice, sha2565 = (p) => existsSync90(p) ? createHash36("sha256").update(readFileSync115(p)).digest("hex") : "n/a", MULTI_FILE_REASON = "multi-file unit: capture not supported (founder default)";
|
|
79290
79518
|
var init_modernize_coordinator = __esm(() => {
|
|
79291
79519
|
init_codemod();
|
|
79292
79520
|
init_search();
|
|
@@ -79619,8 +79847,8 @@ __export(exports_export_sarif, {
|
|
|
79619
79847
|
preRedFromEvents: () => preRedFromEvents,
|
|
79620
79848
|
main: () => main8
|
|
79621
79849
|
});
|
|
79622
|
-
import { existsSync as existsSync92, readFileSync as
|
|
79623
|
-
import { join as
|
|
79850
|
+
import { existsSync as existsSync92, readFileSync as readFileSync116, writeFileSync as writeFileSync68 } from "fs";
|
|
79851
|
+
import { join as join134 } from "path";
|
|
79624
79852
|
function scanDiff(diff) {
|
|
79625
79853
|
const out3 = [];
|
|
79626
79854
|
let file = "";
|
|
@@ -79651,7 +79879,7 @@ function scanDiff(diff) {
|
|
|
79651
79879
|
function preRedFromEvents(runDir) {
|
|
79652
79880
|
try {
|
|
79653
79881
|
let pre2 = [];
|
|
79654
|
-
for (const l of
|
|
79882
|
+
for (const l of readFileSync116(join134(runDir, "events.jsonl"), "utf8").split(`
|
|
79655
79883
|
`)) {
|
|
79656
79884
|
if (!l.includes('"stage.completed"'))
|
|
79657
79885
|
continue;
|
|
@@ -79680,19 +79908,19 @@ async function main8(args, deps = {}) {
|
|
|
79680
79908
|
if (bad || rest.length > 1)
|
|
79681
79909
|
return process.stderr.write(`loki export --sarif: ${bad ? `unknown flag ${bad}` : "more than one run-id"}
|
|
79682
79910
|
`), 2;
|
|
79683
|
-
const runsRoot2 = deps.runsRoot ??
|
|
79911
|
+
const runsRoot2 = deps.runsRoot ?? join134(lokiDir(), "runs");
|
|
79684
79912
|
const runId2 = rest[0] ?? latestRunId(runsRoot2);
|
|
79685
79913
|
if (!runId2)
|
|
79686
79914
|
return process.stderr.write(`loki export --sarif: no runs found
|
|
79687
79915
|
`), 66;
|
|
79688
|
-
const runDir =
|
|
79689
|
-
const receiptPath =
|
|
79916
|
+
const runDir = join134(runsRoot2, runId2);
|
|
79917
|
+
const receiptPath = join134(runDir, "receipt.json");
|
|
79690
79918
|
if (runId2.includes("/") || runId2.includes("..") || !existsSync92(receiptPath))
|
|
79691
79919
|
return process.stderr.write(`loki export --sarif: unknown run ${runId2}
|
|
79692
79920
|
`), 66;
|
|
79693
79921
|
let receipt;
|
|
79694
79922
|
try {
|
|
79695
|
-
receipt = JSON.parse(
|
|
79923
|
+
receipt = JSON.parse(readFileSync116(receiptPath, "utf8"));
|
|
79696
79924
|
} catch {
|
|
79697
79925
|
return process.stderr.write(`loki export --sarif: unreadable receipt for ${runId2}
|
|
79698
79926
|
`), 66;
|
|
@@ -79709,9 +79937,9 @@ async function main8(args, deps = {}) {
|
|
|
79709
79937
|
findings.push(...receiptFindings(receipt, preRedFromEvents(runDir)));
|
|
79710
79938
|
let version2 = "0.0.0";
|
|
79711
79939
|
try {
|
|
79712
|
-
version2 =
|
|
79940
|
+
version2 = readFileSync116(join134(REPO_ROOT, "VERSION"), "utf8").trim() || version2;
|
|
79713
79941
|
} catch {}
|
|
79714
|
-
const out3 =
|
|
79942
|
+
const out3 = join134(runDir, "findings.sarif");
|
|
79715
79943
|
writeFileSync68(out3, JSON.stringify(toSarif(findings, version2, deps.repoDir ?? process.cwd()), null, 2) + `
|
|
79716
79944
|
`);
|
|
79717
79945
|
process.stdout.write(`run: ${runId2}
|
|
@@ -79930,7 +80158,7 @@ var init_output = __esm(() => {
|
|
|
79930
80158
|
|
|
79931
80159
|
// ../../loki-ts/src/features/receipt_dsse.ts
|
|
79932
80160
|
import { createPublicKey as createPublicKey5, sign as sign3, verify as verify3 } from "crypto";
|
|
79933
|
-
import { readFileSync as
|
|
80161
|
+
import { readFileSync as readFileSync117 } from "fs";
|
|
79934
80162
|
function pae2(payloadType, body) {
|
|
79935
80163
|
const t = Buffer.from(payloadType, "utf8");
|
|
79936
80164
|
return Buffer.concat([Buffer.from(`DSSEv1 ${t.length} `), t, Buffer.from(` ${body.length} `), body]);
|
|
@@ -80026,7 +80254,7 @@ function verifyDsseReceipt(env, d) {
|
|
|
80026
80254
|
}
|
|
80027
80255
|
function runIdGuard(receiptPath, runId2) {
|
|
80028
80256
|
try {
|
|
80029
|
-
return envelopeRunIdProblem(JSON.parse(
|
|
80257
|
+
return envelopeRunIdProblem(JSON.parse(readFileSync117(receiptPath, "utf8")), runId2);
|
|
80030
80258
|
} catch {
|
|
80031
80259
|
return null;
|
|
80032
80260
|
}
|
|
@@ -80034,7 +80262,7 @@ function runIdGuard(receiptPath, runId2) {
|
|
|
80034
80262
|
async function exportDsseReceipt(a) {
|
|
80035
80263
|
const fail2 = (rc2, m) => (process.stderr.write(`loki verify --export-dsse: ${m}
|
|
80036
80264
|
`), rc2);
|
|
80037
|
-
const rd2 = a.deps.read ?? ((p) =>
|
|
80265
|
+
const rd2 = a.deps.read ?? ((p) => readFileSync117(p, "utf8"));
|
|
80038
80266
|
let text4;
|
|
80039
80267
|
try {
|
|
80040
80268
|
text4 = rd2(a.receiptPath);
|
|
@@ -80091,10 +80319,10 @@ var init_undo = __esm(() => {
|
|
|
80091
80319
|
});
|
|
80092
80320
|
|
|
80093
80321
|
// ../../loki-ts/src/commands/run_status.ts
|
|
80094
|
-
import { existsSync as existsSync93, readdirSync as readdirSync38, readFileSync as
|
|
80095
|
-
import { basename as basename32, dirname as
|
|
80322
|
+
import { existsSync as existsSync93, readdirSync as readdirSync38, readFileSync as readFileSync118, statSync as statSync36 } from "fs";
|
|
80323
|
+
import { basename as basename32, dirname as dirname50, join as join135, resolve as resolve39 } from "path";
|
|
80096
80324
|
function runsRoot(env, repoDir) {
|
|
80097
|
-
return env.LOKI_DIR ?
|
|
80325
|
+
return env.LOKI_DIR ? join135(resolve39(repoDir, env.LOKI_DIR), "runs") : join135(repoDir, ".loki", "runs");
|
|
80098
80326
|
}
|
|
80099
80327
|
function listRunIds(root) {
|
|
80100
80328
|
if (!existsSync93(root))
|
|
@@ -80106,7 +80334,7 @@ function latestRunId(root) {
|
|
|
80106
80334
|
return ids.length ? ids[ids.length - 1] : null;
|
|
80107
80335
|
}
|
|
80108
80336
|
function eventsPath(root, runId2) {
|
|
80109
|
-
return
|
|
80337
|
+
return join135(root, runId2, "events.jsonl");
|
|
80110
80338
|
}
|
|
80111
80339
|
var TERMINAL2;
|
|
80112
80340
|
var init_run_status = __esm(() => {
|
|
@@ -80123,8 +80351,8 @@ var init_run_status = __esm(() => {
|
|
|
80123
80351
|
|
|
80124
80352
|
// ../../loki-ts/src/util/seal_drift.ts
|
|
80125
80353
|
import { createHash as createHash38 } from "crypto";
|
|
80126
|
-
import { existsSync as existsSync94, readFileSync as
|
|
80127
|
-
import { basename as basename33, dirname as
|
|
80354
|
+
import { existsSync as existsSync94, readFileSync as readFileSync119, realpathSync as realpathSync35 } from "fs";
|
|
80355
|
+
import { basename as basename33, dirname as dirname51, join as join136, relative as relative27 } from "path";
|
|
80128
80356
|
function tornTail(raw2) {
|
|
80129
80357
|
if (raw2 === "" || raw2.endsWith(`
|
|
80130
80358
|
`))
|
|
@@ -80143,7 +80371,7 @@ function tornTail(raw2) {
|
|
|
80143
80371
|
function boundEvents(log, bound) {
|
|
80144
80372
|
if (!existsSync94(log))
|
|
80145
80373
|
return null;
|
|
80146
|
-
const lines2 =
|
|
80374
|
+
const lines2 = readFileSync119(log, "utf8").split(`
|
|
80147
80375
|
`).filter((l) => l.trim() !== ""), h10 = createHash38("sha256");
|
|
80148
80376
|
let n11 = -1;
|
|
80149
80377
|
for (let i = 0;i <= lines2.length; i++) {
|
|
@@ -80171,7 +80399,7 @@ function fabricatedPass(receiptPath, r) {
|
|
|
80171
80399
|
const bound = r["events_sha256"];
|
|
80172
80400
|
if (typeof bound !== "string" || bound === EMPTY_SHA || !Array.isArray(r["checks"]))
|
|
80173
80401
|
return null;
|
|
80174
|
-
const events2 = boundEvents(
|
|
80402
|
+
const events2 = boundEvents(join136(dirname51(receiptPath), "events.jsonl"), bound);
|
|
80175
80403
|
if (!events2 || !events2.some((e10) => e10.stage === "verify"))
|
|
80176
80404
|
return null;
|
|
80177
80405
|
const passed = new Set(events2.filter((e10) => e10.type === "test.result" && e10.stage === "verify" && e10.data["result"] === "pass").map((e10) => String(e10.data["name"])));
|
|
@@ -80179,12 +80407,12 @@ function fabricatedPass(receiptPath, r) {
|
|
|
80179
80407
|
return missing.length ? `receipt claims pass with no test.result pass in events.jsonl: ${missing.join(", ")}` : null;
|
|
80180
80408
|
}
|
|
80181
80409
|
function currentTaskSha(runDir, source, env) {
|
|
80182
|
-
const f = source === "issue" ?
|
|
80183
|
-
return f && existsSync94(f) ? sha6(
|
|
80410
|
+
const f = source === "issue" ? join136(runDir, "issue.json") : env["LOKI_VERIFY_TASK_FILE"];
|
|
80411
|
+
return f && existsSync94(f) ? sha6(readFileSync119(f)) : null;
|
|
80184
80412
|
}
|
|
80185
80413
|
function repoOf(receiptPath) {
|
|
80186
|
-
const runs2 =
|
|
80187
|
-
return basename33(runs2) === "runs" && basename33(
|
|
80414
|
+
const runs2 = dirname51(dirname51(receiptPath));
|
|
80415
|
+
return basename33(runs2) === "runs" && basename33(dirname51(runs2)) === ".loki" ? dirname51(dirname51(runs2)) : null;
|
|
80188
80416
|
}
|
|
80189
80417
|
function overlap(repo, base, sealedHead, head) {
|
|
80190
80418
|
if (typeof base !== "string" || !/^[0-9a-f]{40,64}$/.test(base) || !/^[0-9a-f]{40,64}$/.test(sealedHead))
|
|
@@ -80210,7 +80438,7 @@ function onlyWallPublish(repo, r, sealedHead, head) {
|
|
|
80210
80438
|
} catch {
|
|
80211
80439
|
return x3;
|
|
80212
80440
|
}
|
|
80213
|
-
}, rr2 = real3(repo), want = new Map(wall.map((w) => [relative27(rr2,
|
|
80441
|
+
}, rr2 = real3(repo), want = new Map(wall.map((w) => [relative27(rr2, join136(real3(dirname51(String(w.path))), basename33(String(w.path)))), String(w.sha256)]));
|
|
80214
80442
|
const commits = safeGit(repo, ["rev-list", "--reverse", "--topo-order", `${sealedHead}..${head}`]).split(`
|
|
80215
80443
|
`).filter(Boolean);
|
|
80216
80444
|
if (commits.length === 0 || safeGit(repo, ["rev-list", "--merges", "--count", `${sealedHead}..${head}`]).trim() !== "0")
|
|
@@ -80248,18 +80476,18 @@ function claimsWallPublish(repo, r, sealedHead, head) {
|
|
|
80248
80476
|
function sealDrift(given, r, env = process.env) {
|
|
80249
80477
|
let receiptPath = given;
|
|
80250
80478
|
try {
|
|
80251
|
-
receiptPath =
|
|
80479
|
+
receiptPath = join136(realpathSync35(dirname51(given)), basename33(given));
|
|
80252
80480
|
} catch {}
|
|
80253
80481
|
const fab = fabricatedPass(receiptPath, r);
|
|
80254
80482
|
if (fab)
|
|
80255
80483
|
return { verdict: "TAMPERED", reason: fab };
|
|
80256
80484
|
try {
|
|
80257
|
-
const log =
|
|
80258
|
-
if (existsSync94(log) && tornTail(
|
|
80485
|
+
const log = join136(dirname51(receiptPath), "events.jsonl");
|
|
80486
|
+
if (existsSync94(log) && tornTail(readFileSync119(log, "utf8")))
|
|
80259
80487
|
return { verdict: "UNCHECKED", reason: "events.jsonl ends in a torn, unterminated line (an append cut mid-write); every complete line is intact but the log is not whole" };
|
|
80260
80488
|
} catch {}
|
|
80261
80489
|
const task = r["task"] ?? {};
|
|
80262
|
-
const cur = currentTaskSha(
|
|
80490
|
+
const cur = currentTaskSha(dirname51(receiptPath), task.source, env);
|
|
80263
80491
|
if (cur !== null && typeof task.sha256 === "string" && task.sha256 !== "" && cur !== task.sha256)
|
|
80264
80492
|
return { verdict: "UNCHECKED", reason: `intent drift: sealed task sha256 ${task.sha256} differs from the current spec ${cur}` };
|
|
80265
80493
|
const repo = repoOf(receiptPath);
|
|
@@ -80282,6 +80510,17 @@ function sealDrift(given, r, env = process.env) {
|
|
|
80282
80510
|
}
|
|
80283
80511
|
return null;
|
|
80284
80512
|
}
|
|
80513
|
+
function wallNotComparedNote(receiptPath) {
|
|
80514
|
+
try {
|
|
80515
|
+
const r = JSON.parse(readFileSync119(receiptPath, "utf8"));
|
|
80516
|
+
if (r["schema"] !== "loki.v10.receipt/1")
|
|
80517
|
+
return null;
|
|
80518
|
+
const files = r["wall"]?.files;
|
|
80519
|
+
return Array.isArray(files) && files.length > 0 && !existsSync94(join136(dirname51(receiptPath), "wall")) ? "sealed Wall copies not present: not compared" : null;
|
|
80520
|
+
} catch {
|
|
80521
|
+
return null;
|
|
80522
|
+
}
|
|
80523
|
+
}
|
|
80285
80524
|
var EMPTY_SHA, sha6 = (s) => createHash38("sha256").update(s).digest("hex");
|
|
80286
80525
|
var init_seal_drift = __esm(() => {
|
|
80287
80526
|
init_safe_git();
|
|
@@ -80289,14 +80528,14 @@ var init_seal_drift = __esm(() => {
|
|
|
80289
80528
|
});
|
|
80290
80529
|
|
|
80291
80530
|
// ../../loki-ts/src/util/composite_seal.ts
|
|
80292
|
-
import { existsSync as existsSync95, readFileSync as
|
|
80293
|
-
import { basename as basename34, dirname as
|
|
80531
|
+
import { existsSync as existsSync95, readFileSync as readFileSync120 } from "fs";
|
|
80532
|
+
import { basename as basename34, dirname as dirname52, join as join137 } from "path";
|
|
80294
80533
|
function logProblem(runDir, integ) {
|
|
80295
80534
|
if (typeof integ["log_sha256"] !== "string")
|
|
80296
80535
|
return null;
|
|
80297
80536
|
let b;
|
|
80298
80537
|
try {
|
|
80299
|
-
b =
|
|
80538
|
+
b = readFileSync120(join137(runDir, "integration.log"));
|
|
80300
80539
|
} catch {
|
|
80301
80540
|
return "integration.log is missing but integration.json records its hash";
|
|
80302
80541
|
}
|
|
@@ -80311,10 +80550,10 @@ function integrationProblem(integ) {
|
|
|
80311
80550
|
return null;
|
|
80312
80551
|
}
|
|
80313
80552
|
function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
80314
|
-
const ip =
|
|
80553
|
+
const ip = join137(runDir, "integration.json");
|
|
80315
80554
|
let ibytes;
|
|
80316
80555
|
try {
|
|
80317
|
-
ibytes =
|
|
80556
|
+
ibytes = readFileSync120(ip);
|
|
80318
80557
|
} catch {
|
|
80319
80558
|
throw new Error("integration.json missing; the workspace run did not finish");
|
|
80320
80559
|
}
|
|
@@ -80338,12 +80577,12 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80338
80577
|
const outcome = String(integ["outcomes"][repo] ?? "");
|
|
80339
80578
|
if (outcome !== "ok")
|
|
80340
80579
|
throw new Error(`repo ${text3(repo, 80)} did not finish (${text3(outcome, 80) || "no outcome"}); no composite`);
|
|
80341
|
-
const runsDir =
|
|
80342
|
-
const ids = (dirNames(runsDir) ?? []).filter((n11) => existsSync95(
|
|
80580
|
+
const runsDir = join137(runDir, "worktrees", slugOf(repo), ".loki", "runs");
|
|
80581
|
+
const ids = (dirNames(runsDir) ?? []).filter((n11) => existsSync95(join137(runsDir, n11, "receipt.json")));
|
|
80343
80582
|
const id2 = ids[ids.length - 1];
|
|
80344
80583
|
if (!id2)
|
|
80345
80584
|
throw new Error(`repo ${text3(repo, 80)} has no receipt.json under worktrees/${slugOf(repo)}/.loki/runs`);
|
|
80346
|
-
const rp =
|
|
80585
|
+
const rp = join137(runsDir, id2, "receipt.json"), bytes = readFileSync120(rp), r = readJson7(rp);
|
|
80347
80586
|
if (jsonTooDeep(r))
|
|
80348
80587
|
throw new Error(`repo ${text3(repo, 80)} receipt cannot be hashed (nested too deeply); no composite`);
|
|
80349
80588
|
if (!isObj10(r) || typeof r["receipt_sha256"] !== "string" || rh(r) !== r["receipt_sha256"])
|
|
@@ -80361,7 +80600,7 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80361
80600
|
throw new Error("workspace has no repos");
|
|
80362
80601
|
return {
|
|
80363
80602
|
schema: COMPOSITE_SCHEMA,
|
|
80364
|
-
workspace: basename34(
|
|
80603
|
+
workspace: basename34(dirname52(runDir)),
|
|
80365
80604
|
run_id: basename34(runDir),
|
|
80366
80605
|
integration_sha256: sha4(ibytes),
|
|
80367
80606
|
integration: { status: String(integ["status"]), exit_code: typeof integ["exit_code"] === "number" ? integ["exit_code"] : null, log_sha256: typeof integ["log_sha256"] === "string" ? integ["log_sha256"] : null, heads },
|
|
@@ -80371,7 +80610,7 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80371
80610
|
};
|
|
80372
80611
|
}
|
|
80373
80612
|
async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
80374
|
-
const runDir =
|
|
80613
|
+
const runDir = dirname52(receiptPath);
|
|
80375
80614
|
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
80376
80615
|
const bad = (reason) => ({ problem: { verdict: "TAMPERED", reason: `composite: ${reason}` }, verdict: "FAILED" });
|
|
80377
80616
|
const deep = (what) => ({ problem: { verdict: "UNCHECKED", reason: `composite: ${what} cannot be hashed (nested too deeply)` }, verdict: "FAILED" });
|
|
@@ -80380,13 +80619,13 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
80380
80619
|
return bad("body malformed");
|
|
80381
80620
|
let ibytes;
|
|
80382
80621
|
try {
|
|
80383
|
-
ibytes =
|
|
80622
|
+
ibytes = readFileSync120(join137(runDir, "integration.json"));
|
|
80384
80623
|
} catch {
|
|
80385
80624
|
return bad("integration.json missing");
|
|
80386
80625
|
}
|
|
80387
80626
|
if (sha4(ibytes) !== receipt["integration_sha256"])
|
|
80388
80627
|
return bad("integration.json does not match its recorded hash");
|
|
80389
|
-
const integ = readJson7(
|
|
80628
|
+
const integ = readJson7(join137(runDir, "integration.json"));
|
|
80390
80629
|
if (jsonTooDeep(integ))
|
|
80391
80630
|
return deep("integration.json");
|
|
80392
80631
|
if (!isObj10(integ) || !isObj10(integ["outcomes"]))
|
|
@@ -80423,10 +80662,10 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
80423
80662
|
return bad(`child ${text3(repo, 80) || "?"} has an invalid receipt path`);
|
|
80424
80663
|
if (outcomes[repo] !== "ok")
|
|
80425
80664
|
return bad(`child ${text3(repo, 80)} did not finish ok in integration.json`);
|
|
80426
|
-
const rp =
|
|
80665
|
+
const rp = join137(runDir, rel);
|
|
80427
80666
|
let bytes;
|
|
80428
80667
|
try {
|
|
80429
|
-
bytes =
|
|
80668
|
+
bytes = readFileSync120(rp);
|
|
80430
80669
|
} catch {
|
|
80431
80670
|
return bad(`child ${repo} receipt missing`);
|
|
80432
80671
|
}
|
|
@@ -80486,8 +80725,8 @@ __export(exports_verify_cmd, {
|
|
|
80486
80725
|
main: () => main9,
|
|
80487
80726
|
computeReceiptHash: () => computeReceiptHash
|
|
80488
80727
|
});
|
|
80489
|
-
import { existsSync as existsSync96, readFileSync as
|
|
80490
|
-
import { basename as basename35, dirname as
|
|
80728
|
+
import { existsSync as existsSync96, readFileSync as readFileSync121, renameSync as renameSync23, statSync as statSync37, writeFileSync as writeFileSync69 } from "fs";
|
|
80729
|
+
import { basename as basename35, dirname as dirname53, join as join138 } from "path";
|
|
80491
80730
|
import { createHash as createHash39, createPublicKey as createPublicKey6, verify as verify4 } from "crypto";
|
|
80492
80731
|
function pubFor(kid, given) {
|
|
80493
80732
|
if (given)
|
|
@@ -80495,7 +80734,7 @@ function pubFor(kid, given) {
|
|
|
80495
80734
|
const active = loadSigningKey(false);
|
|
80496
80735
|
const pubs = (process.env["LOKI_RECEIPT_RETIRED_PUBKEYS"] ?? "").split(":").map((f) => f.trim()).filter(Boolean).flatMap((f) => {
|
|
80497
80736
|
try {
|
|
80498
|
-
return [createPublicKey6(
|
|
80737
|
+
return [createPublicKey6(readFileSync121(f))];
|
|
80499
80738
|
} catch {
|
|
80500
80739
|
return [];
|
|
80501
80740
|
}
|
|
@@ -80525,14 +80764,14 @@ function checkAttestation(jwt, expectedHash, given) {
|
|
|
80525
80764
|
}
|
|
80526
80765
|
function wallTamperProblem(receiptPath, receipt) {
|
|
80527
80766
|
const wall = receipt["wall"], files = Array.isArray(wall?.files) ? wall.files : [];
|
|
80528
|
-
const wallDir =
|
|
80767
|
+
const wallDir = join138(dirname53(receiptPath), "wall"), haveWallDir = existsSync96(wallDir);
|
|
80529
80768
|
for (const f of files) {
|
|
80530
80769
|
if (typeof f?.path !== "string" || typeof f.sha256 !== "string")
|
|
80531
80770
|
continue;
|
|
80532
|
-
const copy =
|
|
80771
|
+
const copy = join138(wallDir, basename35(f.path));
|
|
80533
80772
|
let cur;
|
|
80534
80773
|
try {
|
|
80535
|
-
cur = createHash39("sha256").update(
|
|
80774
|
+
cur = createHash39("sha256").update(readFileSync121(copy)).digest("hex");
|
|
80536
80775
|
} catch {
|
|
80537
80776
|
if (haveWallDir)
|
|
80538
80777
|
return `sealed Wall file ${basename35(f.path)} is missing from the run's wall directory: it was deleted after the seal`;
|
|
@@ -80559,10 +80798,10 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
80559
80798
|
const claims = st2 !== null && typeof st2 === "object" && Object.keys(st2).length > 0;
|
|
80560
80799
|
return claims ? "the receipt records stages but binds the empty-log hash, so no events.jsonl can back it (missing, empty or non-empty); the receipt is forged or was sealed without a log. Re-run the task to produce a fresh receipt" : null;
|
|
80561
80800
|
}
|
|
80562
|
-
const path =
|
|
80801
|
+
const path = join138(dirname53(receiptPath), "events.jsonl");
|
|
80563
80802
|
if (!existsSync96(path))
|
|
80564
80803
|
return "events.jsonl is missing";
|
|
80565
|
-
const raw2 =
|
|
80804
|
+
const raw2 = readFileSync121(path, "utf8"), events2 = readEvents(path), all = raw2.split(`
|
|
80566
80805
|
`).filter((l) => l.trim() !== ""), lines2 = tornTail(raw2) ? all.slice(0, -1) : all;
|
|
80567
80806
|
if (events2.length !== lines2.length || events2.some((e10, i) => e10.seq !== i))
|
|
80568
80807
|
return "events.jsonl has a forged, edited or missing line";
|
|
@@ -80582,7 +80821,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
80582
80821
|
return h10.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
|
|
80583
80822
|
}
|
|
80584
80823
|
function checkLogSeal(receiptPath, hash, kid, given) {
|
|
80585
|
-
const path =
|
|
80824
|
+
const path = join138(dirname53(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e10) => e10.type === "run.completed");
|
|
80586
80825
|
if (!events2.some((e10) => e10.type === "receipt.sealed" && e10.data["receipt_sha256"] === hash))
|
|
80587
80826
|
return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
|
|
80588
80827
|
if (done < 0)
|
|
@@ -80590,7 +80829,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
|
|
|
80590
80829
|
const seal = events2[done + 1], d = seal?.type === "log.sealed" ? seal.data : null;
|
|
80591
80830
|
if (!d)
|
|
80592
80831
|
return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
|
|
80593
|
-
const lines2 =
|
|
80832
|
+
const lines2 = readFileSync121(path, "utf8").split(`
|
|
80594
80833
|
`).filter((l) => l.trim() !== ""), sha7 = createHash39("sha256").update(lines2.slice(0, done + 1).join(`
|
|
80595
80834
|
`) + `
|
|
80596
80835
|
`).digest("hex");
|
|
@@ -80604,7 +80843,7 @@ async function verifyReceipt(receiptPath, deps = {}) {
|
|
|
80604
80843
|
return { verdict: "UNCHECKED", reasons: [`receipt not found: ${receiptPath}`] };
|
|
80605
80844
|
let receipt;
|
|
80606
80845
|
try {
|
|
80607
|
-
receipt = JSON.parse((deps.read ?? ((p) =>
|
|
80846
|
+
receipt = JSON.parse((deps.read ?? ((p) => readFileSync121(p, "utf8")))(receiptPath));
|
|
80608
80847
|
} catch {
|
|
80609
80848
|
return { verdict: "UNCHECKED", reasons: ["receipt.json is not valid JSON"] };
|
|
80610
80849
|
}
|
|
@@ -80699,7 +80938,7 @@ function sealCompositeCmd(runDir) {
|
|
|
80699
80938
|
`), 2;
|
|
80700
80939
|
}
|
|
80701
80940
|
const hash = compositeHash(body), sig = signReceipt(body.run_id, hash);
|
|
80702
|
-
const out3 = { ...body, composite_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } }, path =
|
|
80941
|
+
const out3 = { ...body, composite_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } }, path = join138(runDir, "composite.json");
|
|
80703
80942
|
writeFileSync69(`${path}.tmp`, JSON.stringify(out3, null, 2) + `
|
|
80704
80943
|
`);
|
|
80705
80944
|
renameSync23(`${path}.tmp`, path);
|
|
@@ -80715,7 +80954,7 @@ ${compositeLines(out3).join(`
|
|
|
80715
80954
|
function independentLine(receiptPath) {
|
|
80716
80955
|
let checks = [];
|
|
80717
80956
|
try {
|
|
80718
|
-
const c = JSON.parse(
|
|
80957
|
+
const c = JSON.parse(readFileSync121(receiptPath, "utf8")).checks;
|
|
80719
80958
|
if (Array.isArray(c))
|
|
80720
80959
|
checks = c;
|
|
80721
80960
|
} catch {}
|
|
@@ -80725,6 +80964,14 @@ function independentLine(receiptPath) {
|
|
|
80725
80964
|
const k3 = pass.filter((c) => isExecutedProof(c) && (c.provenance === "exogenous" || c.provenance === "independent")).length, m = pass.filter((c) => c.provenance === "agent_authored" || c.provenance === "llm_judge").length;
|
|
80726
80965
|
return { line: `agent-independent: ${k3} of ${pass.length} passing checks (wall/holdout/pre-existing/static/probe); advisory: ${m}`, k: k3, of: pass.length };
|
|
80727
80966
|
}
|
|
80967
|
+
function signedRunIdProblem(receiptPath, runId2) {
|
|
80968
|
+
try {
|
|
80969
|
+
const r = JSON.parse(readFileSync121(receiptPath, "utf8")), s = r["run_id"];
|
|
80970
|
+
return isEnvelope(r) || typeof s !== "string" || s === runId2 ? null : `receipt run_id ${JSON.stringify(printable(s).slice(0, 128))} does not match the run id ${JSON.stringify(runId2)} it was found under (a sealed run copied under another id)`;
|
|
80971
|
+
} catch {
|
|
80972
|
+
return null;
|
|
80973
|
+
}
|
|
80974
|
+
}
|
|
80728
80975
|
async function verifyMain(args, deps, rec2) {
|
|
80729
80976
|
const allowUnsigned = args.includes("--allow-unsigned") || process.env["LOKI_VERIFY_ALLOW_UNSIGNED"] === "1";
|
|
80730
80977
|
const exportDsse = args.includes("--export-dsse"), requireExo = args.includes("--require-exogenous") || process.env["LOKI_VERIFY_REQUIRE_EXOGENOUS"] === "1";
|
|
@@ -80772,20 +81019,20 @@ ${/^(unknown option|expected at most one)/.test(pk2.error) ? `Usage: loki verify
|
|
|
80772
81019
|
args = pk2.args;
|
|
80773
81020
|
if (pk2.pubkey)
|
|
80774
81021
|
deps = { ...deps, pubkey: pk2.pubkey };
|
|
80775
|
-
const runsRoot2 = deps.runsRoot ??
|
|
81022
|
+
const runsRoot2 = deps.runsRoot ?? join138(lokiDir(), "runs");
|
|
80776
81023
|
const runId2 = args[0] ?? latestRunId(runsRoot2) ?? undefined;
|
|
80777
81024
|
if (!runId2)
|
|
80778
81025
|
return process.stderr.write(`loki verify: no runs found
|
|
80779
81026
|
`), 66;
|
|
80780
81027
|
const isFile = existsSync96(runId2) && statSync37(runId2).isFile();
|
|
80781
81028
|
const isPath = isFile || /[\\/]/.test(runId2) || runId2.endsWith(".json");
|
|
80782
|
-
const receiptPath = isPath ? runId2 :
|
|
81029
|
+
const receiptPath = isPath ? runId2 : join138(runsRoot2, runId2, "receipt.json");
|
|
80783
81030
|
const byRunId = !isPath;
|
|
80784
81031
|
rec2.runId = runId2;
|
|
80785
81032
|
rec2.receiptPath = receiptPath;
|
|
80786
81033
|
if (exportDsse)
|
|
80787
81034
|
return exportDsseReceipt({ receiptPath, runId: byRunId ? runId2 : null, deps, verify: verifyReceipt, key: loadSigningKey(false), kidOf: kidOf2 });
|
|
80788
|
-
const bad = byRunId ? runIdGuard(receiptPath, runId2) : null;
|
|
81035
|
+
const bad = byRunId ? runIdGuard(receiptPath, runId2) ?? signedRunIdProblem(receiptPath, runId2) : null;
|
|
80789
81036
|
if (bad)
|
|
80790
81037
|
return rec2.verdict = "TAMPERED", rec2.reasons = [bad], process.stdout.write(`run: ${runId2}
|
|
80791
81038
|
verdict: TAMPERED
|
|
@@ -80795,7 +81042,7 @@ verdict: TAMPERED
|
|
|
80795
81042
|
if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
|
|
80796
81043
|
const d = (() => {
|
|
80797
81044
|
try {
|
|
80798
|
-
return sealDrift(receiptPath, JSON.parse(
|
|
81045
|
+
return sealDrift(receiptPath, JSON.parse(readFileSync121(receiptPath, "utf8")));
|
|
80799
81046
|
} catch {
|
|
80800
81047
|
return null;
|
|
80801
81048
|
}
|
|
@@ -80808,7 +81055,7 @@ verdict: TAMPERED
|
|
|
80808
81055
|
{
|
|
80809
81056
|
const id2 = (() => {
|
|
80810
81057
|
try {
|
|
80811
|
-
const r = JSON.parse(
|
|
81058
|
+
const r = JSON.parse(readFileSync121(receiptPath, "utf8"));
|
|
80812
81059
|
const j10 = r["verification"]?.jwt;
|
|
80813
81060
|
const k3 = result.verdict === "VERIFIED" && typeof j10 === "string" ? JSON.parse(Buffer.from(j10.split(".")[0], "base64url").toString()).kid : null;
|
|
80814
81061
|
return { kid: typeof k3 === "string" ? k3 : null, head: typeof r["head_sha"] === "string" ? r["head_sha"] : null, verdict: typeof r["verdict"] === "string" ? r["verdict"] : null, run: typeof r["run_id"] === "string" ? r["run_id"] : null };
|
|
@@ -80826,7 +81073,7 @@ verdict: TAMPERED
|
|
|
80826
81073
|
if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
|
|
80827
81074
|
const outcome = (() => {
|
|
80828
81075
|
try {
|
|
80829
|
-
return outcomeOf2(JSON.parse(
|
|
81076
|
+
return outcomeOf2(JSON.parse(readFileSync121(receiptPath, "utf8")));
|
|
80830
81077
|
} catch {
|
|
80831
81078
|
return "UNREADABLE";
|
|
80832
81079
|
}
|
|
@@ -80840,6 +81087,11 @@ verdict: NOT VERIFIED (run outcome ${outcome}; receipt integrity ${result.verdic
|
|
|
80840
81087
|
return 4;
|
|
80841
81088
|
}
|
|
80842
81089
|
}
|
|
81090
|
+
if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
|
|
81091
|
+
const note = wallNotComparedNote(receiptPath);
|
|
81092
|
+
if (note)
|
|
81093
|
+
result = { ...result, reasons: [...result.reasons, note] };
|
|
81094
|
+
}
|
|
80843
81095
|
rec2.verdict = result.verdict;
|
|
80844
81096
|
rec2.reasons = result.reasons;
|
|
80845
81097
|
rec2.receiptSha256 = result.receiptSha256 ?? null;
|
|
@@ -80855,7 +81107,7 @@ verdict: ${result.verdict}
|
|
|
80855
81107
|
`);
|
|
80856
81108
|
if (result.verdict !== "TAMPERED")
|
|
80857
81109
|
try {
|
|
80858
|
-
const r = JSON.parse(
|
|
81110
|
+
const r = JSON.parse(readFileSync121(receiptPath, "utf8"));
|
|
80859
81111
|
if (isComposite(r))
|
|
80860
81112
|
for (const l of compositeLines(r))
|
|
80861
81113
|
process.stdout.write(`${l}
|
|
@@ -80913,8 +81165,8 @@ var init_verify_cmd = __esm(() => {
|
|
|
80913
81165
|
});
|
|
80914
81166
|
|
|
80915
81167
|
// src/server/app.ts
|
|
80916
|
-
import { existsSync as existsSync98, readFileSync as
|
|
80917
|
-
import { join as
|
|
81168
|
+
import { existsSync as existsSync98, readFileSync as readFileSync124, statSync as statSync38 } from "fs";
|
|
81169
|
+
import { join as join141, resolve as resolve40, sep as sep23 } from "path";
|
|
80918
81170
|
|
|
80919
81171
|
// node_modules/hono/dist/request/constants.js
|
|
80920
81172
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -91225,9 +91477,9 @@ function mount20(ctx) {
|
|
|
91225
91477
|
}
|
|
91226
91478
|
|
|
91227
91479
|
// src/server/routes/verify.ts
|
|
91228
|
-
import { readFileSync as
|
|
91480
|
+
import { readFileSync as readFileSync122, realpathSync as realpathSync36 } from "fs";
|
|
91229
91481
|
import { createPublicKey as createPublicKey7 } from "crypto";
|
|
91230
|
-
import { join as
|
|
91482
|
+
import { join as join139, sep as sep22 } from "path";
|
|
91231
91483
|
init_verify_cmd();
|
|
91232
91484
|
init_seal();
|
|
91233
91485
|
init_receipt_dsse();
|
|
@@ -91254,11 +91506,11 @@ function mount21(ctx) {
|
|
|
91254
91506
|
return done(404, "receipt not available", "not_found");
|
|
91255
91507
|
let runDir, file;
|
|
91256
91508
|
try {
|
|
91257
|
-
const root = realpathSync36(
|
|
91258
|
-
runDir = realpathSync36(
|
|
91259
|
-
if (runDir !==
|
|
91509
|
+
const root = realpathSync36(join139(repo.p, ".loki", "runs"));
|
|
91510
|
+
runDir = realpathSync36(join139(root, run2));
|
|
91511
|
+
if (runDir !== join139(root, run2))
|
|
91260
91512
|
return done(404, "receipt not found", "not_found");
|
|
91261
|
-
file = realpathSync36(
|
|
91513
|
+
file = realpathSync36(join139(runDir, "receipt.json"));
|
|
91262
91514
|
} catch {
|
|
91263
91515
|
return done(404, "receipt not found", "not_found");
|
|
91264
91516
|
}
|
|
@@ -91277,7 +91529,7 @@ function mount21(ctx) {
|
|
|
91277
91529
|
sha7 = r.receiptSha256 ?? null;
|
|
91278
91530
|
}
|
|
91279
91531
|
try {
|
|
91280
|
-
outcome = outcomeOf2(JSON.parse(
|
|
91532
|
+
outcome = outcomeOf2(JSON.parse(readFileSync122(file, "utf8")));
|
|
91281
91533
|
} catch {
|
|
91282
91534
|
outcome = "UNREADABLE";
|
|
91283
91535
|
}
|
|
@@ -91339,8 +91591,8 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
|
|
|
91339
91591
|
}
|
|
91340
91592
|
|
|
91341
91593
|
// src/server/legacy/shim.ts
|
|
91342
|
-
import { existsSync as existsSync97, readFileSync as
|
|
91343
|
-
import { join as
|
|
91594
|
+
import { existsSync as existsSync97, readFileSync as readFileSync123 } from "fs";
|
|
91595
|
+
import { join as join140 } from "path";
|
|
91344
91596
|
|
|
91345
91597
|
// src/server/legacy/routes.ts
|
|
91346
91598
|
var LEGACY_ROUTES = [
|
|
@@ -91718,10 +91970,10 @@ var logged = new Set;
|
|
|
91718
91970
|
var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
|
|
91719
91971
|
var NOT_SUPPORTED = "not yet supported by the Control Plane";
|
|
91720
91972
|
var repoVersion = () => {
|
|
91721
|
-
for (const f of [
|
|
91973
|
+
for (const f of [join140(import.meta.dir, "../../../../../VERSION")]) {
|
|
91722
91974
|
try {
|
|
91723
91975
|
if (existsSync97(f))
|
|
91724
|
-
return
|
|
91976
|
+
return readFileSync123(f, "utf8").trim();
|
|
91725
91977
|
} catch {}
|
|
91726
91978
|
}
|
|
91727
91979
|
return "unknown";
|
|
@@ -91903,7 +92155,7 @@ function legacyShim(opts) {
|
|
|
91903
92155
|
|
|
91904
92156
|
// src/server/app.ts
|
|
91905
92157
|
var MAX_BODY2 = 1e6;
|
|
91906
|
-
var defaultUiDir = () => [
|
|
92158
|
+
var defaultUiDir = () => [join141(import.meta.dir, "../../ui/dist"), join141(import.meta.dir, "../ui/dist")].find((d) => existsSync98(join141(d, "index.html")));
|
|
91907
92159
|
function createApp(opts) {
|
|
91908
92160
|
const uiDir = opts.uiDir ?? defaultUiDir();
|
|
91909
92161
|
const { db: db2, sqlite } = openDb(opts.dbPath);
|
|
@@ -91932,10 +92184,10 @@ function createApp(opts) {
|
|
|
91932
92184
|
await next();
|
|
91933
92185
|
});
|
|
91934
92186
|
const readInstalled = () => {
|
|
91935
|
-
for (const f of [process.env.LOKI_VERSION_FILE,
|
|
92187
|
+
for (const f of [process.env.LOKI_VERSION_FILE, join141(import.meta.dir, "../../../../VERSION")]) {
|
|
91936
92188
|
try {
|
|
91937
92189
|
if (f)
|
|
91938
|
-
return
|
|
92190
|
+
return readFileSync124(f, "utf8").trim() || "unknown";
|
|
91939
92191
|
} catch {}
|
|
91940
92192
|
}
|
|
91941
92193
|
return "unknown";
|
|
@@ -92050,7 +92302,7 @@ function createApp(opts) {
|
|
|
92050
92302
|
return new Response(Bun.file(f));
|
|
92051
92303
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
92052
92304
|
return c.json({ error: "not found" }, 404);
|
|
92053
|
-
return new Response(Bun.file(
|
|
92305
|
+
return new Response(Bun.file(join141(root, "index.html")));
|
|
92054
92306
|
});
|
|
92055
92307
|
return { app, db: db2, close: () => {
|
|
92056
92308
|
clearInterval(reconciler);
|
|
@@ -92059,9 +92311,9 @@ function createApp(opts) {
|
|
|
92059
92311
|
}
|
|
92060
92312
|
|
|
92061
92313
|
// src/server/serve.ts
|
|
92062
|
-
var
|
|
92063
|
-
if (
|
|
92064
|
-
console.error(
|
|
92314
|
+
var refusal2 = bindRefusal(process.env);
|
|
92315
|
+
if (refusal2) {
|
|
92316
|
+
console.error(refusal2);
|
|
92065
92317
|
process.exit(2);
|
|
92066
92318
|
}
|
|
92067
92319
|
var warning = insecureBindWarning(process.env);
|