loki-mode 11.17.11 → 11.17.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/cost-summary.py +5 -2
- package/autonomy/lib/efficiency_cost.py +13 -0
- package/autonomy/lib/proof-generator.py +5 -0
- package/autonomy/lib/proof-template.html +21 -6
- package/autonomy/lib/trust_trajectory.py +11 -1
- package/autonomy/loki +42 -28
- package/completions/_loki +1 -0
- package/completions/loki.bash +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +79 -11
- package/docs/v10/FAILURE-CLASSES.md +63 -0
- package/docs/v10/PROGRESS.md +2 -0
- package/loki-ts/dist/loki.js +951 -947
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +237 -230
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-CFqo-FpE.js → AdminPage-CwtSZac4.js} +1 -1
- package/web-app/dist/assets/{Avatar-CxDqlcAZ.js → Avatar-BfguNHDC.js} +1 -1
- package/web-app/dist/assets/{Badge-CjZcSHSd.js → Badge-DQGEOIqb.js} +1 -1
- package/web-app/dist/assets/{Button-BsTd60w2.js → Button-CRb-wJga.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BivdM9_z.js → CockpitPage-DnA9wewN.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DEsuYGnF.js → ComparePage-DX6F_G0l.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-Q2L0QzKv.js → ErrorBoundary-VVIdgfkb.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-Da0-q_vi.js → EvidenceReceiptPanel-FxknNXxU.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-MSIQvU9a.js → GitHubIssuesPanel-DqiraoJP.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-Dw-t46_A.js → GitHubPRsPanel-BYkTsRfQ.js} +1 -1
- package/web-app/dist/assets/{HomePage-k_r93vg_.js → HomePage-BjpWZdl4.js} +2 -2
- package/web-app/dist/assets/{LoginPage-C-TlmbEy.js → LoginPage-DdBnFY4Y.js} +1 -1
- package/web-app/dist/assets/{MagicPage-Dv_lGAX0.js → MagicPage-ihQmO1wm.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-BINwnc6C.js → MetricsPage-Dq5YARm1.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-DGbdLAhm.js → NotFoundPage-CLzwsmxk.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-D4GhODo7.js → ProjectPage-Dm8X4ntm.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C9iCGUvI.js → ProjectsPage-DI3PhBwa.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-08SiNkKI.js → SettingsPage-D3bL3Ll-.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-5cq8wXvh.js → ShowcasePage-ypNyQAKe.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-ch0Ex4iS.js → SystemSettingsPage-a9KPi49-.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-eE9Bevpx.js → TeamsPage-B2KmQjeS.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-BLqK2AOM.js → TemplatesPage-BnK5NB62.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-Bw6lAjMM.js → TerminalOutput-CYbPu51X.js} +1 -1
- package/web-app/dist/assets/{activity-mqeYLy0X.js → activity-DBIfCcER.js} +1 -1
- package/web-app/dist/assets/{bell-RrSQYwnk.js → bell-B9HN4QkY.js} +1 -1
- package/web-app/dist/assets/{bot-BAYArzbY.js → bot-DamtEiBN.js} +1 -1
- package/web-app/dist/assets/{check-DpZMgeCp.js → check-DXifl-uv.js} +1 -1
- package/web-app/dist/assets/{chevron-left-HdiZ5i2v.js → chevron-left-BrlJBb8m.js} +1 -1
- package/web-app/dist/assets/{circle-alert-CIGI9S7n.js → circle-alert-CVKCTAb9.js} +1 -1
- package/web-app/dist/assets/{clock-DyGC5H7u.js → clock-HQ6E5gSp.js} +1 -1
- package/web-app/dist/assets/{cloud-CCV2xWgX.js → cloud-B15Ysqug.js} +1 -1
- package/web-app/dist/assets/{code-xml-DZgWjvzk.js → code-xml-hqFIp0_h.js} +1 -1
- package/web-app/dist/assets/{database-kzfwKPqD.js → database-CcSm0M_K.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-jepNmrzR.js → dollar-sign-acxpddMc.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BaJhHJXN.js → file-code-corner-B5IIv12W.js} +1 -1
- package/web-app/dist/assets/{file-plus-rONhSBM8.js → file-plus-CkbMFWJb.js} +1 -1
- package/web-app/dist/assets/{globe-DEKjsEXs.js → globe-CWmZ3xTF.js} +1 -1
- package/web-app/dist/assets/{hammer-LFrBT_V4.js → hammer-BSaCsCAo.js} +1 -1
- package/web-app/dist/assets/{index-DTi6txFh.js → index-BCf0fCNu.js} +3 -3
- package/web-app/dist/assets/{layers-D0AF3hqY.js → layers-CL82nJ3b.js} +1 -1
- package/web-app/dist/assets/{loader-circle-5MojTTeG.js → loader-circle-DBhm8R7M.js} +1 -1
- package/web-app/dist/assets/{lock-DKTO02bm.js → lock-wWcqImfq.js} +1 -1
- package/web-app/dist/assets/{package-0-plMCjY.js → package-BaZa22IO.js} +1 -1
- package/web-app/dist/assets/{plus-CjhYDJ6n.js → plus-TFOQPEeK.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CLC6VIEp.js → refresh-cw-BOKfYIta.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-DInfsBjr.js → rotate-ccw-DrH5oGwW.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DHh5UjH-.js → scroll-text-aY8_wIJd.js} +1 -1
- package/web-app/dist/assets/{server-D0j8HyOw.js → server-C6FQ01rB.js} +1 -1
- package/web-app/dist/assets/{shield-alert-D8wHooc9.js → shield-alert-DurYyWUo.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-Cda_qfHU.js → thumbs-up-wUuSs67Q.js} +1 -1
- package/web-app/dist/assets/{trash-2-eyrU5HYs.js → trash-2-DAob0LKZ.js} +1 -1
- package/web-app/dist/assets/{trending-down-Br_sStsY.js → trending-down-yKL9mp2O.js} +1 -1
- package/web-app/dist/assets/{trending-up-DGmTcXWO.js → trending-up-BD55eCE3.js} +1 -1
- package/web-app/dist/assets/{upload-CvCVXqWR.js → upload-0IJxnT31.js} +1 -1
- package/web-app/dist/assets/{usePolling-DT-cLGOG.js → usePolling-DuBiboP5.js} +1 -1
- package/web-app/dist/assets/{user-tzdYvO9g.js → user-BDw_rGaY.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -7635,10 +7635,43 @@ var init_receipt_signer = () => {};
|
|
|
7635
7635
|
// ../../loki-ts/src/engine10/registry.ts
|
|
7636
7636
|
var init_registry = () => {};
|
|
7637
7637
|
|
|
7638
|
+
// ../../loki-ts/src/engine10/types.ts
|
|
7639
|
+
function pushArgv(a) {
|
|
7640
|
+
switch (a.cmd) {
|
|
7641
|
+
case "push-pr":
|
|
7642
|
+
return ["push-pr", a.repoDir, a.branch, a.title, a.bodyFile, a.draft ? "1" : "0"];
|
|
7643
|
+
case "comment":
|
|
7644
|
+
return ["comment", a.runId, a.prUrl, a.file];
|
|
7645
|
+
case "status":
|
|
7646
|
+
return ["status", a.sha, a.state, a.description];
|
|
7647
|
+
case "issue-comment":
|
|
7648
|
+
return a.update ? ["issue-comment", "--update", a.issueRef, a.bodyFile] : ["issue-comment", a.issueRef, a.bodyFile];
|
|
7649
|
+
}
|
|
7650
|
+
}
|
|
7651
|
+
function taskBlock(task) {
|
|
7652
|
+
return ["Task (untrusted, quoted verbatim):", "<<<TASK", task, "TASK"];
|
|
7653
|
+
}
|
|
7654
|
+
var STAGE_BUDGETS;
|
|
7655
|
+
var init_types = __esm(() => {
|
|
7656
|
+
STAGE_BUDGETS = {
|
|
7657
|
+
intake: { targetS: 15, limitS: 60 },
|
|
7658
|
+
plan: { targetS: 45, limitS: 90 },
|
|
7659
|
+
wall: { targetS: 45, limitS: 90 },
|
|
7660
|
+
implement: { targetS: 180, limitS: 480 },
|
|
7661
|
+
verify: { targetS: 60, limitS: 120 },
|
|
7662
|
+
fix: { targetS: 90, limitS: 180 },
|
|
7663
|
+
commit: { targetS: 5, limitS: 30 },
|
|
7664
|
+
seal: { targetS: 15, limitS: 60 },
|
|
7665
|
+
pr: { targetS: 15, limitS: 60 },
|
|
7666
|
+
deep: { targetS: null, limitS: 2700 }
|
|
7667
|
+
};
|
|
7668
|
+
});
|
|
7669
|
+
|
|
7638
7670
|
// ../../loki-ts/src/engine10/output.ts
|
|
7639
7671
|
var init_output = __esm(() => {
|
|
7640
7672
|
init_registry();
|
|
7641
7673
|
init_redact();
|
|
7674
|
+
init_types();
|
|
7642
7675
|
});
|
|
7643
7676
|
|
|
7644
7677
|
// ../../loki-ts/src/util/atomic.ts
|
|
@@ -8123,38 +8156,6 @@ var init_budget = __esm(() => {
|
|
|
8123
8156
|
PRICING = Object.freeze(_loadPricing());
|
|
8124
8157
|
});
|
|
8125
8158
|
|
|
8126
|
-
// ../../loki-ts/src/engine10/types.ts
|
|
8127
|
-
function pushArgv(a) {
|
|
8128
|
-
switch (a.cmd) {
|
|
8129
|
-
case "push-pr":
|
|
8130
|
-
return ["push-pr", a.repoDir, a.branch, a.title, a.bodyFile, a.draft ? "1" : "0"];
|
|
8131
|
-
case "comment":
|
|
8132
|
-
return ["comment", a.runId, a.prUrl, a.file];
|
|
8133
|
-
case "status":
|
|
8134
|
-
return ["status", a.sha, a.state, a.description];
|
|
8135
|
-
case "issue-comment":
|
|
8136
|
-
return a.update ? ["issue-comment", "--update", a.issueRef, a.bodyFile] : ["issue-comment", a.issueRef, a.bodyFile];
|
|
8137
|
-
}
|
|
8138
|
-
}
|
|
8139
|
-
function taskBlock(task) {
|
|
8140
|
-
return ["Task (untrusted, quoted verbatim):", "<<<TASK", task, "TASK"];
|
|
8141
|
-
}
|
|
8142
|
-
var STAGE_BUDGETS;
|
|
8143
|
-
var init_types = __esm(() => {
|
|
8144
|
-
STAGE_BUDGETS = {
|
|
8145
|
-
intake: { targetS: 15, limitS: 60 },
|
|
8146
|
-
plan: { targetS: 45, limitS: 90 },
|
|
8147
|
-
wall: { targetS: 45, limitS: 90 },
|
|
8148
|
-
implement: { targetS: 180, limitS: 480 },
|
|
8149
|
-
verify: { targetS: 60, limitS: 120 },
|
|
8150
|
-
fix: { targetS: 90, limitS: 180 },
|
|
8151
|
-
commit: { targetS: 5, limitS: 30 },
|
|
8152
|
-
seal: { targetS: 15, limitS: 60 },
|
|
8153
|
-
pr: { targetS: 15, limitS: 60 },
|
|
8154
|
-
deep: { targetS: null, limitS: 2700 }
|
|
8155
|
-
};
|
|
8156
|
-
});
|
|
8157
|
-
|
|
8158
8159
|
// ../../loki-ts/src/runner/router/decision.ts
|
|
8159
8160
|
var init_decision = () => {};
|
|
8160
8161
|
|
|
@@ -8864,16 +8865,25 @@ var init_scope = __esm(() => {
|
|
|
8864
8865
|
dropped = new WeakMap;
|
|
8865
8866
|
});
|
|
8866
8867
|
|
|
8867
|
-
// ../../loki-ts/src/
|
|
8868
|
-
import { basename as basename9
|
|
8868
|
+
// ../../loki-ts/src/util/test_file_text.ts
|
|
8869
|
+
import { basename as basename9 } from "path";
|
|
8869
8870
|
function isTestFile(rel) {
|
|
8870
8871
|
const name = basename9(rel);
|
|
8871
8872
|
return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
|
|
8872
8873
|
}
|
|
8873
|
-
var
|
|
8874
|
+
var JS_TEST_RE, PY_TEST_RE, GO_TEST_RE;
|
|
8875
|
+
var init_test_file_text = __esm(() => {
|
|
8876
|
+
JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
|
|
8877
|
+
PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
|
|
8878
|
+
GO_TEST_RE = /_test\.go$/;
|
|
8879
|
+
});
|
|
8880
|
+
|
|
8881
|
+
// ../../loki-ts/src/engine10/testmap.ts
|
|
8882
|
+
var SKIP_DIRS;
|
|
8874
8883
|
var init_testmap = __esm(() => {
|
|
8875
8884
|
init_resolve();
|
|
8876
8885
|
init_scope();
|
|
8886
|
+
init_test_file_text();
|
|
8877
8887
|
SKIP_DIRS = new Set([
|
|
8878
8888
|
".git",
|
|
8879
8889
|
"node_modules",
|
|
@@ -8889,14 +8899,11 @@ var init_testmap = __esm(() => {
|
|
|
8889
8899
|
".loki",
|
|
8890
8900
|
".next"
|
|
8891
8901
|
]);
|
|
8892
|
-
JS_TEST_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
|
|
8893
|
-
PY_TEST_RE = /^(test_.+|.+_test)\.py$/;
|
|
8894
|
-
GO_TEST_RE = /_test\.go$/;
|
|
8895
8902
|
});
|
|
8896
8903
|
|
|
8897
8904
|
// ../../loki-ts/src/util/check_result.ts
|
|
8898
8905
|
import { mkdirSync as mkdirSync13, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
8899
|
-
import { basename as basename10, join as
|
|
8906
|
+
import { basename as basename10, join as join37 } from "path";
|
|
8900
8907
|
function plainTestEnv(base = process.env) {
|
|
8901
8908
|
const e = {};
|
|
8902
8909
|
for (const [k, v] of Object.entries(tokenFreeEnv(base)))
|
|
@@ -9191,7 +9198,7 @@ function diffFiles(repoDir, baseSha) {
|
|
|
9191
9198
|
return f;
|
|
9192
9199
|
let n2 = 0;
|
|
9193
9200
|
try {
|
|
9194
|
-
n2 = readFileSync28(
|
|
9201
|
+
n2 = readFileSync28(join37(repoDir, path), "utf8").split(`
|
|
9195
9202
|
`).length;
|
|
9196
9203
|
} catch {}
|
|
9197
9204
|
return { path, added: n2, deleted: 0, status: "added" };
|
|
@@ -9199,7 +9206,7 @@ function diffFiles(repoDir, baseSha) {
|
|
|
9199
9206
|
}
|
|
9200
9207
|
function recordRisk(repoDir, a) {
|
|
9201
9208
|
try {
|
|
9202
|
-
const dir =
|
|
9209
|
+
const dir = join37(repoDir, ".loki", "state"), p = join37(dir, "risk-tier.json");
|
|
9203
9210
|
mkdirSync13(dir, { recursive: true });
|
|
9204
9211
|
writeFileSync16(`${p}.tmp`, JSON.stringify(a, null, 2) + `
|
|
9205
9212
|
`);
|
|
@@ -9259,7 +9266,7 @@ var init_state = __esm(() => {
|
|
|
9259
9266
|
|
|
9260
9267
|
// ../../loki-ts/src/runner/repo_profile.ts
|
|
9261
9268
|
import { existsSync as existsSync22, readFileSync as readFileSync29, mkdirSync as mkdirSync14, readdirSync as readdirSync13, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
|
|
9262
|
-
import { basename as basename11, join as
|
|
9269
|
+
import { basename as basename11, join as join38, resolve as resolve13, isAbsolute as isAbsolute2 } from "path";
|
|
9263
9270
|
function loadProfile(repoDir) {
|
|
9264
9271
|
try {
|
|
9265
9272
|
const p = JSON.parse(readFileSync29(commandProfilePath(repoDir), "utf8"));
|
|
@@ -9293,7 +9300,7 @@ function attributeFullSuite(repoDir, baseSha, full, blocked, changed) {
|
|
|
9293
9300
|
const block = new Set(blocked);
|
|
9294
9301
|
return attribute(repoDir, baseSha, bad.map((c) => ({ name: c.name, ...c.ids ? { ids: c.ids } : {}, eligible: (c.ids ?? []).every((i) => !block.has(i) && !changed.some((f) => i.includes(f))) })));
|
|
9295
9302
|
}
|
|
9296
|
-
var commandProfilePath = (repoDir) =>
|
|
9303
|
+
var commandProfilePath = (repoDir) => join38(repoDir, ".loki", "state", "repo-profile.json");
|
|
9297
9304
|
var init_repo_profile = __esm(() => {
|
|
9298
9305
|
init_failures();
|
|
9299
9306
|
init_check_result();
|
|
@@ -9329,12 +9336,12 @@ var init_context = __esm(() => {
|
|
|
9329
9336
|
// ../../loki-ts/src/util/steer.ts
|
|
9330
9337
|
import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync14, lstatSync as lstatSync9, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync30, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync23 } from "fs";
|
|
9331
9338
|
import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
|
|
9332
|
-
import { basename as basename12, join as
|
|
9339
|
+
import { basename as basename12, join as join39 } from "path";
|
|
9333
9340
|
function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
9334
9341
|
for (let i = 0;; i++) {
|
|
9335
9342
|
const name = i === 0 ? `${prefix}.md` : `${prefix}-${i}.md`;
|
|
9336
9343
|
try {
|
|
9337
|
-
link(src,
|
|
9344
|
+
link(src, join39(logs, name));
|
|
9338
9345
|
} catch (e) {
|
|
9339
9346
|
const code = e.code;
|
|
9340
9347
|
if (code === "EEXIST")
|
|
@@ -9342,7 +9349,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
|
|
|
9342
9349
|
if (code !== "EPERM" && code !== "ENOTSUP" && code !== "EXDEV" && code !== "EMLINK")
|
|
9343
9350
|
throw e;
|
|
9344
9351
|
const name2 = `${prefix}-${randomBytes4(4).toString("hex")}.md`;
|
|
9345
|
-
renameSync10(src,
|
|
9352
|
+
renameSync10(src, join39(logs, name2));
|
|
9346
9353
|
onLinked?.(name2);
|
|
9347
9354
|
return name2;
|
|
9348
9355
|
}
|
|
@@ -9361,7 +9368,7 @@ function orphanAlreadyArchived(logs, claim) {
|
|
|
9361
9368
|
if (!/^human-input-.*\.md$/.test(a))
|
|
9362
9369
|
continue;
|
|
9363
9370
|
try {
|
|
9364
|
-
const s = statSync15(
|
|
9371
|
+
const s = statSync15(join39(logs, a));
|
|
9365
9372
|
if (s.ino !== c.ino || s.dev !== c.dev)
|
|
9366
9373
|
continue;
|
|
9367
9374
|
if (/^human-input-(ORPHAN|REJECTED)-/.test(a) || existsSync23(appliedMarker(logs, a)))
|
|
@@ -9381,7 +9388,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
|
|
|
9381
9388
|
for (const n2 of names)
|
|
9382
9389
|
if (n2.startsWith(".applied-") && !present.has(n2.slice(".applied-".length))) {
|
|
9383
9390
|
try {
|
|
9384
|
-
unlinkSync5(
|
|
9391
|
+
unlinkSync5(join39(logs, n2));
|
|
9385
9392
|
} catch {}
|
|
9386
9393
|
}
|
|
9387
9394
|
for (const n2 of names) {
|
|
@@ -9398,7 +9405,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
|
|
|
9398
9405
|
if (alive) {
|
|
9399
9406
|
let ageMs = 0;
|
|
9400
9407
|
try {
|
|
9401
|
-
ageMs = nowMs - statSync15(
|
|
9408
|
+
ageMs = nowMs - statSync15(join39(logs, n2)).mtimeMs;
|
|
9402
9409
|
} catch {
|
|
9403
9410
|
continue;
|
|
9404
9411
|
}
|
|
@@ -9406,11 +9413,11 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
|
|
|
9406
9413
|
continue;
|
|
9407
9414
|
}
|
|
9408
9415
|
try {
|
|
9409
|
-
if (orphanAlreadyArchived(logs,
|
|
9410
|
-
unlinkSync5(
|
|
9416
|
+
if (orphanAlreadyArchived(logs, join39(logs, n2))) {
|
|
9417
|
+
unlinkSync5(join39(logs, n2));
|
|
9411
9418
|
continue;
|
|
9412
9419
|
}
|
|
9413
|
-
archiveTo(logs, `human-input-ORPHAN-${stamp2}`,
|
|
9420
|
+
archiveTo(logs, `human-input-ORPHAN-${stamp2}`, join39(logs, n2), link);
|
|
9414
9421
|
unapplied("orphaned claim");
|
|
9415
9422
|
} catch (e) {
|
|
9416
9423
|
if (e.code === "ENOENT")
|
|
@@ -9422,17 +9429,17 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
|
|
|
9422
9429
|
function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, hooks2) {
|
|
9423
9430
|
if (/^(0|false)$/i.test(env.LOKI_PROMPT_INJECTION ?? ""))
|
|
9424
9431
|
return null;
|
|
9425
|
-
const f =
|
|
9432
|
+
const f = join39(repoDir, ".loki", "HUMAN_INPUT.md");
|
|
9426
9433
|
const unapplied = (reason) => {
|
|
9427
9434
|
sink?.push({ rev: 0, source: null, actor: null, sha: "", at: now2().getTime(), unapplied: true, reason });
|
|
9428
9435
|
};
|
|
9429
9436
|
let fd = -1, claimed = "";
|
|
9430
9437
|
try {
|
|
9431
|
-
const logs =
|
|
9438
|
+
const logs = join39(repoDir, ".loki", "logs");
|
|
9432
9439
|
mkdirSync15(logs, { recursive: true });
|
|
9433
9440
|
const stamp2 = now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "");
|
|
9434
9441
|
sweepOrphans(logs, stamp2, unapplied, hooks2?.link, now2().getTime());
|
|
9435
|
-
claimed =
|
|
9442
|
+
claimed = join39(logs, `.claim-${process.pid}-${randomBytes4(6).toString("hex")}`);
|
|
9436
9443
|
try {
|
|
9437
9444
|
renameSync10(f, claimed);
|
|
9438
9445
|
} catch (e) {
|
|
@@ -9523,7 +9530,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
9523
9530
|
} catch {
|
|
9524
9531
|
if (claimed) {
|
|
9525
9532
|
try {
|
|
9526
|
-
archiveTo(
|
|
9533
|
+
archiveTo(join39(repoDir, ".loki", "logs"), `human-input-${now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "")}`, claimed, hooks2?.link);
|
|
9527
9534
|
unapplied("logs dir unwritable or file unreadable");
|
|
9528
9535
|
} catch {
|
|
9529
9536
|
unapplied(`steer stranded at .loki/logs/${basename12(claimed)}`);
|
|
@@ -9542,7 +9549,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
|
|
|
9542
9549
|
}
|
|
9543
9550
|
}
|
|
9544
9551
|
function recordRevisions(repoDir, text2, archived, at) {
|
|
9545
|
-
const file =
|
|
9552
|
+
const file = join39(repoDir, ".loki", "intent-revisions.jsonl");
|
|
9546
9553
|
let last = 0;
|
|
9547
9554
|
try {
|
|
9548
9555
|
for (const l of readFileSync30(file, "utf8").split(`
|
|
@@ -9599,7 +9606,7 @@ function staleAtSeal(repoDir, ctx) {
|
|
|
9599
9606
|
const frozen = ctx.outputs === undefined || ctx.outputs().wall !== undefined || ctx.wallSealed === true;
|
|
9600
9607
|
return [...new Set([...staleWallRevisions(ctx.intentRevisions, frozen ? ctx.timeline : []), ...late])];
|
|
9601
9608
|
}
|
|
9602
|
-
var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) =>
|
|
9609
|
+
var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) => join39(logs, `.applied-${archive}`), REV_HDR, STEER_REMEDY;
|
|
9603
9610
|
var init_steer = __esm(() => {
|
|
9604
9611
|
init_context();
|
|
9605
9612
|
STEER_MAX_BYTES = 1024 * 1024;
|
|
@@ -9662,18 +9669,18 @@ var init_seal_drift = __esm(() => {
|
|
|
9662
9669
|
});
|
|
9663
9670
|
|
|
9664
9671
|
// ../../loki-ts/src/util/spec_file.ts
|
|
9665
|
-
import { isAbsolute as isAbsolute3, join as
|
|
9672
|
+
import { isAbsolute as isAbsolute3, join as join40, relative } from "path";
|
|
9666
9673
|
function specReceiptBlock(env) {
|
|
9667
9674
|
const { LOKI_E10_SPEC_PATH: p, LOKI_E10_SPEC_SHA256: sha2 } = env;
|
|
9668
9675
|
if (!p || !sha2)
|
|
9669
9676
|
return {};
|
|
9670
|
-
const rel = isAbsolute3(p) && env.LOKI_E10_REPO_DIR ?
|
|
9677
|
+
const rel = isAbsolute3(p) && env.LOKI_E10_REPO_DIR ? relative(env.LOKI_E10_REPO_DIR, p) : p;
|
|
9671
9678
|
return { spec: { path: rel, sha256: sha2 } };
|
|
9672
9679
|
}
|
|
9673
9680
|
var SPEC_DIR;
|
|
9674
9681
|
var init_spec_file = __esm(() => {
|
|
9675
9682
|
init_types();
|
|
9676
|
-
SPEC_DIR =
|
|
9683
|
+
SPEC_DIR = join40(".loki", "specs");
|
|
9677
9684
|
});
|
|
9678
9685
|
|
|
9679
9686
|
// ../../loki-ts/src/engine10/pr_body.ts
|
|
@@ -9695,9 +9702,9 @@ var init_run_cap = __esm(() => {
|
|
|
9695
9702
|
// ../../loki-ts/src/util/mutation_proof.ts
|
|
9696
9703
|
import { existsSync as existsSync24, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync31, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
|
|
9697
9704
|
import { tmpdir as tmpdir4 } from "os";
|
|
9698
|
-
import { basename as basename13, dirname as dirname13, isAbsolute as isAbsolute4, join as
|
|
9705
|
+
import { basename as basename13, dirname as dirname13, isAbsolute as isAbsolute4, join as join41, relative as relative2 } from "path";
|
|
9699
9706
|
function mutationProof(i) {
|
|
9700
|
-
const rels = i.wallFiles.map((f) => isAbsolute4(f.path) ?
|
|
9707
|
+
const rels = i.wallFiles.map((f) => isAbsolute4(f.path) ? relative2(i.repoDir, f.path) : f.path);
|
|
9701
9708
|
if (rels.length === 0)
|
|
9702
9709
|
return np("no Wall tests");
|
|
9703
9710
|
const tests = rels.flatMap((rel) => {
|
|
@@ -9713,25 +9720,25 @@ function mutationProof(i) {
|
|
|
9713
9720
|
const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
|
|
9714
9721
|
let parent = null, wt = null, added = false;
|
|
9715
9722
|
try {
|
|
9716
|
-
parent = mkdtempSync3(
|
|
9717
|
-
wt =
|
|
9723
|
+
parent = mkdtempSync3(join41(tmpdir4(), "loki-mutproof-"));
|
|
9724
|
+
wt = join41(parent, "wt");
|
|
9718
9725
|
const add3 = git(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
|
|
9719
9726
|
added = existsSync24(wt) || add3.status === 0;
|
|
9720
9727
|
if (add3.status !== 0)
|
|
9721
9728
|
return np("could not create the base worktree");
|
|
9722
9729
|
for (const rel of rels) {
|
|
9723
|
-
const sealed =
|
|
9730
|
+
const sealed = join41(i.runDir, "wall", basename13(rel)), src = existsSync24(sealed) ? sealed : join41(i.repoDir, rel);
|
|
9724
9731
|
if (!existsSync24(src))
|
|
9725
9732
|
return np(`Wall file missing: ${rel}`);
|
|
9726
|
-
mkdirSync16(dirname13(
|
|
9727
|
-
writeFileSync19(
|
|
9733
|
+
mkdirSync16(dirname13(join41(wt, rel)), { recursive: true });
|
|
9734
|
+
writeFileSync19(join41(wt, rel), readFileSync31(src));
|
|
9728
9735
|
}
|
|
9729
9736
|
for (const rel of rels) {
|
|
9730
9737
|
const parts = rel.split("/").slice(0, -1);
|
|
9731
9738
|
for (let n2 = 0;n2 <= parts.length; n2++) {
|
|
9732
9739
|
const anc = parts.slice(0, n2).join("/");
|
|
9733
9740
|
for (const d of DEP_DIRS) {
|
|
9734
|
-
const src =
|
|
9741
|
+
const src = join41(i.repoDir, anc, d), dst = join41(wt, anc, d);
|
|
9735
9742
|
if (existsSync24(src) && !existsSync24(dst)) {
|
|
9736
9743
|
try {
|
|
9737
9744
|
symlinkSync(src, dst);
|
|
@@ -11028,7 +11035,7 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
|
|
|
11028
11035
|
import { createHash as createHash12 } from "crypto";
|
|
11029
11036
|
import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync26, mkdirSync as mkdirSync17, readFileSync as readFileSync33, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
|
|
11030
11037
|
import { tmpdir as tmpdir6 } from "os";
|
|
11031
|
-
import { basename as basename15, join as
|
|
11038
|
+
import { basename as basename15, join as join42, relative as relative3 } from "path";
|
|
11032
11039
|
function wallHoldoutRatio(env = process.env) {
|
|
11033
11040
|
if (env["LOKI_WALL_HOLDOUT"]?.trim() === "0")
|
|
11034
11041
|
return 0;
|
|
@@ -11056,32 +11063,32 @@ function stashHoldout(o) {
|
|
|
11056
11063
|
rmSync12(dir, { recursive: true, force: true });
|
|
11057
11064
|
mkdirSync17(dir, { recursive: true, mode: 448 });
|
|
11058
11065
|
const files = held.map((name) => {
|
|
11059
|
-
copyFileSync2(
|
|
11060
|
-
rmSync12(
|
|
11061
|
-
return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync33(
|
|
11066
|
+
copyFileSync2(join42(o.srcDir, name), join42(dir, name));
|
|
11067
|
+
rmSync12(join42(o.srcDir, name), { force: true });
|
|
11068
|
+
return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync33(join42(dir, name), "utf8")) };
|
|
11062
11069
|
});
|
|
11063
|
-
writeFileSync20(
|
|
11070
|
+
writeFileSync20(join42(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
|
|
11064
11071
|
return { dir, names: new Set(held) };
|
|
11065
11072
|
}
|
|
11066
11073
|
function stageHoldout(dir, repoDir) {
|
|
11067
11074
|
const put = [], tests = [], missing = [];
|
|
11068
11075
|
let man = null;
|
|
11069
11076
|
try {
|
|
11070
|
-
man = JSON.parse(readFileSync33(
|
|
11077
|
+
man = JSON.parse(readFileSync33(join42(dir, MANIFEST), "utf8"));
|
|
11071
11078
|
} catch {}
|
|
11072
11079
|
if (!man)
|
|
11073
11080
|
return { tests, missing: [`holdout store unreadable: ${basename15(dir)}`], cleanup: () => {} };
|
|
11074
11081
|
mkdirSync17(man.targetDir, { recursive: true });
|
|
11075
11082
|
man.files.forEach((f, i) => {
|
|
11076
|
-
const src =
|
|
11083
|
+
const src = join42(dir, f.name);
|
|
11077
11084
|
if (!existsSync26(src) || sha2(readFileSync33(src, "utf8")) !== f.sha256) {
|
|
11078
11085
|
missing.push(`holdout ${i + 1} missing or altered`);
|
|
11079
11086
|
return;
|
|
11080
11087
|
}
|
|
11081
|
-
const dest =
|
|
11088
|
+
const dest = join42(man.targetDir, `loki_wall_holdout_${i + 1}${f.name.slice(f.name.indexOf("."))}`);
|
|
11082
11089
|
copyFileSync2(src, dest);
|
|
11083
11090
|
put.push(dest);
|
|
11084
|
-
tests.push({ runner: f.runner, path:
|
|
11091
|
+
tests.push({ runner: f.runner, path: relative3(repoDir, dest) });
|
|
11085
11092
|
});
|
|
11086
11093
|
return { tests, missing, cleanup: () => {
|
|
11087
11094
|
for (const p of put)
|
|
@@ -11091,16 +11098,16 @@ function stageHoldout(dir, repoDir) {
|
|
|
11091
11098
|
function recordHoldoutTriage(runDir, entry) {
|
|
11092
11099
|
try {
|
|
11093
11100
|
mkdirSync17(runDir, { recursive: true });
|
|
11094
|
-
appendFileSync3(
|
|
11101
|
+
appendFileSync3(join42(runDir, HOLDOUT_TRIAGE_FILE), JSON.stringify(entry) + `
|
|
11095
11102
|
`, { mode: 384 });
|
|
11096
11103
|
} catch {}
|
|
11097
11104
|
}
|
|
11098
|
-
var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) =>
|
|
11105
|
+
var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join42(tmpdir6(), `loki-e10-holdout-${sha2(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
|
|
11099
11106
|
var init_holdout = () => {};
|
|
11100
11107
|
|
|
11101
11108
|
// ../../loki-ts/src/features/runner_config.ts
|
|
11102
11109
|
import { readFileSync as readFileSync34 } from "fs";
|
|
11103
|
-
import { dirname as dirname15, join as
|
|
11110
|
+
import { dirname as dirname15, join as join43, normalize as normalize2 } from "path";
|
|
11104
11111
|
function tomlKey2(s, i = 0, eq2 = true) {
|
|
11105
11112
|
const parts = [], ws = () => {
|
|
11106
11113
|
while (/\s/.test(s[i] ?? "x"))
|
|
@@ -11377,8 +11384,8 @@ function referenced(cfg, text2) {
|
|
|
11377
11384
|
}
|
|
11378
11385
|
const dir = dirname15(cfg), explicit = ROOT_DIR.exec(text2), roots = [dir];
|
|
11379
11386
|
if (explicit)
|
|
11380
|
-
roots.push("", ...explicit[1] ? [
|
|
11381
|
-
return [...raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(
|
|
11387
|
+
roots.push("", ...explicit[1] ? [join43(dir, explicit[1])] : []);
|
|
11388
|
+
return [...raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(join43(root, r.replace(/^<rootDir>\/?/, ""))))), ...patchedTargets(cfg, text2).map((t) => normalize2(join43(dir, t)))];
|
|
11382
11389
|
}
|
|
11383
11390
|
function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
|
|
11384
11391
|
const notes = new Set, ch = new Set(changed.map((c) => normalize2(c)));
|
|
@@ -11458,7 +11465,7 @@ var PKG_KEYS, RAW_CONFIGS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, dep
|
|
|
11458
11465
|
}
|
|
11459
11466
|
}, headText = (dir, f) => {
|
|
11460
11467
|
try {
|
|
11461
|
-
return readFileSync34(
|
|
11468
|
+
return readFileSync34(join43(dir, f), "utf8");
|
|
11462
11469
|
} catch {
|
|
11463
11470
|
return "";
|
|
11464
11471
|
}
|
|
@@ -11500,7 +11507,7 @@ var init_runner_config = __esm(() => {
|
|
|
11500
11507
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
11501
11508
|
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync35, rmSync as rmSync13 } from "fs";
|
|
11502
11509
|
import { tmpdir as tmpdir7 } from "os";
|
|
11503
|
-
import { join as
|
|
11510
|
+
import { join as join44 } from "path";
|
|
11504
11511
|
import { basename as basename16 } from "path";
|
|
11505
11512
|
function classifyAssertDelta(inp) {
|
|
11506
11513
|
const f = basename16(inp.path);
|
|
@@ -11510,7 +11517,7 @@ function classifyAssertDelta(inp) {
|
|
|
11510
11517
|
return WEAKENED;
|
|
11511
11518
|
let cwd = "";
|
|
11512
11519
|
try {
|
|
11513
|
-
cwd = mkdtempSync5(
|
|
11520
|
+
cwd = mkdtempSync5(join44(tmpdir7(), "loki-ad-"));
|
|
11514
11521
|
const raw2 = execFileSync3("python3", ["-I", "-c", PY], {
|
|
11515
11522
|
input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
|
|
11516
11523
|
cwd,
|
|
@@ -11541,7 +11548,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
|
|
|
11541
11548
|
return null;
|
|
11542
11549
|
try {
|
|
11543
11550
|
const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
|
|
11544
|
-
const head = headRef ? show(headRef) : readFileSync35(
|
|
11551
|
+
const head = headRef ? show(headRef) : readFileSync35(join44(repoDir, path), "utf8");
|
|
11545
11552
|
const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
|
|
11546
11553
|
return r[0]?.kind === "literal-only" ? r.map((e) => `assertion value changed (not shown to be required by the task): ${e.file}:${e.line} ${e.old} -> ${e.new}`) : null;
|
|
11547
11554
|
} catch {
|
|
@@ -11750,17 +11757,17 @@ var init_runner_errors = __esm(() => {
|
|
|
11750
11757
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
11751
11758
|
import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync17, rmSync as rmSync14 } from "fs";
|
|
11752
11759
|
import { tmpdir as tmpdir8 } from "os";
|
|
11753
|
-
import { basename as basename17, extname
|
|
11760
|
+
import { basename as basename17, extname, join as join45 } from "path";
|
|
11754
11761
|
function changedFilesNamed(out2, repoDir, changed) {
|
|
11755
11762
|
return changed.filter((f) => {
|
|
11756
|
-
if (out2.includes(f) || out2.includes(
|
|
11763
|
+
if (out2.includes(f) || out2.includes(join45(repoDir, f)))
|
|
11757
11764
|
return true;
|
|
11758
11765
|
const segs = f.split("/");
|
|
11759
11766
|
if (suffixes(segs, 2).some((x) => x !== f && bounded(out2, x, "(?![\\w-])")))
|
|
11760
11767
|
return true;
|
|
11761
|
-
if (
|
|
11768
|
+
if (extname(f) === ".go" && segs.length > 1 && suffixes(segs.slice(0, -1), 1).some((d) => new RegExp(`(?<=[\\w-])/${esc(d)}(?![\\w./-])`).test(out2)))
|
|
11762
11769
|
return true;
|
|
11763
|
-
const stem = basename17(f,
|
|
11770
|
+
const stem = basename17(f, extname(f));
|
|
11764
11771
|
if (stem.length < 2 || stem === "index" || stem === "__init__")
|
|
11765
11772
|
return false;
|
|
11766
11773
|
return new RegExp(`(?<![\\w-])${esc(stem)}(?![\\w-])`).test(out2);
|
|
@@ -11864,7 +11871,7 @@ async function loadErrorIsHarnessOwned(i) {
|
|
|
11864
11871
|
return false;
|
|
11865
11872
|
if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
|
|
11866
11873
|
return false;
|
|
11867
|
-
const dir = mkdtempSync6(
|
|
11874
|
+
const dir = mkdtempSync6(join45(tmpdir8(), "e10-loadown-"));
|
|
11868
11875
|
const git3 = (args) => {
|
|
11869
11876
|
safeGit(i.repoDir, args, { stdio: "ignore" });
|
|
11870
11877
|
};
|
|
@@ -11896,7 +11903,7 @@ var init_load_owner = __esm(() => {
|
|
|
11896
11903
|
});
|
|
11897
11904
|
|
|
11898
11905
|
// ../../loki-ts/src/util/wall_owned.ts
|
|
11899
|
-
import { isAbsolute as isAbsolute5, join as
|
|
11906
|
+
import { isAbsolute as isAbsolute5, join as join46, relative as relative4 } from "path";
|
|
11900
11907
|
function failingLocations(raw2, cwd, repoDir) {
|
|
11901
11908
|
const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
|
|
11902
11909
|
`), files = new Set;
|
|
@@ -11928,7 +11935,7 @@ function failingLocations(raw2, cwd, repoDir) {
|
|
|
11928
11935
|
}
|
|
11929
11936
|
if (errors2 === 0 || located !== errors2)
|
|
11930
11937
|
return null;
|
|
11931
|
-
return [...files].map((f) =>
|
|
11938
|
+
return [...files].map((f) => relative4(repoDir, isAbsolute5(f) ? f : join46(cwd, f)));
|
|
11932
11939
|
}
|
|
11933
11940
|
function wallOwnedFailure(raw2, cwd, repoDir, wall) {
|
|
11934
11941
|
const locs = failingLocations(raw2, cwd, repoDir);
|
|
@@ -11949,7 +11956,7 @@ import {
|
|
|
11949
11956
|
writeFileSync as writeFileSync21,
|
|
11950
11957
|
mkdirSync as mkdirSync18
|
|
11951
11958
|
} from "fs";
|
|
11952
|
-
import { basename as basename18, dirname as dirname16, join as
|
|
11959
|
+
import { basename as basename18, dirname as dirname16, join as join47, resolve as resolve14 } from "path";
|
|
11953
11960
|
function readManifest(path) {
|
|
11954
11961
|
if (!existsSync27(path)) {
|
|
11955
11962
|
return null;
|
|
@@ -12008,7 +12015,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
12008
12015
|
for (const child of children) {
|
|
12009
12016
|
if (!matchPattern(name, child))
|
|
12010
12017
|
continue;
|
|
12011
|
-
const full =
|
|
12018
|
+
const full = join47(rootDir, child);
|
|
12012
12019
|
if (seen.has(full))
|
|
12013
12020
|
continue;
|
|
12014
12021
|
let st;
|
|
@@ -12025,7 +12032,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
12025
12032
|
}
|
|
12026
12033
|
if (declared.length === 0) {
|
|
12027
12034
|
for (const child of children) {
|
|
12028
|
-
const full =
|
|
12035
|
+
const full = join47(rootDir, child);
|
|
12029
12036
|
if (seen.has(full))
|
|
12030
12037
|
continue;
|
|
12031
12038
|
let st;
|
|
@@ -12036,7 +12043,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
12036
12043
|
}
|
|
12037
12044
|
if (!st.isDirectory())
|
|
12038
12045
|
continue;
|
|
12039
|
-
if (!existsSync27(
|
|
12046
|
+
if (!existsSync27(join47(full, ".loki", "app.json")))
|
|
12040
12047
|
continue;
|
|
12041
12048
|
seen.add(full);
|
|
12042
12049
|
out2.push(full);
|
|
@@ -12057,17 +12064,17 @@ function cacheKey(manifestPaths) {
|
|
|
12057
12064
|
}
|
|
12058
12065
|
function writeCache(targetDir, key, result) {
|
|
12059
12066
|
try {
|
|
12060
|
-
const cacheDir =
|
|
12067
|
+
const cacheDir = join47(targetDir, ".loki", "state");
|
|
12061
12068
|
mkdirSync18(cacheDir, { recursive: true });
|
|
12062
|
-
const cachePath =
|
|
12069
|
+
const cachePath = join47(cacheDir, "project-graph.json");
|
|
12063
12070
|
writeFileSync21(cachePath, JSON.stringify({ key, result }, null, 2), "utf8");
|
|
12064
12071
|
} catch {}
|
|
12065
12072
|
}
|
|
12066
12073
|
function discoverProjectGraph(targetDir) {
|
|
12067
12074
|
const absTarget = resolve14(targetDir);
|
|
12068
|
-
const targetManifest =
|
|
12075
|
+
const targetManifest = join47(absTarget, ".loki", "app.json");
|
|
12069
12076
|
const parentDir = dirname16(absTarget);
|
|
12070
|
-
const parentManifest =
|
|
12077
|
+
const parentManifest = join47(parentDir, ".loki", "app.json");
|
|
12071
12078
|
const examined = [];
|
|
12072
12079
|
let chosenManifest = null;
|
|
12073
12080
|
let chosenRoot = "";
|
|
@@ -12087,7 +12094,7 @@ function discoverProjectGraph(targetDir) {
|
|
|
12087
12094
|
const members = resolveMembers(chosenRoot, declared, basename18(absTarget));
|
|
12088
12095
|
const filtered = [];
|
|
12089
12096
|
for (const m of members) {
|
|
12090
|
-
const sibManifestPath =
|
|
12097
|
+
const sibManifestPath = join47(m, ".loki", "app.json");
|
|
12091
12098
|
if (existsSync27(sibManifestPath)) {
|
|
12092
12099
|
examined.push(sibManifestPath);
|
|
12093
12100
|
const sibManifest = readManifest(sibManifestPath);
|
|
@@ -12218,7 +12225,7 @@ import { spawn as spawn7 } from "child_process";
|
|
|
12218
12225
|
import { createHash as createHash14, randomBytes as randomBytes5 } from "crypto";
|
|
12219
12226
|
import { existsSync as existsSync28, lstatSync as lstatSync10, mkdirSync as mkdirSync19, readdirSync as readdirSync16, readFileSync as readFileSync37, writeFileSync as writeFileSync22 } from "fs";
|
|
12220
12227
|
import { createServer } from "net";
|
|
12221
|
-
import { dirname as dirname17, isAbsolute as isAbsolute6, join as
|
|
12228
|
+
import { dirname as dirname17, isAbsolute as isAbsolute6, join as join48, normalize as normalize3, relative as relative5, sep as sep10 } from "path";
|
|
12222
12229
|
function routeFor(file) {
|
|
12223
12230
|
let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
|
|
12224
12231
|
r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
|
|
@@ -12228,7 +12235,7 @@ function hashScreens(runDir, rels) {
|
|
|
12228
12235
|
const out2 = [];
|
|
12229
12236
|
for (const rel of rels) {
|
|
12230
12237
|
try {
|
|
12231
|
-
out2.push({ path: rel, sha256: sha256File(
|
|
12238
|
+
out2.push({ path: rel, sha256: sha256File(join48(runDir, rel)) });
|
|
12232
12239
|
} catch {}
|
|
12233
12240
|
}
|
|
12234
12241
|
return out2;
|
|
@@ -12241,10 +12248,10 @@ function checkScreens(runDir, screens) {
|
|
|
12241
12248
|
return "evidence_screens entry is malformed";
|
|
12242
12249
|
if (isAbsolute6(s.path) || normalize3(s.path).startsWith(".."))
|
|
12243
12250
|
return `evidence screenshot path escapes the evidence dir: ${s.path}`;
|
|
12244
|
-
const file =
|
|
12251
|
+
const file = join48(runDir, s.path);
|
|
12245
12252
|
let cur = runDir;
|
|
12246
|
-
for (const seg of normalize3(s.path).split(
|
|
12247
|
-
cur =
|
|
12253
|
+
for (const seg of normalize3(s.path).split(sep10)) {
|
|
12254
|
+
cur = join48(cur, seg);
|
|
12248
12255
|
if (isSymlink(cur))
|
|
12249
12256
|
return `evidence screenshot path is a symlink: ${s.path}`;
|
|
12250
12257
|
}
|
|
@@ -12291,7 +12298,7 @@ async function waitUp(url, ms, signal) {
|
|
|
12291
12298
|
}
|
|
12292
12299
|
function openapiPaths(repoDir) {
|
|
12293
12300
|
for (const f of ["openapi.json", "openapi.yaml", "openapi.yml", "swagger.json"]) {
|
|
12294
|
-
const p =
|
|
12301
|
+
const p = join48(repoDir, f);
|
|
12295
12302
|
if (!existsSync28(p))
|
|
12296
12303
|
continue;
|
|
12297
12304
|
try {
|
|
@@ -12309,24 +12316,24 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
|
|
|
12309
12316
|
if (!pw || !pkg)
|
|
12310
12317
|
return { rels: [], skipped: "playwright e2e video and trace skipped: @playwright/test is not installed in the repo" };
|
|
12311
12318
|
try {
|
|
12312
|
-
const dir =
|
|
12319
|
+
const dir = join48(runDir, relDir, "e2e");
|
|
12313
12320
|
mkdirSync19(dir, { recursive: true });
|
|
12314
|
-
writeFileSync22(
|
|
12315
|
-
writeFileSync22(
|
|
12321
|
+
writeFileSync22(join48(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
|
|
12322
|
+
writeFileSync22(join48(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
|
|
12316
12323
|
`);
|
|
12317
|
-
if (!await shoot(pw, ["test", "--config",
|
|
12324
|
+
if (!await shoot(pw, ["test", "--config", join48(dir, "playwright.config.cjs")], repoDir, ms, signal))
|
|
12318
12325
|
return { rels: [], skipped: "playwright e2e video and trace skipped: the run failed or timed out" };
|
|
12319
12326
|
const rels = [];
|
|
12320
12327
|
const walk = (d) => {
|
|
12321
12328
|
for (const e of readdirSync16(d, { withFileTypes: true })) {
|
|
12322
|
-
const full =
|
|
12329
|
+
const full = join48(d, e.name);
|
|
12323
12330
|
if (e.isDirectory())
|
|
12324
12331
|
walk(full);
|
|
12325
12332
|
else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
|
|
12326
|
-
rels.push(
|
|
12333
|
+
rels.push(join48(relDir, "e2e", relative5(dir, full)));
|
|
12327
12334
|
}
|
|
12328
12335
|
};
|
|
12329
|
-
walk(
|
|
12336
|
+
walk(join48(dir, "out"));
|
|
12330
12337
|
return rels.length > 0 ? { rels, skipped: null } : { rels, skipped: "playwright e2e video and trace skipped: no video or trace was produced" };
|
|
12331
12338
|
} catch (e) {
|
|
12332
12339
|
return { rels: [], skipped: `playwright e2e video and trace skipped: ${String(e?.message ?? e).slice(0, 120)}` };
|
|
@@ -12405,15 +12412,15 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
12405
12412
|
if (!visualEvidenceEnabled(opts.env))
|
|
12406
12413
|
return skip("LOKI_VISUAL_EVIDENCE is 0");
|
|
12407
12414
|
const api = loadProjectApi(repoDir), boot = isMultiRoot(api) ? api.uiBoot() : null;
|
|
12408
|
-
const appDir = boot ?
|
|
12409
|
-
const pkgPath =
|
|
12415
|
+
const appDir = boot ? join48(repoDir, boot.boot.cwd) : repoDir;
|
|
12416
|
+
const pkgPath = join48(appDir, "package.json");
|
|
12410
12417
|
let script = null;
|
|
12411
12418
|
if (!boot) {
|
|
12412
12419
|
if (!existsSync28(pkgPath)) {
|
|
12413
|
-
const subs = ["backend", "frontend"].filter((d) => existsSync28(
|
|
12420
|
+
const subs = ["backend", "frontend"].filter((d) => existsSync28(join48(repoDir, d, "package.json")));
|
|
12414
12421
|
const has = (d) => {
|
|
12415
12422
|
try {
|
|
12416
|
-
return pickScript(JSON.parse(readFileSync37(
|
|
12423
|
+
return pickScript(JSON.parse(readFileSync37(join48(repoDir, d, "package.json"), "utf8"))) !== null;
|
|
12417
12424
|
} catch {
|
|
12418
12425
|
return false;
|
|
12419
12426
|
}
|
|
@@ -12447,20 +12454,20 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
12447
12454
|
}
|
|
12448
12455
|
if (!await waitUp(base, left(), signal))
|
|
12449
12456
|
return skip(aborted() ? "aborted" : `${script} server did not answer within ${Math.round(budget / 1000)}s`);
|
|
12450
|
-
const evRoot =
|
|
12457
|
+
const evRoot = join48(runDir, "evidence");
|
|
12451
12458
|
if (isSymlink(evRoot))
|
|
12452
12459
|
return skip("evidence dir is a symlink");
|
|
12453
12460
|
mkdirSync19(evRoot, { recursive: true });
|
|
12454
12461
|
if (pages.length > 0) {
|
|
12455
|
-
const rel0 =
|
|
12456
|
-
mkdirSync19(
|
|
12462
|
+
const rel0 = join48("evidence", randomBytes5(6).toString("hex"));
|
|
12463
|
+
mkdirSync19(join48(runDir, rel0));
|
|
12457
12464
|
const rels = [];
|
|
12458
12465
|
for (const route of [...new Set(pages.map(routeFor))].slice(0, opts.maxRoutes ?? MAX_ROUTES)) {
|
|
12459
12466
|
if (aborted() || left() <= 0)
|
|
12460
12467
|
break;
|
|
12461
|
-
const rel =
|
|
12462
|
-
const ok = await shoot(pw, ["screenshot", `${base}${route}`,
|
|
12463
|
-
if (ok && !aborted() && !isSymlink(
|
|
12468
|
+
const rel = join48(rel0, `${screenName(route)}.png`);
|
|
12469
|
+
const ok = await shoot(pw, ["screenshot", `${base}${route}`, join48(runDir, rel)], appDir, left(), signal);
|
|
12470
|
+
if (ok && !aborted() && !isSymlink(join48(runDir, rel)) && existsSync28(join48(runDir, rel)))
|
|
12464
12471
|
rels.push(rel);
|
|
12465
12472
|
}
|
|
12466
12473
|
if (aborted())
|
|
@@ -12485,9 +12492,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
12485
12492
|
}
|
|
12486
12493
|
if (aborted())
|
|
12487
12494
|
return skip("aborted");
|
|
12488
|
-
const hdir =
|
|
12495
|
+
const hdir = join48(evRoot, randomBytes5(6).toString("hex"));
|
|
12489
12496
|
mkdirSync19(hdir);
|
|
12490
|
-
writeFileSync22(
|
|
12497
|
+
writeFileSync22(join48(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
|
|
12491
12498
|
`);
|
|
12492
12499
|
return { screens: [], http: true, skipped: null };
|
|
12493
12500
|
} catch (e) {
|
|
@@ -12517,11 +12524,11 @@ function receiptScreensProblem(receiptPath, receipt) {
|
|
|
12517
12524
|
return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname17(receiptPath), receipt["evidence_screens"]);
|
|
12518
12525
|
}
|
|
12519
12526
|
var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash14("sha256").update(readFileSync37(p)).digest("hex"), playwrightBin = (repoDir) => {
|
|
12520
|
-
const bin =
|
|
12527
|
+
const bin = join48(repoDir, "node_modules", ".bin", "playwright");
|
|
12521
12528
|
return existsSync28(bin) ? bin : null;
|
|
12522
12529
|
}, playwrightTestPkg = (repoDir) => {
|
|
12523
|
-
const d =
|
|
12524
|
-
return existsSync28(
|
|
12530
|
+
const d = join48(repoDir, "node_modules", "@playwright", "test");
|
|
12531
|
+
return existsSync28(join48(d, "package.json")) ? d : null;
|
|
12525
12532
|
}, e2eSpecSource = (pkgDir, base, routes) => `const { test } = require(${JSON.stringify(pkgDir)});
|
|
12526
12533
|
test("loki e2e walkthrough", async ({ page }) => {
|
|
12527
12534
|
for (const r of ${JSON.stringify(routes)}) { await page.goto(${JSON.stringify(base)} + r); await page.waitForLoadState("load"); }
|
|
@@ -12564,7 +12571,7 @@ var init_outbox = __esm(() => {
|
|
|
12564
12571
|
});
|
|
12565
12572
|
|
|
12566
12573
|
// ../../loki-ts/src/engine10/stages/pr.ts
|
|
12567
|
-
import { join as
|
|
12574
|
+
import { join as join49 } from "path";
|
|
12568
12575
|
var DEFAULT_PUSH_SH;
|
|
12569
12576
|
var init_pr = __esm(() => {
|
|
12570
12577
|
init_types();
|
|
@@ -12581,12 +12588,12 @@ var init_pr = __esm(() => {
|
|
|
12581
12588
|
init_run_outputs();
|
|
12582
12589
|
init_yaml_key();
|
|
12583
12590
|
init_outbox();
|
|
12584
|
-
DEFAULT_PUSH_SH =
|
|
12591
|
+
DEFAULT_PUSH_SH = join49(REPO_ROOT, "autonomy/lib/engine10-push.sh");
|
|
12585
12592
|
});
|
|
12586
12593
|
|
|
12587
12594
|
// ../../loki-ts/src/util/pr_lessons.ts
|
|
12588
12595
|
import { existsSync as existsSync29, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync7, readFileSync as readFileSync38, rmSync as rmSync15, writeFileSync as writeFileSync23 } from "fs";
|
|
12589
|
-
import { dirname as dirname18, join as
|
|
12596
|
+
import { dirname as dirname18, join as join50 } from "path";
|
|
12590
12597
|
import { createHash as createHash15 } from "crypto";
|
|
12591
12598
|
function loadLessons(repoDir) {
|
|
12592
12599
|
const p = lessonsPath(repoDir);
|
|
@@ -12635,7 +12642,7 @@ function recordRunVerdict(repoDir, runId, verdict) {
|
|
|
12635
12642
|
if (dirty)
|
|
12636
12643
|
save(repoDir, lessons);
|
|
12637
12644
|
}
|
|
12638
|
-
var lessonsPath = (repoDir) =>
|
|
12645
|
+
var lessonsPath = (repoDir) => join50(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), KINDS;
|
|
12639
12646
|
var init_pr_lessons = __esm(() => {
|
|
12640
12647
|
init_atomic();
|
|
12641
12648
|
init_safe_git();
|
|
@@ -12770,10 +12777,10 @@ var init_providers = __esm(() => {
|
|
|
12770
12777
|
|
|
12771
12778
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
12772
12779
|
import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readFileSync as readFileSync40, writeFileSync as writeFileSync24 } from "fs";
|
|
12773
|
-
import { join as
|
|
12780
|
+
import { join as join51 } from "path";
|
|
12774
12781
|
function loadRouteRecord(runDir) {
|
|
12775
12782
|
try {
|
|
12776
|
-
const p =
|
|
12783
|
+
const p = join51(runDir, ROUTE_RECORD_FILE);
|
|
12777
12784
|
if (!existsSync31(p) || !lstatSync11(p).isFile())
|
|
12778
12785
|
return;
|
|
12779
12786
|
const v = JSON.parse(readFileSync40(p, "utf8"));
|
|
@@ -12902,7 +12909,7 @@ var init_worker = __esm(() => {
|
|
|
12902
12909
|
});
|
|
12903
12910
|
|
|
12904
12911
|
// ../../loki-ts/src/project_model/package_suite.ts
|
|
12905
|
-
import { join as
|
|
12912
|
+
import { join as join52 } from "path";
|
|
12906
12913
|
async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
12907
12914
|
const api = loadProjectApi(repoDir);
|
|
12908
12915
|
if (!isMultiRoot(api))
|
|
@@ -12913,7 +12920,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
12913
12920
|
for (const pkg of withTests) {
|
|
12914
12921
|
const tc = pkg.commands.test, name = `full suite: ${pkg.name}`, cmd = `(cd ${tc.cwd} && ${tc.cmd})`;
|
|
12915
12922
|
const started = Date.now();
|
|
12916
|
-
const r = await run(["bash", "-c", tc.cmd], { cwd:
|
|
12923
|
+
const r = await run(["bash", "-c", tc.cmd], { cwd: join52(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
12917
12924
|
const duration_s = (Date.now() - started) / 1000;
|
|
12918
12925
|
if (signal.aborted) {
|
|
12919
12926
|
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
@@ -12922,7 +12929,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
12922
12929
|
}
|
|
12923
12930
|
const out2 = `${r.stdout}
|
|
12924
12931
|
${r.stderr}`;
|
|
12925
|
-
const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd:
|
|
12932
|
+
const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join52(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
12926
12933
|
if (lr) {
|
|
12927
12934
|
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
12928
12935
|
notProven.add(`${lr} (${name}; harness-owned)`);
|
|
@@ -12956,7 +12963,7 @@ __export(exports_deep, {
|
|
|
12956
12963
|
DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
|
|
12957
12964
|
});
|
|
12958
12965
|
import { existsSync as existsSync32, mkdirSync as mkdirSync22, writeFileSync as writeFileSync25 } from "fs";
|
|
12959
|
-
import { join as
|
|
12966
|
+
import { join as join53 } from "path";
|
|
12960
12967
|
async function runFullSuite(ctx, signal, opts, checks, notProven) {
|
|
12961
12968
|
if (await runPackageSuites(ctx.repoDir, signal, { path: opts.path, timeoutMs: opts.fullSuiteTimeoutMs ?? FULL_SUITE_TIMEOUT_MS, baseSha: ctx.baseSha }, checks, notProven))
|
|
12962
12969
|
return;
|
|
@@ -13053,7 +13060,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
|
13053
13060
|
}
|
|
13054
13061
|
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"';
|
|
13055
13062
|
const started = Date.now();
|
|
13056
|
-
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) =>
|
|
13063
|
+
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join53(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
|
|
13057
13064
|
const durationS = (Date.now() - started) / 1000;
|
|
13058
13065
|
if (r.exitCode === 3) {
|
|
13059
13066
|
checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: durationS });
|
|
@@ -13094,7 +13101,7 @@ async function postResults(ctx, opts, checks, notProven, statusState) {
|
|
|
13094
13101
|
const prNumber = prUrl ? PR_NUMBER_RE.exec(prUrl)?.[1] : undefined;
|
|
13095
13102
|
if (prNumber) {
|
|
13096
13103
|
mkdirSync22(ctx.runDir, { recursive: true });
|
|
13097
|
-
const bodyFile =
|
|
13104
|
+
const bodyFile = join53(ctx.runDir, "deep-comment.md");
|
|
13098
13105
|
writeFileSync25(bodyFile, buildCommentBody(checks, notProven, statusState), "utf8");
|
|
13099
13106
|
const commentResult = await run(["bash", scriptPath, ...commentArgv(prNumber, bodyFile)], { cwd: ctx.repoDir, env, timeoutMs: 30000 });
|
|
13100
13107
|
if (commentResult.exitCode !== 0)
|
|
@@ -13148,7 +13155,7 @@ async function runDeep(ctx, signal, opts = {}) {
|
|
|
13148
13155
|
const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
|
|
13149
13156
|
const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
13150
13157
|
mkdirSync22(ctx.runDir, { recursive: true });
|
|
13151
|
-
writeFileSync25(
|
|
13158
|
+
writeFileSync25(join53(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
|
|
13152
13159
|
`);
|
|
13153
13160
|
const pushNotProven = await postResults(ctx, opts, checks, notProvenList, statusState);
|
|
13154
13161
|
const allNotProven = [...notProvenList, ...pushNotProven];
|
|
@@ -13193,18 +13200,18 @@ var init_deep = __esm(() => {
|
|
|
13193
13200
|
// ../../loki-ts/src/engine10/stages/verify.ts
|
|
13194
13201
|
import { existsSync as existsSync33, mkdtempSync as mkdtempSync8, realpathSync as realpathSync18, rmSync as rmSync16 } from "fs";
|
|
13195
13202
|
import { tmpdir as tmpdir9 } from "os";
|
|
13196
|
-
import { dirname as dirname20, isAbsolute as isAbsolute7, join as
|
|
13203
|
+
import { dirname as dirname20, isAbsolute as isAbsolute7, join as join54, relative as relative6 } from "path";
|
|
13197
13204
|
function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
13198
13205
|
const inRepo = (p) => {
|
|
13199
13206
|
try {
|
|
13200
|
-
const r =
|
|
13207
|
+
const r = relative6(realpathSync18(repoDir), realpathSync18(p));
|
|
13201
13208
|
return r !== "" && !r.startsWith("..") && !isAbsolute7(r);
|
|
13202
13209
|
} catch {
|
|
13203
13210
|
return false;
|
|
13204
13211
|
}
|
|
13205
13212
|
};
|
|
13206
13213
|
const venvEnv = process.env["VIRTUAL_ENV"];
|
|
13207
|
-
const project = [
|
|
13214
|
+
const project = [join54(repoDir, ".venv", "bin", bin), join54(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join54(venvEnv, "bin", bin)] : []].find(existsSync33);
|
|
13208
13215
|
return project ? [project, "project"] : [Bun.which(fallback) ? fallback : lastResort, "system"];
|
|
13209
13216
|
}
|
|
13210
13217
|
function runnerCmd(t, repoDir) {
|
|
@@ -13317,7 +13324,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
13317
13324
|
const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
|
|
13318
13325
|
if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length) || signal.aborted)
|
|
13319
13326
|
return out2;
|
|
13320
|
-
const dir = mkdtempSync8(
|
|
13327
|
+
const dir = mkdtempSync8(join54(tmpdir9(), "e10-base-"));
|
|
13321
13328
|
const git3 = (args) => {
|
|
13322
13329
|
safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
|
|
13323
13330
|
};
|
|
@@ -13355,7 +13362,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
13355
13362
|
return out2;
|
|
13356
13363
|
}
|
|
13357
13364
|
function isLokiModeRepo(repoDir) {
|
|
13358
|
-
return existsSync33(
|
|
13365
|
+
return existsSync33(join54(repoDir, "scripts", "select-tests.sh"));
|
|
13359
13366
|
}
|
|
13360
13367
|
async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
13361
13368
|
const { api, ...runOpts } = opts;
|
|
@@ -13372,9 +13379,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
13372
13379
|
}
|
|
13373
13380
|
for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
|
|
13374
13381
|
const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
|
|
13375
|
-
if (existsSync33(
|
|
13382
|
+
if (existsSync33(join54(g.cwd, "tsconfig.json")))
|
|
13376
13383
|
await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
|
|
13377
|
-
if (ESLINT_CONFIGS.some((f) => existsSync33(
|
|
13384
|
+
if (ESLINT_CONFIGS.some((f) => existsSync33(join54(g.cwd, f))))
|
|
13378
13385
|
await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
|
|
13379
13386
|
}
|
|
13380
13387
|
}
|
|
@@ -13432,7 +13439,7 @@ var init_verify = __esm(() => {
|
|
|
13432
13439
|
const impacted = ctx.tests.impacted(map, changed);
|
|
13433
13440
|
const changedTestFiles = map.tests.filter((t) => changed.includes(t.path));
|
|
13434
13441
|
const wall = ctx.outputs().wall ?? {};
|
|
13435
|
-
const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute7(f.path) ?
|
|
13442
|
+
const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute7(f.path) ? relative6(ctx.repoDir, f.path) : f.path));
|
|
13436
13443
|
const wallTests = map.tests.filter((t) => wallPaths.has(t.path));
|
|
13437
13444
|
const intake = ctx.outputs().intake, relevant2 = ctx.tests.impacted(map, namedFiles(intake?.task ?? "", loadRepoMap(intake?.repomap_ref)));
|
|
13438
13445
|
const tests = dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]);
|
|
@@ -13530,7 +13537,7 @@ var init_verify = __esm(() => {
|
|
|
13530
13537
|
|
|
13531
13538
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
13532
13539
|
import { existsSync as existsSync34, readdirSync as readdirSync17, readFileSync as readFileSync41 } from "fs";
|
|
13533
|
-
import { dirname as dirname21, join as
|
|
13540
|
+
import { dirname as dirname21, join as join55 } from "path";
|
|
13534
13541
|
function parseJsonc(text2) {
|
|
13535
13542
|
let out2 = "", i = 0;
|
|
13536
13543
|
while (i < text2.length) {
|
|
@@ -13565,7 +13572,7 @@ function moduleOf(file, depth = 0) {
|
|
|
13565
13572
|
const ext = typeof j.extends === "string" ? j.extends : null;
|
|
13566
13573
|
if (!ext || !ext.startsWith("."))
|
|
13567
13574
|
return null;
|
|
13568
|
-
const next =
|
|
13575
|
+
const next = join55(dirname21(file), ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
13569
13576
|
return existsSync34(next) ? moduleOf(next, depth + 1) : null;
|
|
13570
13577
|
}
|
|
13571
13578
|
function readPackageConventions(pkgDir, runner = null) {
|
|
@@ -13577,13 +13584,13 @@ function readPackageConventions(pkgDir, runner = null) {
|
|
|
13577
13584
|
}
|
|
13578
13585
|
let packageType = null, tsModule = null;
|
|
13579
13586
|
for (const n2 of names) {
|
|
13580
|
-
const j = readJson4(
|
|
13587
|
+
const j = readJson4(join55(pkgDir, n2));
|
|
13581
13588
|
if (!j)
|
|
13582
13589
|
continue;
|
|
13583
13590
|
if (packageType === null && typeof j.type === "string" && typeof j.name === "string")
|
|
13584
13591
|
packageType = j.type;
|
|
13585
13592
|
if (tsModule === null && j.compilerOptions !== undefined)
|
|
13586
|
-
tsModule = moduleOf(
|
|
13593
|
+
tsModule = moduleOf(join55(pkgDir, n2));
|
|
13587
13594
|
}
|
|
13588
13595
|
if (packageType === null && tsModule === null)
|
|
13589
13596
|
return null;
|
|
@@ -13617,13 +13624,13 @@ var init_conventions = () => {};
|
|
|
13617
13624
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
13618
13625
|
import { existsSync as existsSync35, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync9, readFileSync as readFileSync42, readdirSync as readdirSync18, realpathSync as realpathSync19, rmSync as rmSync17, writeFileSync as writeFileSync26 } from "fs";
|
|
13619
13626
|
import { tmpdir as tmpdir10 } from "os";
|
|
13620
|
-
import { dirname as dirname22, isAbsolute as isAbsolute8, join as
|
|
13627
|
+
import { dirname as dirname22, isAbsolute as isAbsolute8, join as join56, relative as relative7 } from "path";
|
|
13621
13628
|
function pytestCollectionIsRed(output, repoDir) {
|
|
13622
13629
|
if (/ModuleNotFoundError/.test(output))
|
|
13623
13630
|
return false;
|
|
13624
13631
|
const real2 = (p) => {
|
|
13625
13632
|
try {
|
|
13626
|
-
return realpathSync19(isAbsolute8(p) ? p :
|
|
13633
|
+
return realpathSync19(isAbsolute8(p) ? p : join56(repoDir, p));
|
|
13627
13634
|
} catch {
|
|
13628
13635
|
return null;
|
|
13629
13636
|
}
|
|
@@ -13660,7 +13667,7 @@ function pytestCollectionIsRed(output, repoDir) {
|
|
|
13660
13667
|
}
|
|
13661
13668
|
function moduleUnderRepo(repoDir, name) {
|
|
13662
13669
|
const rel = name.replace(/\./g, "/");
|
|
13663
|
-
return existsSync35(
|
|
13670
|
+
return existsSync35(join56(repoDir, `${rel}.py`)) || existsSync35(join56(repoDir, rel, "__init__.py"));
|
|
13664
13671
|
}
|
|
13665
13672
|
function pytestExit1IsRed(output) {
|
|
13666
13673
|
if (/^!+ _pytest\.outcomes\.Exit\b/m.test(output))
|
|
@@ -13758,7 +13765,7 @@ ${acceptance.map((a) => `Acceptance: ${a}`).join(`
|
|
|
13758
13765
|
function loadTaskText(ctx, fromPrior) {
|
|
13759
13766
|
if (fromPrior)
|
|
13760
13767
|
return fromPrior;
|
|
13761
|
-
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ??
|
|
13768
|
+
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join56(ctx.runDir, "issue.json");
|
|
13762
13769
|
if (existsSync35(issueJsonPath)) {
|
|
13763
13770
|
try {
|
|
13764
13771
|
const issue = JSON.parse(readFileSync42(issueJsonPath, "utf8"));
|
|
@@ -13773,7 +13780,7 @@ function loadTaskText(ctx, fromPrior) {
|
|
|
13773
13780
|
}
|
|
13774
13781
|
function wallTargetDir(repoDir, existingTests) {
|
|
13775
13782
|
const first = existingTests[0];
|
|
13776
|
-
return first ?
|
|
13783
|
+
return first ? join56(repoDir, dirname22(first.path)) : join56(repoDir, "tests");
|
|
13777
13784
|
}
|
|
13778
13785
|
function guessRunner(fileName, runners) {
|
|
13779
13786
|
if (fileName.endsWith(".py"))
|
|
@@ -13803,12 +13810,12 @@ async function wallAuthor(ctx, signal) {
|
|
|
13803
13810
|
return done({ status: "skipped", data: { size: sz.size, files: [], no_runner: true }, reason: "no runnable test command detected: the Wall cannot write a runnable check" });
|
|
13804
13811
|
const tree = prior.intake?.tree;
|
|
13805
13812
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
13806
|
-
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${
|
|
13807
|
-
const conv2 = readPackageConventions(
|
|
13808
|
-
const cwd = mkdtempSync9(
|
|
13813
|
+
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative7(ctx.repoDir, targetDir)}/x`);
|
|
13814
|
+
const conv2 = readPackageConventions(join56(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
13815
|
+
const cwd = mkdtempSync9(join56(tmpdir10(), "loki-e15-wall-"));
|
|
13809
13816
|
const wm = wallManifestFor(ctx.repoDir, tree, task);
|
|
13810
13817
|
for (const [n2, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm ? [["wall_manifest.txt", wm.text]] : []])
|
|
13811
|
-
writeFileSync26(
|
|
13818
|
+
writeFileSync26(join56(cwd, n2), c, "utf8");
|
|
13812
13819
|
const session = await ctx.sessions.run({
|
|
13813
13820
|
stage: "wall",
|
|
13814
13821
|
brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2), unitSpec()?.acceptance ?? []),
|
|
@@ -13823,15 +13830,15 @@ async function wallAuthor(ctx, signal) {
|
|
|
13823
13830
|
rmSync17(cwd, { recursive: true, force: true });
|
|
13824
13831
|
return done({ status: "failed", data: {}, reason: "wall session aborted, killed, or timed out", killed: true });
|
|
13825
13832
|
}
|
|
13826
|
-
const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync42(
|
|
13827
|
-
const sealedDir =
|
|
13833
|
+
const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync42(join56(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
|
|
13834
|
+
const sealedDir = join56(ctx.runDir, "wall");
|
|
13828
13835
|
if (generated.length > 0)
|
|
13829
13836
|
mkdirSync23(sealedDir, { recursive: true });
|
|
13830
13837
|
const contents = new Map;
|
|
13831
13838
|
const discarded = [];
|
|
13832
13839
|
for (const name of generated) {
|
|
13833
|
-
const content = readFileSync42(
|
|
13834
|
-
writeFileSync26(
|
|
13840
|
+
const content = readFileSync42(join56(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
|
|
13841
|
+
writeFileSync26(join56(sealedDir, name), content, "utf8");
|
|
13835
13842
|
if (bad)
|
|
13836
13843
|
discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
|
|
13837
13844
|
else
|
|
@@ -13851,18 +13858,18 @@ function installWall(ctx, a, baseDir, opts = {}) {
|
|
|
13851
13858
|
const content = contents.get(name);
|
|
13852
13859
|
if (content === undefined)
|
|
13853
13860
|
continue;
|
|
13854
|
-
const dest =
|
|
13861
|
+
const dest = join56(targetDir, name), runner = guessRunner(name, runners);
|
|
13855
13862
|
writeFileSync26(dest, content, "utf8");
|
|
13856
13863
|
sealedFiles.push({ path: dest, sha256: sha2562(content) });
|
|
13857
13864
|
readOnlyFiles.push({ path: dest, content });
|
|
13858
13865
|
if (runner)
|
|
13859
|
-
wallTests.push({ runner, path:
|
|
13866
|
+
wallTests.push({ runner, path: relative7(ctx.repoDir, dest) });
|
|
13860
13867
|
}
|
|
13861
13868
|
ctx.wallSealed = true;
|
|
13862
13869
|
ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
|
|
13863
13870
|
const baseRunner = opts.baseRunner ?? new RealBaseTestRunner, baseRun = { pass: 0, fail: 0, not_run: discarded.length }, notRunFiles = [];
|
|
13864
13871
|
for (const t of wallTests) {
|
|
13865
|
-
const r = baseRunner.run(baseDir, [t]), abs =
|
|
13872
|
+
const r = baseRunner.run(baseDir, [t]), abs = join56(ctx.repoDir, t.path);
|
|
13866
13873
|
baseRun.pass += r.pass;
|
|
13867
13874
|
baseRun.fail += r.fail;
|
|
13868
13875
|
baseRun.not_run += r.not_run ?? 0;
|
|
@@ -13917,14 +13924,14 @@ var init_wall = __esm(() => {
|
|
|
13917
13924
|
|
|
13918
13925
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
13919
13926
|
import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync12, mkdirSync as mkdirSync24, openSync as openSync9, readFileSync as readFileSync43, realpathSync as realpathSync20, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "fs";
|
|
13920
|
-
import { dirname as dirname23, join as
|
|
13927
|
+
import { dirname as dirname23, join as join57, relative as relative8, sep as sep11 } from "path";
|
|
13921
13928
|
function safeRestore(repoDir, f, want, mode) {
|
|
13922
|
-
const root = realpathSync20(repoDir), fp =
|
|
13929
|
+
const root = realpathSync20(repoDir), fp = join57(root, f), rel = relative8(root, dirname23(fp));
|
|
13923
13930
|
if (rel.startsWith(".."))
|
|
13924
13931
|
throw new Error("outside repo");
|
|
13925
13932
|
let cur = root;
|
|
13926
|
-
for (const part of rel === "" ? [] : rel.split(
|
|
13927
|
-
cur =
|
|
13933
|
+
for (const part of rel === "" ? [] : rel.split(sep11)) {
|
|
13934
|
+
cur = join57(cur, part);
|
|
13928
13935
|
let st2;
|
|
13929
13936
|
try {
|
|
13930
13937
|
st2 = lstatSync12(cur);
|
|
@@ -13979,7 +13986,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
13979
13986
|
return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
|
|
13980
13987
|
const notProven = [];
|
|
13981
13988
|
for (const [f, v] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
|
|
13982
|
-
const fp =
|
|
13989
|
+
const fp = join57(repoDir, f);
|
|
13983
13990
|
try {
|
|
13984
13991
|
if (v.startsWith("!")) {
|
|
13985
13992
|
const st = lstatSync12(fp);
|
|
@@ -13998,7 +14005,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
13998
14005
|
try {
|
|
13999
14006
|
let m = 420;
|
|
14000
14007
|
try {
|
|
14001
|
-
const l = lstatSync12(
|
|
14008
|
+
const l = lstatSync12(join57(repoDir, f));
|
|
14002
14009
|
if (l.isFile())
|
|
14003
14010
|
m = l.mode & 511;
|
|
14004
14011
|
} catch {}
|
|
@@ -14074,9 +14081,9 @@ var init_scope2 = __esm(() => {
|
|
|
14074
14081
|
// ../../loki-ts/src/council/role_agents.ts
|
|
14075
14082
|
import { existsSync as existsSync36, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "fs";
|
|
14076
14083
|
import { homedir as homedir9 } from "os";
|
|
14077
|
-
import { join as
|
|
14084
|
+
import { join as join58 } from "path";
|
|
14078
14085
|
function agentDirs(repoDir, env = process.env) {
|
|
14079
|
-
return [env["LOKI_AGENTS_PROJECT_DIR"] ||
|
|
14086
|
+
return [env["LOKI_AGENTS_PROJECT_DIR"] || join58(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join58(env["XDG_CONFIG_HOME"] || join58(homedir9(), ".config"), "loki", "agents")];
|
|
14080
14087
|
}
|
|
14081
14088
|
function parseAgent(file, stem2) {
|
|
14082
14089
|
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync44(file, "utf8"));
|
|
@@ -14104,7 +14111,7 @@ function loadRoleAgent(repoDir, role, env = process.env) {
|
|
|
14104
14111
|
const ordered = [...names.filter((n2) => n2 === `${role}.md`), ...names.filter((n2) => n2 !== `${role}.md`)];
|
|
14105
14112
|
for (const n2 of ordered) {
|
|
14106
14113
|
try {
|
|
14107
|
-
const a = parseAgent(
|
|
14114
|
+
const a = parseAgent(join58(d, n2), n2.slice(0, -3));
|
|
14108
14115
|
if (a && a.role === role)
|
|
14109
14116
|
return a;
|
|
14110
14117
|
} catch {}
|
|
@@ -14122,10 +14129,10 @@ var init_role_agents = __esm(() => {
|
|
|
14122
14129
|
|
|
14123
14130
|
// ../../loki-ts/src/util/run_summary.ts
|
|
14124
14131
|
import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as readFileSync45, renameSync as renameSync11, statSync as statSync18, writeFileSync as writeFileSync28 } from "fs";
|
|
14125
|
-
import { join as
|
|
14132
|
+
import { join as join59 } from "path";
|
|
14126
14133
|
function readRiskRecord(repoDir, sinceMs = 0) {
|
|
14127
14134
|
try {
|
|
14128
|
-
const p =
|
|
14135
|
+
const p = join59(repoDir, ".loki", "state", "risk-tier.json");
|
|
14129
14136
|
if (statSync18(p).mtimeMs < sinceMs)
|
|
14130
14137
|
return null;
|
|
14131
14138
|
const r = JSON.parse(readFileSync45(p, "utf8"));
|
|
@@ -14143,7 +14150,7 @@ var init_run_summary = __esm(() => {
|
|
|
14143
14150
|
|
|
14144
14151
|
// ../../loki-ts/src/engine10/stages/xreview.ts
|
|
14145
14152
|
import { existsSync as existsSync38, readFileSync as readFileSync46 } from "fs";
|
|
14146
|
-
import { join as
|
|
14153
|
+
import { join as join60 } from "path";
|
|
14147
14154
|
function minVerdict(verdict, review) {
|
|
14148
14155
|
const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
|
|
14149
14156
|
return RANK3[ceiling] < RANK3[verdict] ? ceiling : verdict;
|
|
@@ -14156,7 +14163,7 @@ function explicitReview(repoDir, env) {
|
|
|
14156
14163
|
if (flag && isOff(ev))
|
|
14157
14164
|
return "off";
|
|
14158
14165
|
for (const f of ["loki.yaml", "loki.yml"]) {
|
|
14159
|
-
const p =
|
|
14166
|
+
const p = join60(repoDir, f);
|
|
14160
14167
|
if (!existsSync38(p))
|
|
14161
14168
|
continue;
|
|
14162
14169
|
try {
|
|
@@ -14325,7 +14332,7 @@ See also: loki cost --detail (what a run ALREADY spent)
|
|
|
14325
14332
|
|
|
14326
14333
|
// ../../loki-ts/src/features/contract.ts
|
|
14327
14334
|
import { existsSync as existsSync39, lstatSync as lstatSync13, mkdirSync as mkdirSync26, readFileSync as readFileSync47, rmSync as rmSync18, writeFileSync as writeFileSync29 } from "fs";
|
|
14328
|
-
import { dirname as dirname26, join as
|
|
14335
|
+
import { dirname as dirname26, join as join61 } from "path";
|
|
14329
14336
|
import { createHash as createHash16 } from "crypto";
|
|
14330
14337
|
function contractEnabled(env = process.env) {
|
|
14331
14338
|
return env["LOKI_CONTRACT"] !== "0";
|
|
@@ -14357,7 +14364,7 @@ function untracedLines(trace) {
|
|
|
14357
14364
|
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)}`);
|
|
14358
14365
|
}
|
|
14359
14366
|
function contractPath(repoDir) {
|
|
14360
|
-
return
|
|
14367
|
+
return join61(repoDir, ".loki", "contract.json");
|
|
14361
14368
|
}
|
|
14362
14369
|
function readContract(repoDir) {
|
|
14363
14370
|
const p = contractPath(repoDir);
|
|
@@ -14442,16 +14449,16 @@ var init_contract = __esm(() => {
|
|
|
14442
14449
|
init_safe_git();
|
|
14443
14450
|
STOP2 = 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"]);
|
|
14444
14451
|
MAX_CONTRACT_BYTES = 1024 * 1024;
|
|
14445
|
-
REQ_MAP_REL =
|
|
14452
|
+
REQ_MAP_REL = join61(".loki", "state", "requirements-map.json");
|
|
14446
14453
|
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"]);
|
|
14447
14454
|
});
|
|
14448
14455
|
|
|
14449
14456
|
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
14450
14457
|
import { createHash as createHash17 } from "crypto";
|
|
14451
14458
|
import { existsSync as existsSync40, mkdirSync as mkdirSync27, readdirSync as readdirSync20, readFileSync as readFileSync48, renameSync as renameSync12, statSync as statSync19, writeFileSync as writeFileSync30 } from "fs";
|
|
14452
|
-
import { dirname as dirname27, join as
|
|
14459
|
+
import { dirname as dirname27, join as join62 } from "path";
|
|
14453
14460
|
function sealGroup(runDir, rh) {
|
|
14454
|
-
const manifestPath =
|
|
14461
|
+
const manifestPath = join62(runDir, "group", "manifest.json");
|
|
14455
14462
|
if (!existsSync40(manifestPath))
|
|
14456
14463
|
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
14457
14464
|
const notProven = [];
|
|
@@ -14476,7 +14483,7 @@ function sealGroup(runDir, rh) {
|
|
|
14476
14483
|
return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
14477
14484
|
seen.add(id);
|
|
14478
14485
|
seenLower.add(id.toLowerCase());
|
|
14479
|
-
const dir =
|
|
14486
|
+
const dir = join62(unitsDir(runDir), id), rp = join62(dir, "receipt.json"), ep = join62(dir, "events.jsonl");
|
|
14480
14487
|
let bytes;
|
|
14481
14488
|
try {
|
|
14482
14489
|
bytes = readFileSync48(rp);
|
|
@@ -14521,7 +14528,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
14521
14528
|
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
14522
14529
|
const g = receipt["group"];
|
|
14523
14530
|
if (g === undefined)
|
|
14524
|
-
return existsSync40(
|
|
14531
|
+
return existsSync40(join62(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
14525
14532
|
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
14526
14533
|
return bad("group section malformed");
|
|
14527
14534
|
const entries = g["units"];
|
|
@@ -14533,7 +14540,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
14533
14540
|
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
14534
14541
|
let unchecked = null;
|
|
14535
14542
|
for (let i = 0;i < entries.length; i++) {
|
|
14536
|
-
const e = entries[i], id = ids[i], dir =
|
|
14543
|
+
const e = entries[i], id = ids[i], dir = join62(unitsDir(runDir), id), rp = join62(dir, "receipt.json"), ep = join62(dir, "events.jsonl");
|
|
14537
14544
|
if (e["index"] !== i)
|
|
14538
14545
|
return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
|
|
14539
14546
|
let bytes;
|
|
@@ -14569,7 +14576,7 @@ function compositeVerdict(childVerdicts) {
|
|
|
14569
14576
|
const failed2 = childVerdicts.filter((v) => v === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v)).length;
|
|
14570
14577
|
return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v) => PASSING.has(v)) });
|
|
14571
14578
|
}
|
|
14572
|
-
var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) =>
|
|
14579
|
+
var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join62(runDir, "group", "units"), readJson5 = (p) => {
|
|
14573
14580
|
try {
|
|
14574
14581
|
return JSON.parse(readFileSync48(p, "utf8"));
|
|
14575
14582
|
} catch {
|
|
@@ -14590,7 +14597,7 @@ var init_seal_group = __esm(() => {
|
|
|
14590
14597
|
|
|
14591
14598
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
14592
14599
|
import { existsSync as existsSync41, readFileSync as readFileSync49, statSync as statSync20 } from "fs";
|
|
14593
|
-
import { basename as basename21, join as
|
|
14600
|
+
import { basename as basename21, join as join63 } from "path";
|
|
14594
14601
|
function supplyEnabled(env) {
|
|
14595
14602
|
return env["LOKI_SUPPLY_GUARD"] !== "0";
|
|
14596
14603
|
}
|
|
@@ -14605,7 +14612,7 @@ function isManifestPath(path) {
|
|
|
14605
14612
|
return MANIFESTS.test(basename21(path));
|
|
14606
14613
|
}
|
|
14607
14614
|
function readDeclared(repoDir) {
|
|
14608
|
-
const p =
|
|
14615
|
+
const p = join63(repoDir, ".loki", DECLARED_FILE);
|
|
14609
14616
|
if (!existsSync41(p))
|
|
14610
14617
|
return { deps: [], problem: null };
|
|
14611
14618
|
try {
|
|
@@ -14631,7 +14638,7 @@ function readDeclared(repoDir) {
|
|
|
14631
14638
|
}
|
|
14632
14639
|
}
|
|
14633
14640
|
function readAllowlist(repoDir) {
|
|
14634
|
-
const p =
|
|
14641
|
+
const p = join63(repoDir, ".loki", "supply-allowlist");
|
|
14635
14642
|
if (!existsSync41(p))
|
|
14636
14643
|
return new Set;
|
|
14637
14644
|
try {
|
|
@@ -14676,7 +14683,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
14676
14683
|
if (eco === "npm") {
|
|
14677
14684
|
if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
|
|
14678
14685
|
return true;
|
|
14679
|
-
return files(
|
|
14686
|
+
return files(join63(repoDir, ".npmrc"), home ? join63(home, ".npmrc") : "").some((t) => t.split(`
|
|
14680
14687
|
`).some((l) => {
|
|
14681
14688
|
const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
|
|
14682
14689
|
return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
|
|
@@ -14685,7 +14692,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
14685
14692
|
if (eco === "pypi") {
|
|
14686
14693
|
if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
|
|
14687
14694
|
return true;
|
|
14688
|
-
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ?
|
|
14695
|
+
const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join63(home, ".config", "pip", "pip.conf") : "", home ? join63(home, ".pip", "pip.conf") : "", join63(repoDir, "pip.conf")];
|
|
14689
14696
|
return files(...cfg).some((t) => t.split(`
|
|
14690
14697
|
`).some((l) => {
|
|
14691
14698
|
const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
|
|
@@ -14695,7 +14702,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
|
|
|
14695
14702
|
if (eco === "cargo") {
|
|
14696
14703
|
if (Object.keys(env).some((k) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k) || /^CARGO_SOURCE_/.test(k)))
|
|
14697
14704
|
return true;
|
|
14698
|
-
return files(
|
|
14705
|
+
return files(join63(repoDir, ".cargo", "config.toml"), join63(repoDir, ".cargo", "config"), home ? join63(home, ".cargo", "config.toml") : "", home ? join63(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
|
|
14699
14706
|
}
|
|
14700
14707
|
if (eco === "go") {
|
|
14701
14708
|
const gp = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
|
|
@@ -14835,7 +14842,7 @@ var init_supply_guard = __esm(() => {
|
|
|
14835
14842
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
14836
14843
|
import { createHash as createHash18 } from "crypto";
|
|
14837
14844
|
import { existsSync as existsSync42, readdirSync as readdirSync21, mkdirSync as mkdirSync28, readFileSync as readFileSync50, writeFileSync as writeFileSync31 } from "fs";
|
|
14838
|
-
import { basename as basename22, isAbsolute as isAbsolute9, join as
|
|
14845
|
+
import { basename as basename22, isAbsolute as isAbsolute9, join as join64, relative as relative9 } from "path";
|
|
14839
14846
|
function sanitizeReason(s) {
|
|
14840
14847
|
const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
|
|
14841
14848
|
const capped = collapsed.length > 500 ? `${collapsed.slice(0, 500)}...` : collapsed;
|
|
@@ -14910,7 +14917,7 @@ function renderReceiptMd(r) {
|
|
|
14910
14917
|
`);
|
|
14911
14918
|
}
|
|
14912
14919
|
var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash18("sha256").update(s).digest("hex"), str3 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], receiptRel = (ctx) => {
|
|
14913
|
-
const r =
|
|
14920
|
+
const r = relative9(ctx.repoDir, join64(ctx.runDir, "receipt.json"));
|
|
14914
14921
|
return r.startsWith("..") || isAbsolute9(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
|
|
14915
14922
|
}, commitStage, sealStage;
|
|
14916
14923
|
var init_seal = __esm(() => {
|
|
@@ -15019,7 +15026,7 @@ var init_seal = __esm(() => {
|
|
|
15019
15026
|
if (wallNotRun > 0) {
|
|
15020
15027
|
try {
|
|
15021
15028
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename22(String(f.path))));
|
|
15022
|
-
for (const n2 of readdirSync21(
|
|
15029
|
+
for (const n2 of readdirSync21(join64(ctx.runDir, "wall")).sort())
|
|
15023
15030
|
if (!kept.has(n2))
|
|
15024
15031
|
notProven.add(`wall test discarded: ${n2} (not_run)`);
|
|
15025
15032
|
} catch {}
|
|
@@ -15082,19 +15089,19 @@ var init_seal = __esm(() => {
|
|
|
15082
15089
|
for (const [s, d] of Object.entries(o))
|
|
15083
15090
|
if (typeof d?.duration_s === "number")
|
|
15084
15091
|
stages[s] = d.duration_s;
|
|
15085
|
-
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(
|
|
15092
|
+
const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join64(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
|
|
15086
15093
|
const iterIds = Object.values(o).flatMap((d) => [...strs2(d?.iteration_ids), ...strs2([d?.iteration_id])]);
|
|
15087
15094
|
if (iterIds.length === 0)
|
|
15088
15095
|
notProven.add("cost not measured (no iteration ids recorded)");
|
|
15089
15096
|
const cost = ctx.cost.read(ctx.repoDir, iterIds);
|
|
15090
15097
|
if (cost.unmetered)
|
|
15091
15098
|
notProven.add("cost unmetered (CLI invoker; recorded as 0)");
|
|
15092
|
-
const eventsPath =
|
|
15099
|
+
const eventsPath = join64(ctx.runDir, "events.jsonl");
|
|
15093
15100
|
const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
|
|
15094
15101
|
const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
|
|
15095
15102
|
if (wallFiles.length > 0 && wallPassed === null)
|
|
15096
15103
|
notProven.add("wall result not recorded by verify");
|
|
15097
|
-
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(
|
|
15104
|
+
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(join64(ctx.repoDir, ".loki"), liveArchivedCosts(join64(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
|
|
15098
15105
|
if (routeBlock)
|
|
15099
15106
|
for (const l of routeNotProven(routeBlock))
|
|
15100
15107
|
notProven.add(l);
|
|
@@ -15158,13 +15165,13 @@ var init_seal = __esm(() => {
|
|
|
15158
15165
|
}
|
|
15159
15166
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
15160
15167
|
mkdirSync28(ctx.runDir, { recursive: true });
|
|
15161
|
-
const path =
|
|
15168
|
+
const path = join64(ctx.runDir, "receipt.json");
|
|
15162
15169
|
writeFileSync31(path, JSON.stringify(receipt, null, 2) + `
|
|
15163
15170
|
`);
|
|
15164
|
-
writeFileSync31(
|
|
15171
|
+
writeFileSync31(join64(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
15165
15172
|
recordRun(process.env, ctx.repoDir, ranModel(o.implement, ctx.model, o.fix), verdict, cost.usd, cost.unmetered === true, totalS);
|
|
15166
15173
|
try {
|
|
15167
|
-
hooks.sealed?.(ctx.runDir, receipt);
|
|
15174
|
+
hooks.sealed?.(ctx.runDir, JSON.parse(JSON.stringify(receipt), (_k, v) => v && typeof v === "object" ? Object.freeze(v) : v));
|
|
15168
15175
|
} catch (e) {
|
|
15169
15176
|
process.stderr.write(`ai-bom skipped: ${e.message}
|
|
15170
15177
|
`);
|
|
@@ -15274,13 +15281,13 @@ var init_receipt_dsse = () => {};
|
|
|
15274
15281
|
|
|
15275
15282
|
// ../../loki-ts/src/util/composite_seal.ts
|
|
15276
15283
|
import { existsSync as existsSync43, readFileSync as readFileSync52 } from "fs";
|
|
15277
|
-
import { basename as basename23, dirname as dirname29, join as
|
|
15284
|
+
import { basename as basename23, dirname as dirname29, join as join65 } from "path";
|
|
15278
15285
|
function logProblem(runDir, integ) {
|
|
15279
15286
|
if (typeof integ["log_sha256"] !== "string")
|
|
15280
15287
|
return null;
|
|
15281
15288
|
let b;
|
|
15282
15289
|
try {
|
|
15283
|
-
b = readFileSync52(
|
|
15290
|
+
b = readFileSync52(join65(runDir, "integration.log"));
|
|
15284
15291
|
} catch {
|
|
15285
15292
|
return "integration.log is missing but integration.json records its hash";
|
|
15286
15293
|
}
|
|
@@ -15303,13 +15310,13 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
15303
15310
|
return bad("body malformed");
|
|
15304
15311
|
let ibytes;
|
|
15305
15312
|
try {
|
|
15306
|
-
ibytes = readFileSync52(
|
|
15313
|
+
ibytes = readFileSync52(join65(runDir, "integration.json"));
|
|
15307
15314
|
} catch {
|
|
15308
15315
|
return bad("integration.json missing");
|
|
15309
15316
|
}
|
|
15310
15317
|
if (sha3(ibytes) !== receipt["integration_sha256"])
|
|
15311
15318
|
return bad("integration.json does not match its recorded hash");
|
|
15312
|
-
const integ = readJson5(
|
|
15319
|
+
const integ = readJson5(join65(runDir, "integration.json"));
|
|
15313
15320
|
if (!isObj10(integ) || !isObj10(integ["outcomes"]))
|
|
15314
15321
|
return bad("integration.json has no outcomes");
|
|
15315
15322
|
const iprob = integrationProblem(integ);
|
|
@@ -15339,7 +15346,7 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
15339
15346
|
return bad(`child ${text2(repo, 80) || "?"} has an invalid receipt path`);
|
|
15340
15347
|
if (outcomes[repo] !== "ok")
|
|
15341
15348
|
return bad(`child ${text2(repo, 80)} did not finish ok in integration.json`);
|
|
15342
|
-
const rp =
|
|
15349
|
+
const rp = join65(runDir, rel);
|
|
15343
15350
|
let bytes;
|
|
15344
15351
|
try {
|
|
15345
15352
|
bytes = readFileSync52(rp);
|
|
@@ -15392,7 +15399,7 @@ var init_keys_cmd = __esm(() => {
|
|
|
15392
15399
|
|
|
15393
15400
|
// ../../loki-ts/src/engine10/verify_cmd.ts
|
|
15394
15401
|
import { existsSync as existsSync44, readFileSync as readFileSync53, renameSync as renameSync13, statSync as statSync22, writeFileSync as writeFileSync32 } from "fs";
|
|
15395
|
-
import { basename as basename24, dirname as dirname30, join as
|
|
15402
|
+
import { basename as basename24, dirname as dirname30, join as join66 } from "path";
|
|
15396
15403
|
import { createHash as createHash19, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
|
|
15397
15404
|
function pubFor(kid, given) {
|
|
15398
15405
|
if (given)
|
|
@@ -15444,7 +15451,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
15444
15451
|
const claims = st !== null && typeof st === "object" && Object.keys(st).length > 0;
|
|
15445
15452
|
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;
|
|
15446
15453
|
}
|
|
15447
|
-
const path =
|
|
15454
|
+
const path = join66(dirname30(receiptPath), "events.jsonl");
|
|
15448
15455
|
if (!existsSync44(path))
|
|
15449
15456
|
return "events.jsonl is missing";
|
|
15450
15457
|
const raw2 = readFileSync53(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
|
|
@@ -15463,7 +15470,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
15463
15470
|
return h.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
|
|
15464
15471
|
}
|
|
15465
15472
|
function checkLogSeal(receiptPath, hash, kid, given) {
|
|
15466
|
-
const path =
|
|
15473
|
+
const path = join66(dirname30(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
|
|
15467
15474
|
if (!events2.some((e) => e.type === "receipt.sealed" && e.data["receipt_sha256"] === hash))
|
|
15468
15475
|
return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
|
|
15469
15476
|
if (done < 0)
|
|
@@ -15574,7 +15581,7 @@ var init_verify_cmd = __esm(() => {
|
|
|
15574
15581
|
|
|
15575
15582
|
// src/server/app.ts
|
|
15576
15583
|
import { existsSync as existsSync46, readFileSync as readFileSync56, statSync as statSync23 } from "fs";
|
|
15577
|
-
import { join as
|
|
15584
|
+
import { join as join69, resolve as resolve15, sep as sep13 } from "path";
|
|
15578
15585
|
|
|
15579
15586
|
// node_modules/hono/dist/request/constants.js
|
|
15580
15587
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -25858,7 +25865,7 @@ function mount20(ctx) {
|
|
|
25858
25865
|
// src/server/routes/verify.ts
|
|
25859
25866
|
import { readFileSync as readFileSync54, realpathSync as realpathSync21 } from "fs";
|
|
25860
25867
|
import { createPublicKey as createPublicKey5 } from "crypto";
|
|
25861
|
-
import { join as
|
|
25868
|
+
import { join as join67, sep as sep12 } from "path";
|
|
25862
25869
|
init_verify_cmd();
|
|
25863
25870
|
init_seal();
|
|
25864
25871
|
init_receipt_dsse();
|
|
@@ -25885,15 +25892,15 @@ function mount21(ctx) {
|
|
|
25885
25892
|
return done(404, "receipt not available", "not_found");
|
|
25886
25893
|
let runDir, file;
|
|
25887
25894
|
try {
|
|
25888
|
-
const root = realpathSync21(
|
|
25889
|
-
runDir = realpathSync21(
|
|
25890
|
-
if (runDir !==
|
|
25895
|
+
const root = realpathSync21(join67(repo.p, ".loki", "runs"));
|
|
25896
|
+
runDir = realpathSync21(join67(root, run2));
|
|
25897
|
+
if (runDir !== join67(root, run2))
|
|
25891
25898
|
return done(404, "receipt not found", "not_found");
|
|
25892
|
-
file = realpathSync21(
|
|
25899
|
+
file = realpathSync21(join67(runDir, "receipt.json"));
|
|
25893
25900
|
} catch {
|
|
25894
25901
|
return done(404, "receipt not found", "not_found");
|
|
25895
25902
|
}
|
|
25896
|
-
if (!file.startsWith(runDir +
|
|
25903
|
+
if (!file.startsWith(runDir + sep12))
|
|
25897
25904
|
return done(404, "receipt not found", "not_found");
|
|
25898
25905
|
let integrity, reasons, sha4 = null, outcome = "UNREADABLE";
|
|
25899
25906
|
try {
|
|
@@ -25971,7 +25978,7 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
|
|
|
25971
25978
|
|
|
25972
25979
|
// src/server/legacy/shim.ts
|
|
25973
25980
|
import { existsSync as existsSync45, readFileSync as readFileSync55 } from "fs";
|
|
25974
|
-
import { join as
|
|
25981
|
+
import { join as join68 } from "path";
|
|
25975
25982
|
|
|
25976
25983
|
// src/server/legacy/routes.ts
|
|
25977
25984
|
var LEGACY_ROUTES = [
|
|
@@ -26349,7 +26356,7 @@ var logged = new Set;
|
|
|
26349
26356
|
var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
|
|
26350
26357
|
var NOT_SUPPORTED = "not yet supported by the Control Plane";
|
|
26351
26358
|
var repoVersion = () => {
|
|
26352
|
-
for (const f of [
|
|
26359
|
+
for (const f of [join68(import.meta.dir, "../../../../../VERSION")]) {
|
|
26353
26360
|
try {
|
|
26354
26361
|
if (existsSync45(f))
|
|
26355
26362
|
return readFileSync55(f, "utf8").trim();
|
|
@@ -26534,7 +26541,7 @@ function legacyShim(opts) {
|
|
|
26534
26541
|
|
|
26535
26542
|
// src/server/app.ts
|
|
26536
26543
|
var MAX_BODY2 = 1e6;
|
|
26537
|
-
var defaultUiDir = () => [
|
|
26544
|
+
var defaultUiDir = () => [join69(import.meta.dir, "../../ui/dist"), join69(import.meta.dir, "../ui/dist")].find((d) => existsSync46(join69(d, "index.html")));
|
|
26538
26545
|
function createApp(opts) {
|
|
26539
26546
|
const uiDir = opts.uiDir ?? defaultUiDir();
|
|
26540
26547
|
const { db, sqlite } = openDb(opts.dbPath);
|
|
@@ -26563,7 +26570,7 @@ function createApp(opts) {
|
|
|
26563
26570
|
await next();
|
|
26564
26571
|
});
|
|
26565
26572
|
const readInstalled = () => {
|
|
26566
|
-
for (const f of [process.env.LOKI_VERSION_FILE,
|
|
26573
|
+
for (const f of [process.env.LOKI_VERSION_FILE, join69(import.meta.dir, "../../../../VERSION")]) {
|
|
26567
26574
|
try {
|
|
26568
26575
|
if (f)
|
|
26569
26576
|
return readFileSync56(f, "utf8").trim() || "unknown";
|
|
@@ -26677,11 +26684,11 @@ function createApp(opts) {
|
|
|
26677
26684
|
return c.json({ error: "not found" }, 404);
|
|
26678
26685
|
const root = resolve15(uiDir);
|
|
26679
26686
|
const f = resolve15(root, `.${p}`);
|
|
26680
|
-
if (f.startsWith(root +
|
|
26687
|
+
if (f.startsWith(root + sep13) && existsSync46(f) && statSync23(f).isFile())
|
|
26681
26688
|
return new Response(Bun.file(f));
|
|
26682
26689
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
26683
26690
|
return c.json({ error: "not found" }, 404);
|
|
26684
|
-
return new Response(Bun.file(
|
|
26691
|
+
return new Response(Bun.file(join69(root, "index.html")));
|
|
26685
26692
|
});
|
|
26686
26693
|
return { app, db, close: () => {
|
|
26687
26694
|
clearInterval(reconciler);
|