loki-mode 11.81.1 → 11.82.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/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +1217 -1217
- 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 +616 -539
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-Vc1xmG5S.js → AdminPage-BDwJkrfT.js} +1 -1
- package/web-app/dist/assets/{Avatar-DpDwMCRf.js → Avatar-Bjb7tmLG.js} +1 -1
- package/web-app/dist/assets/{Badge-Db74zT9q.js → Badge-BYWNt-lF.js} +1 -1
- package/web-app/dist/assets/{Button-GehhhJSq.js → Button-CEKS68UU.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BGdBtPaF.js → CockpitPage-fAeYAB91.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DpnZuvk5.js → ComparePage-DRiaB5aq.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DzEqEovi.js → ErrorBoundary-C_ts0y6d.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-Cw7HQjzr.js → EvidenceReceiptPanel-CAM2bOHh.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-Cxpn_s6S.js → GitHubIssuesPanel-eTpdboWA.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-DCdf7lvR.js → GitHubPRsPanel-ufk1eqQm.js} +1 -1
- package/web-app/dist/assets/{HomePage-DnVetpJ_.js → HomePage-D8Cg8c0d.js} +2 -2
- package/web-app/dist/assets/{LoginPage-8VjdvfM3.js → LoginPage-DWVzDN9I.js} +1 -1
- package/web-app/dist/assets/{MagicPage-CP5dgazx.js → MagicPage-bmS03_51.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DOpoS7e3.js → MetricsPage-ffCkhsSV.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-COzCrnS6.js → NotFoundPage-CqluOiCR.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-DO4l10Ay.js → ProjectPage-D5XbTRQt.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C0tYUwpA.js → ProjectsPage-BK4mJziQ.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CocOl0Br.js → SettingsPage-BoH4mS-n.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-D1JXy7Uh.js → ShowcasePage-B7xHXyht.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-J2oNgHg2.js → SystemSettingsPage-BFyzSmVR.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-CcE2AFtg.js → TeamsPage-DkuTf7Pm.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DYXxELhl.js → TemplatesPage-DqC4qY5U.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DNQJnu5M.js → TerminalOutput-CiERRLAB.js} +1 -1
- package/web-app/dist/assets/{activity-BZxgQZSK.js → activity-BBdRZTad.js} +1 -1
- package/web-app/dist/assets/{bell-BgmfzWCz.js → bell-CvIl2nxi.js} +1 -1
- package/web-app/dist/assets/{bot-BGir-bWC.js → bot-CWMB2JQE.js} +1 -1
- package/web-app/dist/assets/{check-CveMRLRE.js → check-CSVvxOtd.js} +1 -1
- package/web-app/dist/assets/{chevron-left-Dxd2H6to.js → chevron-left-B7MXj-CB.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CBmik7wR.js → circle-alert-DlegpSSz.js} +1 -1
- package/web-app/dist/assets/{clock-BOKNTHCd.js → clock-CO7alYth.js} +1 -1
- package/web-app/dist/assets/{cloud-CQy11uYO.js → cloud-CmCwC9tD.js} +1 -1
- package/web-app/dist/assets/{code-xml-G-3Gc_8h.js → code-xml-CttGX_KN.js} +1 -1
- package/web-app/dist/assets/{database-DgDzuYJ_.js → database-BFoEsl1d.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-Lp9JyaRP.js → dollar-sign-CsX8E6iv.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BO2cQzOV.js → file-code-corner-AD_LP7Sr.js} +1 -1
- package/web-app/dist/assets/{file-plus-DH7lzils.js → file-plus-D1lrSELb.js} +1 -1
- package/web-app/dist/assets/{globe-BfSvGNE3.js → globe-BO79vdlK.js} +1 -1
- package/web-app/dist/assets/{hammer-DnCBfcc3.js → hammer-ByRAYTmN.js} +1 -1
- package/web-app/dist/assets/{index-BQo5YwJS.js → index-Dhf-7-HA.js} +3 -3
- package/web-app/dist/assets/{layers-BrW-wRnL.js → layers-Ch8twnaQ.js} +1 -1
- package/web-app/dist/assets/{loader-circle-BMGt1Kfa.js → loader-circle-jCLtMahM.js} +1 -1
- package/web-app/dist/assets/{lock-65KUUGOn.js → lock-DYipaQub.js} +1 -1
- package/web-app/dist/assets/{package-BuhQfrbf.js → package-DTU2eDJk.js} +1 -1
- package/web-app/dist/assets/{plus-CCqniqNu.js → plus-Dwtg85R2.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CaTVoaT8.js → refresh-cw-B2BZn7xv.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-G73Ulpkj.js → rotate-ccw-BnDgsF2l.js} +1 -1
- package/web-app/dist/assets/{scroll-text-Bl6ByvVU.js → scroll-text-CHcWlkC1.js} +1 -1
- package/web-app/dist/assets/{server-UW4cgj8y.js → server-DGbuh4v5.js} +1 -1
- package/web-app/dist/assets/{shield-alert-C0FwCrI5.js → shield-alert-BGxG6i1x.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-ApOqvOwV.js → thumbs-up-C4_XsjwR.js} +1 -1
- package/web-app/dist/assets/{trash-2-BsQzJxqd.js → trash-2-CXkZKiJ3.js} +1 -1
- package/web-app/dist/assets/{trending-down-mfvmwkOt.js → trending-down-Ca8gOfqE.js} +1 -1
- package/web-app/dist/assets/{trending-up-DAE5_Gqc.js → trending-up-BwTtd3Ft.js} +1 -1
- package/web-app/dist/assets/{upload-Ci5-pITX.js → upload-DK47bkj8.js} +1 -1
- package/web-app/dist/assets/{usePolling-DdLg3S71.js → usePolling-CrEvFOnC.js} +1 -1
- package/web-app/dist/assets/{user-vdRHG5fO.js → user-Ck5fqwRB.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -65318,27 +65318,102 @@ var init_select = __esm(() => {
|
|
|
65318
65318
|
RANK_LABELS = ["wallPasses", "deterministicFails", "passesInS", "flakyInS", "lintFails", "diffLines", "index"];
|
|
65319
65319
|
});
|
|
65320
65320
|
|
|
65321
|
+
// ../../loki-ts/src/features/dependents.ts
|
|
65322
|
+
import { readFileSync as readFileSync73 } from "fs";
|
|
65323
|
+
import { dirname as dirname33, join as join82, normalize as normalize5 } from "path";
|
|
65324
|
+
function importTargets(rel, text3) {
|
|
65325
|
+
const out3 = [], dir = dirname33(rel);
|
|
65326
|
+
if (JS2.test(rel))
|
|
65327
|
+
for (const m of text3.matchAll(JS_SPEC_RE)) {
|
|
65328
|
+
const spec = m[1] ?? "";
|
|
65329
|
+
if (!spec.startsWith("."))
|
|
65330
|
+
continue;
|
|
65331
|
+
const p = posix3(join82(dir, spec)), stem = p.replace(/\.[cm]?[jt]sx?$/, "");
|
|
65332
|
+
out3.push(p, ...JS_EXT2.flatMap((e10) => [stem + e10, `${p}/index${e10}`]));
|
|
65333
|
+
}
|
|
65334
|
+
else if (PY3.test(rel)) {
|
|
65335
|
+
const add3 = (dots, mod, names) => {
|
|
65336
|
+
const up2 = dots > 0 ? join82(dir, ...Array(dots - 1).fill("..")) : "", roots = dots > 0 ? [up2] : [".", dir], path = mod.split(".").filter(Boolean).join("/");
|
|
65337
|
+
for (const r of roots) {
|
|
65338
|
+
const b = join82(r, path);
|
|
65339
|
+
if (path)
|
|
65340
|
+
out3.push(...pyMod(posix3(b)).map(posix3));
|
|
65341
|
+
for (const n10 of names)
|
|
65342
|
+
out3.push(...pyMod(posix3(join82(b, n10))));
|
|
65343
|
+
}
|
|
65344
|
+
};
|
|
65345
|
+
for (const m of text3.matchAll(PY_FROM)) {
|
|
65346
|
+
const dots = /^\.*/.exec(m[1])[0].length;
|
|
65347
|
+
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)));
|
|
65348
|
+
}
|
|
65349
|
+
for (const m of text3.matchAll(PY_IMP))
|
|
65350
|
+
for (const part of m[1].split(","))
|
|
65351
|
+
add3(0, part.trim().split(/\s+as\s+/)[0], []);
|
|
65352
|
+
}
|
|
65353
|
+
return out3;
|
|
65354
|
+
}
|
|
65355
|
+
function dependentTests(repoDir, map, changed, already) {
|
|
65356
|
+
const chg = new Set(changed.map(posix3).filter((f) => JS2.test(f) || PY3.test(f))), none = { tests: [], dropped: 0, truncated: false };
|
|
65357
|
+
if (chg.size === 0)
|
|
65358
|
+
return none;
|
|
65359
|
+
const isTest = new Set(map.tests.map((t) => t.path)), have = new Set(already.map((t) => t.path)), t02 = Date.now();
|
|
65360
|
+
let bytes = 0, truncated = false;
|
|
65361
|
+
const deps = new Set;
|
|
65362
|
+
for (const rel of listProjectFiles(repoDir)) {
|
|
65363
|
+
if (!(JS2.test(rel) || PY3.test(rel)) || isTest.has(rel) || chg.has(rel))
|
|
65364
|
+
continue;
|
|
65365
|
+
if (bytes > SCAN_MAX_BYTES || Date.now() - t02 > SCAN_MAX_MS) {
|
|
65366
|
+
truncated = true;
|
|
65367
|
+
break;
|
|
65368
|
+
}
|
|
65369
|
+
const text3 = read2(repoDir, rel);
|
|
65370
|
+
bytes += text3.length;
|
|
65371
|
+
if (importsAny(text3, rel, chg))
|
|
65372
|
+
deps.add(rel);
|
|
65373
|
+
}
|
|
65374
|
+
if (deps.size === 0)
|
|
65375
|
+
return { ...none, truncated };
|
|
65376
|
+
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));
|
|
65377
|
+
return { tests: all.slice(0, MAX_DEPENDENT_TESTS), dropped: Math.max(0, all.length - MAX_DEPENDENT_TESTS), truncated };
|
|
65378
|
+
}
|
|
65379
|
+
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) => {
|
|
65380
|
+
try {
|
|
65381
|
+
return readFileSync73(join82(repoDir, rel), "utf8").slice(0, FILE_MAX_BYTES);
|
|
65382
|
+
} catch {
|
|
65383
|
+
return "";
|
|
65384
|
+
}
|
|
65385
|
+
}, 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}`] : []];
|
|
65386
|
+
var init_dependents = __esm(() => {
|
|
65387
|
+
init_safe_git();
|
|
65388
|
+
init_test_file_text();
|
|
65389
|
+
JS2 = /\.(?:[cm]?[jt]sx?)$/;
|
|
65390
|
+
PY3 = /\.py$/;
|
|
65391
|
+
JS_EXT2 = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
65392
|
+
PY_FROM = /^[ \t]*from[ \t]+(\.*[\w.]*)[ \t]+import[ \t]+(\([^)]*\)|[^\n#]+)/gm;
|
|
65393
|
+
PY_IMP = /^[ \t]*import[ \t]+([\w., \t]+)/gm;
|
|
65394
|
+
});
|
|
65395
|
+
|
|
65321
65396
|
// ../../loki-ts/src/util/app_probe.ts
|
|
65322
65397
|
import { spawnSync as spawnSync9 } from "child_process";
|
|
65323
|
-
import { existsSync as existsSync56, mkdirSync as mkdirSync40, readFileSync as
|
|
65324
|
-
import { join as
|
|
65398
|
+
import { existsSync as existsSync56, mkdirSync as mkdirSync40, readFileSync as readFileSync74, renameSync as renameSync18, writeFileSync as writeFileSync38 } from "fs";
|
|
65399
|
+
import { join as join83 } from "path";
|
|
65325
65400
|
function readJson5(p) {
|
|
65326
65401
|
try {
|
|
65327
|
-
const v3 = JSON.parse(
|
|
65402
|
+
const v3 = JSON.parse(readFileSync74(p, "utf8"));
|
|
65328
65403
|
return v3 && typeof v3 === "object" ? v3 : null;
|
|
65329
65404
|
} catch {
|
|
65330
65405
|
return null;
|
|
65331
65406
|
}
|
|
65332
65407
|
}
|
|
65333
65408
|
function stopApp(repoDir, opts = {}) {
|
|
65334
|
-
const runner = opts.runnerPath ??
|
|
65335
|
-
if (!existsSync56(runner) || !existsSync56(
|
|
65409
|
+
const runner = opts.runnerPath ?? join83(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
65410
|
+
if (!existsSync56(runner) || !existsSync56(join83(repoDir, ".loki", "app-runner", "app.pid")))
|
|
65336
65411
|
return;
|
|
65337
65412
|
spawnSync9("bash", ["-c", STOP, "app-probe", repoDir, runner], { cwd: repoDir, env: plainTestEnv(), timeout: opts.timeoutMs ?? 60000, killSignal: "SIGKILL", stdio: "ignore" });
|
|
65338
65413
|
}
|
|
65339
65414
|
async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
65340
|
-
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ??
|
|
65341
|
-
const dir =
|
|
65415
|
+
const timeoutMs = opts.timeoutMs ?? 60000, runner = opts.runnerPath ?? join83(REPO_ROOT, "autonomy", "app-runner.sh");
|
|
65416
|
+
const dir = join83(repoDir, ".loki", "app-runner"), checks = [];
|
|
65342
65417
|
const t02 = Date.now();
|
|
65343
65418
|
const mk3 = (name, result, reason) => ({ name, cmd: "autonomy/app-runner.sh", result, duration_s: (Date.now() - t02) / 1000, reason });
|
|
65344
65419
|
const sh3 = (script) => {
|
|
@@ -65356,9 +65431,9 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65356
65431
|
return { checks, pid, url };
|
|
65357
65432
|
}
|
|
65358
65433
|
const ir2 = Number(m[1]), sr2 = Number(m[2]), hr = Number(m[3]), noApp = m[4] === "1";
|
|
65359
|
-
const pidTxt = existsSync56(
|
|
65434
|
+
const pidTxt = existsSync56(join83(dir, "app.pid")) ? readFileSync74(join83(dir, "app.pid"), "utf8").trim() : "";
|
|
65360
65435
|
pid = /^\d+$/.test(pidTxt) && sr2 >= 0 ? Number(pidTxt) : null;
|
|
65361
|
-
const st2 = readJson5(
|
|
65436
|
+
const st2 = readJson5(join83(dir, "state.json"));
|
|
65362
65437
|
url = typeof st2?.["url"] === "string" ? st2["url"] : null;
|
|
65363
65438
|
if (sr2 < 0) {
|
|
65364
65439
|
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 +65444,7 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65369
65444
|
return { checks, pid, url };
|
|
65370
65445
|
}
|
|
65371
65446
|
checks.push(mk3("app boot", "pass", "app process started"));
|
|
65372
|
-
const health = readJson5(
|
|
65447
|
+
const health = readJson5(join83(dir, "health.json"));
|
|
65373
65448
|
checks.push(hr === 0 && health?.["ok"] === true ? mk3("http probe", "pass", "health.json ok") : mk3("http probe", "fail", "app-runner health check failed"));
|
|
65374
65449
|
if (opts.specText !== undefined && checks[1]?.result === "pass" && url)
|
|
65375
65450
|
checks.push(await functionalVerify(opts, url, dir, lokiDir2, timeoutMs));
|
|
@@ -65382,10 +65457,10 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
|
|
|
65382
65457
|
async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
65383
65458
|
const t02 = Date.now();
|
|
65384
65459
|
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 ??
|
|
65460
|
+
const py2 = await findPython3(), script = opts.verifyPath ?? join83(REPO_ROOT, "autonomy", "lib", "functional-verify.py");
|
|
65386
65461
|
if (!py2 || !existsSync56(script))
|
|
65387
65462
|
return res("not_run", "python3 or functional-verify.py unavailable");
|
|
65388
|
-
const specFile =
|
|
65463
|
+
const specFile = join83(dir, "spec.txt");
|
|
65389
65464
|
writeFileSync38(specFile, opts.specText ?? "");
|
|
65390
65465
|
const r = spawnSync9(py2, ["-I", script, specFile, url], { env: plainTestEnv(), encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
|
|
65391
65466
|
let out3 = null;
|
|
@@ -65397,11 +65472,11 @@ async function functionalVerify(opts, url, dir, lokiDir2, timeoutMs) {
|
|
|
65397
65472
|
}
|
|
65398
65473
|
if (!out3 || r.status !== 0)
|
|
65399
65474
|
return res("not_run", "functional harness produced no result");
|
|
65400
|
-
const q10 =
|
|
65475
|
+
const q10 = join83(lokiDir2, "quality");
|
|
65401
65476
|
mkdirSync40(q10, { recursive: true });
|
|
65402
|
-
const tmp =
|
|
65477
|
+
const tmp = join83(q10, `functional-results.json.tmp.${process.pid}`);
|
|
65403
65478
|
writeFileSync38(tmp, JSON.stringify(out3, null, 2));
|
|
65404
|
-
renameSync18(tmp,
|
|
65479
|
+
renameSync18(tmp, join83(q10, "functional-results.json"));
|
|
65405
65480
|
const s = String(out3["functional_status"] ?? "inconclusive");
|
|
65406
65481
|
return res(s === "verified" ? "pass" : s === "failed" ? "fail" : "not_run", `functional_status ${s}`);
|
|
65407
65482
|
}
|
|
@@ -65433,15 +65508,15 @@ app_runner_stop >/dev/null 2>&1
|
|
|
65433
65508
|
});
|
|
65434
65509
|
|
|
65435
65510
|
// ../../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
|
|
65511
|
+
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
65512
|
import { randomBytes as randomBytes6 } from "crypto";
|
|
65438
65513
|
import { tmpdir as tmpdir12 } from "os";
|
|
65439
|
-
import { basename as basename22, dirname as
|
|
65514
|
+
import { basename as basename22, dirname as dirname34, join as join84, resolve as resolve28, sep as sep17 } from "path";
|
|
65440
65515
|
function fail(error) {
|
|
65441
65516
|
return { ok: false, findings: [], error };
|
|
65442
65517
|
}
|
|
65443
65518
|
async function runSecureScan(targetDir, opts = {}) {
|
|
65444
|
-
const script = opts.scriptPath ??
|
|
65519
|
+
const script = opts.scriptPath ?? join84(REPO_ROOT, "autonomy", "lib", "secure-scan.py");
|
|
65445
65520
|
if (!existsSync57(script))
|
|
65446
65521
|
return fail(`secure-scan script not found: ${script}`);
|
|
65447
65522
|
const py2 = await findPython3();
|
|
@@ -65485,12 +65560,12 @@ async function runSecureScan(targetDir, opts = {}) {
|
|
|
65485
65560
|
return fail(`secure-scan failed (exit ${res.exitCode}): ${tail2}`);
|
|
65486
65561
|
}
|
|
65487
65562
|
async function secureScanChanged(repoDir, changed, scriptPath) {
|
|
65488
|
-
const dir = mkdtempSync9(
|
|
65563
|
+
const dir = mkdtempSync9(join84(tmpdir12(), "loki-deep-secure-"));
|
|
65489
65564
|
try {
|
|
65490
65565
|
for (const f of changed)
|
|
65491
|
-
if (existsSync57(
|
|
65492
|
-
mkdirSync41(
|
|
65493
|
-
copyFileSync5(
|
|
65566
|
+
if (existsSync57(join84(repoDir, f)) && lstatSync23(join84(repoDir, f)).isFile()) {
|
|
65567
|
+
mkdirSync41(dirname34(join84(dir, f)), { recursive: true });
|
|
65568
|
+
copyFileSync5(join84(repoDir, f), join84(dir, f));
|
|
65494
65569
|
}
|
|
65495
65570
|
return await runSecureScan(dir, { ...scriptPath ? { scriptPath } : {}, timeoutMs: 60000 });
|
|
65496
65571
|
} finally {
|
|
@@ -65624,7 +65699,7 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65624
65699
|
const skipped2 = [];
|
|
65625
65700
|
for (const p of untracked2.split("\x00").filter(Boolean)) {
|
|
65626
65701
|
try {
|
|
65627
|
-
const st2 = statSync25(
|
|
65702
|
+
const st2 = statSync25(join84(repoDir, p));
|
|
65628
65703
|
if (!st2.isFile())
|
|
65629
65704
|
continue;
|
|
65630
65705
|
if (st2.size > MAX_ADDED_FILE_BYTES) {
|
|
@@ -65639,14 +65714,14 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65639
65714
|
continue;
|
|
65640
65715
|
}
|
|
65641
65716
|
const lines2 = new Map;
|
|
65642
|
-
|
|
65717
|
+
readFileSync75(join84(repoDir, p), "utf8").split(`
|
|
65643
65718
|
`).forEach((t, i) => lines2.set(i + 1, t));
|
|
65644
65719
|
added.set(p, lines2);
|
|
65645
65720
|
} catch {}
|
|
65646
65721
|
}
|
|
65647
65722
|
if (added.size === 0)
|
|
65648
65723
|
return { ok: true, findings: skipped2 };
|
|
65649
|
-
const mirror = mkdtempSync9(
|
|
65724
|
+
const mirror = mkdtempSync9(join84(tmpdir12(), "loki-secure-added-"));
|
|
65650
65725
|
try {
|
|
65651
65726
|
const root = resolve28(mirror) + sep17;
|
|
65652
65727
|
const chunkMap = new Map;
|
|
@@ -65692,12 +65767,12 @@ async function scanAddedLines(repoDir, opts = {}) {
|
|
|
65692
65767
|
chunks.push(cur);
|
|
65693
65768
|
const whole = chunks.length === 1;
|
|
65694
65769
|
for (const c of chunks) {
|
|
65695
|
-
const rel = whole ? p :
|
|
65770
|
+
const rel = whole ? p : join84(chunkRoot, String(chunkSeq++), basename22(p));
|
|
65696
65771
|
const out3 = whole ? dest : resolve28(mirror, rel);
|
|
65697
65772
|
if (!out3.startsWith(root))
|
|
65698
65773
|
break;
|
|
65699
65774
|
chunkMap.set(rel, { file: p, lines: c.orig });
|
|
65700
|
-
mkdirSync41(
|
|
65775
|
+
mkdirSync41(dirname34(out3), { recursive: true });
|
|
65701
65776
|
writeFileSync39(out3, c.body.join(`
|
|
65702
65777
|
`) + `
|
|
65703
65778
|
`);
|
|
@@ -65744,14 +65819,14 @@ var init_secure_scan = __esm(() => {
|
|
|
65744
65819
|
});
|
|
65745
65820
|
|
|
65746
65821
|
// ../../loki-ts/src/util/run_control.ts
|
|
65747
|
-
import { existsSync as existsSync58, readFileSync as
|
|
65748
|
-
import { join as
|
|
65822
|
+
import { existsSync as existsSync58, readFileSync as readFileSync76, renameSync as renameSync19, writeFileSync as writeFileSync40 } from "fs";
|
|
65823
|
+
import { join as join85 } from "path";
|
|
65749
65824
|
function readRunControl(runDir) {
|
|
65750
|
-
const p =
|
|
65825
|
+
const p = join85(runDir, RUN_CONTROL_FILE);
|
|
65751
65826
|
if (!existsSync58(p))
|
|
65752
65827
|
return null;
|
|
65753
65828
|
try {
|
|
65754
|
-
const a = JSON.parse(
|
|
65829
|
+
const a = JSON.parse(readFileSync76(p, "utf8")).action;
|
|
65755
65830
|
return typeof a === "string" && ACTIONS2.has(a) ? a : null;
|
|
65756
65831
|
} catch {
|
|
65757
65832
|
return null;
|
|
@@ -65809,8 +65884,8 @@ var init_run_control = __esm(() => {
|
|
|
65809
65884
|
});
|
|
65810
65885
|
|
|
65811
65886
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
65812
|
-
import { existsSync as existsSync59, readdirSync as readdirSync27, readFileSync as
|
|
65813
|
-
import { basename as basename23, dirname as
|
|
65887
|
+
import { existsSync as existsSync59, readdirSync as readdirSync27, readFileSync as readFileSync77 } from "fs";
|
|
65888
|
+
import { basename as basename23, dirname as dirname35, isAbsolute as isAbsolute15, join as join86, relative as relative16, resolve as resolve29 } from "path";
|
|
65814
65889
|
function parseJsonc(text3) {
|
|
65815
65890
|
let out3 = "", i = 0;
|
|
65816
65891
|
while (i < text3.length) {
|
|
@@ -65845,7 +65920,7 @@ function moduleOf(file, depth = 0) {
|
|
|
65845
65920
|
const ext = typeof j10.extends === "string" ? j10.extends : null;
|
|
65846
65921
|
if (!ext || !ext.startsWith("."))
|
|
65847
65922
|
return null;
|
|
65848
|
-
const next =
|
|
65923
|
+
const next = join86(dirname35(file), ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
65849
65924
|
return existsSync59(next) ? moduleOf(next, depth + 1) : null;
|
|
65850
65925
|
}
|
|
65851
65926
|
function readPackageConventions(pkgDir, runner = null) {
|
|
@@ -65857,13 +65932,13 @@ function readPackageConventions(pkgDir, runner = null) {
|
|
|
65857
65932
|
}
|
|
65858
65933
|
let packageType = null, tsModule = null;
|
|
65859
65934
|
for (const n10 of names) {
|
|
65860
|
-
const j10 = readJson6(
|
|
65935
|
+
const j10 = readJson6(join86(pkgDir, n10));
|
|
65861
65936
|
if (!j10)
|
|
65862
65937
|
continue;
|
|
65863
65938
|
if (packageType === null && typeof j10.type === "string" && typeof j10.name === "string")
|
|
65864
65939
|
packageType = j10.type;
|
|
65865
65940
|
if (tsModule === null && j10.compilerOptions !== undefined)
|
|
65866
|
-
tsModule = moduleOf(
|
|
65941
|
+
tsModule = moduleOf(join86(pkgDir, n10));
|
|
65867
65942
|
}
|
|
65868
65943
|
if (packageType === null && tsModule === null)
|
|
65869
65944
|
return null;
|
|
@@ -65969,13 +66044,13 @@ function vacuousCheck(fileName, content) {
|
|
|
65969
66044
|
function nearestPackageRoot(testDir, repoDir, fileName) {
|
|
65970
66045
|
const api = loadProjectApi(repoDir);
|
|
65971
66046
|
if (api)
|
|
65972
|
-
return siteFor(api, repoDir, relative16(repoDir,
|
|
66047
|
+
return siteFor(api, repoDir, relative16(repoDir, join86(testDir, fileName)))?.cwd ?? repoDir;
|
|
65973
66048
|
const shaped = (d) => {
|
|
65974
66049
|
try {
|
|
65975
66050
|
return readdirSync27(d).some((f) => {
|
|
65976
66051
|
if (!f.endsWith(".json"))
|
|
65977
66052
|
return false;
|
|
65978
|
-
const j10 = readJson6(
|
|
66053
|
+
const j10 = readJson6(join86(d, f));
|
|
65979
66054
|
return !!j10 && typeof j10.name === "string" && Object.keys(j10).length > 1;
|
|
65980
66055
|
});
|
|
65981
66056
|
} catch {
|
|
@@ -65983,8 +66058,8 @@ function nearestPackageRoot(testDir, repoDir, fileName) {
|
|
|
65983
66058
|
}
|
|
65984
66059
|
};
|
|
65985
66060
|
let pkg = testDir;
|
|
65986
|
-
while (pkg !== repoDir && pkg !==
|
|
65987
|
-
pkg =
|
|
66061
|
+
while (pkg !== repoDir && pkg !== dirname35(pkg) && !shaped(pkg))
|
|
66062
|
+
pkg = dirname35(pkg);
|
|
65988
66063
|
return pkg;
|
|
65989
66064
|
}
|
|
65990
66065
|
function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
@@ -66036,7 +66111,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66036
66111
|
};
|
|
66037
66112
|
const strayInTestDir = (out3) => {
|
|
66038
66113
|
const first = relative16(testDir, out3).split("/")[0];
|
|
66039
|
-
return !!first && first !== "__self__" && !existsSync59(
|
|
66114
|
+
return !!first && first !== "__self__" && !existsSync59(join86(testDir, first)) && [pkg, repoDir].some((d) => d !== testDir && existsSync59(join86(d, first)));
|
|
66040
66115
|
};
|
|
66041
66116
|
const scan = (cwd) => {
|
|
66042
66117
|
const vars = new Map, walk = new Set, taint = new Set, reports = new Map, created = [];
|
|
@@ -66051,7 +66126,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66051
66126
|
if (env)
|
|
66052
66127
|
return ev2(env[1], report);
|
|
66053
66128
|
if (e10 === "fileURLToPath(import.meta.url)" || e10 === "__filename")
|
|
66054
|
-
return
|
|
66129
|
+
return join86(testDir, "__self__");
|
|
66055
66130
|
const url = /^fileURLToPath\(new URL\((["'])([^"']*)\1\s*,\s*import\.meta\.url\)\)$/.exec(e10);
|
|
66056
66131
|
if (url)
|
|
66057
66132
|
return resolve29(testDir, url[2]);
|
|
@@ -66067,11 +66142,11 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66067
66142
|
if (args.some((a) => a === null))
|
|
66068
66143
|
return null;
|
|
66069
66144
|
if (call[1] === "dirname")
|
|
66070
|
-
return
|
|
66145
|
+
return dirname35(args[0]);
|
|
66071
66146
|
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(
|
|
66147
|
+
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
66148
|
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 ?
|
|
66149
|
+
reports.set(`${ln2}|${e10}`, { out: out3, rel: relative16(repoDir, out3), tail: viaWalk ? join86(...args.slice(1)) : undefined });
|
|
66075
66150
|
return out3;
|
|
66076
66151
|
};
|
|
66077
66152
|
for (const line2 of walkCode.split(`
|
|
@@ -66119,7 +66194,7 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66119
66194
|
const runs2 = [...new Set([pkg, repoDir])].map(scan);
|
|
66120
66195
|
const planned = (rel) => !!planText && rel.split("/").some((_, i, a) => {
|
|
66121
66196
|
const pre2 = a.slice(0, i + 1).join("/");
|
|
66122
|
-
return (i > 0 || a.length === 1) && !existsSync59(
|
|
66197
|
+
return (i > 0 || a.length === 1) && !existsSync59(join86(repoDir, pre2)) && new RegExp(`(?<![\\w-])${pre2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(planText);
|
|
66123
66198
|
});
|
|
66124
66199
|
const phantom = (r, created) => {
|
|
66125
66200
|
const rel = r.rel;
|
|
@@ -66129,11 +66204,11 @@ function phantomRepoPaths(content, fileName, testDir, repoDir, planText) {
|
|
|
66129
66204
|
const seen = (from) => {
|
|
66130
66205
|
let d = from;
|
|
66131
66206
|
for (let i = 0;i < 64; i++) {
|
|
66132
|
-
if (existsSync59(
|
|
66207
|
+
if (existsSync59(join86(d, r.tail)))
|
|
66133
66208
|
return true;
|
|
66134
|
-
if (d === repoDir || d ===
|
|
66209
|
+
if (d === repoDir || d === dirname35(d))
|
|
66135
66210
|
return false;
|
|
66136
|
-
d =
|
|
66211
|
+
d = dirname35(d);
|
|
66137
66212
|
}
|
|
66138
66213
|
return false;
|
|
66139
66214
|
};
|
|
@@ -66171,7 +66246,7 @@ function phantomReason(miss, repoFiles, testDir = "", pkgRoot = "") {
|
|
|
66171
66246
|
}
|
|
66172
66247
|
var readJson6 = (p) => {
|
|
66173
66248
|
try {
|
|
66174
|
-
const v3 = parseJsonc(
|
|
66249
|
+
const v3 = parseJsonc(readFileSync77(p, "utf8"));
|
|
66175
66250
|
return v3 && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
66176
66251
|
} catch {
|
|
66177
66252
|
return null;
|
|
@@ -66180,8 +66255,8 @@ var readJson6 = (p) => {
|
|
|
66180
66255
|
${bad.map((b) => `- ${b.name}: ${b.why}`).join(`
|
|
66181
66256
|
`)}`, `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
66257
|
|
|
66183
|
-
`), outOfRepoTests = (repoDir, changed) => changed.filter((f) => /(^|[\/._-])(test|spec)s?[\/._-]|_test\./i.test(f) && existsSync59(
|
|
66184
|
-
const why = outOfRepoTarget(
|
|
66258
|
+
`), outOfRepoTests = (repoDir, changed) => changed.filter((f) => /(^|[\/._-])(test|spec)s?[\/._-]|_test\./i.test(f) && existsSync59(join86(repoDir, f))).flatMap((name) => {
|
|
66259
|
+
const why = outOfRepoTarget(readFileSync77(join86(repoDir, name), "utf8"));
|
|
66185
66260
|
return why ? [{ name, why }] : [];
|
|
66186
66261
|
}), CREATORS;
|
|
66187
66262
|
var init_conventions = __esm(() => {
|
|
@@ -66191,16 +66266,16 @@ var init_conventions = __esm(() => {
|
|
|
66191
66266
|
});
|
|
66192
66267
|
|
|
66193
66268
|
// ../../loki-ts/src/util/pr_lessons.ts
|
|
66194
|
-
import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync10, readFileSync as
|
|
66269
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync10, readFileSync as readFileSync78, rmSync as rmSync22, writeFileSync as writeFileSync41 } from "fs";
|
|
66195
66270
|
import { homedir as homedir10, tmpdir as tmpdir13 } from "os";
|
|
66196
|
-
import { dirname as
|
|
66271
|
+
import { dirname as dirname36, join as join87 } from "path";
|
|
66197
66272
|
import { createHash as createHash26 } from "crypto";
|
|
66198
66273
|
function loadLessons(repoDir) {
|
|
66199
66274
|
const p = lessonsPath(repoDir);
|
|
66200
66275
|
if (!existsSync60(p))
|
|
66201
66276
|
return [];
|
|
66202
66277
|
try {
|
|
66203
|
-
const j10 = JSON.parse(
|
|
66278
|
+
const j10 = JSON.parse(readFileSync78(p, "utf-8"));
|
|
66204
66279
|
return Array.isArray(j10.lessons) ? j10.lessons : [];
|
|
66205
66280
|
} catch {
|
|
66206
66281
|
return [];
|
|
@@ -66208,12 +66283,12 @@ function loadLessons(repoDir) {
|
|
|
66208
66283
|
}
|
|
66209
66284
|
function save3(repoDir, lessons) {
|
|
66210
66285
|
const p = lessonsPath(repoDir);
|
|
66211
|
-
mkdirSync42(
|
|
66286
|
+
mkdirSync42(dirname36(p), { recursive: true });
|
|
66212
66287
|
atomicWriteJson(p, { version: 2, lessons });
|
|
66213
66288
|
}
|
|
66214
66289
|
function loadPromoted() {
|
|
66215
66290
|
try {
|
|
66216
|
-
const j10 = JSON.parse(
|
|
66291
|
+
const j10 = JSON.parse(readFileSync78(promotedPath(), "utf-8"));
|
|
66217
66292
|
return Array.isArray(j10.lessons) ? j10.lessons : [];
|
|
66218
66293
|
} catch {
|
|
66219
66294
|
return [];
|
|
@@ -66324,7 +66399,7 @@ ${body}
|
|
|
66324
66399
|
function learningsBlock(repoDir, limit = 5) {
|
|
66325
66400
|
let items2 = [];
|
|
66326
66401
|
try {
|
|
66327
|
-
const parsed = JSON.parse(
|
|
66402
|
+
const parsed = JSON.parse(readFileSync78(join87(repoDir, ".loki", "state", "relevant-learnings.json"), "utf-8"));
|
|
66328
66403
|
if (Array.isArray(parsed.learnings))
|
|
66329
66404
|
items2 = parsed.learnings;
|
|
66330
66405
|
} catch {
|
|
@@ -66354,7 +66429,7 @@ ${lines2.join(`
|
|
|
66354
66429
|
</untrusted-learnings>
|
|
66355
66430
|
`;
|
|
66356
66431
|
}
|
|
66357
|
-
var lessonsPath = (repoDir) =>
|
|
66432
|
+
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
66433
|
var init_pr_lessons = __esm(() => {
|
|
66359
66434
|
init_redact();
|
|
66360
66435
|
init_atomic();
|
|
@@ -66374,7 +66449,7 @@ import {
|
|
|
66374
66449
|
lstatSync as lstatSync24,
|
|
66375
66450
|
mkdirSync as mkdirSync43,
|
|
66376
66451
|
openSync as openSync13,
|
|
66377
|
-
readFileSync as
|
|
66452
|
+
readFileSync as readFileSync79,
|
|
66378
66453
|
readlinkSync as readlinkSync5,
|
|
66379
66454
|
realpathSync as realpathSync27,
|
|
66380
66455
|
rmSync as rmSync23,
|
|
@@ -66382,7 +66457,7 @@ import {
|
|
|
66382
66457
|
unlinkSync as unlinkSync8,
|
|
66383
66458
|
writeFileSync as writeFileSync42
|
|
66384
66459
|
} from "fs";
|
|
66385
|
-
import { dirname as
|
|
66460
|
+
import { dirname as dirname37, isAbsolute as isAbsolute16, join as join88, relative as relative17, resolve as resolve30, sep as sep18 } from "path";
|
|
66386
66461
|
function git8(root, args) {
|
|
66387
66462
|
return safeGit(root, args);
|
|
66388
66463
|
}
|
|
@@ -66422,7 +66497,7 @@ function safeJoin(root, relPath) {
|
|
|
66422
66497
|
const segment = segments[i];
|
|
66423
66498
|
if (segment === undefined)
|
|
66424
66499
|
continue;
|
|
66425
|
-
cur =
|
|
66500
|
+
cur = join88(cur, segment);
|
|
66426
66501
|
if (i < segments.length - 1) {
|
|
66427
66502
|
let st2;
|
|
66428
66503
|
try {
|
|
@@ -66439,7 +66514,7 @@ function safeJoin(root, relPath) {
|
|
|
66439
66514
|
function assertSymlinkWithinRoot(root, relPath, target) {
|
|
66440
66515
|
if (isAbsolute16(target))
|
|
66441
66516
|
throw new TreeSwapUnsafePathError(`symlink ${relPath} has an absolute target`);
|
|
66442
|
-
const resolvedTarget = resolve30(
|
|
66517
|
+
const resolvedTarget = resolve30(dirname37(join88(resolve30(root), relPath)), target);
|
|
66443
66518
|
const rel = relative17(resolve30(root), resolvedTarget);
|
|
66444
66519
|
if (rel === ".." || rel.startsWith(`..${"/"}`) || isAbsolute16(rel)) {
|
|
66445
66520
|
throw new TreeSwapUnsafePathError(`symlink ${relPath} escapes tree root`);
|
|
@@ -66458,7 +66533,7 @@ function readEntry(root, relPath) {
|
|
|
66458
66533
|
}
|
|
66459
66534
|
const fd2 = openSync13(abs, fsc.O_RDONLY | fsc.O_NOFOLLOW);
|
|
66460
66535
|
try {
|
|
66461
|
-
return { content:
|
|
66536
|
+
return { content: readFileSync79(fd2), mode: st2.mode & 511 };
|
|
66462
66537
|
} finally {
|
|
66463
66538
|
closeSync13(fd2);
|
|
66464
66539
|
}
|
|
@@ -66477,7 +66552,7 @@ function writeEntry(root, relPath, entry2) {
|
|
|
66477
66552
|
assertSymlinkWithinRoot(root, relPath, entry2.symlinkTarget);
|
|
66478
66553
|
}
|
|
66479
66554
|
const abs = safeJoin(root, relPath);
|
|
66480
|
-
mkdirSync43(
|
|
66555
|
+
mkdirSync43(dirname37(abs), { recursive: true });
|
|
66481
66556
|
removeEntry(root, relPath);
|
|
66482
66557
|
if (entry2.symlinkTarget !== undefined) {
|
|
66483
66558
|
symlinkSync4(entry2.symlinkTarget, abs);
|
|
@@ -66600,7 +66675,7 @@ function swapLocked(opts, excludes) {
|
|
|
66600
66675
|
pre2.push({ path, kind: "file", content: e10.content, mode: e10.mode, symlinkTarget: e10.symlinkTarget });
|
|
66601
66676
|
}
|
|
66602
66677
|
mkdirSync43(opts.runDir, { recursive: true });
|
|
66603
|
-
const undoPath =
|
|
66678
|
+
const undoPath = join88(opts.runDir, UNDO_FILE);
|
|
66604
66679
|
const enc = (l) => l.map((e10) => ({ ...e10, content: e10.content?.toString("base64") }));
|
|
66605
66680
|
let fd2;
|
|
66606
66681
|
try {
|
|
@@ -66640,7 +66715,7 @@ function removeLenient(root, relPath) {
|
|
|
66640
66715
|
}
|
|
66641
66716
|
}
|
|
66642
66717
|
function restoreFromUndo(primaryRoot, runDir, excludes = DEFAULT_EXCLUDES) {
|
|
66643
|
-
const rec2 = JSON.parse(
|
|
66718
|
+
const rec2 = JSON.parse(readFileSync79(join88(runDir, UNDO_FILE), "utf8"));
|
|
66644
66719
|
const dec = (l) => l.map((e10) => ({ ...e10, content: e10.content === undefined ? undefined : Buffer.from(e10.content, "base64") }));
|
|
66645
66720
|
const entries = dec(rec2.entries);
|
|
66646
66721
|
const errors2 = [];
|
|
@@ -66660,7 +66735,7 @@ function restoreFromUndo(primaryRoot, runDir, excludes = DEFAULT_EXCLUDES) {
|
|
|
66660
66735
|
throw new AggregateError(errors2, "treeswap: rollback incomplete");
|
|
66661
66736
|
}
|
|
66662
66737
|
function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
66663
|
-
const attemptsRoot =
|
|
66738
|
+
const attemptsRoot = join88(realpathSync27(resolve30(runDir)), "attempts");
|
|
66664
66739
|
let attemptsLst;
|
|
66665
66740
|
try {
|
|
66666
66741
|
attemptsLst = lstatSync24(attemptsRoot);
|
|
@@ -66677,17 +66752,17 @@ function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
|
66677
66752
|
if (isPrimaryOrAncestor(realpathSync27(attemptsRoot)))
|
|
66678
66753
|
throw new TreeSwapUnsafePathError(`attempts dir ${attemptsRoot} resolves to the primary tree`);
|
|
66679
66754
|
const lexical = resolve30(attemptDir);
|
|
66680
|
-
const parent =
|
|
66755
|
+
const parent = dirname37(lexical);
|
|
66681
66756
|
let real3;
|
|
66682
66757
|
try {
|
|
66683
|
-
real3 =
|
|
66758
|
+
real3 = join88(realpathSync27(parent), lexical.slice(parent.length + 1));
|
|
66684
66759
|
lstatSync24(real3);
|
|
66685
66760
|
} catch (err) {
|
|
66686
66761
|
if (err.code === "ENOENT")
|
|
66687
66762
|
return;
|
|
66688
66763
|
throw err;
|
|
66689
66764
|
}
|
|
66690
|
-
if (
|
|
66765
|
+
if (dirname37(real3) !== attemptsRoot)
|
|
66691
66766
|
throw new TreeSwapUnsafePathError(`${attemptDir} is not a direct child of ${attemptsRoot}`);
|
|
66692
66767
|
if (isPrimaryOrAncestor(real3))
|
|
66693
66768
|
throw new TreeSwapUnsafePathError(`${attemptDir} is or contains the primary tree`);
|
|
@@ -66698,7 +66773,7 @@ function cleanupAttempt(primaryRoot, runDir, attemptDir) {
|
|
|
66698
66773
|
throw new TreeSwapUnsafePathError(`${attemptDir} is not a directory`);
|
|
66699
66774
|
if (process.getuid && lst.uid !== process.getuid())
|
|
66700
66775
|
throw new TreeSwapUnsafePathError(`refusing to remove ${attemptDir}: not owned by the current user`);
|
|
66701
|
-
const gitFile =
|
|
66776
|
+
const gitFile = join88(real3, ".git");
|
|
66702
66777
|
let isLinkedWorktree = false;
|
|
66703
66778
|
try {
|
|
66704
66779
|
isLinkedWorktree = lstatSync24(gitFile).isFile();
|
|
@@ -66725,8 +66800,8 @@ var init_treeswap = __esm(() => {
|
|
|
66725
66800
|
});
|
|
66726
66801
|
|
|
66727
66802
|
// ../../loki-ts/src/features/attempts.ts
|
|
66728
|
-
import { existsSync as existsSync61, mkdirSync as mkdirSync44, readFileSync as
|
|
66729
|
-
import { join as
|
|
66803
|
+
import { existsSync as existsSync61, mkdirSync as mkdirSync44, readFileSync as readFileSync80 } from "fs";
|
|
66804
|
+
import { join as join89 } from "path";
|
|
66730
66805
|
function assertScrubbedEnv(env) {
|
|
66731
66806
|
for (const v3 of GITHUB_TOKEN_VARS) {
|
|
66732
66807
|
const val = env[v3] ?? "";
|
|
@@ -66777,19 +66852,19 @@ async function runTwoAttempts(ops, S, wall, signal, env = process.env) {
|
|
|
66777
66852
|
}
|
|
66778
66853
|
}
|
|
66779
66854
|
function treeswapOps(a) {
|
|
66780
|
-
const attemptsDir =
|
|
66855
|
+
const attemptsDir = join89(a.runDir, "attempts"), bDir = join89(attemptsDir, "B");
|
|
66781
66856
|
mkdirSync44(attemptsDir, { recursive: true });
|
|
66782
66857
|
safeGit(a.primary, ["worktree", "add", "--detach", bDir, a.base]);
|
|
66783
66858
|
const pre2 = new Set(untracked2(a.primary));
|
|
66784
66859
|
let snapA = null;
|
|
66785
66860
|
const wallWeakened = (root, isPrimary, p, touched) => {
|
|
66786
|
-
const sealed = a.wallContent?.get(p), f =
|
|
66861
|
+
const sealed = a.wallContent?.get(p), f = join89(root, p);
|
|
66787
66862
|
if (!existsSync61(f))
|
|
66788
66863
|
return isPrimary ? sealed !== undefined || touched.has(p) : false;
|
|
66789
66864
|
if (sealed === undefined)
|
|
66790
66865
|
return touched.has(p);
|
|
66791
66866
|
try {
|
|
66792
|
-
return
|
|
66867
|
+
return readFileSync80(f, "utf8") !== sealed;
|
|
66793
66868
|
} catch {
|
|
66794
66869
|
return true;
|
|
66795
66870
|
}
|
|
@@ -66867,8 +66942,8 @@ var init_attempts = __esm(() => {
|
|
|
66867
66942
|
});
|
|
66868
66943
|
|
|
66869
66944
|
// ../../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
|
|
66945
|
+
import { existsSync as existsSync62, lstatSync as lstatSync25, mkdirSync as mkdirSync45, readFileSync as readFileSync81, writeFileSync as writeFileSync43 } from "fs";
|
|
66946
|
+
import { join as join90 } from "path";
|
|
66872
66947
|
function buildRouteRecord(i) {
|
|
66873
66948
|
const notProven = [...i.notProven, ...i.planModelNote ? [`plan model: NOT PROVEN (owner provider): ${i.planModelNote}`] : []];
|
|
66874
66949
|
const base = { plan_model: i.planModel, shape_key: i.shapeKey, route_not_proven: notProven, applied: PER_UNIT_EXECUTORS_APPLIED };
|
|
@@ -66889,16 +66964,16 @@ function buildRouteRecord(i) {
|
|
|
66889
66964
|
function writeRouteRecord(runDir, record) {
|
|
66890
66965
|
try {
|
|
66891
66966
|
mkdirSync45(runDir, { recursive: true });
|
|
66892
|
-
writeFileSync43(
|
|
66967
|
+
writeFileSync43(join90(runDir, ROUTE_RECORD_FILE), `${JSON.stringify(record, null, 2)}
|
|
66893
66968
|
`);
|
|
66894
66969
|
} catch {}
|
|
66895
66970
|
}
|
|
66896
66971
|
function loadRouteRecord(runDir) {
|
|
66897
66972
|
try {
|
|
66898
|
-
const p =
|
|
66973
|
+
const p = join90(runDir, ROUTE_RECORD_FILE);
|
|
66899
66974
|
if (!existsSync62(p) || !lstatSync25(p).isFile())
|
|
66900
66975
|
return;
|
|
66901
|
-
const v3 = JSON.parse(
|
|
66976
|
+
const v3 = JSON.parse(readFileSync81(p, "utf8"));
|
|
66902
66977
|
return typeof v3 === "object" && v3 !== null && !Array.isArray(v3) ? v3 : undefined;
|
|
66903
66978
|
} catch {
|
|
66904
66979
|
return;
|
|
@@ -66973,10 +67048,10 @@ __export(exports_plan, {
|
|
|
66973
67048
|
planStage: () => planStage,
|
|
66974
67049
|
buildPlanBrief: () => buildPlanBrief
|
|
66975
67050
|
});
|
|
66976
|
-
import { existsSync as existsSync63, mkdirSync as mkdirSync46, readFileSync as
|
|
66977
|
-
import { join as
|
|
67051
|
+
import { existsSync as existsSync63, mkdirSync as mkdirSync46, readFileSync as readFileSync82, writeFileSync as writeFileSync44 } from "fs";
|
|
67052
|
+
import { join as join91 } from "path";
|
|
66978
67053
|
function planOutputPath(runDir) {
|
|
66979
|
-
return
|
|
67054
|
+
return join91(runDir, PLAN_OUTPUT_FILENAME);
|
|
66980
67055
|
}
|
|
66981
67056
|
function truncatePlan(raw2, max = MAX_PLAN_LINES) {
|
|
66982
67057
|
const lines2 = raw2.split(`
|
|
@@ -67046,7 +67121,7 @@ var init_plan = __esm(() => {
|
|
|
67046
67121
|
const cardOn = intentCardEnabled(process.env);
|
|
67047
67122
|
const runPlan = (onSonnet) => ctx.sessions.run({
|
|
67048
67123
|
stage: "plan",
|
|
67049
|
-
brief: buildPlanBrief(task, relevantFiles, outputPath,
|
|
67124
|
+
brief: buildPlanBrief(task, relevantFiles, outputPath, join91(ctx.runDir, PLAN_SCOPE_FILE), pr2.routed, cardOn, mutationStrict(), reviewerBriefEnabled()),
|
|
67050
67125
|
tier: "fast",
|
|
67051
67126
|
iterationId,
|
|
67052
67127
|
limitS: planStage.limitS,
|
|
@@ -67065,11 +67140,11 @@ var init_plan = __esm(() => {
|
|
|
67065
67140
|
if (!session.killed && session.exit !== 0) {
|
|
67066
67141
|
pr2.record({ planModel, planModelNote, skipReason: `plan session failed (exit ${session.exit})` });
|
|
67067
67142
|
mkdirSync46(ctx.runDir, { recursive: true });
|
|
67068
|
-
const stderrPath =
|
|
67143
|
+
const stderrPath = join91(ctx.runDir, `${iterationId}.stderr.log`);
|
|
67069
67144
|
writeFileSync44(stderrPath, session.stderrTail ?? "", "utf8");
|
|
67070
67145
|
return { status: "failed", reason: classifyExitCause(session.exit, false), data: { iteration_ids: [iterationId], duration_s: session.durationS, stderr_path: stderrPath } };
|
|
67071
67146
|
}
|
|
67072
|
-
const rawPlan = existsSync63(outputPath) ?
|
|
67147
|
+
const rawPlan = existsSync63(outputPath) ? readFileSync82(outputPath, "utf8") : "";
|
|
67073
67148
|
const ic2 = await applyIntent(rawPlan, cardOn, ctx.runDir, (d) => ctx.emit("variant", "plan", d));
|
|
67074
67149
|
const plan = truncatePlan(ic2.rest);
|
|
67075
67150
|
const route_record = pr2.record({ planModel, planModelNote }), oor = planOutOfRepo(ctx.runDir);
|
|
@@ -67094,9 +67169,9 @@ var init_plan = __esm(() => {
|
|
|
67094
67169
|
|
|
67095
67170
|
// ../../loki-ts/src/util/conflict_resume.ts
|
|
67096
67171
|
import { createHash as createHash27 } from "crypto";
|
|
67097
|
-
import { existsSync as existsSync64, mkdtempSync as mkdtempSync11, readFileSync as
|
|
67172
|
+
import { existsSync as existsSync64, mkdtempSync as mkdtempSync11, readFileSync as readFileSync83, rmSync as rmSync24, writeFileSync as writeFileSync45 } from "fs";
|
|
67098
67173
|
import { tmpdir as tmpdir14 } from "os";
|
|
67099
|
-
import { basename as basename24, join as
|
|
67174
|
+
import { basename as basename24, join as join92, relative as relative18 } from "path";
|
|
67100
67175
|
async function resumeAfterConflict(ctx, first, firstSession) {
|
|
67101
67176
|
if ((ctx.implementLeftS?.() ?? Infinity) < RESUME_MIN_LEFT_S)
|
|
67102
67177
|
return { session: firstSession, iterationId: first.iterationId };
|
|
@@ -67120,9 +67195,9 @@ async function adjudicateWallConflict(ctx, first, firstSession, wall) {
|
|
|
67120
67195
|
const reason = firstSession.markers.specConflict, rels = wall.map((f10) => relative18(ctx.repoDir, f10.path)), a = reason ? wallAnchor(reason, rels) : null;
|
|
67121
67196
|
if (!reason || !a)
|
|
67122
67197
|
return null;
|
|
67123
|
-
const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync11(
|
|
67198
|
+
const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync11(join92(tmpdir14(), "loki-e15-wall-")), name = basename24(f.path);
|
|
67124
67199
|
try {
|
|
67125
|
-
writeFileSync45(
|
|
67200
|
+
writeFileSync45(join92(cwd, name), f.content, "utf8");
|
|
67126
67201
|
const id2 = `${first.iterationId}-wa`;
|
|
67127
67202
|
ids.push(id2);
|
|
67128
67203
|
const au2 = await ctx.sessions.run({
|
|
@@ -67142,7 +67217,7 @@ async function adjudicateWallConflict(ctx, first, firstSession, wall) {
|
|
|
67142
67217
|
|
|
67143
67218
|
`)
|
|
67144
67219
|
});
|
|
67145
|
-
const next = !au2.killed && au2.exit === 0 && existsSync64(
|
|
67220
|
+
const next = !au2.killed && au2.exit === 0 && existsSync64(join92(cwd, name)) ? readFileSync83(join92(cwd, name), "utf8") : "";
|
|
67146
67221
|
const rewritten = next.trim() !== "" && next !== f.content;
|
|
67147
67222
|
if (rewritten) {
|
|
67148
67223
|
f.content = next;
|
|
@@ -67237,8 +67312,8 @@ __export(exports_implement, {
|
|
|
67237
67312
|
briefCtx: () => briefCtx,
|
|
67238
67313
|
applyExternalPatch: () => applyExternalPatch
|
|
67239
67314
|
});
|
|
67240
|
-
import { existsSync as existsSync65, mkdirSync as mkdirSync47, readFileSync as
|
|
67241
|
-
import { join as
|
|
67315
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync47, readFileSync as readFileSync84, rmSync as rmSync25, writeFileSync as writeFileSync46 } from "fs";
|
|
67316
|
+
import { join as join93, relative as relative19 } from "path";
|
|
67242
67317
|
function impactedTests(ctx) {
|
|
67243
67318
|
const o = ctx.outputs();
|
|
67244
67319
|
const map = o.intake?.testmap;
|
|
@@ -67266,7 +67341,7 @@ ${plan}` : "No separate plan was made: plan the change yourself in this session,
|
|
|
67266
67341
|
function restoreReadOnly(files) {
|
|
67267
67342
|
const reverted = [];
|
|
67268
67343
|
for (const f of files) {
|
|
67269
|
-
const current = existsSync65(f.path) ?
|
|
67344
|
+
const current = existsSync65(f.path) ? readFileSync84(f.path, "utf8") : null;
|
|
67270
67345
|
if (current !== f.content) {
|
|
67271
67346
|
writeFileSync46(f.path, f.content, "utf8");
|
|
67272
67347
|
reverted.push(f.path);
|
|
@@ -67285,7 +67360,7 @@ function specFor(ctx) {
|
|
|
67285
67360
|
if (!process.env.LOKI_E10_SPEC_SHA256)
|
|
67286
67361
|
return null;
|
|
67287
67362
|
try {
|
|
67288
|
-
return loadSpecFile(
|
|
67363
|
+
return loadSpecFile(join93(ctx.runDir, "spec.snapshot.md"));
|
|
67289
67364
|
} catch {
|
|
67290
67365
|
return null;
|
|
67291
67366
|
}
|
|
@@ -67298,7 +67373,7 @@ function applyExternalPatch(ctx, patchPath) {
|
|
|
67298
67373
|
`)[0]}` };
|
|
67299
67374
|
}
|
|
67300
67375
|
const testsReverted = restoreReadOnly(ctx.outputs().wall?.readOnlyFiles ?? []);
|
|
67301
|
-
return { status: "completed", data: { exit: "external", external: true, patch_sha256: sha2562(
|
|
67376
|
+
return { status: "completed", data: { exit: "external", external: true, patch_sha256: sha2562(readFileSync84(patchPath, "utf8")), tests_reverted: testsReverted, impacted_tests: impactedTests(ctx), iteration_ids: [] } };
|
|
67302
67377
|
}
|
|
67303
67378
|
var briefCtx = (ctx) => briefContext(ctx, { select: selectRelevantFiles, cmd: (t, repoDir) => {
|
|
67304
67379
|
const c = commandFor(t, repoDir, loadProjectApi(repoDir));
|
|
@@ -67330,7 +67405,7 @@ var init_implement = __esm(() => {
|
|
|
67330
67405
|
targetS: 180,
|
|
67331
67406
|
limitS: 480,
|
|
67332
67407
|
async run(ctx, signal) {
|
|
67333
|
-
rmSync25(
|
|
67408
|
+
rmSync25(join93(ctx.repoDir, ".loki", "supply-declared.json"), { force: true });
|
|
67334
67409
|
if (ctx.externalPatch)
|
|
67335
67410
|
return applyExternalPatch(ctx, ctx.externalPatch);
|
|
67336
67411
|
const prior = ctx.outputs();
|
|
@@ -67459,7 +67534,7 @@ var init_implement = __esm(() => {
|
|
|
67459
67534
|
return { status: "completed", data };
|
|
67460
67535
|
const stderrTail = session.stderrTail ?? "";
|
|
67461
67536
|
mkdirSync47(ctx.runDir, { recursive: true });
|
|
67462
|
-
const stderrPath =
|
|
67537
|
+
const stderrPath = join93(ctx.runDir, `${iterationId}.stderr.log`);
|
|
67463
67538
|
writeFileSync46(stderrPath, stderrTail, "utf8");
|
|
67464
67539
|
data.stderr_path = stderrPath;
|
|
67465
67540
|
return { status: "failed", reason: classifyExitCause(session.exit, false), data };
|
|
@@ -67470,17 +67545,17 @@ var init_implement = __esm(() => {
|
|
|
67470
67545
|
|
|
67471
67546
|
// ../../loki-ts/src/engine10/machine.ts
|
|
67472
67547
|
import { existsSync as existsSync66, mkdirSync as mkdirSync48, rmSync as rmSync26, writeFileSync as writeFileSync47 } from "fs";
|
|
67473
|
-
import { isAbsolute as isAbsolute17, join as
|
|
67548
|
+
import { isAbsolute as isAbsolute17, join as join94, relative as relative20 } from "path";
|
|
67474
67549
|
async function optional(path) {
|
|
67475
|
-
const abs = isAbsolute17(path) ? path :
|
|
67550
|
+
const abs = isAbsolute17(path) ? path : join94(import.meta.dir, path);
|
|
67476
67551
|
if (!existsSync66(abs))
|
|
67477
67552
|
return null;
|
|
67478
67553
|
return await import(abs);
|
|
67479
67554
|
}
|
|
67480
67555
|
function defaultLoader(dir) {
|
|
67481
67556
|
return async (name) => {
|
|
67482
|
-
const reg = dir ===
|
|
67483
|
-
const mod = reg ? await reg() : await optional(
|
|
67557
|
+
const reg = dir === join94(import.meta.dir, "stages") ? REGISTRY[`./stages/${name}.ts`] : undefined;
|
|
67558
|
+
const mod = reg ? await reg() : await optional(join94(dir, `${name}.ts`));
|
|
67484
67559
|
return mod ? mod.stage ?? mod.default ?? null : null;
|
|
67485
67560
|
};
|
|
67486
67561
|
}
|
|
@@ -67489,7 +67564,7 @@ function softCapS(capS) {
|
|
|
67489
67564
|
return Math.max(0, Math.min(plain2, budget));
|
|
67490
67565
|
}
|
|
67491
67566
|
async function runMachine(ctx, opts = {}) {
|
|
67492
|
-
const load = opts.load ?? defaultLoader(opts.stagesDir ??
|
|
67567
|
+
const load = opts.load ?? defaultLoader(opts.stagesDir ?? join94(import.meta.dir, "stages"));
|
|
67493
67568
|
const outputs = {};
|
|
67494
67569
|
let capHit = false, fatal = null;
|
|
67495
67570
|
if (opts.restored)
|
|
@@ -67705,9 +67780,9 @@ ${timeBudgetNote(limitS)}`;
|
|
|
67705
67780
|
else
|
|
67706
67781
|
try {
|
|
67707
67782
|
const w = a;
|
|
67708
|
-
mkdirSync48(
|
|
67783
|
+
mkdirSync48(join94(base, relative20(ctx.repoDir, w.targetDir)), { recursive: true });
|
|
67709
67784
|
for (const [n10, c] of w.contents)
|
|
67710
|
-
writeFileSync47(
|
|
67785
|
+
writeFileSync47(join94(base, relative20(ctx.repoDir, w.targetDir), n10), c, "utf8");
|
|
67711
67786
|
r = j10.split.install(sctx, a, base);
|
|
67712
67787
|
const changed = hooks.wall.changedSinceBase(ctx.repoDir, ctx.baseSha);
|
|
67713
67788
|
if (r.status === "completed") {
|
|
@@ -68014,8 +68089,8 @@ __export(exports_worker, {
|
|
|
68014
68089
|
main: () => main2,
|
|
68015
68090
|
assertWorkerEnv: () => assertWorkerEnv
|
|
68016
68091
|
});
|
|
68017
|
-
import { readFileSync as
|
|
68018
|
-
import { join as
|
|
68092
|
+
import { readFileSync as readFileSync85 } from "fs";
|
|
68093
|
+
import { join as join95 } from "path";
|
|
68019
68094
|
function assertWorkerEnv(env = process.env) {
|
|
68020
68095
|
if (env.LOKI_ALLOW_AGENT_GITHUB_TOKEN === "1")
|
|
68021
68096
|
return;
|
|
@@ -68045,7 +68120,7 @@ async function main2(args) {
|
|
|
68045
68120
|
return 2;
|
|
68046
68121
|
}
|
|
68047
68122
|
const repoDir = process.cwd();
|
|
68048
|
-
const lokiRoot =
|
|
68123
|
+
const lokiRoot = join95(repoDir, ".loki");
|
|
68049
68124
|
const deep = mode === "deep";
|
|
68050
68125
|
globalThis[Symbol.for("loki.ownsStopSignals")] = true;
|
|
68051
68126
|
for (const sig of ["SIGTERM", "SIGINT"])
|
|
@@ -68073,7 +68148,7 @@ async function main2(args) {
|
|
|
68073
68148
|
externalPatch,
|
|
68074
68149
|
runId,
|
|
68075
68150
|
repoDir,
|
|
68076
|
-
runDir:
|
|
68151
|
+
runDir: join95(lokiRoot, "runs", runId),
|
|
68077
68152
|
branch: `loki/${runId}`,
|
|
68078
68153
|
provider,
|
|
68079
68154
|
model,
|
|
@@ -68087,7 +68162,7 @@ async function main2(args) {
|
|
|
68087
68162
|
tests: new RealTestMapProvider,
|
|
68088
68163
|
cost: {
|
|
68089
68164
|
read(dir, ids) {
|
|
68090
|
-
const c = sumResultCosts(
|
|
68165
|
+
const c = sumResultCosts(join95(dir, ".loki"), liveArchivedCosts(join95(dir, ".loki"), ids, UNMETERED));
|
|
68091
68166
|
return costTotalsOf(c);
|
|
68092
68167
|
}
|
|
68093
68168
|
},
|
|
@@ -68097,7 +68172,7 @@ async function main2(args) {
|
|
|
68097
68172
|
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
68173
|
let flow = FLOW.filter((s) => s !== "pr"), restored;
|
|
68099
68174
|
if (process.env.LOKI_E10_RESUME === "1") {
|
|
68100
|
-
const p =
|
|
68175
|
+
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
68176
|
if (!r.ok) {
|
|
68102
68177
|
emit("escalated", null, { stop: `resume refused: ${r.reason}` });
|
|
68103
68178
|
return;
|
|
@@ -68145,12 +68220,12 @@ __export(exports_deep, {
|
|
|
68145
68220
|
});
|
|
68146
68221
|
import { existsSync as existsSync67, mkdirSync as mkdirSync49, mkdtempSync as mkdtempSync12, rmSync as rmSync27, writeFileSync as writeFileSync48 } from "fs";
|
|
68147
68222
|
import { tmpdir as tmpdir15 } from "os";
|
|
68148
|
-
import { join as
|
|
68223
|
+
import { join as join96 } from "path";
|
|
68149
68224
|
function sessionCouncil(sessions) {
|
|
68150
68225
|
return { async run(input, signal) {
|
|
68151
|
-
const cwd = mkdtempSync12(
|
|
68226
|
+
const cwd = mkdtempSync12(join96(tmpdir15(), "loki-deep-council-"));
|
|
68152
68227
|
try {
|
|
68153
|
-
writeFileSync48(
|
|
68228
|
+
writeFileSync48(join96(cwd, "diff.patch"), input.diff, "utf8");
|
|
68154
68229
|
const r = await sessions.run({
|
|
68155
68230
|
stage: "deep",
|
|
68156
68231
|
tier: "development",
|
|
@@ -68220,7 +68295,7 @@ ${r.stderr}`), lr2 = r.exitCode === 0 ? undefined : await harnessLoadReason({ re
|
|
|
68220
68295
|
async function runAppBoot(ctx, opts, checks, notProven) {
|
|
68221
68296
|
let r;
|
|
68222
68297
|
try {
|
|
68223
|
-
r = await (opts.appProbe ?? appProbe)(ctx.repoDir,
|
|
68298
|
+
r = await (opts.appProbe ?? appProbe)(ctx.repoDir, join96(ctx.repoDir, ".loki"));
|
|
68224
68299
|
} catch (err) {
|
|
68225
68300
|
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
68301
|
}
|
|
@@ -68278,7 +68353,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
|
68278
68353
|
}
|
|
68279
68354
|
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
68355
|
const started = Date.now();
|
|
68281
|
-
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) =>
|
|
68356
|
+
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join96(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
|
|
68282
68357
|
const sec = await secureScanChanged(ctx.repoDir, changed, opts.secureScanPath), gaps = [], reasons = [];
|
|
68283
68358
|
const hits = r.exitCode === 3 ? [] : r.stdout.split(`
|
|
68284
68359
|
`).map((l) => l.trim()).filter(Boolean), high = sec.findings.filter((f) => String(f.severity).toUpperCase() === "HIGH");
|
|
@@ -68331,7 +68406,7 @@ async function runDeep(ctx, signal, opts = {}) {
|
|
|
68331
68406
|
const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
|
|
68332
68407
|
const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
68333
68408
|
mkdirSync49(ctx.runDir, { recursive: true });
|
|
68334
|
-
writeFileSync48(
|
|
68409
|
+
writeFileSync48(join96(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
|
|
68335
68410
|
`);
|
|
68336
68411
|
const headSha = (await safeGitRun(ctx.repoDir, ["rev-parse", "HEAD"], { timeoutMs: 1e4 })).stdout.trim();
|
|
68337
68412
|
const pushNotProven = await postDeepResults({
|
|
@@ -68357,11 +68432,11 @@ async function deepWorker(args, deps = {}) {
|
|
|
68357
68432
|
`);
|
|
68358
68433
|
return 2;
|
|
68359
68434
|
}
|
|
68360
|
-
const repoDir = process.cwd(), lokiRoot =
|
|
68435
|
+
const repoDir = process.cwd(), lokiRoot = join96(repoDir, ".loki"), runDir = join96(lokiRoot, "runs", runId);
|
|
68361
68436
|
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
68437
|
let outputs;
|
|
68363
68438
|
try {
|
|
68364
|
-
outputs = outputsFromEvents2(readEvents2(
|
|
68439
|
+
outputs = outputsFromEvents2(readEvents2(join96(repoDir, eventsRelPath2(runId))));
|
|
68365
68440
|
} catch (err) {
|
|
68366
68441
|
process.stderr.write(`engine10 deep-worker: cannot read run events: ${err.message}
|
|
68367
68442
|
`);
|
|
@@ -68451,9 +68526,9 @@ __export(exports_verify, {
|
|
|
68451
68526
|
commandFor: () => commandFor,
|
|
68452
68527
|
changedFiles: () => changedFiles
|
|
68453
68528
|
});
|
|
68454
|
-
import { existsSync as existsSync68, mkdtempSync as mkdtempSync13, readFileSync as
|
|
68529
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync13, readFileSync as readFileSync86, rmSync as rmSync28 } from "fs";
|
|
68455
68530
|
import { tmpdir as tmpdir16 } from "os";
|
|
68456
|
-
import { basename as basename25, isAbsolute as isAbsolute18, join as
|
|
68531
|
+
import { basename as basename25, isAbsolute as isAbsolute18, join as join97, relative as relative21 } from "path";
|
|
68457
68532
|
async function runOnce3(cmd, args, cwd, signal, opts) {
|
|
68458
68533
|
if (!Bun.which(cmd, { PATH: opts.path ?? process.env["PATH"] ?? "" }))
|
|
68459
68534
|
return { ok: false, missing: true, cut: false, out: "" };
|
|
@@ -68535,7 +68610,7 @@ async function probeZeroChecks(repoDir, tests, signal, budgetS = 120, cap = 300)
|
|
|
68535
68610
|
rmNewUntracked(repoDir, before);
|
|
68536
68611
|
return { measured: measured.sort(), zero: zero.sort() };
|
|
68537
68612
|
}
|
|
68538
|
-
async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true, zeroIntake = new Set) {
|
|
68613
|
+
async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true, zeroIntake = new Set, dep = new Set) {
|
|
68539
68614
|
const out3 = { ids: [], names: [], weak: [], zero: [], cnt: {} };
|
|
68540
68615
|
const pairs = checks.flatMap((c) => {
|
|
68541
68616
|
const t = tests.find((x3) => testCheckName(x3) === c.name);
|
|
@@ -68546,7 +68621,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68546
68621
|
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
68622
|
if (!(un2.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length || zc2.length) || signal.aborted)
|
|
68548
68623
|
return out3;
|
|
68549
|
-
const dir = mkdtempSync13(
|
|
68624
|
+
const dir = mkdtempSync13(join97(tmpdir16(), "e10-base-"));
|
|
68550
68625
|
const git9 = (args) => {
|
|
68551
68626
|
safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
|
|
68552
68627
|
};
|
|
@@ -68565,9 +68640,9 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68565
68640
|
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
68641
|
}
|
|
68567
68642
|
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
|
-
|
|
68643
|
+
{
|
|
68569
68644
|
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))) {
|
|
68645
|
+
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
68646
|
out3.names.push(c.name);
|
|
68572
68647
|
out3.ids.push(...c.ids);
|
|
68573
68648
|
}
|
|
@@ -68585,15 +68660,15 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
|
|
|
68585
68660
|
return out3;
|
|
68586
68661
|
}
|
|
68587
68662
|
function isLokiModeRepo(repoDir) {
|
|
68588
|
-
return existsSync68(
|
|
68663
|
+
return existsSync68(join97(repoDir, "scripts", "select-tests.sh"));
|
|
68589
68664
|
}
|
|
68590
68665
|
function projectDeclaresRuff(repoDir) {
|
|
68591
|
-
if (["ruff.toml", ".ruff.toml"].some((f) => existsSync68(
|
|
68666
|
+
if (["ruff.toml", ".ruff.toml"].some((f) => existsSync68(join97(repoDir, f))))
|
|
68592
68667
|
return true;
|
|
68593
68668
|
const files = ["pyproject.toml", "setup.cfg", "tox.ini", ".pre-commit-config.yaml", "Pipfile", "requirements.txt", "requirements-dev.txt", "dev-requirements.txt"];
|
|
68594
68669
|
return files.some((f) => {
|
|
68595
68670
|
try {
|
|
68596
|
-
return /\bruff\b/i.test(
|
|
68671
|
+
return /\bruff\b/i.test(readFileSync86(join97(repoDir, f), "utf8"));
|
|
68597
68672
|
} catch {
|
|
68598
68673
|
return false;
|
|
68599
68674
|
}
|
|
@@ -68619,9 +68694,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
68619
68694
|
}
|
|
68620
68695
|
for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
|
|
68621
68696
|
const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
|
|
68622
|
-
if (existsSync68(
|
|
68697
|
+
if (existsSync68(join97(g.cwd, "tsconfig.json")))
|
|
68623
68698
|
await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["--no-install", "tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
|
|
68624
|
-
if (ESLINT_CONFIGS.some((f) => existsSync68(
|
|
68699
|
+
if (ESLINT_CONFIGS.some((f) => existsSync68(join97(g.cwd, f)))) {
|
|
68625
68700
|
const c = await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["--no-install", "eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
|
|
68626
68701
|
if (await excuseLint(ctx, signal, c, "eslint", "npx", ["--no-install", "eslint"], g.cwd, g.rel, co))
|
|
68627
68702
|
pre2.push(c.name);
|
|
@@ -68636,7 +68711,7 @@ var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name),
|
|
|
68636
68711
|
return r.missing || r.cut ? null : r;
|
|
68637
68712
|
}, base: (f) => {
|
|
68638
68713
|
try {
|
|
68639
|
-
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative21(ctx.repoDir,
|
|
68714
|
+
return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative21(ctx.repoDir, join97(cwd, f))}`], { stdio: ["ignore", "pipe", "ignore"] });
|
|
68640
68715
|
} catch {
|
|
68641
68716
|
return null;
|
|
68642
68717
|
}
|
|
@@ -68648,6 +68723,7 @@ var init_verify = __esm(() => {
|
|
|
68648
68723
|
init_assert_delta();
|
|
68649
68724
|
init_failures();
|
|
68650
68725
|
init_select();
|
|
68726
|
+
init_dependents();
|
|
68651
68727
|
init_load_owner();
|
|
68652
68728
|
init_sizing();
|
|
68653
68729
|
init_testmap();
|
|
@@ -68711,7 +68787,8 @@ var init_verify = __esm(() => {
|
|
|
68711
68787
|
const runner = rec2 ?? guessRunner(basename25(p), map.runners, p);
|
|
68712
68788
|
return runner && (runner !== "bun" || map.runners.includes("bun") || /[._](?:test|spec)\.[cm]?[jt]sx?$/.test(p)) ? [{ runner, path: p }] : [];
|
|
68713
68789
|
});
|
|
68714
|
-
const
|
|
68790
|
+
const dep = dependentTests(ctx.repoDir, map, changed, [...impacted, ...changedTestFiles, ...wallTests, ...relevant2]), depNames = new Set(dep.tests.map(testCheckName));
|
|
68791
|
+
const tests = failedFirst(dedupeTests([...impacted, ...dep.tests, ...changedTestFiles, ...wallTests, ...relevant2]), ctx.outputs().verify?.checks);
|
|
68715
68792
|
const scopedOut = scopedOutOf(map);
|
|
68716
68793
|
if (scopedOut.length)
|
|
68717
68794
|
ctx.emit("test.scoped_out", "verify", { tests: scopedOut });
|
|
@@ -68740,7 +68817,7 @@ var init_verify = __esm(() => {
|
|
|
68740
68817
|
}
|
|
68741
68818
|
const targetNames = new Set([...[...wallTests, ...relevant2].map(testCheckName), ...checks.filter(isHold).map((c) => c.name)]);
|
|
68742
68819
|
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 ?? []));
|
|
68820
|
+
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
68821
|
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
68822
|
attr.introducedChecks = [...new Set(attr.introducedChecks.map((n10) => isHoldoutCheck(n10) ? "holdout" : n10))];
|
|
68746
68823
|
preRed.names.push(...attr.preExistingChecks);
|
|
@@ -68808,11 +68885,11 @@ ${x3}` : c.cmd };
|
|
|
68808
68885
|
return [`weakened test: ${t.path}`, ...assertDeltaNotes(ctx.repoDir, ctx.baseSha, null, t.path, intake?.task ?? "", k3?.b, k3?.h) ?? []];
|
|
68809
68886
|
});
|
|
68810
68887
|
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"))];
|
|
68888
|
+
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
68889
|
const wallDropped2 = [...wallPaths].filter((p) => !wallTests.some((t) => t.path === p));
|
|
68813
68890
|
notProven.push(...wallDropped2.map((p) => `Wall test not executed: ${p}: ${NO_RUNNER_REASON}`));
|
|
68814
68891
|
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 } };
|
|
68892
|
+
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
68893
|
}
|
|
68817
68894
|
};
|
|
68818
68895
|
stage5 = verifyStage;
|
|
@@ -68843,9 +68920,9 @@ __export(exports_wall, {
|
|
|
68843
68920
|
BASE_RUN_TIMEOUT_MS: () => BASE_RUN_TIMEOUT_MS
|
|
68844
68921
|
});
|
|
68845
68922
|
import { spawnSync as spawnSync10 } from "child_process";
|
|
68846
|
-
import { existsSync as existsSync69, mkdirSync as mkdirSync50, mkdtempSync as mkdtempSync14, readFileSync as
|
|
68923
|
+
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
68924
|
import { tmpdir as tmpdir17 } from "os";
|
|
68848
|
-
import { dirname as
|
|
68925
|
+
import { dirname as dirname39, join as join98, relative as relative22 } from "path";
|
|
68849
68926
|
|
|
68850
68927
|
class RealBaseTestRunner {
|
|
68851
68928
|
api;
|
|
@@ -68911,10 +68988,10 @@ ${acceptance2.map((a) => `Acceptance: ${a}`).join(`
|
|
|
68911
68988
|
function loadTaskText(ctx, fromPrior) {
|
|
68912
68989
|
if (fromPrior)
|
|
68913
68990
|
return fromPrior;
|
|
68914
|
-
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ??
|
|
68991
|
+
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join98(ctx.runDir, "issue.json");
|
|
68915
68992
|
if (existsSync69(issueJsonPath)) {
|
|
68916
68993
|
try {
|
|
68917
|
-
const issue = JSON.parse(
|
|
68994
|
+
const issue = JSON.parse(readFileSync87(issueJsonPath, "utf8"));
|
|
68918
68995
|
const text3 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
|
|
68919
68996
|
|
|
68920
68997
|
`);
|
|
@@ -68926,7 +69003,7 @@ function loadTaskText(ctx, fromPrior) {
|
|
|
68926
69003
|
}
|
|
68927
69004
|
function wallTargetDir(repoDir, existingTests) {
|
|
68928
69005
|
const first = existingTests[0];
|
|
68929
|
-
return first ?
|
|
69006
|
+
return first ? join98(repoDir, dirname39(first.path)) : join98(repoDir, "tests");
|
|
68930
69007
|
}
|
|
68931
69008
|
async function wallAuthor(ctx, signal, retry) {
|
|
68932
69009
|
const done = (result) => ({ kind: "done", result });
|
|
@@ -68952,11 +69029,11 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
68952
69029
|
const tree = prior.intake?.tree;
|
|
68953
69030
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
68954
69031
|
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative22(ctx.repoDir, targetDir)}/x`);
|
|
68955
|
-
const conv2 = readPackageConventions(
|
|
68956
|
-
const cwd = mkdtempSync14(
|
|
69032
|
+
const conv2 = readPackageConventions(join98(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
69033
|
+
const cwd = mkdtempSync14(join98(tmpdir17(), "loki-e15-wall-"));
|
|
68957
69034
|
const wm2 = wallManifestFor(ctx.repoDir, tree, task);
|
|
68958
69035
|
for (const [n10, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm2 ? [["wall_manifest.txt", wm2.text]] : []])
|
|
68959
|
-
writeFileSync49(
|
|
69036
|
+
writeFileSync49(join98(cwd, n10), c, "utf8");
|
|
68960
69037
|
const clauseSet = extractClauses(task);
|
|
68961
69038
|
const model = retry?.model ?? wallFirstModel(sz2.size), iterationId = `${ctx.runId}-wall${retry?.suffix ?? ""}`;
|
|
68962
69039
|
const session = await ctx.sessions.run({
|
|
@@ -68975,21 +69052,21 @@ async function wallAuthor(ctx, signal, retry) {
|
|
|
68975
69052
|
}
|
|
68976
69053
|
const planText = typeof prior.plan?.plan === "string" ? prior.plan.plan : null, repoFiles = repoMap?.files ?? [];
|
|
68977
69054
|
const oor = () => readdirSync28(cwd).filter((f) => f.startsWith(WALL_PREFIX)).flatMap((name) => {
|
|
68978
|
-
const text3 =
|
|
69055
|
+
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
69056
|
return why ? [{ name, why }] : [];
|
|
68980
69057
|
});
|
|
68981
69058
|
const bad1 = oor();
|
|
68982
69059
|
if (bad1.length > 0 && !signal.aborted && !ctx.overCap?.())
|
|
68983
69060
|
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 =
|
|
69061
|
+
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));
|
|
69062
|
+
const sealedDir = join98(ctx.runDir, "wall");
|
|
68986
69063
|
if (generated.length > 0)
|
|
68987
69064
|
mkdirSync50(sealedDir, { recursive: true });
|
|
68988
69065
|
const contents = new Map;
|
|
68989
69066
|
const discarded = [];
|
|
68990
69067
|
for (const name of generated) {
|
|
68991
|
-
const content =
|
|
68992
|
-
writeFileSync49(
|
|
69068
|
+
const content = readFileSync87(join98(cwd, name), "utf8"), oorWhy = oorBad.get(name), bad = oorWhy ?? conventionViolation(conv2, name, content);
|
|
69069
|
+
writeFileSync49(join98(sealedDir, name), content, "utf8");
|
|
68993
69070
|
if (oorWhy)
|
|
68994
69071
|
discarded.push({ file: name, reason: `${oorWhy}; wall test discarded after one rewrite request` });
|
|
68995
69072
|
else if (bad)
|
|
@@ -69018,7 +69095,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
69018
69095
|
const content = contents.get(name);
|
|
69019
69096
|
if (content === undefined)
|
|
69020
69097
|
continue;
|
|
69021
|
-
const dest =
|
|
69098
|
+
const dest = join98(targetDir, name), runner = guessRunner(name, runners, relative22(ctx.repoDir, dest));
|
|
69022
69099
|
writeFileSync49(dest, content, "utf8");
|
|
69023
69100
|
sealedFiles.push({ path: dest, sha256: sha2562(content), ...runner ? { runner } : {} });
|
|
69024
69101
|
readOnlyFiles.push({ path: dest, content });
|
|
@@ -69035,7 +69112,7 @@ function* installCore(ctx, a, baseDir, opts) {
|
|
|
69035
69112
|
}
|
|
69036
69113
|
const each = yield { runner: baseRunner, tests: wallTests };
|
|
69037
69114
|
for (const [i, t] of wallTests.entries()) {
|
|
69038
|
-
const e10 = each?.[i], r = e10 ?? baseRunner.run(baseDir, [t]), abs =
|
|
69115
|
+
const e10 = each?.[i], r = e10 ?? baseRunner.run(baseDir, [t]), abs = join98(ctx.repoDir, t.path);
|
|
69039
69116
|
baseRun.pass += r.pass;
|
|
69040
69117
|
baseRun.fail += r.fail;
|
|
69041
69118
|
baseRun.not_run += r.not_run ?? 0;
|
|
@@ -69078,7 +69155,7 @@ async function runWall(ctx, signal, opts = {}) {
|
|
|
69078
69155
|
if (a.kind === "authored") {
|
|
69079
69156
|
for (const f of first.data.files ?? [])
|
|
69080
69157
|
rmSync29(f.path, { force: true });
|
|
69081
|
-
rmSync29(
|
|
69158
|
+
rmSync29(join98(ctx.runDir, "wall"), { recursive: true, force: true });
|
|
69082
69159
|
ctx.wallSealed = false;
|
|
69083
69160
|
}
|
|
69084
69161
|
removeHoldout(ctx.runId, ctx.repoDir);
|
|
@@ -69118,15 +69195,15 @@ var init_wall = __esm(() => {
|
|
|
69118
69195
|
});
|
|
69119
69196
|
|
|
69120
69197
|
// ../../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
|
|
69198
|
+
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";
|
|
69199
|
+
import { dirname as dirname40, join as join99, relative as relative23, sep as sep19 } from "path";
|
|
69123
69200
|
function safeRestore(repoDir, f, want, mode) {
|
|
69124
|
-
const root = realpathSync29(repoDir), fp2 =
|
|
69201
|
+
const root = realpathSync29(repoDir), fp2 = join99(root, f), rel = relative23(root, dirname40(fp2));
|
|
69125
69202
|
if (rel.startsWith(".."))
|
|
69126
69203
|
throw new Error("outside repo");
|
|
69127
69204
|
let cur = root;
|
|
69128
69205
|
for (const part of rel === "" ? [] : rel.split(sep19)) {
|
|
69129
|
-
cur =
|
|
69206
|
+
cur = join99(cur, part);
|
|
69130
69207
|
let st3;
|
|
69131
69208
|
try {
|
|
69132
69209
|
st3 = lstatSync26(cur);
|
|
@@ -69143,7 +69220,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
69143
69220
|
} catch {
|
|
69144
69221
|
st2 = null;
|
|
69145
69222
|
}
|
|
69146
|
-
if (st2?.isFile() &&
|
|
69223
|
+
if (st2?.isFile() && readFileSync88(fp2).equals(want)) {
|
|
69147
69224
|
chmodSync6(fp2, mode);
|
|
69148
69225
|
return;
|
|
69149
69226
|
}
|
|
@@ -69180,7 +69257,7 @@ async function discardIfSatisfied(git9, base, o, staged, keep, repoDir) {
|
|
|
69180
69257
|
return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
|
|
69181
69258
|
const notProven = [];
|
|
69182
69259
|
for (const [f, v3] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
|
|
69183
|
-
const fp2 =
|
|
69260
|
+
const fp2 = join99(repoDir, f);
|
|
69184
69261
|
try {
|
|
69185
69262
|
if (v3.startsWith("!")) {
|
|
69186
69263
|
const st2 = lstatSync26(fp2);
|
|
@@ -69199,7 +69276,7 @@ async function discardIfSatisfied(git9, base, o, staged, keep, repoDir) {
|
|
|
69199
69276
|
try {
|
|
69200
69277
|
let m = 420;
|
|
69201
69278
|
try {
|
|
69202
|
-
const l = lstatSync26(
|
|
69279
|
+
const l = lstatSync26(join99(repoDir, f));
|
|
69203
69280
|
if (l.isFile())
|
|
69204
69281
|
m = l.mode & 511;
|
|
69205
69282
|
} catch {}
|
|
@@ -69215,7 +69292,7 @@ var init_discard = __esm(() => {
|
|
|
69215
69292
|
});
|
|
69216
69293
|
|
|
69217
69294
|
// ../../loki-ts/src/e10ext/scope.ts
|
|
69218
|
-
import { basename as basename26, dirname as
|
|
69295
|
+
import { basename as basename26, dirname as dirname41 } from "path";
|
|
69219
69296
|
function contractText(o) {
|
|
69220
69297
|
const c = o.intake?.contract_snapshot?.contract;
|
|
69221
69298
|
return Array.isArray(c?.criteria) ? c.criteria.map((x3) => typeof x3?.text === "string" ? x3.text : "").join(`
|
|
@@ -69229,8 +69306,8 @@ function outsideScope(o, staged) {
|
|
|
69229
69306
|
const text3 = `${plan}
|
|
69230
69307
|
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
69231
69308
|
${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(
|
|
69309
|
+
const toks = surfaceTokens(text3), plannedDirs = new Set(rel.map((r) => dirname41(r)).filter((d) => d !== "."));
|
|
69310
|
+
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
69311
|
}
|
|
69235
69312
|
function flagOutsideScope(o, staged) {
|
|
69236
69313
|
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
@@ -69245,14 +69322,14 @@ var init_scope2 = __esm(() => {
|
|
|
69245
69322
|
});
|
|
69246
69323
|
|
|
69247
69324
|
// ../../loki-ts/src/council/role_agents.ts
|
|
69248
|
-
import { existsSync as existsSync70, readdirSync as readdirSync29, readFileSync as
|
|
69325
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, readFileSync as readFileSync89 } from "fs";
|
|
69249
69326
|
import { homedir as homedir11 } from "os";
|
|
69250
|
-
import { join as
|
|
69327
|
+
import { join as join100 } from "path";
|
|
69251
69328
|
function agentDirs(repoDir, env = process.env) {
|
|
69252
|
-
return [env["LOKI_AGENTS_PROJECT_DIR"] ||
|
|
69329
|
+
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
69330
|
}
|
|
69254
69331
|
function parseAgent(file, stem2) {
|
|
69255
|
-
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(
|
|
69332
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync89(file, "utf8"));
|
|
69256
69333
|
if (!m)
|
|
69257
69334
|
return null;
|
|
69258
69335
|
const body = m[2].trim();
|
|
@@ -69277,7 +69354,7 @@ function loadRoleAgent(repoDir, role, env = process.env) {
|
|
|
69277
69354
|
const ordered = [...names.filter((n10) => n10 === `${role}.md`), ...names.filter((n10) => n10 !== `${role}.md`)];
|
|
69278
69355
|
for (const n10 of ordered) {
|
|
69279
69356
|
try {
|
|
69280
|
-
const a = parseAgent(
|
|
69357
|
+
const a = parseAgent(join100(d, n10), n10.slice(0, -3));
|
|
69281
69358
|
if (a && a.role === role)
|
|
69282
69359
|
return a;
|
|
69283
69360
|
} catch {}
|
|
@@ -69296,11 +69373,11 @@ function explicitReview(repoDir, env) {
|
|
|
69296
69373
|
if (flag && isOff(ev2))
|
|
69297
69374
|
return "off";
|
|
69298
69375
|
for (const f of ["loki.yaml", "loki.yml"]) {
|
|
69299
|
-
const p =
|
|
69376
|
+
const p = join100(repoDir, f);
|
|
69300
69377
|
if (!existsSync70(p))
|
|
69301
69378
|
continue;
|
|
69302
69379
|
try {
|
|
69303
|
-
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(
|
|
69380
|
+
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync89(p, "utf8"));
|
|
69304
69381
|
const v3 = asProvider(m?.[1]);
|
|
69305
69382
|
if (v3)
|
|
69306
69383
|
return v3;
|
|
@@ -69333,7 +69410,7 @@ var init_role_agents = __esm(() => {
|
|
|
69333
69410
|
|
|
69334
69411
|
// ../../loki-ts/src/util/child_ledger.ts
|
|
69335
69412
|
import { appendFileSync as appendFileSync10, mkdirSync as mkdirSync52 } from "fs";
|
|
69336
|
-
import { join as
|
|
69413
|
+
import { join as join101 } from "path";
|
|
69337
69414
|
function unmeasuredRecord(phase, model, source) {
|
|
69338
69415
|
return { phase, model, input_tokens: 0, output_tokens: 0, cache_creation_tokens: 0, cache_read_tokens: 0, source, cost_status: "unmeasured" };
|
|
69339
69416
|
}
|
|
@@ -69358,9 +69435,9 @@ function recordFromClaudeResult(phase, payload, source = "claude-json") {
|
|
|
69358
69435
|
}
|
|
69359
69436
|
function appendChildLedger(lokiDir2, rec2) {
|
|
69360
69437
|
try {
|
|
69361
|
-
const dir =
|
|
69438
|
+
const dir = join101(lokiDir2, "metrics");
|
|
69362
69439
|
mkdirSync52(dir, { recursive: true });
|
|
69363
|
-
appendFileSync10(
|
|
69440
|
+
appendFileSync10(join101(dir, "child-sessions.jsonl"), `${JSON.stringify(rec2)}
|
|
69364
69441
|
`);
|
|
69365
69442
|
return true;
|
|
69366
69443
|
} catch {
|
|
@@ -69390,7 +69467,7 @@ var init_child_ledger = __esm(() => {
|
|
|
69390
69467
|
});
|
|
69391
69468
|
|
|
69392
69469
|
// ../../loki-ts/src/engine10/stages/xreview.ts
|
|
69393
|
-
import { join as
|
|
69470
|
+
import { join as join102 } from "path";
|
|
69394
69471
|
function minVerdict(verdict, review) {
|
|
69395
69472
|
const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
|
|
69396
69473
|
return RANK4[ceiling] < RANK4[verdict] ? ceiling : verdict;
|
|
@@ -69488,9 +69565,9 @@ Review ONLY the diff below. Do not modify files.` : "You are an independent code
|
|
|
69488
69565
|
try {
|
|
69489
69566
|
if (p === "claude")
|
|
69490
69567
|
await ensureClaudeHelpCache();
|
|
69491
|
-
const r = await withChildLedger(run,
|
|
69568
|
+
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
69569
|
const costId = `${ctx.runId}-xreview-${p}`;
|
|
69493
|
-
writeReviewerCost(
|
|
69570
|
+
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
69571
|
if (r.exitCode !== 0)
|
|
69495
69572
|
return { ...tag({ provider: p, level: "not_run", notes: [`cross-review not run: ${p} exited ${r.exitCode}`] }), cost_iteration: costId };
|
|
69496
69573
|
return { ...tag(parseReview(p, r.stdout)), cost_iteration: costId };
|
|
@@ -69671,9 +69748,9 @@ __export(exports_contract, {
|
|
|
69671
69748
|
MAX_CONTRACT_BYTES: () => MAX_CONTRACT_BYTES,
|
|
69672
69749
|
CONSTRAINT_KINDS: () => CONSTRAINT_KINDS
|
|
69673
69750
|
});
|
|
69674
|
-
import { existsSync as existsSync71, lstatSync as lstatSync27, mkdirSync as mkdirSync53, readFileSync as
|
|
69751
|
+
import { existsSync as existsSync71, lstatSync as lstatSync27, mkdirSync as mkdirSync53, readFileSync as readFileSync90, rmSync as rmSync30, writeFileSync as writeFileSync51 } from "fs";
|
|
69675
69752
|
import { spawnSync as spawnSync11 } from "child_process";
|
|
69676
|
-
import { dirname as
|
|
69753
|
+
import { dirname as dirname42, join as join103 } from "path";
|
|
69677
69754
|
import { createHash as createHash28 } from "crypto";
|
|
69678
69755
|
function contractEnabled(env = process.env) {
|
|
69679
69756
|
return env["LOKI_CONTRACT"] !== "0";
|
|
@@ -69740,7 +69817,7 @@ function assignCriteria(units, criteria2) {
|
|
|
69740
69817
|
return { units: out3, orphans: criteria2.filter((c) => !owned.has(c.id)) };
|
|
69741
69818
|
}
|
|
69742
69819
|
function groupContractPath(repoDir, groupId) {
|
|
69743
|
-
return
|
|
69820
|
+
return join103(repoDir, ".loki", "groups", groupId.replace(/[^A-Za-z0-9._-]/g, "_"), "contract.json");
|
|
69744
69821
|
}
|
|
69745
69822
|
function freezeGroupContract(repoDir, groupId, units, contract) {
|
|
69746
69823
|
const a = assignCriteria(units, contract.criteria);
|
|
@@ -69748,7 +69825,7 @@ function freezeGroupContract(repoDir, groupId, units, contract) {
|
|
|
69748
69825
|
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
69826
|
const gc2 = { group: groupId, units: a.units, orphans: [] };
|
|
69750
69827
|
const path = groupContractPath(repoDir, groupId);
|
|
69751
|
-
mkdirSync53(
|
|
69828
|
+
mkdirSync53(dirname42(path), { recursive: true });
|
|
69752
69829
|
atomicWriteJson(path, gc2);
|
|
69753
69830
|
return { ok: true, path, contract: gc2 };
|
|
69754
69831
|
}
|
|
@@ -69805,7 +69882,7 @@ function untracedLines(trace) {
|
|
|
69805
69882
|
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
69883
|
}
|
|
69807
69884
|
function contractPath(repoDir) {
|
|
69808
|
-
return
|
|
69885
|
+
return join103(repoDir, ".loki", "contract.json");
|
|
69809
69886
|
}
|
|
69810
69887
|
function readContract(repoDir) {
|
|
69811
69888
|
const p = contractPath(repoDir);
|
|
@@ -69821,7 +69898,7 @@ function readContract(repoDir) {
|
|
|
69821
69898
|
return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
|
|
69822
69899
|
let raw2;
|
|
69823
69900
|
try {
|
|
69824
|
-
raw2 =
|
|
69901
|
+
raw2 = readFileSync90(p);
|
|
69825
69902
|
} catch {
|
|
69826
69903
|
return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
|
|
69827
69904
|
}
|
|
@@ -69893,9 +69970,9 @@ function main3(args) {
|
|
|
69893
69970
|
`);
|
|
69894
69971
|
return 2;
|
|
69895
69972
|
}
|
|
69896
|
-
const contract = parseContract(
|
|
69973
|
+
const contract = parseContract(readFileSync90(file, "utf8"), file);
|
|
69897
69974
|
const out3 = contractPath(repoRoot(process.cwd()));
|
|
69898
|
-
mkdirSync53(
|
|
69975
|
+
mkdirSync53(dirname42(out3), { recursive: true });
|
|
69899
69976
|
writeFileSync51(out3, JSON.stringify(contract, null, 2) + `
|
|
69900
69977
|
`);
|
|
69901
69978
|
process.stdout.write(renderContract(contract));
|
|
@@ -69952,7 +70029,7 @@ function fromSpecText(raw2) {
|
|
|
69952
70029
|
}
|
|
69953
70030
|
}
|
|
69954
70031
|
function fromPrdText(text3, python = "python3") {
|
|
69955
|
-
const script =
|
|
70032
|
+
const script = join103(REPO_ROOT, "autonomy", "lib", "requirements_contract.py");
|
|
69956
70033
|
if (!existsSync71(script))
|
|
69957
70034
|
return null;
|
|
69958
70035
|
const code = `import sys,json,importlib.util as u
|
|
@@ -69995,12 +70072,12 @@ function mapRequirements(reqs, ran2, revision) {
|
|
|
69995
70072
|
return { version: 1, revision, requirements: out3 };
|
|
69996
70073
|
}
|
|
69997
70074
|
function fromChecklist(lokiDir2) {
|
|
69998
|
-
const p =
|
|
70075
|
+
const p = join103(lokiDir2, "checklist", "checklist.json");
|
|
69999
70076
|
if (!existsSync71(p))
|
|
70000
70077
|
return null;
|
|
70001
70078
|
let doc;
|
|
70002
70079
|
try {
|
|
70003
|
-
doc = JSON.parse(
|
|
70080
|
+
doc = JSON.parse(readFileSync90(p, "utf8"));
|
|
70004
70081
|
} catch {
|
|
70005
70082
|
return null;
|
|
70006
70083
|
}
|
|
@@ -70032,7 +70109,7 @@ function writeRequirementsMap(repoDir, lokiDir2, reqs, ran2) {
|
|
|
70032
70109
|
if (!reqs || reqs.length === 0)
|
|
70033
70110
|
return null;
|
|
70034
70111
|
const m = mapRequirements(reqs, ran2, currentRevision(repoDir));
|
|
70035
|
-
atomicWriteJson(
|
|
70112
|
+
atomicWriteJson(join103(lokiDir2, "state", "requirements-map.json"), m);
|
|
70036
70113
|
return m;
|
|
70037
70114
|
} catch {
|
|
70038
70115
|
return null;
|
|
@@ -70044,17 +70121,17 @@ function writeFromChecklist(repoDir, lokiDir2) {
|
|
|
70044
70121
|
}
|
|
70045
70122
|
function writeFromEngine10(repoDir, lokiDir2, runDir, task, events2) {
|
|
70046
70123
|
let reqs = null;
|
|
70047
|
-
const snap =
|
|
70124
|
+
const snap = join103(runDir, "spec.snapshot.md");
|
|
70048
70125
|
if (existsSync71(snap)) {
|
|
70049
70126
|
try {
|
|
70050
|
-
reqs = fromSpecText(
|
|
70127
|
+
reqs = fromSpecText(readFileSync90(snap, "utf8"));
|
|
70051
70128
|
} catch {
|
|
70052
70129
|
reqs = null;
|
|
70053
70130
|
}
|
|
70054
70131
|
}
|
|
70055
70132
|
if (!reqs && task)
|
|
70056
70133
|
reqs = fromPrdText(task);
|
|
70057
|
-
const mapPath =
|
|
70134
|
+
const mapPath = join103(lokiDir2, "state", "requirements-map.json");
|
|
70058
70135
|
if (!reqs || reqs.length === 0) {
|
|
70059
70136
|
try {
|
|
70060
70137
|
rmSync30(mapPath, { force: true });
|
|
@@ -70080,7 +70157,7 @@ function uncoveredCount(m) {
|
|
|
70080
70157
|
}
|
|
70081
70158
|
function readRequirementsMap(lokiDir2) {
|
|
70082
70159
|
try {
|
|
70083
|
-
const m = JSON.parse(
|
|
70160
|
+
const m = JSON.parse(readFileSync90(join103(lokiDir2, "state", "requirements-map.json"), "utf8"));
|
|
70084
70161
|
return m.version === 1 && Array.isArray(m.requirements) ? m : null;
|
|
70085
70162
|
} catch {
|
|
70086
70163
|
return null;
|
|
@@ -70108,17 +70185,17 @@ var init_contract = __esm(() => {
|
|
|
70108
70185
|
BULLET = /^\s*(?:[-*+]|\d+[.)])\s+(.+)$/;
|
|
70109
70186
|
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
70187
|
MAX_CONTRACT_BYTES = 1024 * 1024;
|
|
70111
|
-
REQ_MAP_REL =
|
|
70188
|
+
REQ_MAP_REL = join103(".loki", "state", "requirements-map.json");
|
|
70112
70189
|
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
70190
|
LINK_RE = /\s*\[checks?:\s*([^\]]+)\]\s*$/i;
|
|
70114
70191
|
});
|
|
70115
70192
|
|
|
70116
70193
|
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
70117
70194
|
import { createHash as createHash29 } from "crypto";
|
|
70118
|
-
import { existsSync as existsSync72, mkdirSync as mkdirSync54, readdirSync as readdirSync30, readFileSync as
|
|
70119
|
-
import { dirname as
|
|
70195
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync54, readdirSync as readdirSync30, readFileSync as readFileSync91, renameSync as renameSync20, statSync as statSync26, writeFileSync as writeFileSync52 } from "fs";
|
|
70196
|
+
import { dirname as dirname43, join as join104 } from "path";
|
|
70120
70197
|
function sealGroup(runDir, rh) {
|
|
70121
|
-
const manifestPath =
|
|
70198
|
+
const manifestPath = join104(runDir, "group", "manifest.json");
|
|
70122
70199
|
if (!existsSync72(manifestPath))
|
|
70123
70200
|
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
70124
70201
|
const notProven = [];
|
|
@@ -70143,10 +70220,10 @@ function sealGroup(runDir, rh) {
|
|
|
70143
70220
|
return fail2(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
70144
70221
|
seen.add(id2);
|
|
70145
70222
|
seenLower.add(id2.toLowerCase());
|
|
70146
|
-
const dir =
|
|
70223
|
+
const dir = join104(unitsDir(runDir), id2), rp = join104(dir, "receipt.json"), ep2 = join104(dir, "events.jsonl");
|
|
70147
70224
|
let bytes;
|
|
70148
70225
|
try {
|
|
70149
|
-
bytes =
|
|
70226
|
+
bytes = readFileSync91(rp);
|
|
70150
70227
|
} catch {
|
|
70151
70228
|
return fail2(`unit ${id2} sub-receipt missing`);
|
|
70152
70229
|
}
|
|
@@ -70165,7 +70242,7 @@ function sealGroup(runDir, rh) {
|
|
|
70165
70242
|
unit_id: id2,
|
|
70166
70243
|
sub_receipt_sha256: sha4(bytes),
|
|
70167
70244
|
receipt_sha256: sub["receipt_sha256"],
|
|
70168
|
-
events_file_sha256: existsSync72(ep2) ? sha4(
|
|
70245
|
+
events_file_sha256: existsSync72(ep2) ? sha4(readFileSync91(ep2)) : null,
|
|
70169
70246
|
verdict,
|
|
70170
70247
|
goal: text3(u10["goal"], 200),
|
|
70171
70248
|
files: (Array.isArray(u10["files"]) ? u10["files"] : []).map((f) => text3(f, 200)).filter(Boolean).slice(0, 50),
|
|
@@ -70185,12 +70262,12 @@ function capGroupVerdict(v3, g) {
|
|
|
70185
70262
|
return !g.allUnitsPass && (v3 === "VERIFIED" || v3 === "ALREADY_SATISFIED") ? "PARTIAL" : v3;
|
|
70186
70263
|
}
|
|
70187
70264
|
async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
70188
|
-
const runDir =
|
|
70265
|
+
const runDir = dirname43(receiptPath);
|
|
70189
70266
|
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
70190
70267
|
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
70191
70268
|
const g = receipt["group"];
|
|
70192
70269
|
if (g === undefined)
|
|
70193
|
-
return existsSync72(
|
|
70270
|
+
return existsSync72(join104(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
70194
70271
|
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
70195
70272
|
return bad("group section malformed");
|
|
70196
70273
|
const entries = g["units"];
|
|
@@ -70202,20 +70279,20 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
70202
70279
|
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
70203
70280
|
let unchecked = null;
|
|
70204
70281
|
for (let i = 0;i < entries.length; i++) {
|
|
70205
|
-
const e10 = entries[i], id2 = ids[i], dir =
|
|
70282
|
+
const e10 = entries[i], id2 = ids[i], dir = join104(unitsDir(runDir), id2), rp = join104(dir, "receipt.json"), ep2 = join104(dir, "events.jsonl");
|
|
70206
70283
|
if (e10["index"] !== i)
|
|
70207
70284
|
return bad(`unit ${id2} is out of order (index ${String(e10["index"])} at position ${i})`);
|
|
70208
70285
|
let bytes;
|
|
70209
70286
|
try {
|
|
70210
70287
|
if (!statSync26(dir).isDirectory())
|
|
70211
70288
|
return bad(`unit ${id2} is not a directory`);
|
|
70212
|
-
bytes =
|
|
70289
|
+
bytes = readFileSync91(rp);
|
|
70213
70290
|
} catch {
|
|
70214
70291
|
return bad(`unit ${id2} sub-receipt missing`);
|
|
70215
70292
|
}
|
|
70216
70293
|
if (sha4(bytes) !== e10["sub_receipt_sha256"])
|
|
70217
70294
|
return bad(`unit ${id2} sub-receipt does not match its recorded hash`);
|
|
70218
|
-
const evSha = existsSync72(ep2) ? sha4(
|
|
70295
|
+
const evSha = existsSync72(ep2) ? sha4(readFileSync91(ep2)) : null;
|
|
70219
70296
|
if (evSha !== (e10["events_file_sha256"] ?? null))
|
|
70220
70297
|
return bad(`unit ${id2} events.jsonl does not match its recorded hash`);
|
|
70221
70298
|
const sub = readJson7(rp);
|
|
@@ -70244,7 +70321,7 @@ function composeGroupReceipt(groupDir, rh, o) {
|
|
|
70244
70321
|
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
70322
|
const hash = rh(body), sig = signReceipt(gid, hash);
|
|
70246
70323
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
70247
|
-
const path =
|
|
70324
|
+
const path = join104(groupDir, "receipt.json"), tmp = `${path}.${process.pid}.tmp`;
|
|
70248
70325
|
mkdirSync54(groupDir, { recursive: true });
|
|
70249
70326
|
writeFileSync52(tmp, JSON.stringify(receipt, null, 2) + `
|
|
70250
70327
|
`);
|
|
@@ -70256,9 +70333,9 @@ function compositeVerdict(childVerdicts) {
|
|
|
70256
70333
|
const failed2 = childVerdicts.filter((v3) => v3 === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v3)).length;
|
|
70257
70334
|
return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v3) => PASSING.has(v3)) });
|
|
70258
70335
|
}
|
|
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) =>
|
|
70336
|
+
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
70337
|
try {
|
|
70261
|
-
return JSON.parse(
|
|
70338
|
+
return JSON.parse(readFileSync91(p, "utf8"));
|
|
70262
70339
|
} catch {
|
|
70263
70340
|
return;
|
|
70264
70341
|
}
|
|
@@ -70276,8 +70353,8 @@ var init_seal_group = __esm(() => {
|
|
|
70276
70353
|
});
|
|
70277
70354
|
|
|
70278
70355
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
70279
|
-
import { existsSync as existsSync73, readFileSync as
|
|
70280
|
-
import { basename as basename27, join as
|
|
70356
|
+
import { existsSync as existsSync73, readFileSync as readFileSync92, statSync as statSync27 } from "fs";
|
|
70357
|
+
import { basename as basename27, join as join105 } from "path";
|
|
70281
70358
|
function supplyEnabled(env) {
|
|
70282
70359
|
return env["LOKI_SUPPLY_GUARD"] !== "0";
|
|
70283
70360
|
}
|
|
@@ -70292,13 +70369,13 @@ function isManifestPath(path) {
|
|
|
70292
70369
|
return MANIFESTS2.test(basename27(path));
|
|
70293
70370
|
}
|
|
70294
70371
|
function readDeclared(repoDir) {
|
|
70295
|
-
const p =
|
|
70372
|
+
const p = join105(repoDir, ".loki", DECLARED_FILE);
|
|
70296
70373
|
if (!existsSync73(p))
|
|
70297
70374
|
return { deps: [], problem: null };
|
|
70298
70375
|
try {
|
|
70299
70376
|
if (statSync27(p).size > MAX_FILE_BYTES)
|
|
70300
70377
|
return { deps: [], problem: "declaration file too large" };
|
|
70301
|
-
const j10 = JSON.parse(
|
|
70378
|
+
const j10 = JSON.parse(readFileSync92(p, "utf8"));
|
|
70302
70379
|
if (!Array.isArray(j10))
|
|
70303
70380
|
return { deps: [], problem: "declaration is not a JSON array" };
|
|
70304
70381
|
const deps = [];
|
|
@@ -70318,11 +70395,11 @@ function readDeclared(repoDir) {
|
|
|
70318
70395
|
}
|
|
70319
70396
|
}
|
|
70320
70397
|
function readAllowlist(repoDir) {
|
|
70321
|
-
const p =
|
|
70398
|
+
const p = join105(repoDir, ".loki", "supply-allowlist");
|
|
70322
70399
|
if (!existsSync73(p))
|
|
70323
70400
|
return new Set;
|
|
70324
70401
|
try {
|
|
70325
|
-
return new Set(
|
|
70402
|
+
return new Set(readFileSync92(p, "utf8").split(`
|
|
70326
70403
|
`).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
|
|
70327
70404
|
} catch {
|
|
70328
70405
|
return new Set;
|
|
@@ -70363,7 +70440,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70363
70440
|
if (eco === "npm") {
|
|
70364
70441
|
if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
|
|
70365
70442
|
return true;
|
|
70366
|
-
return files(
|
|
70443
|
+
return files(join105(repoDir, ".npmrc"), home ? join105(home, ".npmrc") : "").some((t) => t.split(`
|
|
70367
70444
|
`).some((l) => {
|
|
70368
70445
|
const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
|
|
70369
70446
|
return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
|
|
@@ -70372,7 +70449,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70372
70449
|
if (eco === "pypi") {
|
|
70373
70450
|
if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
|
|
70374
70451
|
return true;
|
|
70375
|
-
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ?
|
|
70452
|
+
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join105(home, ".config", "pip", "pip.conf") : "", home ? join105(home, ".pip", "pip.conf") : "", join105(repoDir, "pip.conf")];
|
|
70376
70453
|
return files(...cfg).some((t) => t.split(`
|
|
70377
70454
|
`).some((l) => {
|
|
70378
70455
|
const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
|
|
@@ -70382,7 +70459,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
70382
70459
|
if (eco === "cargo") {
|
|
70383
70460
|
if (Object.keys(env).some((k3) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k3) || /^CARGO_SOURCE_/.test(k3)))
|
|
70384
70461
|
return true;
|
|
70385
|
-
return files(
|
|
70462
|
+
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
70463
|
}
|
|
70387
70464
|
if (eco === "go") {
|
|
70388
70465
|
const gp2 = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
|
|
@@ -70505,7 +70582,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
|
|
|
70505
70582
|
}
|
|
70506
70583
|
}, 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
70584
|
try {
|
|
70508
|
-
return statSync27(p).size <= MAX_FILE_BYTES ?
|
|
70585
|
+
return statSync27(p).size <= MAX_FILE_BYTES ? readFileSync92(p, "utf8") : "";
|
|
70509
70586
|
} catch {
|
|
70510
70587
|
return "";
|
|
70511
70588
|
}
|
|
@@ -70544,8 +70621,8 @@ __export(exports_seal, {
|
|
|
70544
70621
|
AGENT_ONLY_REASON: () => AGENT_ONLY_REASON
|
|
70545
70622
|
});
|
|
70546
70623
|
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
|
|
70624
|
+
import { existsSync as existsSync74, readdirSync as readdirSync31, mkdirSync as mkdirSync55, readFileSync as readFileSync93 } from "fs";
|
|
70625
|
+
import { basename as basename28, isAbsolute as isAbsolute20, join as join106, relative as relative24 } from "path";
|
|
70549
70626
|
async function leanSymbolGap(ctx, o, rawDiff, head, vraw) {
|
|
70550
70627
|
if (externalRun(o) || Array.isArray(o.wall?.files) && o.wall.files.length > 0 || o.intake?.already_satisfied === true || o.implement?.exit === "already_done")
|
|
70551
70628
|
return [];
|
|
@@ -70566,7 +70643,7 @@ async function leanSymbolGap(ctx, o, rawDiff, head, vraw) {
|
|
|
70566
70643
|
const n11 = String(c.name ?? ""), p = n11.slice(n11.indexOf(":") + 1);
|
|
70567
70644
|
if (n11.includes(":") && isTestFile(p))
|
|
70568
70645
|
try {
|
|
70569
|
-
sources2.push(
|
|
70646
|
+
sources2.push(readFileSync93(join106(ctx.repoDir, p), "utf8"));
|
|
70570
70647
|
} catch {}
|
|
70571
70648
|
}
|
|
70572
70649
|
return symbolGap(changedSymbols(d.stdout), sources2);
|
|
@@ -70649,7 +70726,7 @@ function renderReceiptMd(r) {
|
|
|
70649
70726
|
`);
|
|
70650
70727
|
}
|
|
70651
70728
|
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,
|
|
70729
|
+
const r = relative24(ctx.repoDir, join106(ctx.runDir, "receipt.json"));
|
|
70653
70730
|
return r.startsWith("..") || isAbsolute20(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
70654
70731
|
}, commitStage, wallGreenOnBaseOf = (o) => {
|
|
70655
70732
|
const b = o.wall?.base_run ?? {};
|
|
@@ -70791,7 +70868,7 @@ var init_seal = __esm(() => {
|
|
|
70791
70868
|
if (wallNotRun > 0) {
|
|
70792
70869
|
try {
|
|
70793
70870
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename28(String(f.path))));
|
|
70794
|
-
for (const n11 of readdirSync31(
|
|
70871
|
+
for (const n11 of readdirSync31(join106(ctx.runDir, "wall")).sort())
|
|
70795
70872
|
if (!kept.has(n11))
|
|
70796
70873
|
notProven.add(`wall test discarded: ${n11} (not_run)`);
|
|
70797
70874
|
} catch {}
|
|
@@ -70862,19 +70939,19 @@ var init_seal = __esm(() => {
|
|
|
70862
70939
|
for (const [s, d] of Object.entries(o))
|
|
70863
70940
|
if (typeof d?.duration_s === "number")
|
|
70864
70941
|
stages[s] = d.duration_s;
|
|
70865
|
-
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(
|
|
70942
|
+
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
70943
|
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
70944
|
if (iterIds.length === 0)
|
|
70868
70945
|
notProven.add("cost not measured (no iteration ids recorded)");
|
|
70869
70946
|
const cost = ctx.cost.read(ctx.repoDir, iterIds);
|
|
70870
70947
|
if (cost.unmetered)
|
|
70871
70948
|
notProven.add("cost unmetered (CLI invoker; recorded as 0)");
|
|
70872
|
-
const eventsPath =
|
|
70949
|
+
const eventsPath = join106(ctx.runDir, "events.jsonl");
|
|
70873
70950
|
const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
|
|
70874
70951
|
const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
|
|
70875
70952
|
if (wallFiles.length > 0 && wallPassed === null)
|
|
70876
70953
|
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(
|
|
70954
|
+
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
70955
|
if (routeBlock)
|
|
70879
70956
|
for (const l of routeNotProven(routeBlock))
|
|
70880
70957
|
notProven.add(l);
|
|
@@ -70917,7 +70994,7 @@ var init_seal = __esm(() => {
|
|
|
70917
70994
|
model: externalRun(o) ? EXTERNAL_MODEL_LABEL : ctx.model,
|
|
70918
70995
|
...externalRun(o) ? { implement: { exit: "external", patch_sha256: str3(o.implement?.patch_sha256) ?? "" } } : {},
|
|
70919
70996
|
resumed: o.intake?.resumed === true,
|
|
70920
|
-
events_sha256: sha2562(existsSync74(eventsPath) ?
|
|
70997
|
+
events_sha256: sha2562(existsSync74(eventsPath) ? readFileSync93(eventsPath) : ""),
|
|
70921
70998
|
...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
|
|
70922
70999
|
log_seal: true,
|
|
70923
71000
|
toolchain: collectToolchain(),
|
|
@@ -70945,10 +71022,10 @@ var init_seal = __esm(() => {
|
|
|
70945
71022
|
}
|
|
70946
71023
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
70947
71024
|
mkdirSync55(ctx.runDir, { recursive: true });
|
|
70948
|
-
const path =
|
|
71025
|
+
const path = join106(ctx.runDir, "receipt.json");
|
|
70949
71026
|
atomicWriteText(path, JSON.stringify(receipt, null, 2) + `
|
|
70950
71027
|
`);
|
|
70951
|
-
atomicWriteText(
|
|
71028
|
+
atomicWriteText(join106(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
70952
71029
|
recordRun(process.env, ctx.repoDir, ranModel(o.implement, ctx.model, o.fix), verdict, cost.usd, cost.unmetered === true, totalS);
|
|
70953
71030
|
try {
|
|
70954
71031
|
hooks.sealed?.(ctx.runDir, JSON.parse(JSON.stringify(receipt), (_k2, v3) => v3 && typeof v3 === "object" ? Object.freeze(v3) : v3));
|
|
@@ -71022,7 +71099,7 @@ var init_github_token = __esm(() => {
|
|
|
71022
71099
|
// ../../loki-ts/src/engine10/fetch_issue.ts
|
|
71023
71100
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
71024
71101
|
import { writeFileSync as writeFileSync54 } from "fs";
|
|
71025
|
-
import { join as
|
|
71102
|
+
import { join as join107 } from "path";
|
|
71026
71103
|
function defaultExec(cmd, args) {
|
|
71027
71104
|
const ms = Number(process.env.LOKI_FETCH_ISSUE_TIMEOUT_MS) || 60000;
|
|
71028
71105
|
return execFileSync7(cmd, args, { encoding: "utf8", env: process.env, timeout: ms, killSignal: "SIGKILL" });
|
|
@@ -71049,7 +71126,7 @@ function fetchIssueToFile(ref, outFile, exec = defaultExec) {
|
|
|
71049
71126
|
var ISSUE_PROVIDERS_SH;
|
|
71050
71127
|
var init_fetch_issue = __esm(() => {
|
|
71051
71128
|
init_paths();
|
|
71052
|
-
ISSUE_PROVIDERS_SH =
|
|
71129
|
+
ISSUE_PROVIDERS_SH = join107(REPO_ROOT, "autonomy/issue-providers.sh");
|
|
71053
71130
|
if (false) {}
|
|
71054
71131
|
});
|
|
71055
71132
|
|
|
@@ -71597,14 +71674,14 @@ var init_capability = __esm(() => {
|
|
|
71597
71674
|
var init_raster = () => {};
|
|
71598
71675
|
|
|
71599
71676
|
// ../../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
|
|
71677
|
+
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
71678
|
import { spawnSync as spawnSync12 } from "child_process";
|
|
71602
71679
|
import { homedir as homedir12, tmpdir as tmpdir18 } from "os";
|
|
71603
|
-
import { join as
|
|
71680
|
+
import { join as join108, resolve as resolve31 } from "path";
|
|
71604
71681
|
function loadRequirements(file = REQUIREMENTS_FILE) {
|
|
71605
71682
|
if (file === REQUIREMENTS_FILE && cached)
|
|
71606
71683
|
return cached;
|
|
71607
|
-
const t = JSON.parse(
|
|
71684
|
+
const t = JSON.parse(readFileSync94(file, "utf8"));
|
|
71608
71685
|
if (file === REQUIREMENTS_FILE)
|
|
71609
71686
|
cached = t;
|
|
71610
71687
|
return t;
|
|
@@ -71635,7 +71712,7 @@ function providerLoginIssue(provider, cli, env) {
|
|
|
71635
71712
|
const said = `${r.stdout}${r.stderr}`;
|
|
71636
71713
|
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
71714
|
}
|
|
71638
|
-
if (PROVIDER_API_KEY_VARS.some(key) || provider === "opencode" && existsSync75(
|
|
71715
|
+
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
71716
|
return null;
|
|
71640
71717
|
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
71718
|
}
|
|
@@ -71646,9 +71723,9 @@ function providerAuthPath(provider, env) {
|
|
|
71646
71723
|
const v3 = own.find(set);
|
|
71647
71724
|
if (v3)
|
|
71648
71725
|
return `${v3 === "CLAUDE_CODE_OAUTH_TOKEN" ? "oauth_token" : "api_key"}:${v3}`;
|
|
71649
|
-
if (provider === "opencode" && existsSync75(
|
|
71726
|
+
if (provider === "opencode" && existsSync75(join108(env.XDG_DATA_HOME || join108(home, ".local", "share"), "opencode", "auth.json")))
|
|
71650
71727
|
return "cli_login:opencode";
|
|
71651
|
-
if (provider === "cline" && existsSync75(
|
|
71728
|
+
if (provider === "cline" && existsSync75(join108(home, ".cline")))
|
|
71652
71729
|
return "cli_login:cline";
|
|
71653
71730
|
return provider === "claude" || provider === "codex" ? `cli_login:${provider}` : "none";
|
|
71654
71731
|
}
|
|
@@ -71673,9 +71750,9 @@ function claudeAuthStatusLoggedIn(cli = "claude", env = process.env) {
|
|
|
71673
71750
|
}
|
|
71674
71751
|
}
|
|
71675
71752
|
function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
71676
|
-
const file =
|
|
71753
|
+
const file = join108(env.HOME || homedir12(), ".loki", "claude-login-ok.json");
|
|
71677
71754
|
try {
|
|
71678
|
-
const c = JSON.parse(
|
|
71755
|
+
const c = JSON.parse(readFileSync94(file, "utf8"));
|
|
71679
71756
|
if (c?.cli === cli && typeof c.at === "number" && now2 - c.at >= 0 && now2 - c.at < CLAUDE_LOGIN_TTL_MS)
|
|
71680
71757
|
return "yes";
|
|
71681
71758
|
} catch {}
|
|
@@ -71684,7 +71761,7 @@ function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
|
71684
71761
|
li2 = claudeAuthStatusLoggedIn(cli, env);
|
|
71685
71762
|
if (li2 === "yes") {
|
|
71686
71763
|
try {
|
|
71687
|
-
mkdirSync56(
|
|
71764
|
+
mkdirSync56(join108(file, ".."), { recursive: true });
|
|
71688
71765
|
writeFileSync56(file, JSON.stringify({ cli, at: now2 }));
|
|
71689
71766
|
} catch {}
|
|
71690
71767
|
}
|
|
@@ -71693,16 +71770,16 @@ function claudeLoginProbeCached(cli, env = process.env, now2 = Date.now()) {
|
|
|
71693
71770
|
async function ghAuthProbeCached(env, probe, now2 = Date.now()) {
|
|
71694
71771
|
const bin = "gh";
|
|
71695
71772
|
const gh = Bun.which(bin, { PATH: env.PATH ?? process.env.PATH ?? "" }) ?? bin;
|
|
71696
|
-
const file =
|
|
71773
|
+
const file = join108(env.HOME || homedir12(), ".loki", "gh-auth-ok.json");
|
|
71697
71774
|
try {
|
|
71698
|
-
const c = JSON.parse(
|
|
71775
|
+
const c = JSON.parse(readFileSync94(file, "utf8"));
|
|
71699
71776
|
if (c?.gh === gh && typeof c.at === "number" && now2 - c.at >= 0 && now2 - c.at < CLAUDE_LOGIN_TTL_MS)
|
|
71700
71777
|
return true;
|
|
71701
71778
|
} catch {}
|
|
71702
71779
|
const ok3 = await probe();
|
|
71703
71780
|
if (ok3) {
|
|
71704
71781
|
try {
|
|
71705
|
-
mkdirSync56(
|
|
71782
|
+
mkdirSync56(join108(file, ".."), { recursive: true });
|
|
71706
71783
|
writeFileSync56(file, JSON.stringify({ gh, at: now2 }));
|
|
71707
71784
|
} catch {}
|
|
71708
71785
|
}
|
|
@@ -71777,7 +71854,7 @@ var init_first_run_repo = __esm(() => {
|
|
|
71777
71854
|
|
|
71778
71855
|
// ../../loki-ts/src/engine10/preflight.ts
|
|
71779
71856
|
import { accessSync as accessSync3, constants as fsc2, mkdirSync as mkdirSync57, statfsSync as statfsSync2, writeFileSync as writeFileSync57 } from "fs";
|
|
71780
|
-
import { join as
|
|
71857
|
+
import { join as join109 } from "path";
|
|
71781
71858
|
async function sh3(argv, opts) {
|
|
71782
71859
|
try {
|
|
71783
71860
|
return await run(argv, opts);
|
|
@@ -71861,7 +71938,7 @@ async function checkPreflight(o) {
|
|
|
71861
71938
|
if (o.runDir) {
|
|
71862
71939
|
try {
|
|
71863
71940
|
mkdirSync57(o.runDir, { recursive: true });
|
|
71864
|
-
writeFileSync57(
|
|
71941
|
+
writeFileSync57(join109(o.runDir, "preflight.json"), JSON.stringify({ provider: o.provider, auth_path, probe }) + `
|
|
71865
71942
|
`);
|
|
71866
71943
|
} catch {}
|
|
71867
71944
|
}
|
|
@@ -71909,7 +71986,7 @@ var exports_ship_hook = {};
|
|
|
71909
71986
|
__export(exports_ship_hook, {
|
|
71910
71987
|
startShip: () => startShip
|
|
71911
71988
|
});
|
|
71912
|
-
import { dirname as
|
|
71989
|
+
import { dirname as dirname45 } from "path";
|
|
71913
71990
|
async function startShip(repoDir, eventsPath, env) {
|
|
71914
71991
|
let url = shipEnabled(env);
|
|
71915
71992
|
if (!url) {
|
|
@@ -71919,7 +71996,7 @@ async function startShip(repoDir, eventsPath, env) {
|
|
|
71919
71996
|
}
|
|
71920
71997
|
if (!url)
|
|
71921
71998
|
return;
|
|
71922
|
-
startShipLoop({ runDir:
|
|
71999
|
+
startShipLoop({ runDir: dirname45(eventsPath), url, source: sourceId(repoDir), token: env.LOKI_CONTROL_TOKEN });
|
|
71923
72000
|
}
|
|
71924
72001
|
var init_ship_hook = __esm(() => {
|
|
71925
72002
|
init_discover();
|
|
@@ -72526,10 +72603,10 @@ __export(exports_run_group, {
|
|
|
72526
72603
|
groupCostLine: () => groupCostLine,
|
|
72527
72604
|
NOT_PROVEN: () => NOT_PROVEN
|
|
72528
72605
|
});
|
|
72529
|
-
import { cpSync as cpSync2, existsSync as existsSync76, mkdirSync as mkdirSync58, readdirSync as readdirSync34, readFileSync as
|
|
72606
|
+
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
72607
|
import { createHash as createHash31 } from "crypto";
|
|
72531
72608
|
import { spawn as spawn12 } from "child_process";
|
|
72532
|
-
import { join as
|
|
72609
|
+
import { join as join110, resolve as resolve32 } from "path";
|
|
72533
72610
|
function scopedEnv(env) {
|
|
72534
72611
|
const out3 = {};
|
|
72535
72612
|
for (const [k3, v3] of Object.entries(env))
|
|
@@ -72566,7 +72643,7 @@ function groupCostLine(costs, provider = "claude") {
|
|
|
72566
72643
|
`;
|
|
72567
72644
|
}
|
|
72568
72645
|
function writeGroupCostRecord(repoDir, name, costs, provider) {
|
|
72569
|
-
const dir =
|
|
72646
|
+
const dir = join110(repoDir, ".loki", "metrics", "efficiency");
|
|
72570
72647
|
const timestamp = new Date().toISOString();
|
|
72571
72648
|
try {
|
|
72572
72649
|
const base = { phase: "implement", provider, status: "group", kind: "group_cost", timestamp };
|
|
@@ -72580,7 +72657,7 @@ function writeGroupCostRecord(repoDir, name, costs, provider) {
|
|
|
72580
72657
|
if (recs.length === 0)
|
|
72581
72658
|
return;
|
|
72582
72659
|
mkdirSync58(dir, { recursive: true });
|
|
72583
|
-
recs.forEach((r, k3) => atomicWriteJson(
|
|
72660
|
+
recs.forEach((r, k3) => atomicWriteJson(join110(dir, `iteration-group-${name}-${String(k3).padStart(3, "0")}.json`), r));
|
|
72584
72661
|
} catch {}
|
|
72585
72662
|
}
|
|
72586
72663
|
function testCommand(repoDir, env) {
|
|
@@ -72593,7 +72670,7 @@ function testCommand(repoDir, env) {
|
|
|
72593
72670
|
return [];
|
|
72594
72671
|
}
|
|
72595
72672
|
function findResumable(repoDir, specSha, unitIds) {
|
|
72596
|
-
const root =
|
|
72673
|
+
const root = join110(repoDir, ".loki", "groups");
|
|
72597
72674
|
let names = [];
|
|
72598
72675
|
try {
|
|
72599
72676
|
names = readdirSync34(root);
|
|
@@ -72604,7 +72681,7 @@ function findResumable(repoDir, specSha, unitIds) {
|
|
|
72604
72681
|
for (const gid of names) {
|
|
72605
72682
|
if (!GID_RE.test(gid))
|
|
72606
72683
|
continue;
|
|
72607
|
-
const p =
|
|
72684
|
+
const p = join110(root, gid, "dag.json"), d = readJson8(p);
|
|
72608
72685
|
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
72686
|
continue;
|
|
72610
72687
|
let at2 = 0;
|
|
@@ -72621,7 +72698,7 @@ function findResumable(repoDir, specSha, unitIds) {
|
|
|
72621
72698
|
async function unitDone(verifyReceipt, repoDir, gid, n11, id2) {
|
|
72622
72699
|
if (!UNIT_ID_RE.test(id2))
|
|
72623
72700
|
return false;
|
|
72624
|
-
const rp =
|
|
72701
|
+
const rp = join110(repoDir, ".loki", "groups", gid, "group", "units", id2, "receipt.json");
|
|
72625
72702
|
const rec2 = readJson8(rp);
|
|
72626
72703
|
if (!rec2 || rec2["verdict"] !== "VERIFIED")
|
|
72627
72704
|
return false;
|
|
@@ -72636,7 +72713,7 @@ async function adoptJournaled(verifyReceipt, repoDir, dir, key, gid, n11, id2, t
|
|
|
72636
72713
|
return false;
|
|
72637
72714
|
if (!await unitDone(verifyReceipt, repoDir, e10.gid, e10.n, id2))
|
|
72638
72715
|
return false;
|
|
72639
|
-
const signed = readJson8(
|
|
72716
|
+
const signed = readJson8(join110(repoDir, ".loki", "groups", e10.gid, "group", "units", id2, "receipt.json"));
|
|
72640
72717
|
const signedTask = (signed?.["task"] ?? {}).sha256;
|
|
72641
72718
|
const signedSpec = (signed?.["unit_spec"] ?? {}).sha256;
|
|
72642
72719
|
if (typeof signedSpec !== "string" || signedSpec === "" || signedSpec !== specSha)
|
|
@@ -72646,9 +72723,9 @@ async function adoptJournaled(verifyReceipt, repoDir, dir, key, gid, n11, id2, t
|
|
|
72646
72723
|
const tip = git11(repoDir, ["rev-parse", "--verify", "--quiet", `refs/heads/loki/unit-${e10.gid}-${e10.n}`]);
|
|
72647
72724
|
if (tip === "" || tip !== e10.head)
|
|
72648
72725
|
return false;
|
|
72649
|
-
const dst =
|
|
72726
|
+
const dst = join110(repoDir, ".loki", "groups", gid, "group", "units", id2);
|
|
72650
72727
|
rmSync32(dst, { recursive: true, force: true });
|
|
72651
|
-
cpSync2(
|
|
72728
|
+
cpSync2(join110(repoDir, ".loki", "groups", e10.gid, "group", "units", id2), dst, { recursive: true });
|
|
72652
72729
|
if (safeGitSpawn(repoDir, ["update-ref", `refs/heads/loki/unit-${gid}-${n11}`, tip], { encoding: "utf8" }).status !== 0)
|
|
72653
72730
|
return false;
|
|
72654
72731
|
if (!await unitDone(verifyReceipt, repoDir, gid, n11, id2))
|
|
@@ -72683,8 +72760,8 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72683
72760
|
const revised = resumable !== null && exact === null;
|
|
72684
72761
|
const changed = new Set;
|
|
72685
72762
|
const groupId = resumable?.gid ?? `g${Date.now().toString(36)}`;
|
|
72686
|
-
const groupDir =
|
|
72687
|
-
const receiptPath =
|
|
72763
|
+
const groupDir = join110(repoDir, ".loki", "groups", groupId);
|
|
72764
|
+
const receiptPath = join110(groupDir, "receipt.json");
|
|
72688
72765
|
const slugOf = () => originSlug(repoDir);
|
|
72689
72766
|
let baseRef;
|
|
72690
72767
|
let startBranch = "";
|
|
@@ -72776,10 +72853,10 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72776
72853
|
const accOf = new Map;
|
|
72777
72854
|
for (const cu2 of Array.isArray(gc2?.["units"]) ? gc2["units"] : [])
|
|
72778
72855
|
accOf.set(cu2.id, cu2.criteria.map((c) => c.text));
|
|
72779
|
-
const specDir =
|
|
72856
|
+
const specDir = join110(groupDir, "unit_specs");
|
|
72780
72857
|
mkdirSync58(specDir, { recursive: true });
|
|
72781
72858
|
for (const u10 of units) {
|
|
72782
|
-
const spec =
|
|
72859
|
+
const spec = join110(specDir, `${u10.id}.json`);
|
|
72783
72860
|
const isFix = !!u10.fixKind;
|
|
72784
72861
|
if (!isFix)
|
|
72785
72862
|
u10.base = baseRef;
|
|
@@ -72805,19 +72882,19 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72805
72882
|
say(`loki: unit ${u10.id} skipped-unchanged
|
|
72806
72883
|
`);
|
|
72807
72884
|
} else if (resumable && UNIT_ID_RE.test(u10.id))
|
|
72808
|
-
rmSync32(
|
|
72885
|
+
rmSync32(join110(groupDir, "group", "units", u10.id), { recursive: true, force: true });
|
|
72809
72886
|
}
|
|
72810
72887
|
const cut2 = units.findIndex((u10) => u10.fixKind && !u10.done);
|
|
72811
72888
|
if (cut2 >= 0)
|
|
72812
72889
|
for (const u10 of units.splice(cut2)) {
|
|
72813
72890
|
if (u10.done)
|
|
72814
72891
|
doneCount--;
|
|
72815
|
-
rmSync32(
|
|
72892
|
+
rmSync32(join110(groupDir, "group", "units", u10.id), { recursive: true, force: true });
|
|
72816
72893
|
}
|
|
72817
72894
|
if (resumable)
|
|
72818
72895
|
say(`loki: resuming group ${groupId}: ${doneCount} of ${units.length} units already VERIFIED
|
|
72819
72896
|
`);
|
|
72820
|
-
const dagPath =
|
|
72897
|
+
const dagPath = join110(groupDir, "dag.json");
|
|
72821
72898
|
atomicWriteJson(dagPath, { group: groupId, spec_sha256: specSha, base_ref: baseRef, start_branch: startBranch, ...full, units });
|
|
72822
72899
|
try {
|
|
72823
72900
|
const chk = await checkDecomposable(full, { map: (() => {
|
|
@@ -72847,7 +72924,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72847
72924
|
const n11 = Math.min(slots, pending);
|
|
72848
72925
|
say(`loki: group ${groupId}: ${units.length} units, ${n11} parallel slot(s) (provider ${provider})
|
|
72849
72926
|
`);
|
|
72850
|
-
const backlog =
|
|
72927
|
+
const backlog = join110(REPO_ROOT, "autonomy", "lib", "backlog.py");
|
|
72851
72928
|
const feed = createGroupFeed(groupId, units, createGroupRenderer({ write: say, isTTY: false }));
|
|
72852
72929
|
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
72930
|
launchCode = res.code;
|
|
@@ -72887,7 +72964,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72887
72964
|
const testCmd = testCommand(repoDir, env), fixes = units.filter((u10) => u10.fixKind);
|
|
72888
72965
|
const putDag = (us2) => atomicWriteJson(dagPath, { group: groupId, spec_sha256: specSha, base_ref: baseRef, start_branch: startBranch, ...full, units: us2 });
|
|
72889
72966
|
const launchFix = async (fix) => {
|
|
72890
|
-
const key = `unit-${groupId}-${units.length + 1}`, spec =
|
|
72967
|
+
const key = `unit-${groupId}-${units.length + 1}`, spec = join110(specDir, `${fix.id}.json`), slug = slugOf();
|
|
72891
72968
|
if (!slug)
|
|
72892
72969
|
return null;
|
|
72893
72970
|
atomicWriteJson(spec, { id: fix.id, writeSet: fix.writeSet, pack: fix.writeSet, tokenBudget: 1e9, acceptance: fix.acceptance });
|
|
@@ -72896,7 +72973,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72896
72973
|
fix.base = git11(repoDir, ["rev-parse", "HEAD"]);
|
|
72897
72974
|
units.push(fix);
|
|
72898
72975
|
putDag(units.map((u10) => u10 === fix ? u10 : { ...u10, done: true }));
|
|
72899
|
-
const res = await run2([
|
|
72976
|
+
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
72977
|
costs.push(parseGroupCost(res.stdout));
|
|
72901
72978
|
if (res.code !== 0 || !new RegExp(`^backlog: ${key} (VERIFIED|PR \\S+)$`, "m").test(res.stdout)) {
|
|
72902
72979
|
units.pop();
|
|
@@ -72930,7 +73007,7 @@ async function runGroup(launcher, dag, ctx) {
|
|
|
72930
73007
|
return 1;
|
|
72931
73008
|
}
|
|
72932
73009
|
const order2 = units.map((u10) => ({ unit_id: u10.id, goal: u10.items.join("; "), files: u10.writeSet }));
|
|
72933
|
-
atomicWriteJson(
|
|
73010
|
+
atomicWriteJson(join110(groupDir, "group", "manifest.json"), { group_id: groupId, units: order2 });
|
|
72934
73011
|
const head = git11(repoDir, ["rev-parse", "--verify", `refs/heads/${r.branch}`]);
|
|
72935
73012
|
let verdict = "", unitVerdicts = [], why = "";
|
|
72936
73013
|
try {
|
|
@@ -72976,7 +73053,7 @@ var NOT_PROVEN = 4, ENV_KEEP, defaultLauncher = (argv, env, cwd, onOut) => new P
|
|
|
72976
73053
|
return r.status === 0 ? String(r.stdout).trim() : "";
|
|
72977
73054
|
}, 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
73055
|
try {
|
|
72979
|
-
const v3 = JSON.parse(
|
|
73056
|
+
const v3 = JSON.parse(readFileSync95(p, "utf8"));
|
|
72980
73057
|
return v3 !== null && typeof v3 === "object" && !Array.isArray(v3) ? v3 : null;
|
|
72981
73058
|
} catch {
|
|
72982
73059
|
return null;
|
|
@@ -73011,7 +73088,7 @@ __export(exports_route, {
|
|
|
73011
73088
|
MAX_SPEC_BYTES: () => MAX_SPEC_BYTES2,
|
|
73012
73089
|
MAX_SEQ_TASK_BYTES: () => MAX_SEQ_TASK_BYTES
|
|
73013
73090
|
});
|
|
73014
|
-
import { closeSync as closeSync15, constants as constants5, fstatSync as fstatSync8, openSync as openSync15, readFileSync as
|
|
73091
|
+
import { closeSync as closeSync15, constants as constants5, fstatSync as fstatSync8, openSync as openSync15, readFileSync as readFileSync96, realpathSync as realpathSync32 } from "fs";
|
|
73015
73092
|
import { isAbsolute as isAbsolute21, relative as relative25, resolve as resolve33 } from "path";
|
|
73016
73093
|
function providerSlots(env, provider) {
|
|
73017
73094
|
provider = (provider || env.LOKI_PROVIDER || "claude").toLowerCase();
|
|
@@ -73038,7 +73115,7 @@ function readSpec(task, repoDir, cwd) {
|
|
|
73038
73115
|
return { kind: "text" };
|
|
73039
73116
|
if (st2.size > MAX_SPEC_BYTES2)
|
|
73040
73117
|
return { kind: "reject", reason: `spec file over ${MAX_SPEC_BYTES2} bytes` };
|
|
73041
|
-
const buf =
|
|
73118
|
+
const buf = readFileSync96(fd2);
|
|
73042
73119
|
if (buf.length > MAX_SPEC_BYTES2)
|
|
73043
73120
|
return { kind: "reject", reason: `spec file over ${MAX_SPEC_BYTES2} bytes` };
|
|
73044
73121
|
if (buf.includes(0))
|
|
@@ -73157,15 +73234,15 @@ var init_route = __esm(() => {
|
|
|
73157
73234
|
});
|
|
73158
73235
|
|
|
73159
73236
|
// ../../loki-ts/src/contrib/forecast.ts
|
|
73160
|
-
import { appendFileSync as appendFileSync12, existsSync as existsSync77, mkdirSync as mkdirSync59, readFileSync as
|
|
73161
|
-
import { join as
|
|
73237
|
+
import { appendFileSync as appendFileSync12, existsSync as existsSync77, mkdirSync as mkdirSync59, readFileSync as readFileSync97 } from "fs";
|
|
73238
|
+
import { join as join111 } from "path";
|
|
73162
73239
|
function readWindowDeltas(lokiDir2) {
|
|
73163
73240
|
const p = historyPath2(lokiDir2);
|
|
73164
73241
|
if (!existsSync77(p))
|
|
73165
73242
|
return [];
|
|
73166
73243
|
const out3 = [];
|
|
73167
73244
|
try {
|
|
73168
|
-
for (const line2 of
|
|
73245
|
+
for (const line2 of readFileSync97(p, "utf8").split(`
|
|
73169
73246
|
`)) {
|
|
73170
73247
|
if (!line2.trim())
|
|
73171
73248
|
continue;
|
|
@@ -73216,17 +73293,17 @@ function forecastLine(reading, history, opts = {}) {
|
|
|
73216
73293
|
const w = range(history.map((h10) => h10.week));
|
|
73217
73294
|
return fit(`forecast: ~${s}% of session window, ~${w}% of week (basis: ${history.length} past runs; ${used})`, width);
|
|
73218
73295
|
}
|
|
73219
|
-
async function printForecast(lokiDir2,
|
|
73296
|
+
async function printForecast(lokiDir2, read3, write, env = process.env) {
|
|
73220
73297
|
if (!forecastOn(env))
|
|
73221
73298
|
return;
|
|
73222
73299
|
try {
|
|
73223
|
-
const line2 = forecastLine(await
|
|
73300
|
+
const line2 = forecastLine(await read3(), readWindowDeltas(lokiDir2), { env });
|
|
73224
73301
|
if (line2)
|
|
73225
73302
|
write(line2 + `
|
|
73226
73303
|
`);
|
|
73227
73304
|
} catch {}
|
|
73228
73305
|
}
|
|
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) =>
|
|
73306
|
+
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
73307
|
const lo = Math.floor(Math.min(...xs2)), hi2 = Math.ceil(Math.max(...xs2));
|
|
73231
73308
|
return lo === hi2 ? `${hi2}` : `${lo}-${hi2}`;
|
|
73232
73309
|
};
|
|
@@ -73235,8 +73312,8 @@ var init_forecast = __esm(() => {
|
|
|
73235
73312
|
});
|
|
73236
73313
|
|
|
73237
73314
|
// ../../loki-ts/src/commands/queue.ts
|
|
73238
|
-
import { existsSync as existsSync78, mkdirSync as mkdirSync60, readFileSync as
|
|
73239
|
-
import { join as
|
|
73315
|
+
import { existsSync as existsSync78, mkdirSync as mkdirSync60, readFileSync as readFileSync98, readdirSync as readdirSync35, renameSync as renameSync21, statSync as statSync31, writeFileSync as writeFileSync58 } from "fs";
|
|
73316
|
+
import { join as join112, resolve as resolve34 } from "path";
|
|
73240
73317
|
function normalizeRef(raw2) {
|
|
73241
73318
|
const m = URL_RE2.exec(raw2);
|
|
73242
73319
|
if (m)
|
|
@@ -73246,11 +73323,11 @@ function normalizeRef(raw2) {
|
|
|
73246
73323
|
return /^0+$/.test(raw2.replace(/^.*#/, "")) ? null : raw2;
|
|
73247
73324
|
}
|
|
73248
73325
|
function queuePath(lokiDir2) {
|
|
73249
|
-
return
|
|
73326
|
+
return join112(lokiDir2, "issue-queue.json");
|
|
73250
73327
|
}
|
|
73251
73328
|
function readQueue(lokiDir2) {
|
|
73252
73329
|
try {
|
|
73253
|
-
const d = JSON.parse(
|
|
73330
|
+
const d = JSON.parse(readFileSync98(queuePath(lokiDir2), "utf8"));
|
|
73254
73331
|
return Array.isArray(d.items) ? d.items.filter((i) => typeof i?.ref === "string") : [];
|
|
73255
73332
|
} catch {
|
|
73256
73333
|
return [];
|
|
@@ -73261,7 +73338,7 @@ function quarantineCorruptQueue(lokiDir2, now2, warn) {
|
|
|
73261
73338
|
if (!existsSync78(p))
|
|
73262
73339
|
return;
|
|
73263
73340
|
try {
|
|
73264
|
-
const d = JSON.parse(
|
|
73341
|
+
const d = JSON.parse(readFileSync98(p, "utf8"));
|
|
73265
73342
|
if (d !== null && typeof d === "object" && Array.isArray(d.items))
|
|
73266
73343
|
return;
|
|
73267
73344
|
} catch {}
|
|
@@ -73463,8 +73540,8 @@ ${QUEUE_USAGE}`);
|
|
|
73463
73540
|
try {
|
|
73464
73541
|
mkdirSync60(d.lokiDir, { recursive: true });
|
|
73465
73542
|
const stamp2 = finished.toISOString().replace(/[:.]/g, "-");
|
|
73466
|
-
writeFileSync58(
|
|
73467
|
-
writeFileSync58(
|
|
73543
|
+
writeFileSync58(join112(d.lokiDir, `queue-digest-${stamp2}.txt`), text4);
|
|
73544
|
+
writeFileSync58(join112(d.lokiDir, "queue-digest-latest.txt"), text4);
|
|
73468
73545
|
} catch (e10) {
|
|
73469
73546
|
d.err(`loki queue: could not write digest: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
73470
73547
|
`);
|
|
@@ -73474,11 +73551,11 @@ ${QUEUE_USAGE}`);
|
|
|
73474
73551
|
}
|
|
73475
73552
|
function newestRecord(lokiDir2, since) {
|
|
73476
73553
|
for (const [sub2, file] of [["runs", "receipt.json"], ["proofs", "proof.json"]]) {
|
|
73477
|
-
const dir =
|
|
73554
|
+
const dir = join112(lokiDir2, sub2);
|
|
73478
73555
|
let best = null;
|
|
73479
73556
|
try {
|
|
73480
73557
|
for (const name of readdirSync35(dir)) {
|
|
73481
|
-
const p =
|
|
73558
|
+
const p = join112(dir, name, file);
|
|
73482
73559
|
if (!existsSync78(p))
|
|
73483
73560
|
continue;
|
|
73484
73561
|
const t = statSync31(p).mtimeMs;
|
|
@@ -73487,7 +73564,7 @@ function newestRecord(lokiDir2, since) {
|
|
|
73487
73564
|
}
|
|
73488
73565
|
if (!best)
|
|
73489
73566
|
continue;
|
|
73490
|
-
const d = JSON.parse(
|
|
73567
|
+
const d = JSON.parse(readFileSync98(best.p, "utf8"));
|
|
73491
73568
|
const usd = d.cost?.usd;
|
|
73492
73569
|
const unmetered = d.cost?.source === "cli-invoker-unmetered";
|
|
73493
73570
|
return {
|
|
@@ -73521,7 +73598,7 @@ function makeDefaultRunner(lokiDir2) {
|
|
|
73521
73598
|
return async (ref, opts) => {
|
|
73522
73599
|
const since = Date.now();
|
|
73523
73600
|
const argv = [resolve34(REPO_ROOT, "bin", "loki"), ...queueStartArgs(ref, !!opts.pr)];
|
|
73524
|
-
const runLoki = opts.cwd ?
|
|
73601
|
+
const runLoki = opts.cwd ? join112(opts.cwd, ".loki") : lokiDir2;
|
|
73525
73602
|
const env = runnerEnv(opts, runLoki);
|
|
73526
73603
|
const proc = Bun.spawn(argv, { stdout: "pipe", stderr: "pipe", stdin: "ignore", env, ...opts.cwd ? { cwd: opts.cwd } : {} });
|
|
73527
73604
|
const mins2 = itemTimeoutMin(process.env["LOKI_QUEUE_ITEM_TIMEOUT_MIN"]);
|
|
@@ -73531,9 +73608,9 @@ function makeDefaultRunner(lokiDir2) {
|
|
|
73531
73608
|
clearTimeout(timer);
|
|
73532
73609
|
const output = so + se2;
|
|
73533
73610
|
try {
|
|
73534
|
-
const logDir =
|
|
73611
|
+
const logDir = join112(lokiDir2, "queue-logs");
|
|
73535
73612
|
mkdirSync60(logDir, { recursive: true });
|
|
73536
|
-
writeFileSync58(
|
|
73613
|
+
writeFileSync58(join112(logDir, `${(opts.logName ?? ref).replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 120)}.log`), output);
|
|
73537
73614
|
} catch {}
|
|
73538
73615
|
const proof = newestRecord(runLoki, since);
|
|
73539
73616
|
return { rc: rc2, output, verdict: proof.verdict, costUsd: proof.costUsd, runId: proof.runId ?? null };
|
|
@@ -73713,13 +73790,13 @@ function renderEpicTree(n11, title, rows) {
|
|
|
73713
73790
|
}
|
|
73714
73791
|
function makeSessionDecompose(repoDir, lokiDir2, provider) {
|
|
73715
73792
|
return async (slug, issue, triageReason) => {
|
|
73716
|
-
const { mkdirSync: mkdirSync61, readFileSync:
|
|
73717
|
-
const { join:
|
|
73793
|
+
const { mkdirSync: mkdirSync61, readFileSync: readFileSync99, existsSync: existsSync79 } = await import("fs");
|
|
73794
|
+
const { join: join113 } = await import("path");
|
|
73718
73795
|
const { createSessionRunner: createSessionRunner2 } = await Promise.resolve().then(() => (init_session(), exports_session));
|
|
73719
73796
|
const { envOverride: envOverride2 } = await Promise.resolve().then(() => (init_decision(), exports_decision));
|
|
73720
|
-
const dir =
|
|
73797
|
+
const dir = join113(lokiDir2, "issues-run", "decompose");
|
|
73721
73798
|
mkdirSync61(dir, { recursive: true });
|
|
73722
|
-
const outPath =
|
|
73799
|
+
const outPath = join113(dir, `issue-${issue.number}-${Date.now()}.json`);
|
|
73723
73800
|
const runner = createSessionRunner2({ provider, lokiRoot: lokiDir2 });
|
|
73724
73801
|
const r = await runner.run({
|
|
73725
73802
|
stage: "plan",
|
|
@@ -73732,7 +73809,7 @@ function makeSessionDecompose(repoDir, lokiDir2, provider) {
|
|
|
73732
73809
|
...provider === "claude" && envOverride2(process.env) === null ? { model: "opus" } : {}
|
|
73733
73810
|
});
|
|
73734
73811
|
if (existsSync79(outPath))
|
|
73735
|
-
return
|
|
73812
|
+
return readFileSync99(outPath, "utf8");
|
|
73736
73813
|
return r.summary ?? "";
|
|
73737
73814
|
};
|
|
73738
73815
|
}
|
|
@@ -73759,7 +73836,7 @@ __export(exports_issues_run, {
|
|
|
73759
73836
|
import { spawnSync as spawnSync15 } from "child_process";
|
|
73760
73837
|
import { cpSync as cpSync3, existsSync as existsSync79, mkdirSync as mkdirSync61, mkdtempSync as mkdtempSync15, rmSync as rmSync33, writeFileSync as writeFileSync59 } from "fs";
|
|
73761
73838
|
import { tmpdir as tmpdir19 } from "os";
|
|
73762
|
-
import { join as
|
|
73839
|
+
import { join as join113, resolve as resolve35 } from "path";
|
|
73763
73840
|
import { createInterface as createInterface3 } from "readline";
|
|
73764
73841
|
function parseIssuesArgs(args) {
|
|
73765
73842
|
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 +74092,7 @@ ${USAGE}`);
|
|
|
74015
74092
|
}
|
|
74016
74093
|
}
|
|
74017
74094
|
const stamp2 = started.toISOString().replace(/[:.]/g, "-");
|
|
74018
|
-
const runDir =
|
|
74095
|
+
const runDir = join113(d.lokiDir, "issues-run", stamp2);
|
|
74019
74096
|
mkdirSync61(runDir, { recursive: true });
|
|
74020
74097
|
const byRef = new Map(actionable.map((i) => [`${slug}#${i.number}`, i]));
|
|
74021
74098
|
const sink = () => {};
|
|
@@ -74105,14 +74182,14 @@ ${USAGE}`);
|
|
|
74105
74182
|
${trees.join(`
|
|
74106
74183
|
`)}` : "");
|
|
74107
74184
|
try {
|
|
74108
|
-
writeFileSync59(
|
|
74185
|
+
writeFileSync59(join113(runDir, "digest.md"), text4);
|
|
74109
74186
|
} catch (e10) {
|
|
74110
74187
|
d.err(`loki issues run: could not write digest: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
74111
74188
|
`);
|
|
74112
74189
|
}
|
|
74113
74190
|
d.out(`
|
|
74114
74191
|
${text4}
|
|
74115
|
-
digest: ${
|
|
74192
|
+
digest: ${join113(runDir, "digest.md")}
|
|
74116
74193
|
`);
|
|
74117
74194
|
return 0;
|
|
74118
74195
|
}
|
|
@@ -74122,11 +74199,11 @@ function perRun(est) {
|
|
|
74122
74199
|
return est.prior ? { usd: est.prior.usd, tilde: "~", label: " (rough prior)" } : null;
|
|
74123
74200
|
}
|
|
74124
74201
|
function keepReceipt(wt, runId2, runDir, err) {
|
|
74125
|
-
const src =
|
|
74202
|
+
const src = join113(wt, ".loki", "runs", runId2);
|
|
74126
74203
|
if (!/^[A-Za-z0-9_.-]+$/.test(runId2) || !existsSync79(src))
|
|
74127
74204
|
return;
|
|
74128
74205
|
try {
|
|
74129
|
-
cpSync3(src,
|
|
74206
|
+
cpSync3(src, join113(runDir, "receipts", runId2), { recursive: true });
|
|
74130
74207
|
} catch (e10) {
|
|
74131
74208
|
err(`loki issues run: could not keep the receipt of ${runId2}: ${e10 instanceof Error ? e10.message : String(e10)}
|
|
74132
74209
|
`);
|
|
@@ -74173,8 +74250,8 @@ function makeWorktrees(repoDir) {
|
|
|
74173
74250
|
let root = null;
|
|
74174
74251
|
return {
|
|
74175
74252
|
create: (name, base) => {
|
|
74176
|
-
root ??= mkdtempSync15(
|
|
74177
|
-
const p =
|
|
74253
|
+
root ??= mkdtempSync15(join113(tmpdir19(), "loki-issues-"));
|
|
74254
|
+
const p = join113(root, name);
|
|
74178
74255
|
safeGit(repoDir, ["worktree", "add", "-B", `loki/${name}`, p, base]);
|
|
74179
74256
|
return p;
|
|
74180
74257
|
},
|
|
@@ -74267,7 +74344,7 @@ __export(exports_satisfaction, {
|
|
|
74267
74344
|
});
|
|
74268
74345
|
import { appendFileSync as appendFileSync13, mkdirSync as mkdirSync62 } from "fs";
|
|
74269
74346
|
import { homedir as homedir13 } from "os";
|
|
74270
|
-
import { join as
|
|
74347
|
+
import { join as join114 } from "path";
|
|
74271
74348
|
import { createInterface as createInterface4 } from "readline";
|
|
74272
74349
|
function satisfactionEnabled(env, tty) {
|
|
74273
74350
|
if (!tty)
|
|
@@ -74287,9 +74364,9 @@ function parseScore(line2) {
|
|
|
74287
74364
|
return { score: Number(m[1]), again: m[2] ? m[2].toLowerCase() === "y" : null };
|
|
74288
74365
|
}
|
|
74289
74366
|
function recordSatisfaction(home, row) {
|
|
74290
|
-
const dir =
|
|
74367
|
+
const dir = join114(home, ".loki");
|
|
74291
74368
|
mkdirSync62(dir, { recursive: true, mode: 448 });
|
|
74292
|
-
appendFileSync13(
|
|
74369
|
+
appendFileSync13(join114(dir, "satisfaction.jsonl"), `${JSON.stringify(row)}
|
|
74293
74370
|
`, { mode: 384 });
|
|
74294
74371
|
}
|
|
74295
74372
|
async function maybeAsk(o) {
|
|
@@ -74360,8 +74437,8 @@ __export(exports_supervisor, {
|
|
|
74360
74437
|
});
|
|
74361
74438
|
import { spawn as spawn13, spawnSync as spawnSync16 } from "child_process";
|
|
74362
74439
|
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
|
|
74440
|
+
import { existsSync as existsSync80, mkdirSync as mkdirSync63, readFileSync as readFileSync99, writeFileSync as writeFileSync60 } from "fs";
|
|
74441
|
+
import { join as join115, relative as relative26, resolve as resolve36 } from "path";
|
|
74365
74442
|
async function slackEvent(...a) {
|
|
74366
74443
|
try {
|
|
74367
74444
|
await (await Promise.resolve().then(() => (init_slack_events(), exports_slack_events))).notifyEvent(...a);
|
|
@@ -74390,7 +74467,7 @@ class SupervisorLog {
|
|
|
74390
74467
|
this.log = new EventLog(path, runId2);
|
|
74391
74468
|
this.hash = createHash32("sha256");
|
|
74392
74469
|
try {
|
|
74393
|
-
this.hash.update(
|
|
74470
|
+
this.hash.update(readFileSync99(path));
|
|
74394
74471
|
} catch {}
|
|
74395
74472
|
}
|
|
74396
74473
|
implementOpen = false;
|
|
@@ -74445,7 +74522,7 @@ class SupervisorLog {
|
|
|
74445
74522
|
const expected = this.hash.copy().digest("hex");
|
|
74446
74523
|
let actual = "";
|
|
74447
74524
|
try {
|
|
74448
|
-
actual = createHash32("sha256").update(
|
|
74525
|
+
actual = createHash32("sha256").update(readFileSync99(this.path)).digest("hex");
|
|
74449
74526
|
} catch {}
|
|
74450
74527
|
if (actual === expected)
|
|
74451
74528
|
return true;
|
|
@@ -74467,15 +74544,15 @@ async function runSupervisor(opts) {
|
|
|
74467
74544
|
const t02 = Date.now();
|
|
74468
74545
|
const startedProvider = opts.started?.["provider"];
|
|
74469
74546
|
const env = opts.env ?? process.env;
|
|
74470
|
-
await assertPreflight({ repoDir: opts.repoDir, provider: typeof startedProvider === "string" ? startedProvider : "claude", pr: opts.pr !== undefined, env, runDir:
|
|
74547
|
+
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
74548
|
writeEngineMarker(opts.repoDir, opts.runId);
|
|
74472
74549
|
const origin = readOriginUrl(opts.repoDir);
|
|
74473
|
-
const rmRunPid = writeRunPid(
|
|
74550
|
+
const rmRunPid = writeRunPid(join115(opts.repoDir, ".loki", "runs", opts.runId), opts.runId);
|
|
74474
74551
|
process.once("exit", rmRunPid);
|
|
74475
|
-
const log = new SupervisorLog(
|
|
74552
|
+
const log = new SupervisorLog(join115(opts.repoDir, eventsRelPath(opts.runId)), opts.runId);
|
|
74476
74553
|
if ((env.LOKI_CONTROL ?? process.env.LOKI_CONTROL) !== "0")
|
|
74477
74554
|
Promise.resolve().then(() => (init_ship_hook(), exports_ship_hook)).then((m) => m.startShip(opts.repoDir, log.path, env)).catch(() => {});
|
|
74478
|
-
const aliveDir =
|
|
74555
|
+
const aliveDir = join115(opts.repoDir, ".loki", "runs", opts.runId), lastAlive = opts.resume ? readAliveBeat(aliveDir) : null;
|
|
74479
74556
|
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
74557
|
if (!opts.resume)
|
|
74481
74558
|
Promise.resolve().then(() => (init_writeback(), exports_writeback)).then((m) => m.writeBack({ phase: "started", verdict: "", prUrl: null, receiptSha256: null, task: "" }, env));
|
|
@@ -74510,7 +74587,7 @@ async function runSupervisor(opts) {
|
|
|
74510
74587
|
if (e10?.type === "receipt.sealed")
|
|
74511
74588
|
sealed = e10.data;
|
|
74512
74589
|
if (e10?.type === "variant" && e10.data.intent_confirm === true && workerEnv.LOKI_INTENT_TTY === "1") {
|
|
74513
|
-
askIntent(String(e10.data.card ?? ""),
|
|
74590
|
+
askIntent(String(e10.data.card ?? ""), join115(opts.repoDir, ".loki", "runs", opts.runId));
|
|
74514
74591
|
}
|
|
74515
74592
|
}, (stopped) => {
|
|
74516
74593
|
for (const g10 of sessionGroups)
|
|
@@ -74609,8 +74686,8 @@ async function runSupervisor(opts) {
|
|
|
74609
74686
|
}
|
|
74610
74687
|
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
74688
|
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(
|
|
74689
|
+
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));
|
|
74690
|
+
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
74691
|
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
74692
|
rmRunPid();
|
|
74616
74693
|
process.off("exit", rmRunPid);
|
|
@@ -74740,7 +74817,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74740
74817
|
return rec2;
|
|
74741
74818
|
}
|
|
74742
74819
|
const runId2 = `e10-${new Date().toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z")}-${Math.random().toString(16).slice(2, 6)}`;
|
|
74743
|
-
const runDir =
|
|
74820
|
+
const runDir = join115(repoDir, ".loki", "runs", runId2);
|
|
74744
74821
|
const cap = resolveCap(maxCost, repoDir);
|
|
74745
74822
|
if ("error" in cap) {
|
|
74746
74823
|
process.stderr.write(`engine10: ${cap.error}
|
|
@@ -74778,7 +74855,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74778
74855
|
}
|
|
74779
74856
|
if (spec) {
|
|
74780
74857
|
mkdirSync63(runDir, { recursive: true });
|
|
74781
|
-
writeFileSync60(
|
|
74858
|
+
writeFileSync60(join115(runDir, "spec.snapshot.md"), spec.raw);
|
|
74782
74859
|
for (const e10 of [env, process.env]) {
|
|
74783
74860
|
e10.LOKI_E10_SPEC_PATH = relative26(repoDir, spec.path);
|
|
74784
74861
|
e10.LOKI_E10_SPEC_SHA256 = spec.sha256;
|
|
@@ -74803,9 +74880,9 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74803
74880
|
mkdirSync63(runDir, { recursive: true });
|
|
74804
74881
|
try {
|
|
74805
74882
|
if (trackerRef)
|
|
74806
|
-
await fetchTrackerIssueToFile(trackerRef,
|
|
74883
|
+
await fetchTrackerIssueToFile(trackerRef, join115(runDir, "issue.json"));
|
|
74807
74884
|
else
|
|
74808
|
-
fetchIssueToFile(task,
|
|
74885
|
+
fetchIssueToFile(task, join115(runDir, "issue.json"));
|
|
74809
74886
|
} catch (err) {
|
|
74810
74887
|
process.stderr.write(`engine10: issue fetch failed: ${err.message.split(`
|
|
74811
74888
|
`)[0]}
|
|
@@ -74835,7 +74912,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74835
74912
|
process.stdout.write(`${capLine}
|
|
74836
74913
|
`);
|
|
74837
74914
|
const t02 = Date.now();
|
|
74838
|
-
const eventsPath =
|
|
74915
|
+
const eventsPath = join115(repoDir, eventsRelPath(runId2));
|
|
74839
74916
|
const live2 = (e10) => {
|
|
74840
74917
|
const clockS = (Date.parse(e10.ts) - t02) / 1000;
|
|
74841
74918
|
const d = e10.data;
|
|
@@ -74882,7 +74959,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74882
74959
|
const reqOnce = async (evs) => {
|
|
74883
74960
|
if (reqMap === undefined) {
|
|
74884
74961
|
const rq2 = await Promise.resolve().then(() => (init_contract(), exports_contract));
|
|
74885
|
-
reqMap = rq2.writeFromEngine10(repoDir,
|
|
74962
|
+
reqMap = rq2.writeFromEngine10(repoDir, join115(repoDir, ".loki"), runDir, isIssue ? null : task, evs);
|
|
74886
74963
|
}
|
|
74887
74964
|
return reqMap;
|
|
74888
74965
|
};
|
|
@@ -74945,7 +75022,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
|
|
|
74945
75022
|
comment: noPr ? undefined : async ({ issueRef, reason, prUrl }) => {
|
|
74946
75023
|
const { DEFAULT_PUSH_SH: DEFAULT_PUSH_SH2 } = await Promise.resolve().then(() => (init_pr(), exports_pr));
|
|
74947
75024
|
mkdirSync63(runDir, { recursive: true });
|
|
74948
|
-
const bodyFile =
|
|
75025
|
+
const bodyFile = join115(runDir, "backstop-comment.md");
|
|
74949
75026
|
writeFileSync60(bodyFile, `<!-- loki-backstop -->
|
|
74950
75027
|
Loki 10 run ${runId2} ${prUrl ? `opened draft PR ${prUrl}` : "ended without a PR"}.
|
|
74951
75028
|
|
|
@@ -75007,7 +75084,7 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
|
|
|
75007
75084
|
const rr2 = resultOf(res.outcome);
|
|
75008
75085
|
if (res.outcome === "BUDGET_STOP" && cap.usd > 0)
|
|
75009
75086
|
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 ?
|
|
75087
|
+
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
75088
|
const rdy = events2.find((e10) => e10.type === "stage.completed" && e10.stage === "intake")?.data.readiness, foldTail = [handoffRef, typeof rdy === "string" ? rdy : ""].filter(Boolean).join("; ");
|
|
75012
75089
|
const riskLine = readRiskSummary(repoDir, t02);
|
|
75013
75090
|
process.stdout.write(json2 ? `${JSON.stringify({ ...JSON.parse(out3), summary: { ...summaryObject(ui2), ...riskLine ? { risk: riskLine } : {} } })}
|
|
@@ -75062,8 +75139,8 @@ var init_supervisor = __esm(() => {
|
|
|
75062
75139
|
});
|
|
75063
75140
|
|
|
75064
75141
|
// ../../loki-ts/src/e10ext/compound_match.ts
|
|
75065
|
-
import { readFileSync as
|
|
75066
|
-
import { basename as basename29, join as
|
|
75142
|
+
import { readFileSync as readFileSync100 } from "fs";
|
|
75143
|
+
import { basename as basename29, join as join116 } from "path";
|
|
75067
75144
|
function parts(s) {
|
|
75068
75145
|
return s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
75069
75146
|
}
|
|
@@ -75090,7 +75167,7 @@ function linkedHits(word, repoMap, testMap, repoDir) {
|
|
|
75090
75167
|
continue;
|
|
75091
75168
|
let body;
|
|
75092
75169
|
try {
|
|
75093
|
-
body = importLines(
|
|
75170
|
+
body = importLines(readFileSync100(join116(repoDir, t.path), "utf8"));
|
|
75094
75171
|
} catch {
|
|
75095
75172
|
continue;
|
|
75096
75173
|
}
|
|
@@ -75111,8 +75188,8 @@ var init_compound_match = __esm(() => {
|
|
|
75111
75188
|
});
|
|
75112
75189
|
|
|
75113
75190
|
// ../../loki-ts/src/util/already_done_evidence.ts
|
|
75114
|
-
import { existsSync as existsSync81, readFileSync as
|
|
75115
|
-
import { basename as basename30, join as
|
|
75191
|
+
import { existsSync as existsSync81, readFileSync as readFileSync101 } from "fs";
|
|
75192
|
+
import { basename as basename30, join as join117 } from "path";
|
|
75116
75193
|
function keywords2(task) {
|
|
75117
75194
|
const words3 = task.toLowerCase().match(/[a-z0-9_]+/g) ?? [];
|
|
75118
75195
|
return Array.from(new Set(words3.filter((w) => w.length > 2 && !STOP_WORDS.has(w))));
|
|
@@ -75144,7 +75221,7 @@ function docEvidence(words3, repoDir) {
|
|
|
75144
75221
|
for (const name of DOC_FILES) {
|
|
75145
75222
|
let text4;
|
|
75146
75223
|
try {
|
|
75147
|
-
text4 =
|
|
75224
|
+
text4 = readFileSync101(join117(repoDir, name), "utf8");
|
|
75148
75225
|
} catch {
|
|
75149
75226
|
continue;
|
|
75150
75227
|
}
|
|
@@ -75206,7 +75283,7 @@ function citesToken(text4, token) {
|
|
|
75206
75283
|
function citesRealHit(text4, hit, repoDir) {
|
|
75207
75284
|
if (hit.source === "changelog")
|
|
75208
75285
|
return false;
|
|
75209
|
-
return (citesToken(text4, hit.path) || citesToken(text4, basename30(hit.path))) && existsSync81(
|
|
75286
|
+
return (citesToken(text4, hit.path) || citesToken(text4, basename30(hit.path))) && existsSync81(join117(repoDir, hit.path));
|
|
75210
75287
|
}
|
|
75211
75288
|
function renderAlreadyDoneComment(evidence) {
|
|
75212
75289
|
return ["Loki 10: no change needed. This already appears to be implemented.", "", "Evidence:", ...evidence.map((e10) => `- ${e10}`), ""].join(`
|
|
@@ -75408,9 +75485,9 @@ __export(exports_warm, {
|
|
|
75408
75485
|
WarmEngine: () => WarmEngine
|
|
75409
75486
|
});
|
|
75410
75487
|
import { createHash as createHash33 } from "crypto";
|
|
75411
|
-
import { existsSync as existsSync82, mkdirSync as mkdirSync64, readFileSync as
|
|
75488
|
+
import { existsSync as existsSync82, mkdirSync as mkdirSync64, readFileSync as readFileSync102, statSync as statSync32, unlinkSync as unlinkSync11 } from "fs";
|
|
75412
75489
|
import { createServer as createServer2 } from "net";
|
|
75413
|
-
import { dirname as
|
|
75490
|
+
import { dirname as dirname46, resolve as resolve37 } from "path";
|
|
75414
75491
|
function speedEnabled() {
|
|
75415
75492
|
return process.env["LOKI_SPEED"] !== "0";
|
|
75416
75493
|
}
|
|
@@ -75438,7 +75515,7 @@ function dirtyHash(repoDir) {
|
|
|
75438
75515
|
try {
|
|
75439
75516
|
const p = resolve37(repoDir, rel);
|
|
75440
75517
|
if (existsSync82(p) && statSync32(p).isFile() && statSync32(p).size <= MAX_HASHED_BYTES)
|
|
75441
|
-
h10.update(
|
|
75518
|
+
h10.update(readFileSync102(p));
|
|
75442
75519
|
} catch {}
|
|
75443
75520
|
}
|
|
75444
75521
|
return h10.digest("hex");
|
|
@@ -75491,7 +75568,7 @@ function startWarmIfEnabled() {
|
|
|
75491
75568
|
}
|
|
75492
75569
|
}
|
|
75493
75570
|
function startWarmServer(path = warmSocketPath(), engine = new WarmEngine) {
|
|
75494
|
-
mkdirSync64(
|
|
75571
|
+
mkdirSync64(dirname46(path), { recursive: true });
|
|
75495
75572
|
try {
|
|
75496
75573
|
unlinkSync11(path);
|
|
75497
75574
|
} catch {}
|
|
@@ -75550,7 +75627,7 @@ var init_warm = __esm(() => {
|
|
|
75550
75627
|
import { execFile as execFile3 } from "child_process";
|
|
75551
75628
|
import { mkdirSync as mkdirSync65, mkdtempSync as mkdtempSync16, rmSync as rmSync34 } from "fs";
|
|
75552
75629
|
import { tmpdir as tmpdir20 } from "os";
|
|
75553
|
-
import { join as
|
|
75630
|
+
import { join as join118 } from "path";
|
|
75554
75631
|
function hitsUnchangedFromBase(repoDir, baseSha, paths) {
|
|
75555
75632
|
if (paths.length === 0 || !baseSha)
|
|
75556
75633
|
return false;
|
|
@@ -75588,23 +75665,23 @@ function dropRoot(root) {
|
|
|
75588
75665
|
function pinBaseTree(ctx, signal) {
|
|
75589
75666
|
let root;
|
|
75590
75667
|
try {
|
|
75591
|
-
root = mkdtempSync16(
|
|
75668
|
+
root = mkdtempSync16(join118(tmpdir20(), "loki-already-done-"));
|
|
75592
75669
|
} catch {
|
|
75593
75670
|
return Promise.resolve(null);
|
|
75594
75671
|
}
|
|
75595
75672
|
trackRoot(root);
|
|
75596
75673
|
try {
|
|
75597
|
-
mkdirSync65(
|
|
75674
|
+
mkdirSync65(join118(root, "tree"));
|
|
75598
75675
|
} catch {
|
|
75599
75676
|
dropRoot(root);
|
|
75600
75677
|
return Promise.resolve(null);
|
|
75601
75678
|
}
|
|
75602
|
-
const tarball =
|
|
75679
|
+
const tarball = join118(root, "base.tar");
|
|
75603
75680
|
const step = (cmd2, args, cwd) => new Promise((res) => {
|
|
75604
75681
|
execFile3(cmd2, args, { env: process.env, signal, cwd }, (err) => res(!err));
|
|
75605
75682
|
});
|
|
75606
75683
|
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",
|
|
75684
|
+
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
75685
|
dropRoot(root);
|
|
75609
75686
|
return null;
|
|
75610
75687
|
}
|
|
@@ -75662,7 +75739,7 @@ function deferAlreadyDone(ctx, signal, task, repoMap, testMap, apply) {
|
|
|
75662
75739
|
if (!root)
|
|
75663
75740
|
return;
|
|
75664
75741
|
try {
|
|
75665
|
-
const r = await checkAlreadyDone({ ...ctx, repoDir:
|
|
75742
|
+
const r = await checkAlreadyDone({ ...ctx, repoDir: join118(root, "tree"), sessions: inner }, check.signal, task, repoMap, testMap);
|
|
75666
75743
|
const ph = phase;
|
|
75667
75744
|
if (r && ph !== "done" && !check.signal.aborted) {
|
|
75668
75745
|
hit = r;
|
|
@@ -75688,8 +75765,8 @@ __export(exports_intake, {
|
|
|
75688
75765
|
stage: () => stage8,
|
|
75689
75766
|
runIntake: () => runIntake
|
|
75690
75767
|
});
|
|
75691
|
-
import { appendFileSync as appendFileSync14, existsSync as existsSync83, mkdirSync as mkdirSync66, readFileSync as
|
|
75692
|
-
import { dirname as
|
|
75768
|
+
import { appendFileSync as appendFileSync14, existsSync as existsSync83, mkdirSync as mkdirSync66, readFileSync as readFileSync103, writeFileSync as writeFileSync61 } from "fs";
|
|
75769
|
+
import { dirname as dirname47, join as join119, resolve as resolve38 } from "path";
|
|
75693
75770
|
function issueRefOf(raw2) {
|
|
75694
75771
|
return typeof raw2.repo === "string" && raw2.repo && typeof raw2.number === "number" ? `${raw2.repo}#${raw2.number}` : null;
|
|
75695
75772
|
}
|
|
@@ -75709,15 +75786,15 @@ function ensureBranch(repoDir, branch, from) {
|
|
|
75709
75786
|
}
|
|
75710
75787
|
}
|
|
75711
75788
|
function excludeLokiDir(repoDir) {
|
|
75712
|
-
let path =
|
|
75789
|
+
let path = join119(repoDir, ".git", "info", "exclude");
|
|
75713
75790
|
try {
|
|
75714
75791
|
path = resolve38(repoDir, git13(repoDir, ["rev-parse", "--git-path", "info/exclude"]));
|
|
75715
75792
|
} catch {}
|
|
75716
|
-
const existing = existsSync83(path) ?
|
|
75793
|
+
const existing = existsSync83(path) ? readFileSync103(path, "utf8") : "";
|
|
75717
75794
|
if (existing.split(`
|
|
75718
75795
|
`).some((l) => l.trim() === ".loki/"))
|
|
75719
75796
|
return;
|
|
75720
|
-
mkdirSync66(
|
|
75797
|
+
mkdirSync66(dirname47(path), { recursive: true });
|
|
75721
75798
|
const sep20 = existing.length > 0 && !existing.endsWith(`
|
|
75722
75799
|
`) ? `
|
|
75723
75800
|
` : "";
|
|
@@ -75725,7 +75802,7 @@ function excludeLokiDir(repoDir) {
|
|
|
75725
75802
|
`);
|
|
75726
75803
|
}
|
|
75727
75804
|
function loadIssue(path) {
|
|
75728
|
-
const raw2 = JSON.parse(
|
|
75805
|
+
const raw2 = JSON.parse(readFileSync103(path, "utf8"));
|
|
75729
75806
|
return { state: typeof raw2.state === "string" ? raw2.state.toLowerCase() : null, closed_by_merged_pr: raw2.closed_by_merged_pr === true };
|
|
75730
75807
|
}
|
|
75731
75808
|
function isAlreadyDone(issue) {
|
|
@@ -75775,7 +75852,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75775
75852
|
ensureBranch(ctx.repoDir, ctx.branch);
|
|
75776
75853
|
const tree = git13(ctx.repoDir, ["rev-parse", "HEAD^{tree}"]);
|
|
75777
75854
|
excludeLokiDir(ctx.repoDir);
|
|
75778
|
-
const issueJsonPath = opts.issueJsonPath ?? process.env.LOKI_E10_ISSUE_JSON ??
|
|
75855
|
+
const issueJsonPath = opts.issueJsonPath ?? process.env.LOKI_E10_ISSUE_JSON ?? join119(ctx.runDir, "issue.json");
|
|
75779
75856
|
const taskText = opts.taskText ?? process.env.LOKI_E10_TASK_TEXT;
|
|
75780
75857
|
let source;
|
|
75781
75858
|
let taskSha256;
|
|
@@ -75784,7 +75861,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75784
75861
|
let issueRef = null;
|
|
75785
75862
|
if (existsSync83(issueJsonPath)) {
|
|
75786
75863
|
source = "issue";
|
|
75787
|
-
const raw2 =
|
|
75864
|
+
const raw2 = readFileSync103(issueJsonPath, "utf8");
|
|
75788
75865
|
taskSha256 = sha2562(raw2);
|
|
75789
75866
|
const i = JSON.parse(raw2);
|
|
75790
75867
|
task = [i.title, i.body].filter((x3) => typeof x3 === "string" && x3 !== "").join(`
|
|
@@ -75805,7 +75882,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75805
75882
|
return { status: "completed", data: { ...common, task_sha256: taskSha256, source, base_sha: baseSha, tree, branch: ctx.branch, already_satisfied: true } };
|
|
75806
75883
|
}
|
|
75807
75884
|
mkdirSync66(ctx.runDir, { recursive: true });
|
|
75808
|
-
const repomapRef =
|
|
75885
|
+
const repomapRef = join119(ctx.runDir, "repomap.json");
|
|
75809
75886
|
const cacheDir = repoCacheDir(repoKey(null, ctx.repoDir));
|
|
75810
75887
|
const repoMap = cachedRepoMap(cacheDir, tree, () => buildRepoMap(ctx.repoDir));
|
|
75811
75888
|
writeFileSync61(repomapRef, JSON.stringify(repoMap));
|
|
@@ -75826,7 +75903,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
|
|
|
75826
75903
|
const already = speedEnabled() ? null : await checkAlreadyDone(ctx, signal, task, repoMap, testmap);
|
|
75827
75904
|
const alreadyData = (already2) => {
|
|
75828
75905
|
const comment = renderAlreadyDoneComment(already2.evidence);
|
|
75829
|
-
const bodyFile =
|
|
75906
|
+
const bodyFile = join119(ctx.runDir, "already-done-comment.md");
|
|
75830
75907
|
writeFileSync61(bodyFile, comment, "utf8");
|
|
75831
75908
|
const commentArgv = source === "issue" && issueRef ? buildAlreadyDoneCommentArgv(ctx.runId, issueRef, bodyFile) : undefined;
|
|
75832
75909
|
return { already_satisfied: true, evidence: already2.evidence, iteration_ids: [`${ctx.runId}-already-done`], comment, ...commentArgv ? { comment_argv: commentArgv } : {} };
|
|
@@ -76020,7 +76097,7 @@ __export(exports_keys_cmd, {
|
|
|
76020
76097
|
takePubkey: () => takePubkey,
|
|
76021
76098
|
main: () => main5
|
|
76022
76099
|
});
|
|
76023
|
-
import { readFileSync as
|
|
76100
|
+
import { readFileSync as readFileSync104 } from "fs";
|
|
76024
76101
|
import { parseArgs } from "util";
|
|
76025
76102
|
import { createPublicKey as createPublicKey4 } from "crypto";
|
|
76026
76103
|
function takePubkey(args) {
|
|
@@ -76033,7 +76110,7 @@ function takePubkey(args) {
|
|
|
76033
76110
|
return { args: rest };
|
|
76034
76111
|
if (!(file = pubkey[0]))
|
|
76035
76112
|
throw new Error("--pubkey requires a file argument");
|
|
76036
|
-
const t =
|
|
76113
|
+
const t = readFileSync104(file, "utf8"), key = createPublicKey4(t.trim().startsWith("{") ? { key: JSON.parse(t), format: "jwk" } : t);
|
|
76037
76114
|
return key.asymmetricKeyType === "ed25519" ? { args: rest, pubkey: key } : { args: rest, error: `cannot read an Ed25519 public key from ${file}` };
|
|
76038
76115
|
} catch (e10) {
|
|
76039
76116
|
return { args: [], error: file ? `cannot read an Ed25519 public key from ${file}` : e10.message.replace(/^./, (c) => c.toLowerCase()) };
|
|
@@ -76291,7 +76368,7 @@ var groupRoute = async (repoDir, rawGroup) => {
|
|
|
76291
76368
|
};
|
|
76292
76369
|
|
|
76293
76370
|
// ../../loki-ts/src/engine10/modernize/types.ts
|
|
76294
|
-
import { join as
|
|
76371
|
+
import { join as join120 } from "path";
|
|
76295
76372
|
function makeModernizeId(now2 = new Date) {
|
|
76296
76373
|
const utc = now2.toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z");
|
|
76297
76374
|
const short = Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0");
|
|
@@ -76301,13 +76378,13 @@ function isModernizeId(mid) {
|
|
|
76301
76378
|
return MID_RE.test(mid);
|
|
76302
76379
|
}
|
|
76303
76380
|
function modernizeRoot(repoDir, mid) {
|
|
76304
|
-
return
|
|
76381
|
+
return join120(repoDir, ".loki", "modernize", mid);
|
|
76305
76382
|
}
|
|
76306
76383
|
function modernizeEventsPath(repoDir, mid) {
|
|
76307
|
-
return
|
|
76384
|
+
return join120(modernizeRoot(repoDir, mid), "events.jsonl");
|
|
76308
76385
|
}
|
|
76309
76386
|
function planPath(repoDir, mid) {
|
|
76310
|
-
return
|
|
76387
|
+
return join120(modernizeRoot(repoDir, mid), "plan.json");
|
|
76311
76388
|
}
|
|
76312
76389
|
function isSafeUnitId(unit) {
|
|
76313
76390
|
return typeof unit === "string" && unit.length <= MAX_UNIT_ID && UNIT_ID_RE2.test(unit) && !unit.includes("..");
|
|
@@ -76318,13 +76395,13 @@ function encodeUnitId(unit) {
|
|
|
76318
76395
|
return unit.replace(/\//g, "%2F");
|
|
76319
76396
|
}
|
|
76320
76397
|
function oracleDir(repoDir, mid, unit) {
|
|
76321
|
-
return
|
|
76398
|
+
return join120(modernizeRoot(repoDir, mid), "oracle", encodeUnitId(unit));
|
|
76322
76399
|
}
|
|
76323
76400
|
function reportJsonPath(repoDir, mid) {
|
|
76324
|
-
return
|
|
76401
|
+
return join120(modernizeRoot(repoDir, mid), "report.json");
|
|
76325
76402
|
}
|
|
76326
76403
|
function reportMdPath(repoDir, mid) {
|
|
76327
|
-
return
|
|
76404
|
+
return join120(modernizeRoot(repoDir, mid), "report.md");
|
|
76328
76405
|
}
|
|
76329
76406
|
var MID_RE, UNIT_ID_SEGMENT = "[A-Za-z0-9][A-Za-z0-9_.-]*", UNIT_ID_RE2, MAX_UNIT_ID = 128;
|
|
76330
76407
|
var init_types2 = __esm(() => {
|
|
@@ -76364,9 +76441,9 @@ __export(exports_dashboard, {
|
|
|
76364
76441
|
listModernizeIds: () => listModernizeIds
|
|
76365
76442
|
});
|
|
76366
76443
|
import { existsSync as existsSync84, readdirSync as readdirSync36 } from "fs";
|
|
76367
|
-
import { join as
|
|
76444
|
+
import { join as join121 } from "path";
|
|
76368
76445
|
function modernizeDir(repoDir) {
|
|
76369
|
-
return
|
|
76446
|
+
return join121(repoDir, ".loki", "modernize");
|
|
76370
76447
|
}
|
|
76371
76448
|
function listModernizeIds(repoDir) {
|
|
76372
76449
|
const dir = modernizeDir(repoDir);
|
|
@@ -76701,11 +76778,11 @@ var init_engine10_dashboard = __esm(() => {
|
|
|
76701
76778
|
});
|
|
76702
76779
|
|
|
76703
76780
|
// ../../loki-ts/src/engine10/modernize/inventory.ts
|
|
76704
|
-
import { readFileSync as
|
|
76705
|
-
import { extname as extname4, join as
|
|
76781
|
+
import { readFileSync as readFileSync105 } from "fs";
|
|
76782
|
+
import { extname as extname4, join as join122 } from "path";
|
|
76706
76783
|
function readCapped2(absPath) {
|
|
76707
76784
|
try {
|
|
76708
|
-
return
|
|
76785
|
+
return readFileSync105(absPath, "utf8").slice(0, MAX_SCAN_BYTES2);
|
|
76709
76786
|
} catch {
|
|
76710
76787
|
return "";
|
|
76711
76788
|
}
|
|
@@ -76722,9 +76799,9 @@ function detectEntryPoints(repoDir, files) {
|
|
|
76722
76799
|
const out3 = [];
|
|
76723
76800
|
for (const rel of files) {
|
|
76724
76801
|
const ext = extname4(rel);
|
|
76725
|
-
if (ext === ".py" && PY_MAIN_RE.test(readCapped2(
|
|
76802
|
+
if (ext === ".py" && PY_MAIN_RE.test(readCapped2(join122(repoDir, rel))))
|
|
76726
76803
|
out3.push(rel);
|
|
76727
|
-
else if (ext === ".java" && JAVA_MAIN_RE.test(readCapped2(
|
|
76804
|
+
else if (ext === ".java" && JAVA_MAIN_RE.test(readCapped2(join122(repoDir, rel))))
|
|
76728
76805
|
out3.push(rel);
|
|
76729
76806
|
}
|
|
76730
76807
|
return out3;
|
|
@@ -76774,7 +76851,7 @@ var init_inventory = __esm(() => {
|
|
|
76774
76851
|
});
|
|
76775
76852
|
|
|
76776
76853
|
// ../../loki-ts/src/engine10/modernize/lang/python.ts
|
|
76777
|
-
import { join as
|
|
76854
|
+
import { join as join123 } from "path";
|
|
76778
76855
|
async function buildPythonGraph(repoDir, files, opts = {}) {
|
|
76779
76856
|
if (files.length === 0)
|
|
76780
76857
|
return { graph: { nodes: [], edges: [] }, unresolved: [] };
|
|
@@ -76813,7 +76890,7 @@ var init_python2 = __esm(() => {
|
|
|
76813
76890
|
init_paths();
|
|
76814
76891
|
init_python();
|
|
76815
76892
|
init_shell();
|
|
76816
|
-
SCRIPT =
|
|
76893
|
+
SCRIPT = join123(REPO_ROOT, "autonomy", "lib", "modernize", "py_imports.py");
|
|
76817
76894
|
});
|
|
76818
76895
|
|
|
76819
76896
|
// ../../loki-ts/src/engine10/modernize/cluster.ts
|
|
@@ -76992,8 +77069,8 @@ var init_codemod = __esm(() => {
|
|
|
76992
77069
|
|
|
76993
77070
|
// ../../loki-ts/src/engine10/modernize/oracle/seal.ts
|
|
76994
77071
|
import { createHash as createHash34 } from "crypto";
|
|
76995
|
-
import { existsSync as existsSync85, mkdirSync as mkdirSync67, readFileSync as
|
|
76996
|
-
import { join as
|
|
77072
|
+
import { existsSync as existsSync85, mkdirSync as mkdirSync67, readFileSync as readFileSync106, writeFileSync as writeFileSync62 } from "fs";
|
|
77073
|
+
import { join as join124 } from "path";
|
|
76997
77074
|
function normalizersSha(n11) {
|
|
76998
77075
|
return sha2564(JSON.stringify({
|
|
76999
77076
|
float_tolerance: n11.float_tolerance,
|
|
@@ -77055,9 +77132,9 @@ function alreadySealedInLog(repoDir, mid, unit) {
|
|
|
77055
77132
|
}
|
|
77056
77133
|
function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS) {
|
|
77057
77134
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77058
|
-
const casesPath =
|
|
77059
|
-
const coveragePath =
|
|
77060
|
-
const sealedPath =
|
|
77135
|
+
const casesPath = join124(dir, "cases.jsonl");
|
|
77136
|
+
const coveragePath = join124(dir, "coverage.json");
|
|
77137
|
+
const sealedPath = join124(dir, "sealed.json");
|
|
77061
77138
|
if (alreadySealedInLog(repoDir, mid, unit)) {
|
|
77062
77139
|
throw new Error(`oracle seal: ${unit} already has a sealing event in the modernize log; re-seal refused (seal is write-once)`);
|
|
77063
77140
|
}
|
|
@@ -77068,8 +77145,8 @@ function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS)
|
|
|
77068
77145
|
throw new Error(`oracle seal: missing ${casesPath}`);
|
|
77069
77146
|
if (!existsSync85(coveragePath))
|
|
77070
77147
|
throw new Error(`oracle seal: missing ${coveragePath}`);
|
|
77071
|
-
const casesRaw =
|
|
77072
|
-
const coverageRaw =
|
|
77148
|
+
const casesRaw = readFileSync106(casesPath, "utf8");
|
|
77149
|
+
const coverageRaw = readFileSync106(coveragePath, "utf8");
|
|
77073
77150
|
const normalizersHash = normalizersSha(normalizers);
|
|
77074
77151
|
const sealed = buildSealedOracle(unit, casesRaw, coverageRaw, normalizersHash);
|
|
77075
77152
|
mkdirSync67(dir, { recursive: true });
|
|
@@ -77088,9 +77165,9 @@ function sealOracle(repoDir, mid, unit, log, normalizers = DEFAULT_NORMALIZERS)
|
|
|
77088
77165
|
}
|
|
77089
77166
|
function verifySeal(repoDir, mid, unit) {
|
|
77090
77167
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77091
|
-
const sealedPath =
|
|
77092
|
-
const casesPath =
|
|
77093
|
-
const coveragePath =
|
|
77168
|
+
const sealedPath = join124(dir, "sealed.json");
|
|
77169
|
+
const casesPath = join124(dir, "cases.jsonl");
|
|
77170
|
+
const coveragePath = join124(dir, "coverage.json");
|
|
77094
77171
|
if (!existsSync85(sealedPath))
|
|
77095
77172
|
return { ok: false, reason: "no sealed.json" };
|
|
77096
77173
|
if (!existsSync85(casesPath))
|
|
@@ -77101,11 +77178,11 @@ function verifySeal(repoDir, mid, unit) {
|
|
|
77101
77178
|
if (!sealEvent) {
|
|
77102
77179
|
return { ok: false, reason: "no sealing event for this unit in the modernize log; sealed.json is not anchored" };
|
|
77103
77180
|
}
|
|
77104
|
-
const casesRaw =
|
|
77181
|
+
const casesRaw = readFileSync106(casesPath, "utf8");
|
|
77105
77182
|
if (sha2564(casesRaw) !== sealEvent.data.cases_sha256) {
|
|
77106
77183
|
return { ok: false, reason: "cases.jsonl does not match the sealing event's hash (tampered or re-captured)" };
|
|
77107
77184
|
}
|
|
77108
|
-
const coverageRaw =
|
|
77185
|
+
const coverageRaw = readFileSync106(coveragePath, "utf8");
|
|
77109
77186
|
if (sha2564(coverageRaw) !== sealEvent.data.coverage_sha256) {
|
|
77110
77187
|
return { ok: false, reason: "coverage.json does not match the sealing event's hash (tampered or re-captured)" };
|
|
77111
77188
|
}
|
|
@@ -77121,7 +77198,7 @@ function verifySeal(repoDir, mid, unit) {
|
|
|
77121
77198
|
reason: `verdict does not match the sealing event (event type ${sealEvent.type}, recomputed verdict ${recomputed.verdict})`
|
|
77122
77199
|
};
|
|
77123
77200
|
}
|
|
77124
|
-
const sealed = JSON.parse(
|
|
77201
|
+
const sealed = JSON.parse(readFileSync106(sealedPath, "utf8"));
|
|
77125
77202
|
if (JSON.stringify(sealed) !== JSON.stringify(recomputed)) {
|
|
77126
77203
|
return { ok: false, reason: "sealed.json does not match the record recomputed from cases.jsonl and coverage.json (hand-edited)" };
|
|
77127
77204
|
}
|
|
@@ -77137,9 +77214,9 @@ var init_seal2 = __esm(() => {
|
|
|
77137
77214
|
|
|
77138
77215
|
// ../../loki-ts/src/engine10/modernize/oracle/search.ts
|
|
77139
77216
|
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
|
|
77217
|
+
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
77218
|
import { tmpdir as tmpdir21 } from "os";
|
|
77142
|
-
import { basename as basename31, dirname as
|
|
77219
|
+
import { basename as basename31, dirname as dirname48, join as join125 } from "path";
|
|
77143
77220
|
function search(unitSource, seedCases, propose, runCapture, opts = {}) {
|
|
77144
77221
|
const maxRounds = opts.maxRounds ?? 10;
|
|
77145
77222
|
const plateauLimit = opts.plateauRounds ?? 2;
|
|
@@ -77196,10 +77273,10 @@ function realCaptureRunner(unitPath, cases, outPath) {
|
|
|
77196
77273
|
return captureFailed("old runtime unavailable");
|
|
77197
77274
|
let dir = "";
|
|
77198
77275
|
try {
|
|
77199
|
-
dir = mkdtempSync17(
|
|
77200
|
-
const casesFile =
|
|
77201
|
-
const outFile =
|
|
77202
|
-
const covFile =
|
|
77276
|
+
dir = mkdtempSync17(join125(tmpdir21(), "m10-search-"));
|
|
77277
|
+
const casesFile = join125(dir, "cases.jsonl");
|
|
77278
|
+
const outFile = join125(dir, "out.jsonl");
|
|
77279
|
+
const covFile = join125(dir, "coverage.json");
|
|
77203
77280
|
const lines2 = cases.map((c) => JSON.stringify({ entry: c.entry, args: c.args, kwargs: c.kwargs }));
|
|
77204
77281
|
writeFileSync63(casesFile, lines2.length ? lines2.join(`
|
|
77205
77282
|
`) + `
|
|
@@ -77220,7 +77297,7 @@ function realCaptureRunner(unitPath, cases, outPath) {
|
|
|
77220
77297
|
`).find((l) => l.trim().length > 0) ?? "(no stderr)";
|
|
77221
77298
|
return captureFailed(`py_capture.py exit ${r.status}: ${firstErrLine}`);
|
|
77222
77299
|
}
|
|
77223
|
-
const raw2 = JSON.parse(
|
|
77300
|
+
const raw2 = JSON.parse(readFileSync107(covFile, "utf8"));
|
|
77224
77301
|
if (outPath)
|
|
77225
77302
|
copyFileSync6(outFile, outPath);
|
|
77226
77303
|
return {
|
|
@@ -77247,13 +77324,13 @@ function resolveOldRuntimeSync() {
|
|
|
77247
77324
|
}
|
|
77248
77325
|
function makeProposeInputs(session, cap = 20) {
|
|
77249
77326
|
return (unitPath, missing, round2) => {
|
|
77250
|
-
const cwd = mkdtempSync17(
|
|
77327
|
+
const cwd = mkdtempSync17(join125(tmpdir21(), "m27-propose-"));
|
|
77251
77328
|
try {
|
|
77252
|
-
const unitFile =
|
|
77329
|
+
const unitFile = join125(cwd, basename31(unitPath));
|
|
77253
77330
|
copyFileSync6(unitPath, unitFile);
|
|
77254
77331
|
session({ cwd, env: tokenFreeEnv(), unitFile, missing, round: round2 });
|
|
77255
77332
|
const out3 = [];
|
|
77256
|
-
for (const line2 of
|
|
77333
|
+
for (const line2 of readFileSync107(join125(cwd, "proposals.jsonl"), "utf8").split(`
|
|
77257
77334
|
`)) {
|
|
77258
77335
|
try {
|
|
77259
77336
|
const c = JSON.parse(line2);
|
|
@@ -77271,7 +77348,7 @@ function makeProposeInputs(session, cap = 20) {
|
|
|
77271
77348
|
}
|
|
77272
77349
|
function captureUnitOracle(a) {
|
|
77273
77350
|
const dir = oracleDir(a.repoDir, a.mid, a.unit);
|
|
77274
|
-
if (existsSync86(
|
|
77351
|
+
if (existsSync86(join125(dir, "cases.jsonl")) || alreadySealedInLog(a.repoDir, a.mid, a.unit)) {
|
|
77275
77352
|
return { ok: false, reason: "oracle already captured (write-once)" };
|
|
77276
77353
|
}
|
|
77277
77354
|
const run2 = a.runCapture ?? realCaptureRunner;
|
|
@@ -77291,21 +77368,21 @@ function captureUnitOracle(a) {
|
|
|
77291
77368
|
}
|
|
77292
77369
|
if (r.cases.length === 0)
|
|
77293
77370
|
return { ok: false, reason: "no cases captured" };
|
|
77294
|
-
const scratch = mkdtempSync17(
|
|
77295
|
-
const t12 =
|
|
77371
|
+
const scratch = mkdtempSync17(join125(tmpdir21(), "m27-replay-"));
|
|
77372
|
+
const t12 = join125(scratch, "cases"), t22 = join125(scratch, "replay");
|
|
77296
77373
|
const created = [];
|
|
77297
|
-
for (let p = dir;!existsSync86(p) && !created.includes(p); p =
|
|
77374
|
+
for (let p = dir;!existsSync86(p) && !created.includes(p); p = dirname48(p))
|
|
77298
77375
|
created.push(p);
|
|
77299
|
-
const
|
|
77376
|
+
const read3 = (p) => readFileSync107(p, "utf8").split(`
|
|
77300
77377
|
`).filter(Boolean).map((l) => JSON.parse(l));
|
|
77301
|
-
const tmpCases =
|
|
77302
|
-
const tmpCov =
|
|
77378
|
+
const tmpCases = join125(dir, `.cases.${process.pid}.tmp`);
|
|
77379
|
+
const tmpCov = join125(dir, `.coverage.${process.pid}.tmp`);
|
|
77303
77380
|
try {
|
|
77304
77381
|
const cov = run2(a.unitPath, r.cases, t12);
|
|
77305
77382
|
const cov2 = run2(a.unitPath, r.cases, t22);
|
|
77306
77383
|
if (cov.branchesTotal < 0 || cov2.branchesTotal < 0)
|
|
77307
77384
|
return { ok: false, reason: cov.error ?? cov2.error ?? "replay failed" };
|
|
77308
|
-
const recs =
|
|
77385
|
+
const recs = read3(t12), again = read3(t22);
|
|
77309
77386
|
if (recs.length !== r.cases.length || again.length !== recs.length)
|
|
77310
77387
|
return { ok: false, reason: "capture records missing" };
|
|
77311
77388
|
recs.forEach((rec2, i) => {
|
|
@@ -77327,10 +77404,10 @@ function captureUnitOracle(a) {
|
|
|
77327
77404
|
branch_pct: cov.branchPct,
|
|
77328
77405
|
missing: cov.missing
|
|
77329
77406
|
}));
|
|
77330
|
-
if (existsSync86(
|
|
77407
|
+
if (existsSync86(join125(dir, "cases.jsonl")))
|
|
77331
77408
|
return { ok: false, reason: "oracle already captured (write-once)" };
|
|
77332
|
-
renameSync22(tmpCov,
|
|
77333
|
-
(a.link ?? linkSync4)(tmpCases,
|
|
77409
|
+
renameSync22(tmpCov, join125(dir, "coverage.json"));
|
|
77410
|
+
(a.link ?? linkSync4)(tmpCases, join125(dir, "cases.jsonl"));
|
|
77334
77411
|
return { ok: true, cases: r.cases.length, branchPct: cov.branchPct, stoppedReason: r.stoppedReason };
|
|
77335
77412
|
} catch (e10) {
|
|
77336
77413
|
return { ok: false, reason: `capture error: ${e10 instanceof Error ? e10.message : String(e10)}` };
|
|
@@ -77338,8 +77415,8 @@ function captureUnitOracle(a) {
|
|
|
77338
77415
|
rmSync35(scratch, { recursive: true, force: true });
|
|
77339
77416
|
for (const t of [tmpCases, tmpCov])
|
|
77340
77417
|
rmSync35(t, { force: true });
|
|
77341
|
-
if (created[0] === dir && !existsSync86(
|
|
77342
|
-
rmSync35(
|
|
77418
|
+
if (created[0] === dir && !existsSync86(join125(dir, "cases.jsonl")))
|
|
77419
|
+
rmSync35(join125(dir, "coverage.json"), { force: true });
|
|
77343
77420
|
for (const p of created) {
|
|
77344
77421
|
try {
|
|
77345
77422
|
rmdirSync2(p);
|
|
@@ -77355,12 +77432,12 @@ var init_search = __esm(() => {
|
|
|
77355
77432
|
init_safe_git();
|
|
77356
77433
|
init_types2();
|
|
77357
77434
|
init_seal2();
|
|
77358
|
-
PY_CAPTURE_SCRIPT =
|
|
77435
|
+
PY_CAPTURE_SCRIPT = join125(REPO_ROOT, "autonomy", "lib", "modernize", "py_capture.py");
|
|
77359
77436
|
});
|
|
77360
77437
|
|
|
77361
77438
|
// ../../loki-ts/src/engine10/modernize/equiv.ts
|
|
77362
|
-
import { readFileSync as
|
|
77363
|
-
import { join as
|
|
77439
|
+
import { readFileSync as readFileSync108 } from "fs";
|
|
77440
|
+
import { join as join126 } from "path";
|
|
77364
77441
|
function parseCases(raw2) {
|
|
77365
77442
|
const out3 = [];
|
|
77366
77443
|
for (const line2 of raw2.split(`
|
|
@@ -77555,11 +77632,11 @@ function checkEquivalence(repoDir, mid, unit, newTreeDir, normalizers, runNew, l
|
|
|
77555
77632
|
return notProvenResult(unit, "normalizers invalid: skip_fields covers every field, nothing would be compared", log);
|
|
77556
77633
|
}
|
|
77557
77634
|
const dir = oracleDir(repoDir, mid, unit);
|
|
77558
|
-
const sealed = JSON.parse(
|
|
77635
|
+
const sealed = JSON.parse(readFileSync108(join126(dir, "sealed.json"), "utf8"));
|
|
77559
77636
|
const normCheck = verifyNormalizersAgainstSeal(sealed, normalizers);
|
|
77560
77637
|
if (!normCheck.ok)
|
|
77561
77638
|
return notProvenResult(unit, `normalizers: ${normCheck.reason ?? "check failed"}`, log);
|
|
77562
|
-
const records = parseCases(
|
|
77639
|
+
const records = parseCases(readFileSync108(join126(dir, "cases.jsonl"), "utf8"));
|
|
77563
77640
|
const heldOutSet = new Set(sealed.held_out);
|
|
77564
77641
|
let pass = 0;
|
|
77565
77642
|
let fail2 = 0;
|
|
@@ -77750,7 +77827,7 @@ var init_reslice = __esm(() => {
|
|
|
77750
77827
|
});
|
|
77751
77828
|
|
|
77752
77829
|
// ../../loki-ts/src/engine10/modernize/scheduler.ts
|
|
77753
|
-
import { join as
|
|
77830
|
+
import { join as join127 } from "path";
|
|
77754
77831
|
function mergeOnce(unit, ops, log, completed, worktree) {
|
|
77755
77832
|
if (completed.has(unit))
|
|
77756
77833
|
return "already_completed";
|
|
@@ -77871,7 +77948,7 @@ async function schedule(plan, opts) {
|
|
|
77871
77948
|
reason = hit ? "budget stop" : "per-unit cost cap reached";
|
|
77872
77949
|
break;
|
|
77873
77950
|
}
|
|
77874
|
-
const path =
|
|
77951
|
+
const path = join127(modernizeRoot(opts.repoDir, opts.mid), "wt", variant === 0 ? encodeUnitId(unit.id) : `${encodeUnitId(unit.id)}${VARIANT_SEP}${variant}`);
|
|
77875
77952
|
let outcome;
|
|
77876
77953
|
attempts++;
|
|
77877
77954
|
let resumeRunId;
|
|
@@ -77980,21 +78057,21 @@ var init_scheduler = __esm(() => {
|
|
|
77980
78057
|
});
|
|
77981
78058
|
|
|
77982
78059
|
// ../../loki-ts/src/engine10/modernize/resume.ts
|
|
77983
|
-
import { existsSync as existsSync87, readFileSync as
|
|
78060
|
+
import { existsSync as existsSync87, readFileSync as readFileSync109 } from "fs";
|
|
77984
78061
|
function loadResumeState(repoDir, mid) {
|
|
77985
78062
|
const path = modernizeEventsPath(repoDir, mid);
|
|
77986
78063
|
if (!existsSync87(path))
|
|
77987
78064
|
return { ok: false, reason: `no modernize log at ${path}` };
|
|
77988
78065
|
let text4;
|
|
77989
78066
|
try {
|
|
77990
|
-
text4 =
|
|
78067
|
+
text4 = readFileSync109(path, "utf8");
|
|
77991
78068
|
} catch (e10) {
|
|
77992
78069
|
return { ok: false, reason: `modernize log unreadable: ${e10 instanceof Error ? e10.message : String(e10)}` };
|
|
77993
78070
|
}
|
|
77994
78071
|
const pj2 = planPath(repoDir, mid);
|
|
77995
78072
|
if (existsSync87(pj2)) {
|
|
77996
78073
|
try {
|
|
77997
|
-
JSON.parse(
|
|
78074
|
+
JSON.parse(readFileSync109(pj2, "utf8"));
|
|
77998
78075
|
} catch {
|
|
77999
78076
|
return { ok: false, reason: `plan.json is corrupt or partial: ${pj2}` };
|
|
78000
78077
|
}
|
|
@@ -78107,8 +78184,8 @@ var init_resume = __esm(() => {
|
|
|
78107
78184
|
});
|
|
78108
78185
|
|
|
78109
78186
|
// ../../loki-ts/src/engine10/modernize/report.ts
|
|
78110
|
-
import { mkdirSync as mkdirSync69, readFileSync as
|
|
78111
|
-
import { dirname as
|
|
78187
|
+
import { mkdirSync as mkdirSync69, readFileSync as readFileSync110, writeFileSync as writeFileSync64 } from "fs";
|
|
78188
|
+
import { dirname as dirname49 } from "path";
|
|
78112
78189
|
function buildReport(o) {
|
|
78113
78190
|
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
78191
|
const waves = o.waves.map((w) => ({
|
|
@@ -78151,7 +78228,7 @@ function renderReportMd(r) {
|
|
|
78151
78228
|
function writeReport(o) {
|
|
78152
78229
|
const sealed = sealReport(buildReport(o), o.sign);
|
|
78153
78230
|
const jp2 = reportJsonPath(o.repoDir, o.mid);
|
|
78154
|
-
mkdirSync69(
|
|
78231
|
+
mkdirSync69(dirname49(jp2), { recursive: true });
|
|
78155
78232
|
writeFileSync64(jp2, JSON.stringify(sealed, null, 2) + `
|
|
78156
78233
|
`, "utf8");
|
|
78157
78234
|
writeFileSync64(reportMdPath(o.repoDir, o.mid), renderReportMd(sealed), "utf8");
|
|
@@ -78168,7 +78245,7 @@ var init_report = __esm(() => {
|
|
|
78168
78245
|
|
|
78169
78246
|
// ../../loki-ts/src/engine10/modernize/ship.ts
|
|
78170
78247
|
import { mkdirSync as mkdirSync70, writeFileSync as writeFileSync65 } from "fs";
|
|
78171
|
-
import { join as
|
|
78248
|
+
import { join as join128 } from "path";
|
|
78172
78249
|
function waveIsDraft(verdict, units) {
|
|
78173
78250
|
return verdict === null || verdict.verified !== true || units.length === 0 || units.some((x3) => x3.verdict !== "PROVEN");
|
|
78174
78251
|
}
|
|
@@ -78189,9 +78266,9 @@ function shipWave(o) {
|
|
|
78189
78266
|
return fail2("no pinned origin: refusing to push (Rule of Two)");
|
|
78190
78267
|
if (draft)
|
|
78191
78268
|
return fail2("wave not verified: branch stays local, not pushed");
|
|
78192
|
-
const dir =
|
|
78269
|
+
const dir = join128(o.repoDir, ".loki", "modernize", o.mid);
|
|
78193
78270
|
mkdirSync70(dir, { recursive: true });
|
|
78194
|
-
const bodyFile =
|
|
78271
|
+
const bodyFile = join128(dir, `wave-${o.wave}-pr-body.md`);
|
|
78195
78272
|
writeFileSync65(bodyFile, renderWaveBody(o.wave, o.verdict, o.units), "utf8");
|
|
78196
78273
|
const r = (o.push ?? runPushPr)({ repoDir: o.repoDir, branch: o.branch, title: `Loki modernize: wave ${o.wave}`, bodyFile, draft, pinnedOrigin });
|
|
78197
78274
|
if (!r.ok)
|
|
@@ -78211,8 +78288,8 @@ var init_ship2 = __esm(() => {
|
|
|
78211
78288
|
});
|
|
78212
78289
|
|
|
78213
78290
|
// ../../loki-ts/src/engine10/modernize/presealed_wall.ts
|
|
78214
|
-
import { existsSync as existsSync88, mkdirSync as mkdirSync71, readFileSync as
|
|
78215
|
-
import { join as
|
|
78291
|
+
import { existsSync as existsSync88, mkdirSync as mkdirSync71, readFileSync as readFileSync111, writeFileSync as writeFileSync66 } from "fs";
|
|
78292
|
+
import { join as join129 } from "path";
|
|
78216
78293
|
function isRealFailCount(n11) {
|
|
78217
78294
|
return typeof n11 === "number" && Number.isInteger(n11) && n11 >= 1;
|
|
78218
78295
|
}
|
|
@@ -78235,7 +78312,7 @@ function classifyBaseRun(o, repoDir) {
|
|
|
78235
78312
|
return "not_run";
|
|
78236
78313
|
}
|
|
78237
78314
|
function preSealedPath(repoDir, mid, unit) {
|
|
78238
|
-
return
|
|
78315
|
+
return join129(oracleDir(repoDir, mid, unit), "presealed_wall.json");
|
|
78239
78316
|
}
|
|
78240
78317
|
function alreadySealed(repoDir, mid, unit) {
|
|
78241
78318
|
return readModernizeEvents(repoDir, mid).some((e10) => e10.type === SEALED_EVENT && e10.data.unit === unit);
|
|
@@ -78249,7 +78326,7 @@ function sealPreSealedWall(repoDir, mid, unit, target, runConformance, log, base
|
|
|
78249
78326
|
if (!oracleCheck.ok)
|
|
78250
78327
|
return refuse(`oracle seal invalid: ${oracleCheck.reason ?? "unknown"}; presealed wall refused`);
|
|
78251
78328
|
const dir = oracleDir(repoDir, mid, unit);
|
|
78252
|
-
const oracleSealed = JSON.parse(
|
|
78329
|
+
const oracleSealed = JSON.parse(readFileSync111(join129(dir, "sealed.json"), "utf8"));
|
|
78253
78330
|
if (oracleSealed.verdict !== "PROVEN_ORACLE") {
|
|
78254
78331
|
return refuse(`oracle seal invalid: oracle is ${oracleSealed.verdict} (${oracleSealed.not_proven ?? "no reason recorded"}); presealed wall refused`);
|
|
78255
78332
|
}
|
|
@@ -78318,7 +78395,7 @@ function verifyPreSealedWall(repoDir, mid, unit) {
|
|
|
78318
78395
|
const expectedSha = event.data.sealed_sha256;
|
|
78319
78396
|
if (typeof expectedSha !== "string")
|
|
78320
78397
|
return { ok: false, reason: "sealing event has no sealed_sha256" };
|
|
78321
|
-
const sealedRaw =
|
|
78398
|
+
const sealedRaw = readFileSync111(sealedPath, "utf8");
|
|
78322
78399
|
const actualSha = sha2564(sealedRaw);
|
|
78323
78400
|
if (actualSha !== expectedSha) {
|
|
78324
78401
|
return { ok: false, reason: "presealed_wall.json does not match the sealing event's hash (tampered or rewritten)" };
|
|
@@ -78327,7 +78404,7 @@ function verifyPreSealedWall(repoDir, mid, unit) {
|
|
|
78327
78404
|
if (!oracleCheck.ok) {
|
|
78328
78405
|
return { ok: false, reason: `bound oracle seal is no longer valid: ${oracleCheck.reason ?? "unknown"}` };
|
|
78329
78406
|
}
|
|
78330
|
-
const oracleSealed = JSON.parse(
|
|
78407
|
+
const oracleSealed = JSON.parse(readFileSync111(join129(oracleDir(repoDir, mid, unit), "sealed.json"), "utf8"));
|
|
78331
78408
|
const carried = JSON.parse(sealedRaw);
|
|
78332
78409
|
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
78410
|
return { ok: false, reason: "carried oracle hashes do not match the current oracle seal" };
|
|
@@ -78353,9 +78430,9 @@ var init_presealed_wall = __esm(() => {
|
|
|
78353
78430
|
// ../../loki-ts/src/engine10/modernize/unit.ts
|
|
78354
78431
|
import { spawnSync as spawnSync19 } from "child_process";
|
|
78355
78432
|
import { createHash as createHash35 } from "crypto";
|
|
78356
|
-
import { lstatSync as lstatSync29, readFileSync as
|
|
78433
|
+
import { lstatSync as lstatSync29, readFileSync as readFileSync112, readdirSync as readdirSync37, readlinkSync as readlinkSync7, realpathSync as realpathSync33, rmSync as rmSync36 } from "fs";
|
|
78357
78434
|
import { tmpdir as tmpdir22 } from "os";
|
|
78358
|
-
import { join as
|
|
78435
|
+
import { join as join130, sep as sep20 } from "path";
|
|
78359
78436
|
function isSealedName(rel) {
|
|
78360
78437
|
return TEST_FILE2.test(rel) || PYTEST_CFG.test(rel);
|
|
78361
78438
|
}
|
|
@@ -78370,7 +78447,7 @@ function purgePycache(dir) {
|
|
|
78370
78447
|
for (const e10 of ents) {
|
|
78371
78448
|
if (!e10.isDirectory())
|
|
78372
78449
|
continue;
|
|
78373
|
-
const full =
|
|
78450
|
+
const full = join130(d, e10.name);
|
|
78374
78451
|
if (e10.name === "__pycache__")
|
|
78375
78452
|
rmSync36(full, { recursive: true, force: true });
|
|
78376
78453
|
else if (!skipName(e10.name))
|
|
@@ -78425,13 +78502,13 @@ function outsideTargetDigest(dir, full) {
|
|
|
78425
78502
|
}
|
|
78426
78503
|
for (const n11 of names) {
|
|
78427
78504
|
h10.update("D" + n11);
|
|
78428
|
-
walk(
|
|
78505
|
+
walk(join130(p, n11));
|
|
78429
78506
|
}
|
|
78430
78507
|
return;
|
|
78431
78508
|
}
|
|
78432
78509
|
if (st2.isFile()) {
|
|
78433
78510
|
try {
|
|
78434
|
-
h10.update(
|
|
78511
|
+
h10.update(readFileSync112(p));
|
|
78435
78512
|
} catch {
|
|
78436
78513
|
h10.update("unreadable");
|
|
78437
78514
|
}
|
|
@@ -78446,7 +78523,7 @@ function conformanceHashes(dir) {
|
|
|
78446
78523
|
const walk = (sub2, inSkip) => {
|
|
78447
78524
|
let ents;
|
|
78448
78525
|
try {
|
|
78449
|
-
ents = readdirSync37(
|
|
78526
|
+
ents = readdirSync37(join130(dir, sub2), { withFileTypes: true });
|
|
78450
78527
|
} catch {
|
|
78451
78528
|
return;
|
|
78452
78529
|
}
|
|
@@ -78477,14 +78554,14 @@ function conformanceHashes(dir) {
|
|
|
78477
78554
|
for (const rel of rels) {
|
|
78478
78555
|
let data;
|
|
78479
78556
|
try {
|
|
78480
|
-
const st2 = lstatSync29(
|
|
78557
|
+
const st2 = lstatSync29(join130(dir, rel));
|
|
78481
78558
|
if (st2.isSymbolicLink()) {
|
|
78482
|
-
out3[rel] = `${LINK}${readlinkSync7(
|
|
78559
|
+
out3[rel] = `${LINK}${readlinkSync7(join130(dir, rel))}|${outsideTargetDigest(dir, join130(dir, rel))}`;
|
|
78483
78560
|
continue;
|
|
78484
78561
|
}
|
|
78485
78562
|
if (!st2.isFile())
|
|
78486
78563
|
continue;
|
|
78487
|
-
data =
|
|
78564
|
+
data = readFileSync112(join130(dir, rel));
|
|
78488
78565
|
} catch {
|
|
78489
78566
|
continue;
|
|
78490
78567
|
}
|
|
@@ -78543,7 +78620,7 @@ function notProvenUnitResult(unit, reason, oracle, wall) {
|
|
|
78543
78620
|
return { unit, verdict: "NOT_PROVEN", oracle, wall, equiv: null, not_proven: [reason], conformance: null };
|
|
78544
78621
|
}
|
|
78545
78622
|
function readOracleSealed(repoDir, mid, unit) {
|
|
78546
|
-
return JSON.parse(
|
|
78623
|
+
return JSON.parse(readFileSync112(join130(oracleDir(repoDir, mid, unit), "sealed.json"), "utf8"));
|
|
78547
78624
|
}
|
|
78548
78625
|
function runUnit(card, log, runConformance, implement, runNew, runStub, collect) {
|
|
78549
78626
|
const { repoDir, mid, unit } = card;
|
|
@@ -78654,8 +78731,8 @@ var init_unit = __esm(() => {
|
|
|
78654
78731
|
|
|
78655
78732
|
// ../../loki-ts/src/engine10/modernize/wave.ts
|
|
78656
78733
|
import { spawnSync as spawnSync20 } from "child_process";
|
|
78657
|
-
import { readFileSync as
|
|
78658
|
-
import { join as
|
|
78734
|
+
import { readFileSync as readFileSync113, statSync as statSync33 } from "fs";
|
|
78735
|
+
import { join as join131 } from "path";
|
|
78659
78736
|
function clampTimeout(ms) {
|
|
78660
78737
|
if (ms === undefined || !Number.isFinite(ms) || ms <= 0)
|
|
78661
78738
|
return DEFAULT_STEP_TIMEOUT_MS;
|
|
@@ -78724,7 +78801,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78724
78801
|
const none = { build: null, integration: null, original_suite: null };
|
|
78725
78802
|
const text4 = () => {
|
|
78726
78803
|
try {
|
|
78727
|
-
return
|
|
78804
|
+
return readFileSync113(join131(target, marker ?? ""), "utf8");
|
|
78728
78805
|
} catch {
|
|
78729
78806
|
return "";
|
|
78730
78807
|
}
|
|
@@ -78736,7 +78813,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78736
78813
|
if (system === "gradle") {
|
|
78737
78814
|
let gw2 = "gradle";
|
|
78738
78815
|
try {
|
|
78739
|
-
if (inv.files.includes("gradlew") && (statSync33(
|
|
78816
|
+
if (inv.files.includes("gradlew") && (statSync33(join131(target, "gradlew")).mode & 73) !== 0)
|
|
78740
78817
|
gw2 = "./gradlew";
|
|
78741
78818
|
} catch {}
|
|
78742
78819
|
return { build: { argv: [gw2, "assemble"] }, integration: text4().includes("integrationTest") ? { argv: [gw2, "integrationTest"] } : null, original_suite: { argv: [gw2, "test"] } };
|
|
@@ -78748,7 +78825,7 @@ function detectWaveCommands(inv, target) {
|
|
|
78748
78825
|
let toxIni = "";
|
|
78749
78826
|
if (inv.files.includes("tox.ini")) {
|
|
78750
78827
|
try {
|
|
78751
|
-
toxIni =
|
|
78828
|
+
toxIni = readFileSync113(join131(target, "tox.ini"), "utf8");
|
|
78752
78829
|
} catch {}
|
|
78753
78830
|
}
|
|
78754
78831
|
const integration = toxIni.includes("[testenv:integration") ? { argv: ["tox", "-e", "integration"] } : itDir && pytest ? { argv: ["python3", "-m", "pytest", "-q", itDir] } : null;
|
|
@@ -78780,9 +78857,9 @@ var init_wave = __esm(() => {
|
|
|
78780
78857
|
|
|
78781
78858
|
// ../../loki-ts/src/util/modernize_unit.ts
|
|
78782
78859
|
import { spawnSync as spawnSync21 } from "child_process";
|
|
78783
|
-
import { existsSync as existsSync89, lstatSync as lstatSync30, mkdtempSync as mkdtempSync18, readFileSync as
|
|
78860
|
+
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
78861
|
import { tmpdir as tmpdir23 } from "os";
|
|
78785
|
-
import { join as
|
|
78862
|
+
import { join as join132, sep as sep21 } from "path";
|
|
78786
78863
|
function parseUnitArgs(args) {
|
|
78787
78864
|
const f = {};
|
|
78788
78865
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -78854,7 +78931,7 @@ function makeUnitRunners(o) {
|
|
|
78854
78931
|
}
|
|
78855
78932
|
function makeSessionRunner(o) {
|
|
78856
78933
|
const limitS = o.sessionLimitS ?? SESSION_LIMIT_S2;
|
|
78857
|
-
const cli = import.meta.path.endsWith("modernize_unit.ts") ?
|
|
78934
|
+
const cli = import.meta.path.endsWith("modernize_unit.ts") ? join132(import.meta.dir, "..", "cli.ts") : import.meta.path;
|
|
78858
78935
|
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
78936
|
}
|
|
78860
78937
|
function defaultUnitFile(unitId, newTreeDir) {
|
|
@@ -78862,7 +78939,7 @@ function defaultUnitFile(unitId, newTreeDir) {
|
|
|
78862
78939
|
return null;
|
|
78863
78940
|
try {
|
|
78864
78941
|
const root = realpathSync34(newTreeDir);
|
|
78865
|
-
const real3 = realpathSync34(
|
|
78942
|
+
const real3 = realpathSync34(join132(root, unitId));
|
|
78866
78943
|
return real3.startsWith(root + sep21) ? real3 : null;
|
|
78867
78944
|
} catch {
|
|
78868
78945
|
return null;
|
|
@@ -78899,16 +78976,16 @@ function runPythonCase(o, unitId, newTreeDir, rec2, stub) {
|
|
|
78899
78976
|
const src = o.unitFile ? o.unitFile(unitId, newTreeDir) : defaultUnitFile(unitId, newTreeDir);
|
|
78900
78977
|
if (!src || !src.endsWith(".py") || !existsSync89(src))
|
|
78901
78978
|
throw new Error(`cannot locate the source of unit ${unitId} in the new tree`);
|
|
78902
|
-
const dir = mkdtempSync18(
|
|
78979
|
+
const dir = mkdtempSync18(join132(tmpdir23(), "loki-newcase-"));
|
|
78903
78980
|
try {
|
|
78904
|
-
const cases =
|
|
78981
|
+
const cases = join132(dir, "in.jsonl"), out3 = join132(dir, "out.jsonl");
|
|
78905
78982
|
writeFileSync67(cases, JSON.stringify({ entry: rec2.entry, args: rec2.args, kwargs: rec2.kwargs, boundaries: boundariesFromCase(rec2) }) + `
|
|
78906
78983
|
`, "utf8");
|
|
78907
|
-
const r = spawnSync21(o.pythonBin ?? "python3", [
|
|
78984
|
+
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
78985
|
if (r.status !== 0 || !existsSync89(out3))
|
|
78909
78986
|
throw new Error(`new-tree case runner failed (${r.status ?? r.signal ?? "no status"}): ${String(r.stderr ?? "").trim().split(`
|
|
78910
78987
|
`).pop() ?? ""}`);
|
|
78911
|
-
const line2 =
|
|
78988
|
+
const line2 = readFileSync114(out3, "utf8").split(`
|
|
78912
78989
|
`).find((l) => l.trim() !== "");
|
|
78913
78990
|
if (!line2)
|
|
78914
78991
|
throw new Error("new-tree case runner produced no record");
|
|
@@ -78934,7 +79011,7 @@ Usage: ${UNIT_USAGE}
|
|
|
78934
79011
|
const root = u10.tmpRoot ?? (runTmp !== "" && isRealDir(runTmp) ? runTmp : tmpdir23());
|
|
78935
79012
|
let repoDir;
|
|
78936
79013
|
try {
|
|
78937
|
-
repoDir = mkdtempSync18(
|
|
79014
|
+
repoDir = mkdtempSync18(join132(root, "loki-unit-"));
|
|
78938
79015
|
} catch (e10) {
|
|
78939
79016
|
process.stderr.write(`modernize unit: cannot create a temp checkout directory: ${e10.message}
|
|
78940
79017
|
`);
|
|
@@ -79030,11 +79107,11 @@ var init_modernize_unit = __esm(() => {
|
|
|
79030
79107
|
|
|
79031
79108
|
// ../../loki-ts/src/util/modernize_coordinator.ts
|
|
79032
79109
|
import { createHash as createHash36 } from "crypto";
|
|
79033
|
-
import { existsSync as existsSync90, mkdtempSync as mkdtempSync19, readFileSync as
|
|
79110
|
+
import { existsSync as existsSync90, mkdtempSync as mkdtempSync19, readFileSync as readFileSync115, rmSync as rmSync38 } from "fs";
|
|
79034
79111
|
import { tmpdir as tmpdir24 } from "os";
|
|
79035
|
-
import { join as
|
|
79112
|
+
import { join as join133 } from "path";
|
|
79036
79113
|
function shipUnitOf(d, unit, o) {
|
|
79037
|
-
const sealed =
|
|
79114
|
+
const sealed = join133(oracleDir(d.repoDir, d.mid, unit), "sealed.json");
|
|
79038
79115
|
const eq3 = o?.result?.equiv;
|
|
79039
79116
|
return {
|
|
79040
79117
|
unit,
|
|
@@ -79051,7 +79128,7 @@ function scopeBuildToWave(cmd2, repoDir, units) {
|
|
|
79051
79128
|
const x3 = cmd2?.argv.indexOf("-x") ?? -1;
|
|
79052
79129
|
if (!cmd2 || !cmd2.argv.includes("compileall") || x3 < 0)
|
|
79053
79130
|
return cmd2;
|
|
79054
|
-
const files = [...new Set(units.flatMap((u10) => u10.nodes))].filter((n11) => n11.endsWith(".py") && isSafeUnitId(n11) && existsSync90(
|
|
79131
|
+
const files = [...new Set(units.flatMap((u10) => u10.nodes))].filter((n11) => n11.endsWith(".py") && isSafeUnitId(n11) && existsSync90(join133(repoDir, n11)));
|
|
79055
79132
|
return files.length ? { ...cmd2, argv: [...cmd2.argv.slice(0, x3 + 2), ...files] } : cmd2;
|
|
79056
79133
|
}
|
|
79057
79134
|
async function runWaves(plan, d) {
|
|
@@ -79210,16 +79287,16 @@ function makeAttemptRunner(o) {
|
|
|
79210
79287
|
}
|
|
79211
79288
|
function makeUnitPrep(o) {
|
|
79212
79289
|
const runtimeOk = o.runtimeOk ?? (() => {
|
|
79213
|
-
const dir = mkdtempSync19(
|
|
79290
|
+
const dir = mkdtempSync19(join133(tmpdir24(), "loki-probe-"));
|
|
79214
79291
|
try {
|
|
79215
|
-
return realCaptureRunner(
|
|
79292
|
+
return realCaptureRunner(join133(dir, "probe.py"), []).error !== "old runtime unavailable";
|
|
79216
79293
|
} finally {
|
|
79217
79294
|
rmSync38(dir, { recursive: true, force: true });
|
|
79218
79295
|
}
|
|
79219
79296
|
});
|
|
79220
79297
|
let runtime = null;
|
|
79221
79298
|
return (unit) => {
|
|
79222
|
-
if (existsSync90(
|
|
79299
|
+
if (existsSync90(join133(oracleDir(o.repoDir, o.mid, unit.id), "cases.jsonl")) || alreadySealedInLog(o.repoDir, o.mid, unit.id))
|
|
79223
79300
|
return null;
|
|
79224
79301
|
runtime ??= runtimeOk();
|
|
79225
79302
|
if (!runtime)
|
|
@@ -79227,7 +79304,7 @@ function makeUnitPrep(o) {
|
|
|
79227
79304
|
const node = unit.nodes.length === 1 ? unit.nodes[0] : "";
|
|
79228
79305
|
if (!node.endsWith(".py") || !isSafeUnitId(node))
|
|
79229
79306
|
return MULTI_FILE_REASON;
|
|
79230
|
-
const r = (o.capture ?? captureUnitOracle)({ repoDir: o.repoDir, mid: o.mid, unit: unit.id, unitPath:
|
|
79307
|
+
const r = (o.capture ?? captureUnitOracle)({ repoDir: o.repoDir, mid: o.mid, unit: unit.id, unitPath: join133(o.repoDir, node), propose: o.propose });
|
|
79231
79308
|
return r.ok ? null : r.reason;
|
|
79232
79309
|
};
|
|
79233
79310
|
}
|
|
@@ -79286,7 +79363,7 @@ function productionWaveDeps(o) {
|
|
|
79286
79363
|
}
|
|
79287
79364
|
};
|
|
79288
79365
|
}
|
|
79289
|
-
var productionReslice, sha2565 = (p) => existsSync90(p) ? createHash36("sha256").update(
|
|
79366
|
+
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
79367
|
var init_modernize_coordinator = __esm(() => {
|
|
79291
79368
|
init_codemod();
|
|
79292
79369
|
init_search();
|
|
@@ -79619,8 +79696,8 @@ __export(exports_export_sarif, {
|
|
|
79619
79696
|
preRedFromEvents: () => preRedFromEvents,
|
|
79620
79697
|
main: () => main8
|
|
79621
79698
|
});
|
|
79622
|
-
import { existsSync as existsSync92, readFileSync as
|
|
79623
|
-
import { join as
|
|
79699
|
+
import { existsSync as existsSync92, readFileSync as readFileSync116, writeFileSync as writeFileSync68 } from "fs";
|
|
79700
|
+
import { join as join134 } from "path";
|
|
79624
79701
|
function scanDiff(diff) {
|
|
79625
79702
|
const out3 = [];
|
|
79626
79703
|
let file = "";
|
|
@@ -79651,7 +79728,7 @@ function scanDiff(diff) {
|
|
|
79651
79728
|
function preRedFromEvents(runDir) {
|
|
79652
79729
|
try {
|
|
79653
79730
|
let pre2 = [];
|
|
79654
|
-
for (const l of
|
|
79731
|
+
for (const l of readFileSync116(join134(runDir, "events.jsonl"), "utf8").split(`
|
|
79655
79732
|
`)) {
|
|
79656
79733
|
if (!l.includes('"stage.completed"'))
|
|
79657
79734
|
continue;
|
|
@@ -79680,19 +79757,19 @@ async function main8(args, deps = {}) {
|
|
|
79680
79757
|
if (bad || rest.length > 1)
|
|
79681
79758
|
return process.stderr.write(`loki export --sarif: ${bad ? `unknown flag ${bad}` : "more than one run-id"}
|
|
79682
79759
|
`), 2;
|
|
79683
|
-
const runsRoot2 = deps.runsRoot ??
|
|
79760
|
+
const runsRoot2 = deps.runsRoot ?? join134(lokiDir(), "runs");
|
|
79684
79761
|
const runId2 = rest[0] ?? latestRunId(runsRoot2);
|
|
79685
79762
|
if (!runId2)
|
|
79686
79763
|
return process.stderr.write(`loki export --sarif: no runs found
|
|
79687
79764
|
`), 66;
|
|
79688
|
-
const runDir =
|
|
79689
|
-
const receiptPath =
|
|
79765
|
+
const runDir = join134(runsRoot2, runId2);
|
|
79766
|
+
const receiptPath = join134(runDir, "receipt.json");
|
|
79690
79767
|
if (runId2.includes("/") || runId2.includes("..") || !existsSync92(receiptPath))
|
|
79691
79768
|
return process.stderr.write(`loki export --sarif: unknown run ${runId2}
|
|
79692
79769
|
`), 66;
|
|
79693
79770
|
let receipt;
|
|
79694
79771
|
try {
|
|
79695
|
-
receipt = JSON.parse(
|
|
79772
|
+
receipt = JSON.parse(readFileSync116(receiptPath, "utf8"));
|
|
79696
79773
|
} catch {
|
|
79697
79774
|
return process.stderr.write(`loki export --sarif: unreadable receipt for ${runId2}
|
|
79698
79775
|
`), 66;
|
|
@@ -79709,9 +79786,9 @@ async function main8(args, deps = {}) {
|
|
|
79709
79786
|
findings.push(...receiptFindings(receipt, preRedFromEvents(runDir)));
|
|
79710
79787
|
let version2 = "0.0.0";
|
|
79711
79788
|
try {
|
|
79712
|
-
version2 =
|
|
79789
|
+
version2 = readFileSync116(join134(REPO_ROOT, "VERSION"), "utf8").trim() || version2;
|
|
79713
79790
|
} catch {}
|
|
79714
|
-
const out3 =
|
|
79791
|
+
const out3 = join134(runDir, "findings.sarif");
|
|
79715
79792
|
writeFileSync68(out3, JSON.stringify(toSarif(findings, version2, deps.repoDir ?? process.cwd()), null, 2) + `
|
|
79716
79793
|
`);
|
|
79717
79794
|
process.stdout.write(`run: ${runId2}
|
|
@@ -79930,7 +80007,7 @@ var init_output = __esm(() => {
|
|
|
79930
80007
|
|
|
79931
80008
|
// ../../loki-ts/src/features/receipt_dsse.ts
|
|
79932
80009
|
import { createPublicKey as createPublicKey5, sign as sign3, verify as verify3 } from "crypto";
|
|
79933
|
-
import { readFileSync as
|
|
80010
|
+
import { readFileSync as readFileSync117 } from "fs";
|
|
79934
80011
|
function pae2(payloadType, body) {
|
|
79935
80012
|
const t = Buffer.from(payloadType, "utf8");
|
|
79936
80013
|
return Buffer.concat([Buffer.from(`DSSEv1 ${t.length} `), t, Buffer.from(` ${body.length} `), body]);
|
|
@@ -80026,7 +80103,7 @@ function verifyDsseReceipt(env, d) {
|
|
|
80026
80103
|
}
|
|
80027
80104
|
function runIdGuard(receiptPath, runId2) {
|
|
80028
80105
|
try {
|
|
80029
|
-
return envelopeRunIdProblem(JSON.parse(
|
|
80106
|
+
return envelopeRunIdProblem(JSON.parse(readFileSync117(receiptPath, "utf8")), runId2);
|
|
80030
80107
|
} catch {
|
|
80031
80108
|
return null;
|
|
80032
80109
|
}
|
|
@@ -80034,7 +80111,7 @@ function runIdGuard(receiptPath, runId2) {
|
|
|
80034
80111
|
async function exportDsseReceipt(a) {
|
|
80035
80112
|
const fail2 = (rc2, m) => (process.stderr.write(`loki verify --export-dsse: ${m}
|
|
80036
80113
|
`), rc2);
|
|
80037
|
-
const rd2 = a.deps.read ?? ((p) =>
|
|
80114
|
+
const rd2 = a.deps.read ?? ((p) => readFileSync117(p, "utf8"));
|
|
80038
80115
|
let text4;
|
|
80039
80116
|
try {
|
|
80040
80117
|
text4 = rd2(a.receiptPath);
|
|
@@ -80091,10 +80168,10 @@ var init_undo = __esm(() => {
|
|
|
80091
80168
|
});
|
|
80092
80169
|
|
|
80093
80170
|
// ../../loki-ts/src/commands/run_status.ts
|
|
80094
|
-
import { existsSync as existsSync93, readdirSync as readdirSync38, readFileSync as
|
|
80095
|
-
import { basename as basename32, dirname as
|
|
80171
|
+
import { existsSync as existsSync93, readdirSync as readdirSync38, readFileSync as readFileSync118, statSync as statSync36 } from "fs";
|
|
80172
|
+
import { basename as basename32, dirname as dirname50, join as join135, resolve as resolve39 } from "path";
|
|
80096
80173
|
function runsRoot(env, repoDir) {
|
|
80097
|
-
return env.LOKI_DIR ?
|
|
80174
|
+
return env.LOKI_DIR ? join135(resolve39(repoDir, env.LOKI_DIR), "runs") : join135(repoDir, ".loki", "runs");
|
|
80098
80175
|
}
|
|
80099
80176
|
function listRunIds(root) {
|
|
80100
80177
|
if (!existsSync93(root))
|
|
@@ -80106,7 +80183,7 @@ function latestRunId(root) {
|
|
|
80106
80183
|
return ids.length ? ids[ids.length - 1] : null;
|
|
80107
80184
|
}
|
|
80108
80185
|
function eventsPath(root, runId2) {
|
|
80109
|
-
return
|
|
80186
|
+
return join135(root, runId2, "events.jsonl");
|
|
80110
80187
|
}
|
|
80111
80188
|
var TERMINAL2;
|
|
80112
80189
|
var init_run_status = __esm(() => {
|
|
@@ -80123,8 +80200,8 @@ var init_run_status = __esm(() => {
|
|
|
80123
80200
|
|
|
80124
80201
|
// ../../loki-ts/src/util/seal_drift.ts
|
|
80125
80202
|
import { createHash as createHash38 } from "crypto";
|
|
80126
|
-
import { existsSync as existsSync94, readFileSync as
|
|
80127
|
-
import { basename as basename33, dirname as
|
|
80203
|
+
import { existsSync as existsSync94, readFileSync as readFileSync119, realpathSync as realpathSync35 } from "fs";
|
|
80204
|
+
import { basename as basename33, dirname as dirname51, join as join136, relative as relative27 } from "path";
|
|
80128
80205
|
function tornTail(raw2) {
|
|
80129
80206
|
if (raw2 === "" || raw2.endsWith(`
|
|
80130
80207
|
`))
|
|
@@ -80143,7 +80220,7 @@ function tornTail(raw2) {
|
|
|
80143
80220
|
function boundEvents(log, bound) {
|
|
80144
80221
|
if (!existsSync94(log))
|
|
80145
80222
|
return null;
|
|
80146
|
-
const lines2 =
|
|
80223
|
+
const lines2 = readFileSync119(log, "utf8").split(`
|
|
80147
80224
|
`).filter((l) => l.trim() !== ""), h10 = createHash38("sha256");
|
|
80148
80225
|
let n11 = -1;
|
|
80149
80226
|
for (let i = 0;i <= lines2.length; i++) {
|
|
@@ -80171,7 +80248,7 @@ function fabricatedPass(receiptPath, r) {
|
|
|
80171
80248
|
const bound = r["events_sha256"];
|
|
80172
80249
|
if (typeof bound !== "string" || bound === EMPTY_SHA || !Array.isArray(r["checks"]))
|
|
80173
80250
|
return null;
|
|
80174
|
-
const events2 = boundEvents(
|
|
80251
|
+
const events2 = boundEvents(join136(dirname51(receiptPath), "events.jsonl"), bound);
|
|
80175
80252
|
if (!events2 || !events2.some((e10) => e10.stage === "verify"))
|
|
80176
80253
|
return null;
|
|
80177
80254
|
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 +80256,12 @@ function fabricatedPass(receiptPath, r) {
|
|
|
80179
80256
|
return missing.length ? `receipt claims pass with no test.result pass in events.jsonl: ${missing.join(", ")}` : null;
|
|
80180
80257
|
}
|
|
80181
80258
|
function currentTaskSha(runDir, source, env) {
|
|
80182
|
-
const f = source === "issue" ?
|
|
80183
|
-
return f && existsSync94(f) ? sha6(
|
|
80259
|
+
const f = source === "issue" ? join136(runDir, "issue.json") : env["LOKI_VERIFY_TASK_FILE"];
|
|
80260
|
+
return f && existsSync94(f) ? sha6(readFileSync119(f)) : null;
|
|
80184
80261
|
}
|
|
80185
80262
|
function repoOf(receiptPath) {
|
|
80186
|
-
const runs2 =
|
|
80187
|
-
return basename33(runs2) === "runs" && basename33(
|
|
80263
|
+
const runs2 = dirname51(dirname51(receiptPath));
|
|
80264
|
+
return basename33(runs2) === "runs" && basename33(dirname51(runs2)) === ".loki" ? dirname51(dirname51(runs2)) : null;
|
|
80188
80265
|
}
|
|
80189
80266
|
function overlap(repo, base, sealedHead, head) {
|
|
80190
80267
|
if (typeof base !== "string" || !/^[0-9a-f]{40,64}$/.test(base) || !/^[0-9a-f]{40,64}$/.test(sealedHead))
|
|
@@ -80210,7 +80287,7 @@ function onlyWallPublish(repo, r, sealedHead, head) {
|
|
|
80210
80287
|
} catch {
|
|
80211
80288
|
return x3;
|
|
80212
80289
|
}
|
|
80213
|
-
}, rr2 = real3(repo), want = new Map(wall.map((w) => [relative27(rr2,
|
|
80290
|
+
}, 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
80291
|
const commits = safeGit(repo, ["rev-list", "--reverse", "--topo-order", `${sealedHead}..${head}`]).split(`
|
|
80215
80292
|
`).filter(Boolean);
|
|
80216
80293
|
if (commits.length === 0 || safeGit(repo, ["rev-list", "--merges", "--count", `${sealedHead}..${head}`]).trim() !== "0")
|
|
@@ -80248,18 +80325,18 @@ function claimsWallPublish(repo, r, sealedHead, head) {
|
|
|
80248
80325
|
function sealDrift(given, r, env = process.env) {
|
|
80249
80326
|
let receiptPath = given;
|
|
80250
80327
|
try {
|
|
80251
|
-
receiptPath =
|
|
80328
|
+
receiptPath = join136(realpathSync35(dirname51(given)), basename33(given));
|
|
80252
80329
|
} catch {}
|
|
80253
80330
|
const fab = fabricatedPass(receiptPath, r);
|
|
80254
80331
|
if (fab)
|
|
80255
80332
|
return { verdict: "TAMPERED", reason: fab };
|
|
80256
80333
|
try {
|
|
80257
|
-
const log =
|
|
80258
|
-
if (existsSync94(log) && tornTail(
|
|
80334
|
+
const log = join136(dirname51(receiptPath), "events.jsonl");
|
|
80335
|
+
if (existsSync94(log) && tornTail(readFileSync119(log, "utf8")))
|
|
80259
80336
|
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
80337
|
} catch {}
|
|
80261
80338
|
const task = r["task"] ?? {};
|
|
80262
|
-
const cur = currentTaskSha(
|
|
80339
|
+
const cur = currentTaskSha(dirname51(receiptPath), task.source, env);
|
|
80263
80340
|
if (cur !== null && typeof task.sha256 === "string" && task.sha256 !== "" && cur !== task.sha256)
|
|
80264
80341
|
return { verdict: "UNCHECKED", reason: `intent drift: sealed task sha256 ${task.sha256} differs from the current spec ${cur}` };
|
|
80265
80342
|
const repo = repoOf(receiptPath);
|
|
@@ -80289,14 +80366,14 @@ var init_seal_drift = __esm(() => {
|
|
|
80289
80366
|
});
|
|
80290
80367
|
|
|
80291
80368
|
// ../../loki-ts/src/util/composite_seal.ts
|
|
80292
|
-
import { existsSync as existsSync95, readFileSync as
|
|
80293
|
-
import { basename as basename34, dirname as
|
|
80369
|
+
import { existsSync as existsSync95, readFileSync as readFileSync120 } from "fs";
|
|
80370
|
+
import { basename as basename34, dirname as dirname52, join as join137 } from "path";
|
|
80294
80371
|
function logProblem(runDir, integ) {
|
|
80295
80372
|
if (typeof integ["log_sha256"] !== "string")
|
|
80296
80373
|
return null;
|
|
80297
80374
|
let b;
|
|
80298
80375
|
try {
|
|
80299
|
-
b =
|
|
80376
|
+
b = readFileSync120(join137(runDir, "integration.log"));
|
|
80300
80377
|
} catch {
|
|
80301
80378
|
return "integration.log is missing but integration.json records its hash";
|
|
80302
80379
|
}
|
|
@@ -80311,10 +80388,10 @@ function integrationProblem(integ) {
|
|
|
80311
80388
|
return null;
|
|
80312
80389
|
}
|
|
80313
80390
|
function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
80314
|
-
const ip =
|
|
80391
|
+
const ip = join137(runDir, "integration.json");
|
|
80315
80392
|
let ibytes;
|
|
80316
80393
|
try {
|
|
80317
|
-
ibytes =
|
|
80394
|
+
ibytes = readFileSync120(ip);
|
|
80318
80395
|
} catch {
|
|
80319
80396
|
throw new Error("integration.json missing; the workspace run did not finish");
|
|
80320
80397
|
}
|
|
@@ -80338,12 +80415,12 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80338
80415
|
const outcome = String(integ["outcomes"][repo] ?? "");
|
|
80339
80416
|
if (outcome !== "ok")
|
|
80340
80417
|
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(
|
|
80418
|
+
const runsDir = join137(runDir, "worktrees", slugOf(repo), ".loki", "runs");
|
|
80419
|
+
const ids = (dirNames(runsDir) ?? []).filter((n11) => existsSync95(join137(runsDir, n11, "receipt.json")));
|
|
80343
80420
|
const id2 = ids[ids.length - 1];
|
|
80344
80421
|
if (!id2)
|
|
80345
80422
|
throw new Error(`repo ${text3(repo, 80)} has no receipt.json under worktrees/${slugOf(repo)}/.loki/runs`);
|
|
80346
|
-
const rp =
|
|
80423
|
+
const rp = join137(runsDir, id2, "receipt.json"), bytes = readFileSync120(rp), r = readJson7(rp);
|
|
80347
80424
|
if (jsonTooDeep(r))
|
|
80348
80425
|
throw new Error(`repo ${text3(repo, 80)} receipt cannot be hashed (nested too deeply); no composite`);
|
|
80349
80426
|
if (!isObj10(r) || typeof r["receipt_sha256"] !== "string" || rh(r) !== r["receipt_sha256"])
|
|
@@ -80361,7 +80438,7 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80361
80438
|
throw new Error("workspace has no repos");
|
|
80362
80439
|
return {
|
|
80363
80440
|
schema: COMPOSITE_SCHEMA,
|
|
80364
|
-
workspace: basename34(
|
|
80441
|
+
workspace: basename34(dirname52(runDir)),
|
|
80365
80442
|
run_id: basename34(runDir),
|
|
80366
80443
|
integration_sha256: sha4(ibytes),
|
|
80367
80444
|
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 +80448,7 @@ function composeComposite(runDir, rh, toolchain = collectToolchain()) {
|
|
|
80371
80448
|
};
|
|
80372
80449
|
}
|
|
80373
80450
|
async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
80374
|
-
const runDir =
|
|
80451
|
+
const runDir = dirname52(receiptPath);
|
|
80375
80452
|
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
80376
80453
|
const bad = (reason) => ({ problem: { verdict: "TAMPERED", reason: `composite: ${reason}` }, verdict: "FAILED" });
|
|
80377
80454
|
const deep = (what) => ({ problem: { verdict: "UNCHECKED", reason: `composite: ${what} cannot be hashed (nested too deeply)` }, verdict: "FAILED" });
|
|
@@ -80380,13 +80457,13 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
80380
80457
|
return bad("body malformed");
|
|
80381
80458
|
let ibytes;
|
|
80382
80459
|
try {
|
|
80383
|
-
ibytes =
|
|
80460
|
+
ibytes = readFileSync120(join137(runDir, "integration.json"));
|
|
80384
80461
|
} catch {
|
|
80385
80462
|
return bad("integration.json missing");
|
|
80386
80463
|
}
|
|
80387
80464
|
if (sha4(ibytes) !== receipt["integration_sha256"])
|
|
80388
80465
|
return bad("integration.json does not match its recorded hash");
|
|
80389
|
-
const integ = readJson7(
|
|
80466
|
+
const integ = readJson7(join137(runDir, "integration.json"));
|
|
80390
80467
|
if (jsonTooDeep(integ))
|
|
80391
80468
|
return deep("integration.json");
|
|
80392
80469
|
if (!isObj10(integ) || !isObj10(integ["outcomes"]))
|
|
@@ -80423,10 +80500,10 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
80423
80500
|
return bad(`child ${text3(repo, 80) || "?"} has an invalid receipt path`);
|
|
80424
80501
|
if (outcomes[repo] !== "ok")
|
|
80425
80502
|
return bad(`child ${text3(repo, 80)} did not finish ok in integration.json`);
|
|
80426
|
-
const rp =
|
|
80503
|
+
const rp = join137(runDir, rel);
|
|
80427
80504
|
let bytes;
|
|
80428
80505
|
try {
|
|
80429
|
-
bytes =
|
|
80506
|
+
bytes = readFileSync120(rp);
|
|
80430
80507
|
} catch {
|
|
80431
80508
|
return bad(`child ${repo} receipt missing`);
|
|
80432
80509
|
}
|
|
@@ -80486,8 +80563,8 @@ __export(exports_verify_cmd, {
|
|
|
80486
80563
|
main: () => main9,
|
|
80487
80564
|
computeReceiptHash: () => computeReceiptHash
|
|
80488
80565
|
});
|
|
80489
|
-
import { existsSync as existsSync96, readFileSync as
|
|
80490
|
-
import { basename as basename35, dirname as
|
|
80566
|
+
import { existsSync as existsSync96, readFileSync as readFileSync121, renameSync as renameSync23, statSync as statSync37, writeFileSync as writeFileSync69 } from "fs";
|
|
80567
|
+
import { basename as basename35, dirname as dirname53, join as join138 } from "path";
|
|
80491
80568
|
import { createHash as createHash39, createPublicKey as createPublicKey6, verify as verify4 } from "crypto";
|
|
80492
80569
|
function pubFor(kid, given) {
|
|
80493
80570
|
if (given)
|
|
@@ -80495,7 +80572,7 @@ function pubFor(kid, given) {
|
|
|
80495
80572
|
const active = loadSigningKey(false);
|
|
80496
80573
|
const pubs = (process.env["LOKI_RECEIPT_RETIRED_PUBKEYS"] ?? "").split(":").map((f) => f.trim()).filter(Boolean).flatMap((f) => {
|
|
80497
80574
|
try {
|
|
80498
|
-
return [createPublicKey6(
|
|
80575
|
+
return [createPublicKey6(readFileSync121(f))];
|
|
80499
80576
|
} catch {
|
|
80500
80577
|
return [];
|
|
80501
80578
|
}
|
|
@@ -80525,14 +80602,14 @@ function checkAttestation(jwt, expectedHash, given) {
|
|
|
80525
80602
|
}
|
|
80526
80603
|
function wallTamperProblem(receiptPath, receipt) {
|
|
80527
80604
|
const wall = receipt["wall"], files = Array.isArray(wall?.files) ? wall.files : [];
|
|
80528
|
-
const wallDir =
|
|
80605
|
+
const wallDir = join138(dirname53(receiptPath), "wall"), haveWallDir = existsSync96(wallDir);
|
|
80529
80606
|
for (const f of files) {
|
|
80530
80607
|
if (typeof f?.path !== "string" || typeof f.sha256 !== "string")
|
|
80531
80608
|
continue;
|
|
80532
|
-
const copy =
|
|
80609
|
+
const copy = join138(wallDir, basename35(f.path));
|
|
80533
80610
|
let cur;
|
|
80534
80611
|
try {
|
|
80535
|
-
cur = createHash39("sha256").update(
|
|
80612
|
+
cur = createHash39("sha256").update(readFileSync121(copy)).digest("hex");
|
|
80536
80613
|
} catch {
|
|
80537
80614
|
if (haveWallDir)
|
|
80538
80615
|
return `sealed Wall file ${basename35(f.path)} is missing from the run's wall directory: it was deleted after the seal`;
|
|
@@ -80559,10 +80636,10 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
80559
80636
|
const claims = st2 !== null && typeof st2 === "object" && Object.keys(st2).length > 0;
|
|
80560
80637
|
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
80638
|
}
|
|
80562
|
-
const path =
|
|
80639
|
+
const path = join138(dirname53(receiptPath), "events.jsonl");
|
|
80563
80640
|
if (!existsSync96(path))
|
|
80564
80641
|
return "events.jsonl is missing";
|
|
80565
|
-
const raw2 =
|
|
80642
|
+
const raw2 = readFileSync121(path, "utf8"), events2 = readEvents(path), all = raw2.split(`
|
|
80566
80643
|
`).filter((l) => l.trim() !== ""), lines2 = tornTail(raw2) ? all.slice(0, -1) : all;
|
|
80567
80644
|
if (events2.length !== lines2.length || events2.some((e10, i) => e10.seq !== i))
|
|
80568
80645
|
return "events.jsonl has a forged, edited or missing line";
|
|
@@ -80582,7 +80659,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
80582
80659
|
return h10.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
|
|
80583
80660
|
}
|
|
80584
80661
|
function checkLogSeal(receiptPath, hash, kid, given) {
|
|
80585
|
-
const path =
|
|
80662
|
+
const path = join138(dirname53(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e10) => e10.type === "run.completed");
|
|
80586
80663
|
if (!events2.some((e10) => e10.type === "receipt.sealed" && e10.data["receipt_sha256"] === hash))
|
|
80587
80664
|
return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
|
|
80588
80665
|
if (done < 0)
|
|
@@ -80590,7 +80667,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
|
|
|
80590
80667
|
const seal = events2[done + 1], d = seal?.type === "log.sealed" ? seal.data : null;
|
|
80591
80668
|
if (!d)
|
|
80592
80669
|
return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
|
|
80593
|
-
const lines2 =
|
|
80670
|
+
const lines2 = readFileSync121(path, "utf8").split(`
|
|
80594
80671
|
`).filter((l) => l.trim() !== ""), sha7 = createHash39("sha256").update(lines2.slice(0, done + 1).join(`
|
|
80595
80672
|
`) + `
|
|
80596
80673
|
`).digest("hex");
|
|
@@ -80604,7 +80681,7 @@ async function verifyReceipt(receiptPath, deps = {}) {
|
|
|
80604
80681
|
return { verdict: "UNCHECKED", reasons: [`receipt not found: ${receiptPath}`] };
|
|
80605
80682
|
let receipt;
|
|
80606
80683
|
try {
|
|
80607
|
-
receipt = JSON.parse((deps.read ?? ((p) =>
|
|
80684
|
+
receipt = JSON.parse((deps.read ?? ((p) => readFileSync121(p, "utf8")))(receiptPath));
|
|
80608
80685
|
} catch {
|
|
80609
80686
|
return { verdict: "UNCHECKED", reasons: ["receipt.json is not valid JSON"] };
|
|
80610
80687
|
}
|
|
@@ -80699,7 +80776,7 @@ function sealCompositeCmd(runDir) {
|
|
|
80699
80776
|
`), 2;
|
|
80700
80777
|
}
|
|
80701
80778
|
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 =
|
|
80779
|
+
const out3 = { ...body, composite_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } }, path = join138(runDir, "composite.json");
|
|
80703
80780
|
writeFileSync69(`${path}.tmp`, JSON.stringify(out3, null, 2) + `
|
|
80704
80781
|
`);
|
|
80705
80782
|
renameSync23(`${path}.tmp`, path);
|
|
@@ -80715,7 +80792,7 @@ ${compositeLines(out3).join(`
|
|
|
80715
80792
|
function independentLine(receiptPath) {
|
|
80716
80793
|
let checks = [];
|
|
80717
80794
|
try {
|
|
80718
|
-
const c = JSON.parse(
|
|
80795
|
+
const c = JSON.parse(readFileSync121(receiptPath, "utf8")).checks;
|
|
80719
80796
|
if (Array.isArray(c))
|
|
80720
80797
|
checks = c;
|
|
80721
80798
|
} catch {}
|
|
@@ -80772,14 +80849,14 @@ ${/^(unknown option|expected at most one)/.test(pk2.error) ? `Usage: loki verify
|
|
|
80772
80849
|
args = pk2.args;
|
|
80773
80850
|
if (pk2.pubkey)
|
|
80774
80851
|
deps = { ...deps, pubkey: pk2.pubkey };
|
|
80775
|
-
const runsRoot2 = deps.runsRoot ??
|
|
80852
|
+
const runsRoot2 = deps.runsRoot ?? join138(lokiDir(), "runs");
|
|
80776
80853
|
const runId2 = args[0] ?? latestRunId(runsRoot2) ?? undefined;
|
|
80777
80854
|
if (!runId2)
|
|
80778
80855
|
return process.stderr.write(`loki verify: no runs found
|
|
80779
80856
|
`), 66;
|
|
80780
80857
|
const isFile = existsSync96(runId2) && statSync37(runId2).isFile();
|
|
80781
80858
|
const isPath = isFile || /[\\/]/.test(runId2) || runId2.endsWith(".json");
|
|
80782
|
-
const receiptPath = isPath ? runId2 :
|
|
80859
|
+
const receiptPath = isPath ? runId2 : join138(runsRoot2, runId2, "receipt.json");
|
|
80783
80860
|
const byRunId = !isPath;
|
|
80784
80861
|
rec2.runId = runId2;
|
|
80785
80862
|
rec2.receiptPath = receiptPath;
|
|
@@ -80795,7 +80872,7 @@ verdict: TAMPERED
|
|
|
80795
80872
|
if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
|
|
80796
80873
|
const d = (() => {
|
|
80797
80874
|
try {
|
|
80798
|
-
return sealDrift(receiptPath, JSON.parse(
|
|
80875
|
+
return sealDrift(receiptPath, JSON.parse(readFileSync121(receiptPath, "utf8")));
|
|
80799
80876
|
} catch {
|
|
80800
80877
|
return null;
|
|
80801
80878
|
}
|
|
@@ -80808,7 +80885,7 @@ verdict: TAMPERED
|
|
|
80808
80885
|
{
|
|
80809
80886
|
const id2 = (() => {
|
|
80810
80887
|
try {
|
|
80811
|
-
const r = JSON.parse(
|
|
80888
|
+
const r = JSON.parse(readFileSync121(receiptPath, "utf8"));
|
|
80812
80889
|
const j10 = r["verification"]?.jwt;
|
|
80813
80890
|
const k3 = result.verdict === "VERIFIED" && typeof j10 === "string" ? JSON.parse(Buffer.from(j10.split(".")[0], "base64url").toString()).kid : null;
|
|
80814
80891
|
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 +80903,7 @@ verdict: TAMPERED
|
|
|
80826
80903
|
if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
|
|
80827
80904
|
const outcome = (() => {
|
|
80828
80905
|
try {
|
|
80829
|
-
return outcomeOf2(JSON.parse(
|
|
80906
|
+
return outcomeOf2(JSON.parse(readFileSync121(receiptPath, "utf8")));
|
|
80830
80907
|
} catch {
|
|
80831
80908
|
return "UNREADABLE";
|
|
80832
80909
|
}
|
|
@@ -80855,7 +80932,7 @@ verdict: ${result.verdict}
|
|
|
80855
80932
|
`);
|
|
80856
80933
|
if (result.verdict !== "TAMPERED")
|
|
80857
80934
|
try {
|
|
80858
|
-
const r = JSON.parse(
|
|
80935
|
+
const r = JSON.parse(readFileSync121(receiptPath, "utf8"));
|
|
80859
80936
|
if (isComposite(r))
|
|
80860
80937
|
for (const l of compositeLines(r))
|
|
80861
80938
|
process.stdout.write(`${l}
|
|
@@ -80913,8 +80990,8 @@ var init_verify_cmd = __esm(() => {
|
|
|
80913
80990
|
});
|
|
80914
80991
|
|
|
80915
80992
|
// src/server/app.ts
|
|
80916
|
-
import { existsSync as existsSync98, readFileSync as
|
|
80917
|
-
import { join as
|
|
80993
|
+
import { existsSync as existsSync98, readFileSync as readFileSync124, statSync as statSync38 } from "fs";
|
|
80994
|
+
import { join as join141, resolve as resolve40, sep as sep23 } from "path";
|
|
80918
80995
|
|
|
80919
80996
|
// node_modules/hono/dist/request/constants.js
|
|
80920
80997
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -91225,9 +91302,9 @@ function mount20(ctx) {
|
|
|
91225
91302
|
}
|
|
91226
91303
|
|
|
91227
91304
|
// src/server/routes/verify.ts
|
|
91228
|
-
import { readFileSync as
|
|
91305
|
+
import { readFileSync as readFileSync122, realpathSync as realpathSync36 } from "fs";
|
|
91229
91306
|
import { createPublicKey as createPublicKey7 } from "crypto";
|
|
91230
|
-
import { join as
|
|
91307
|
+
import { join as join139, sep as sep22 } from "path";
|
|
91231
91308
|
init_verify_cmd();
|
|
91232
91309
|
init_seal();
|
|
91233
91310
|
init_receipt_dsse();
|
|
@@ -91254,11 +91331,11 @@ function mount21(ctx) {
|
|
|
91254
91331
|
return done(404, "receipt not available", "not_found");
|
|
91255
91332
|
let runDir, file;
|
|
91256
91333
|
try {
|
|
91257
|
-
const root = realpathSync36(
|
|
91258
|
-
runDir = realpathSync36(
|
|
91259
|
-
if (runDir !==
|
|
91334
|
+
const root = realpathSync36(join139(repo.p, ".loki", "runs"));
|
|
91335
|
+
runDir = realpathSync36(join139(root, run2));
|
|
91336
|
+
if (runDir !== join139(root, run2))
|
|
91260
91337
|
return done(404, "receipt not found", "not_found");
|
|
91261
|
-
file = realpathSync36(
|
|
91338
|
+
file = realpathSync36(join139(runDir, "receipt.json"));
|
|
91262
91339
|
} catch {
|
|
91263
91340
|
return done(404, "receipt not found", "not_found");
|
|
91264
91341
|
}
|
|
@@ -91277,7 +91354,7 @@ function mount21(ctx) {
|
|
|
91277
91354
|
sha7 = r.receiptSha256 ?? null;
|
|
91278
91355
|
}
|
|
91279
91356
|
try {
|
|
91280
|
-
outcome = outcomeOf2(JSON.parse(
|
|
91357
|
+
outcome = outcomeOf2(JSON.parse(readFileSync122(file, "utf8")));
|
|
91281
91358
|
} catch {
|
|
91282
91359
|
outcome = "UNREADABLE";
|
|
91283
91360
|
}
|
|
@@ -91339,8 +91416,8 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
|
|
|
91339
91416
|
}
|
|
91340
91417
|
|
|
91341
91418
|
// src/server/legacy/shim.ts
|
|
91342
|
-
import { existsSync as existsSync97, readFileSync as
|
|
91343
|
-
import { join as
|
|
91419
|
+
import { existsSync as existsSync97, readFileSync as readFileSync123 } from "fs";
|
|
91420
|
+
import { join as join140 } from "path";
|
|
91344
91421
|
|
|
91345
91422
|
// src/server/legacy/routes.ts
|
|
91346
91423
|
var LEGACY_ROUTES = [
|
|
@@ -91718,10 +91795,10 @@ var logged = new Set;
|
|
|
91718
91795
|
var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
|
|
91719
91796
|
var NOT_SUPPORTED = "not yet supported by the Control Plane";
|
|
91720
91797
|
var repoVersion = () => {
|
|
91721
|
-
for (const f of [
|
|
91798
|
+
for (const f of [join140(import.meta.dir, "../../../../../VERSION")]) {
|
|
91722
91799
|
try {
|
|
91723
91800
|
if (existsSync97(f))
|
|
91724
|
-
return
|
|
91801
|
+
return readFileSync123(f, "utf8").trim();
|
|
91725
91802
|
} catch {}
|
|
91726
91803
|
}
|
|
91727
91804
|
return "unknown";
|
|
@@ -91903,7 +91980,7 @@ function legacyShim(opts) {
|
|
|
91903
91980
|
|
|
91904
91981
|
// src/server/app.ts
|
|
91905
91982
|
var MAX_BODY2 = 1e6;
|
|
91906
|
-
var defaultUiDir = () => [
|
|
91983
|
+
var defaultUiDir = () => [join141(import.meta.dir, "../../ui/dist"), join141(import.meta.dir, "../ui/dist")].find((d) => existsSync98(join141(d, "index.html")));
|
|
91907
91984
|
function createApp(opts) {
|
|
91908
91985
|
const uiDir = opts.uiDir ?? defaultUiDir();
|
|
91909
91986
|
const { db: db2, sqlite } = openDb(opts.dbPath);
|
|
@@ -91932,10 +92009,10 @@ function createApp(opts) {
|
|
|
91932
92009
|
await next();
|
|
91933
92010
|
});
|
|
91934
92011
|
const readInstalled = () => {
|
|
91935
|
-
for (const f of [process.env.LOKI_VERSION_FILE,
|
|
92012
|
+
for (const f of [process.env.LOKI_VERSION_FILE, join141(import.meta.dir, "../../../../VERSION")]) {
|
|
91936
92013
|
try {
|
|
91937
92014
|
if (f)
|
|
91938
|
-
return
|
|
92015
|
+
return readFileSync124(f, "utf8").trim() || "unknown";
|
|
91939
92016
|
} catch {}
|
|
91940
92017
|
}
|
|
91941
92018
|
return "unknown";
|
|
@@ -92050,7 +92127,7 @@ function createApp(opts) {
|
|
|
92050
92127
|
return new Response(Bun.file(f));
|
|
92051
92128
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
92052
92129
|
return c.json({ error: "not found" }, 404);
|
|
92053
|
-
return new Response(Bun.file(
|
|
92130
|
+
return new Response(Bun.file(join141(root, "index.html")));
|
|
92054
92131
|
});
|
|
92055
92132
|
return { app, db: db2, close: () => {
|
|
92056
92133
|
clearInterval(reconciler);
|