loki-mode 11.5.1 → 11.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +12 -201
- package/autonomy/notification-checker.py +1 -1
- package/dashboard/__init__.py +3 -10
- package/dashboard/control.py +5 -435
- package/docs/ARCHITECTURE.md +1 -2
- package/docs/CLI-CORE-VERBS.md +2 -6
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/COMPONENTS.md +0 -2
- package/docs/INSTALLATION.md +1 -1
- package/docs/authentication.md +19 -1
- package/docs/dev/release-checklist.md +9 -8
- package/docs/enterprise/security.md +3 -234
- package/docs/v10/ARCHITECT-CUTS.md +304 -0
- package/docs/v10/DECISIONS.md +5 -5
- package/docs/v10/ENGINE.md +735 -299
- package/docs/v10/GUARDS.md +16 -14
- package/docs/v10/GUIDE.md +5 -7
- package/docs/v10/PROGRESS.md +12 -1
- package/docs/v11/MARKET-SLICES.md +1 -5
- package/integrations/openclaw/README.md +20 -0
- package/integrations/vibe-kanban.md +12 -50
- package/loki-ts/dist/loki.js +1183 -1182
- package/mcp/__init__.py +1 -1
- package/mcp/_sdk_loader.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +630 -613
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/references/quality-control.md +1 -116
- package/skills/00-index.md +2 -2
- package/skills/artifacts.md +0 -22
- package/skills/production.md +2 -38
- package/web-app/dist/assets/{AdminPage-Cbu3pXL8.js → AdminPage-DhXdJNQk.js} +1 -1
- package/web-app/dist/assets/{Avatar-DGqGGcGx.js → Avatar-ixVj76fM.js} +1 -1
- package/web-app/dist/assets/{Badge-Bhlipt6v.js → Badge-BGMSp22s.js} +1 -1
- package/web-app/dist/assets/{Button-CpN2sO61.js → Button-pYJc32tG.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BqeDJwdL.js → CockpitPage-C1JBBouA.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DUieA2ba.js → ComparePage-qD0NV4RK.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DTWsYrOm.js → ErrorBoundary-C-yxO58j.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-BU_B9X19.js → EvidenceReceiptPanel-ByPzuE1S.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DEZoLOsP.js → GitHubIssuesPanel-BNv_2BEJ.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-BEsnrq7Y.js → GitHubPRsPanel-CuLZQ9CS.js} +1 -1
- package/web-app/dist/assets/{HomePage-BoUVuq7h.js → HomePage-CS_FW8Je.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CmOED7vb.js → LoginPage-DwiNf1Wm.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DATZitrZ.js → MagicPage-CmQybLPZ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DGL1v0I-.js → MetricsPage-D9ERdpv8.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-C2WgOjZd.js → NotFoundPage-D9ccgdbF.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BMi1tepj.js → ProjectPage-B9Jslmgv.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-vc3y5YPh.js → ProjectsPage-DnU99Go2.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-kbq0Ftvi.js → SettingsPage-DcTyx6wo.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Bn6Q8Kbg.js → ShowcasePage-jEY9ghSr.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Basmhs_b.js → SystemSettingsPage-CSGltW-8.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-BTqOc4TR.js → TeamsPage-gUuJXb9l.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-2P9002VL.js → TemplatesPage-37Zhe--v.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-CAoSPBrg.js → TerminalOutput-B09hRwaR.js} +1 -1
- package/web-app/dist/assets/{activity-BcWVWCqU.js → activity-q_4MY9J0.js} +1 -1
- package/web-app/dist/assets/{bell-CYRqqgZ6.js → bell-X8OC_PFP.js} +1 -1
- package/web-app/dist/assets/{bot-CU7gdn3g.js → bot-C-N1PUOD.js} +1 -1
- package/web-app/dist/assets/{check-DLlCpz9V.js → check-B2c76Jmp.js} +1 -1
- package/web-app/dist/assets/{chevron-left-CE9Cb30C.js → chevron-left-BF76YLNw.js} +1 -1
- package/web-app/dist/assets/{circle-alert-uou4bjua.js → circle-alert-AeFKBD8h.js} +1 -1
- package/web-app/dist/assets/{clock-C_dSJcDX.js → clock-CiXRf-FH.js} +1 -1
- package/web-app/dist/assets/{cloud-DZ22ITF6.js → cloud-DKQ8SRJ5.js} +1 -1
- package/web-app/dist/assets/{code-xml-BrJS0hhS.js → code-xml-DEb6jXWP.js} +1 -1
- package/web-app/dist/assets/{database-D2HOmxtl.js → database-6W7e-E9c.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-CQ1vK_6q.js → dollar-sign-Ds2GOuyW.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-w2vpGm5d.js → file-code-corner-CZU0jg52.js} +1 -1
- package/web-app/dist/assets/{file-plus-DlF6wjkD.js → file-plus-DTVYnXCN.js} +1 -1
- package/web-app/dist/assets/{globe-Dy3lBJg1.js → globe-0mUzKYDe.js} +1 -1
- package/web-app/dist/assets/{hammer-C3xIiRXN.js → hammer-BMHZg3YX.js} +1 -1
- package/web-app/dist/assets/{index-4t-_IW2y.js → index-BvOTvjax.js} +3 -3
- package/web-app/dist/assets/{layers-Y8Fs8qXI.js → layers-Df7TdcWB.js} +1 -1
- package/web-app/dist/assets/{loader-circle-CxgN1v4m.js → loader-circle-kPsVfrSY.js} +1 -1
- package/web-app/dist/assets/{lock-DFFNbXDs.js → lock-CXYcbEc5.js} +1 -1
- package/web-app/dist/assets/{package-5e6qCTUg.js → package-Cqhua1ID.js} +1 -1
- package/web-app/dist/assets/{plus-C0Go_ytj.js → plus-lseXhsn-.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-D4i-NW3o.js → refresh-cw-OZriI6gD.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-YlKkiUW6.js → rotate-ccw-CKCfjPg8.js} +1 -1
- package/web-app/dist/assets/{scroll-text-4qXOHTap.js → scroll-text-DoVyyfKb.js} +1 -1
- package/web-app/dist/assets/{server-BB6zXNp9.js → server-DGy7TflW.js} +1 -1
- package/web-app/dist/assets/{shield-alert-D4tzjB1H.js → shield-alert-BCzRcMXi.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-DZiRwdFj.js → thumbs-up-C_znJd5g.js} +1 -1
- package/web-app/dist/assets/{trash-2-Dv_LkRIK.js → trash-2-BosCbeeA.js} +1 -1
- package/web-app/dist/assets/{trending-down-BJYp9PQe.js → trending-down-CkR5zDkV.js} +1 -1
- package/web-app/dist/assets/{trending-up-BTcXLklK.js → trending-up-DpUIfOH4.js} +1 -1
- package/web-app/dist/assets/{upload-fcHqwOxr.js → upload-CH9aKc8L.js} +1 -1
- package/web-app/dist/assets/{usePolling-BeJYw_4L.js → usePolling-pzxrHJeg.js} +1 -1
- package/web-app/dist/assets/{user-BcDwUCsO.js → user-B7OHa-VQ.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/dashboard/run.py +0 -63
- package/docs/openclaw-integration.md +0 -52
- package/docs/v10/HANDOFF-NEXT-WEEK.md +0 -40
- package/docs/v10/MORNING-BRIEF-1003.md +0 -25
- package/docs/v10/MORNING-BRIEF.md +0 -52
- package/docs/v10/TODO.md +0 -35
- package/mcp/resources.py +0 -351
- package/mcp/tools.py +0 -200
|
@@ -7325,6 +7325,25 @@ var init_paths = __esm(() => {
|
|
|
7325
7325
|
REPO_ROOT = findRepoRoot();
|
|
7326
7326
|
});
|
|
7327
7327
|
|
|
7328
|
+
// ../../loki-ts/src/engine10/registry.ts
|
|
7329
|
+
var init_registry = () => {};
|
|
7330
|
+
|
|
7331
|
+
// ../../loki-ts/src/engine10/output.ts
|
|
7332
|
+
var init_output = __esm(() => {
|
|
7333
|
+
init_registry();
|
|
7334
|
+
init_redact();
|
|
7335
|
+
});
|
|
7336
|
+
|
|
7337
|
+
// ../../loki-ts/src/commands/run_status.ts
|
|
7338
|
+
var STALE_S, TERMINAL2;
|
|
7339
|
+
var init_run_status = __esm(() => {
|
|
7340
|
+
init_discover();
|
|
7341
|
+
init_events();
|
|
7342
|
+
init_output();
|
|
7343
|
+
STALE_S = 30 * 60;
|
|
7344
|
+
TERMINAL2 = new Set(["stage.completed", "stage.failed", "stage.skipped"]);
|
|
7345
|
+
});
|
|
7346
|
+
|
|
7328
7347
|
// ../../loki-ts/src/engine10/types.ts
|
|
7329
7348
|
function pushArgv(a) {
|
|
7330
7349
|
switch (a.cmd) {
|
|
@@ -7372,243 +7391,6 @@ var init_spec_file = __esm(() => {
|
|
|
7372
7391
|
SPEC_DIR = join26(".loki", "specs");
|
|
7373
7392
|
});
|
|
7374
7393
|
|
|
7375
|
-
// ../../loki-ts/src/engine10/registry.ts
|
|
7376
|
-
var init_registry = () => {};
|
|
7377
|
-
|
|
7378
|
-
// ../../loki-ts/src/engine10/output.ts
|
|
7379
|
-
var init_output = __esm(() => {
|
|
7380
|
-
init_registry();
|
|
7381
|
-
init_redact();
|
|
7382
|
-
});
|
|
7383
|
-
|
|
7384
|
-
// ../../loki-ts/src/runner/router/flag.ts
|
|
7385
|
-
function routerMode(env = process.env) {
|
|
7386
|
-
const v = (env.LOKI_ROUTER ?? "").trim().toLowerCase();
|
|
7387
|
-
if (v === "0" || v === "false" || v === "off")
|
|
7388
|
-
return "opt-out";
|
|
7389
|
-
if (v === "1" || v === "true" || v === "on")
|
|
7390
|
-
return "on";
|
|
7391
|
-
return "off";
|
|
7392
|
-
}
|
|
7393
|
-
var routerEnabled = (env = process.env) => routerMode(env) === "on";
|
|
7394
|
-
|
|
7395
|
-
// ../../loki-ts/src/runner/router/route_block.ts
|
|
7396
|
-
function advisorUnavailableReason(env, provider) {
|
|
7397
|
-
if (provider !== "claude")
|
|
7398
|
-
return `provider ${provider} has no advisor tool`;
|
|
7399
|
-
if (env["CLAUDE_CODE_USE_BEDROCK"] || env["CLAUDE_CODE_USE_VERTEX"] || env["CLAUDE_CODE_USE_FOUNDRY"])
|
|
7400
|
-
return "advisor tool is unsupported on Bedrock, Vertex and Foundry";
|
|
7401
|
-
if ((env["LOKI_ROUTER_ADVISOR"] ?? "").trim().toLowerCase() === "off")
|
|
7402
|
-
return "LOKI_ROUTER_ADVISOR=off";
|
|
7403
|
-
return null;
|
|
7404
|
-
}
|
|
7405
|
-
function toEsc(raw2) {
|
|
7406
|
-
const esc = Array.isArray(raw2) ? raw2 : [];
|
|
7407
|
-
return esc.map((e) => ({ trigger: s0(e["trigger"]) ?? "unknown", from: modelLabel(s0(e["from"]) ?? "?"), to: modelLabel(s0(e["to"]) ?? "?"), evidence: s0(e["evidence"]) ?? "none recorded" }));
|
|
7408
|
-
}
|
|
7409
|
-
function buildRouteBlock(env, provider, route, telemetry, runModel) {
|
|
7410
|
-
if (!routerEnabled(env))
|
|
7411
|
-
return null;
|
|
7412
|
-
const applied = route?.["applied"] !== false;
|
|
7413
|
-
const executor = s0(route?.["executor"]);
|
|
7414
|
-
const unavailable = s0(route?.["advisor_unavailable_reason"]) ?? advisorUnavailableReason(env, provider);
|
|
7415
|
-
const total = nN(telemetry?.requests_total);
|
|
7416
|
-
const over = nN(telemetry?.requests_over_100k);
|
|
7417
|
-
const shape = s0(route?.["shape_key"]);
|
|
7418
|
-
const escalations = toEsc(route?.["escalations"]);
|
|
7419
|
-
const source = s0(route?.["source"]);
|
|
7420
|
-
const reason = s0(route?.["reason"]) ?? (executor ? "no reason recorded" : "no route recorded by implement");
|
|
7421
|
-
const rawUnits = Array.isArray(route?.["units"]) ? route["units"] : [];
|
|
7422
|
-
const units = rawUnits.length > 0 ? rawUnits.map((u, i) => ({ id: s0(u["id"]) ?? String(i + 1), executor: modelLabel(s0(u["executor"]) ?? "unknown"), applied, assigned_by: assignedBy(s0(u["source"]) ?? source, u["assigned_by"]), reason: s0(u["reason"]) ?? "no reason recorded", escalations: toEsc(u["escalations"]) })) : executor && route?.["routed"] !== false ? [{ id: "run", executor: modelLabel(executor), applied, assigned_by: assignedBy(source, route?.["assigned_by"]), reason, escalations }] : [];
|
|
7423
|
-
return {
|
|
7424
|
-
routed: route?.["routed"] === false ? false : executor !== null || units.length > 0,
|
|
7425
|
-
units,
|
|
7426
|
-
executor: !applied ? `${runModel ? modelLabel(runModel) : "run model"} (per-unit assignment not applied)` : executor ? modelLabel(executor) : units[0]?.executor ?? null,
|
|
7427
|
-
advisor: unavailable ? null : modelLabel(s0(route?.["advisor"]) ?? "opus"),
|
|
7428
|
-
advisor_unavailable_reason: unavailable,
|
|
7429
|
-
reason,
|
|
7430
|
-
source,
|
|
7431
|
-
shape_key: shape,
|
|
7432
|
-
shape_parity: shape ? `NOT PROVEN (no B9 row for shape ${shape})` : "NOT PROVEN (no shape key recorded)",
|
|
7433
|
-
escalations: units.length > 0 ? units.flatMap((u) => u.escalations) : escalations,
|
|
7434
|
-
requests_total: total,
|
|
7435
|
-
requests_over_100k: over,
|
|
7436
|
-
over_100k_share: total !== null && over !== null && total > 0 ? Math.round(over / total * 1e4) / 1e4 : null,
|
|
7437
|
-
advisor_calls: nN(telemetry?.advisor_calls),
|
|
7438
|
-
advisor_input_tokens: nN(telemetry?.advisor_input_tokens),
|
|
7439
|
-
advisor_output_tokens: nN(telemetry?.advisor_output_tokens),
|
|
7440
|
-
plan_model: s0(route?.["plan_model"]),
|
|
7441
|
-
applied,
|
|
7442
|
-
run_model: runModel ?? null,
|
|
7443
|
-
not_proven: Array.isArray(route?.["route_not_proven"]) ? route["route_not_proven"].filter((x) => typeof x === "string") : []
|
|
7444
|
-
};
|
|
7445
|
-
}
|
|
7446
|
-
function routePrLine(r) {
|
|
7447
|
-
if (!r.routed)
|
|
7448
|
-
return `Route: not routed (${r.reason})`;
|
|
7449
|
-
const adv = r.advisor ? `advisor ${r.advisor}` : "advisor unavailable";
|
|
7450
|
-
return `Route: executor ${r.executor}, ${adv}; advisor tokens ${rec(r.advisor_input_tokens)} in / ${rec(r.advisor_output_tokens)} out; over 100K: ${over(r, " requests")}`;
|
|
7451
|
-
}
|
|
7452
|
-
function routeReceiptLines(r) {
|
|
7453
|
-
if (!r.routed)
|
|
7454
|
-
return [`- Route: not routed (${r.reason})`, `- Route shape_parity: ${r.shape_parity}`];
|
|
7455
|
-
return [
|
|
7456
|
-
`- Route: executor ${r.executor}, ${r.advisor ? `advisor ${r.advisor}` : `advisor unavailable: ${r.advisor_unavailable_reason}`}: ${r.reason}`,
|
|
7457
|
-
`- Route shape_key: ${r.shape_key ?? "unknown"} shape_parity: ${r.shape_parity}`,
|
|
7458
|
-
`- Route escalations: ${r.escalations.length === 0 ? "none" : r.escalations.map((e) => `${e.from} -> ${e.to} (${e.trigger}; evidence ${e.evidence})`).join("; ")}`,
|
|
7459
|
-
`- Route advisor: ${rec(r.advisor_calls)} calls, ${rec(r.advisor_input_tokens)} in / ${rec(r.advisor_output_tokens)} out tokens`,
|
|
7460
|
-
...r.units.map((u) => `- Route unit ${u.id}: executor ${u.applied ? u.executor : `not applied (assigned ${u.executor})`}, assigned by ${u.assigned_by}: ${u.reason}; escalation: ${u.escalations.length === 0 ? "none" : u.escalations.map((e) => `${e.from} -> ${e.to} (${e.trigger})`).join(", ")}`),
|
|
7461
|
-
`- Route requests over 100K: ${over(r, "")}`
|
|
7462
|
-
];
|
|
7463
|
-
}
|
|
7464
|
-
function routeNotProven(r) {
|
|
7465
|
-
return [
|
|
7466
|
-
...r.advisor_unavailable_reason ? [`advisor: NOT PROVEN (owner provider): ${r.advisor_unavailable_reason}`] : [],
|
|
7467
|
-
`route.shape_parity: ${r.shape_parity}`,
|
|
7468
|
-
...r.applied ? [] : [`route.executor: NOT PROVEN (owner engine): per-unit executor assignment is not applied (R1-11); every stage ran ${r.run_model ?? "the run model"}`],
|
|
7469
|
-
...r.not_proven
|
|
7470
|
-
];
|
|
7471
|
-
}
|
|
7472
|
-
var ALIAS, modelLabel = (m) => ALIAS[m] ?? m, nN = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, rec = (v) => v === null ? "not recorded" : String(v), s0 = (v) => typeof v === "string" && v.trim() ? v.trim() : null, assignedBy = (src, explicit) => s0(explicit) ?? (src === null || src === "opus" ? "opus" : src), over = (r, unit) => r.requests_total === null || r.requests_over_100k === null ? "not recorded" : `${r.requests_over_100k} of ${r.requests_total}${unit} (${pct(r)})`, pct = (r) => r.over_100k_share === null ? "n/a (no requests)" : `${(r.over_100k_share * 100).toFixed(1)}%`;
|
|
7473
|
-
var init_route_block = __esm(() => {
|
|
7474
|
-
ALIAS = { haiku: "haiku-5.5", sonnet: "sonnet-5.5", opus: "opus-5.5" };
|
|
7475
|
-
});
|
|
7476
|
-
|
|
7477
|
-
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
7478
|
-
import { createHash as createHash6 } from "crypto";
|
|
7479
|
-
import { existsSync as existsSync15, readdirSync as readdirSync9, readFileSync as readFileSync18, statSync as statSync11 } from "fs";
|
|
7480
|
-
import { dirname as dirname7, join as join27 } from "path";
|
|
7481
|
-
function sealGroup(runDir, rh) {
|
|
7482
|
-
const manifestPath = join27(runDir, "group", "manifest.json");
|
|
7483
|
-
if (!existsSync15(manifestPath))
|
|
7484
|
-
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
7485
|
-
const notProven = [];
|
|
7486
|
-
let problems = 0;
|
|
7487
|
-
const fail = (m2) => {
|
|
7488
|
-
problems++;
|
|
7489
|
-
notProven.push(`group: ${m2}`);
|
|
7490
|
-
};
|
|
7491
|
-
const m = readJson3(manifestPath);
|
|
7492
|
-
const list = isObj10(m) && Array.isArray(m["units"]) ? m["units"] : [];
|
|
7493
|
-
if (!isObj10(m) || !ID_RE.test(String(m["group_id"] ?? "")) || list.length === 0) {
|
|
7494
|
-
fail("manifest missing, unreadable or empty");
|
|
7495
|
-
return { section: undefined, notProven, problems, allUnitsPass: false };
|
|
7496
|
-
}
|
|
7497
|
-
const units = [];
|
|
7498
|
-
const seen = new Set, seenLower = new Set;
|
|
7499
|
-
let allUnitsPass = true;
|
|
7500
|
-
list.forEach((raw2, index2) => {
|
|
7501
|
-
const u = isObj10(raw2) ? raw2 : {};
|
|
7502
|
-
const id = String(u["unit_id"] ?? "");
|
|
7503
|
-
if (!ID_RE.test(id) || seen.has(id) || seenLower.has(id.toLowerCase()))
|
|
7504
|
-
return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
7505
|
-
seen.add(id);
|
|
7506
|
-
seenLower.add(id.toLowerCase());
|
|
7507
|
-
const dir = join27(unitsDir(runDir), id), rp = join27(dir, "receipt.json"), ep = join27(dir, "events.jsonl");
|
|
7508
|
-
let bytes;
|
|
7509
|
-
try {
|
|
7510
|
-
bytes = readFileSync18(rp);
|
|
7511
|
-
} catch {
|
|
7512
|
-
return fail(`unit ${id} sub-receipt missing`);
|
|
7513
|
-
}
|
|
7514
|
-
const sub = readJson3(rp);
|
|
7515
|
-
if (!isObj10(sub) || typeof sub["receipt_sha256"] !== "string" || rh(sub) !== sub["receipt_sha256"])
|
|
7516
|
-
return fail(`unit ${id} sub-receipt unreadable or its hash does not recompute`);
|
|
7517
|
-
const verdict = String(sub["verdict"] ?? "");
|
|
7518
|
-
if (!PASSING.has(verdict)) {
|
|
7519
|
-
allUnitsPass = false;
|
|
7520
|
-
notProven.push(`group: unit ${id} verdict ${verdict || "unknown"}`);
|
|
7521
|
-
}
|
|
7522
|
-
units.push({
|
|
7523
|
-
index: index2,
|
|
7524
|
-
unit_id: id,
|
|
7525
|
-
sub_receipt_sha256: sha2(bytes),
|
|
7526
|
-
receipt_sha256: sub["receipt_sha256"],
|
|
7527
|
-
events_file_sha256: existsSync15(ep) ? sha2(readFileSync18(ep)) : null,
|
|
7528
|
-
verdict,
|
|
7529
|
-
goal: text2(u["goal"], 200),
|
|
7530
|
-
files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
|
|
7531
|
-
tests: num3(u["tests"]),
|
|
7532
|
-
tokens: num3(u["tokens"]),
|
|
7533
|
-
model: text2(u["model"], 64)
|
|
7534
|
-
});
|
|
7535
|
-
});
|
|
7536
|
-
const extra = (dirNames(unitsDir(runDir)) ?? []).filter((n2) => !seen.has(n2));
|
|
7537
|
-
for (const n2 of extra)
|
|
7538
|
-
fail(`unit directory ${text2(n2, 64)} is not in the manifest`);
|
|
7539
|
-
return { section: problems === 0 ? { group_id: String(m["group_id"]), units } : undefined, notProven, problems, allUnitsPass: allUnitsPass && problems === 0 };
|
|
7540
|
-
}
|
|
7541
|
-
function capGroupVerdict(v, g) {
|
|
7542
|
-
if (g.problems > 0)
|
|
7543
|
-
return v === "SPEC_CONFLICT" ? v : "FAILED";
|
|
7544
|
-
return !g.allUnitsPass && (v === "VERIFIED" || v === "ALREADY_SATISFIED") ? "PARTIAL" : v;
|
|
7545
|
-
}
|
|
7546
|
-
async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
7547
|
-
const runDir = dirname7(receiptPath);
|
|
7548
|
-
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
7549
|
-
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
7550
|
-
const g = receipt["group"];
|
|
7551
|
-
if (g === undefined)
|
|
7552
|
-
return existsSync15(join27(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
7553
|
-
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
7554
|
-
return bad("group section malformed");
|
|
7555
|
-
const entries = g["units"];
|
|
7556
|
-
const ids = entries.map((e) => isObj10(e) ? String(e["unit_id"] ?? "") : "");
|
|
7557
|
-
if (ids.some((id) => !ID_RE.test(id)) || new Set(ids.map((i) => i.toLowerCase())).size !== ids.length)
|
|
7558
|
-
return bad("unit ids invalid, duplicated or case-colliding");
|
|
7559
|
-
const onDisk = dirNames(unitsDir(runDir));
|
|
7560
|
-
if (onDisk === null || onDisk.join("\x00") !== [...ids].sort().join("\x00"))
|
|
7561
|
-
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
7562
|
-
let unchecked = null;
|
|
7563
|
-
for (let i = 0;i < entries.length; i++) {
|
|
7564
|
-
const e = entries[i], id = ids[i], dir = join27(unitsDir(runDir), id), rp = join27(dir, "receipt.json"), ep = join27(dir, "events.jsonl");
|
|
7565
|
-
if (e["index"] !== i)
|
|
7566
|
-
return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
|
|
7567
|
-
let bytes;
|
|
7568
|
-
try {
|
|
7569
|
-
if (!statSync11(dir).isDirectory())
|
|
7570
|
-
return bad(`unit ${id} is not a directory`);
|
|
7571
|
-
bytes = readFileSync18(rp);
|
|
7572
|
-
} catch {
|
|
7573
|
-
return bad(`unit ${id} sub-receipt missing`);
|
|
7574
|
-
}
|
|
7575
|
-
if (sha2(bytes) !== e["sub_receipt_sha256"])
|
|
7576
|
-
return bad(`unit ${id} sub-receipt does not match its recorded hash`);
|
|
7577
|
-
const evSha = existsSync15(ep) ? sha2(readFileSync18(ep)) : null;
|
|
7578
|
-
if (evSha !== (e["events_file_sha256"] ?? null))
|
|
7579
|
-
return bad(`unit ${id} events.jsonl does not match its recorded hash`);
|
|
7580
|
-
const sub = readJson3(rp);
|
|
7581
|
-
if (!isObj10(sub) || sub["receipt_sha256"] !== e["receipt_sha256"] || rh(sub) !== e["receipt_sha256"])
|
|
7582
|
-
return bad(`unit ${id} sub-receipt hash does not recompute`);
|
|
7583
|
-
if (String(sub["verdict"] ?? "") !== e["verdict"])
|
|
7584
|
-
return bad(`unit ${id} verdict differs from the combined receipt`);
|
|
7585
|
-
const r = await verifyOne(rp, deps);
|
|
7586
|
-
if (r.verdict === "UNSIGNED" && signed)
|
|
7587
|
-
unchecked ??= `unit ${id} sub-receipt is unsigned under a signed combined receipt`;
|
|
7588
|
-
if (r.verdict === "TAMPERED")
|
|
7589
|
-
return bad(`unit ${id} sub-receipt failed verify: ${r.reasons.join("; ")}`);
|
|
7590
|
-
if (r.verdict === "UNCHECKED")
|
|
7591
|
-
unchecked ??= `unit ${id} sub-receipt not checked: ${r.reasons.join("; ")}`;
|
|
7592
|
-
}
|
|
7593
|
-
return unchecked ? { verdict: "UNCHECKED", reason: `group: ${unchecked}` } : null;
|
|
7594
|
-
}
|
|
7595
|
-
var ID_RE, PASSING, sha2 = (b) => createHash6("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) : "", num3 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join27(runDir, "group", "units"), readJson3 = (p) => {
|
|
7596
|
-
try {
|
|
7597
|
-
return JSON.parse(readFileSync18(p, "utf8"));
|
|
7598
|
-
} catch {
|
|
7599
|
-
return;
|
|
7600
|
-
}
|
|
7601
|
-
}, dirNames = (d) => {
|
|
7602
|
-
try {
|
|
7603
|
-
return readdirSync9(d).filter((n2) => !n2.startsWith(".")).sort();
|
|
7604
|
-
} catch {
|
|
7605
|
-
return null;
|
|
7606
|
-
}
|
|
7607
|
-
};
|
|
7608
|
-
var init_seal_group = __esm(() => {
|
|
7609
|
-
ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
7610
|
-
PASSING = new Set(["VERIFIED", "ALREADY_SATISFIED"]);
|
|
7611
|
-
});
|
|
7612
7394
|
// ../../loki-ts/src/engine10/pr_body.ts
|
|
7613
7395
|
function aiTrailers(i, env = process.env) {
|
|
7614
7396
|
if (!markingOn(env))
|
|
@@ -7616,16 +7398,11 @@ function aiTrailers(i, env = process.env) {
|
|
|
7616
7398
|
return ["AI-Generated: true", `AI-Provider: ${clean(i.provider)}`, `AI-Model: ${clean(i.model)}`, `Loki-Receipt: ${clean(i.receiptRel)}`];
|
|
7617
7399
|
}
|
|
7618
7400
|
var markingOn = (env) => env["LOKI_AI_MARKING"] === "1", clean = (v) => v.replace(/[\u0000-\u001f\u007f\u2028\u2029]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 100) || "unknown";
|
|
7619
|
-
var init_pr_body = __esm(() => {
|
|
7620
|
-
init_output();
|
|
7621
|
-
init_route_block();
|
|
7622
|
-
init_seal_group();
|
|
7623
|
-
});
|
|
7624
7401
|
|
|
7625
7402
|
// ../../loki-ts/src/util/credential_env.ts
|
|
7626
|
-
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, statSync as
|
|
7403
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, statSync as statSync11, lstatSync as lstatSync4 } from "fs";
|
|
7627
7404
|
import { tmpdir as tmpdir3 } from "os";
|
|
7628
|
-
import { join as
|
|
7405
|
+
import { join as join27 } from "path";
|
|
7629
7406
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
7630
7407
|
function withheldSentinel(fresh = false) {
|
|
7631
7408
|
if (fresh)
|
|
@@ -7644,7 +7421,7 @@ function emptyGhConfigDir(env = process.env) {
|
|
|
7644
7421
|
const runTmp = env["LOKI_RUN_TMP"] ?? "";
|
|
7645
7422
|
const root = runTmp !== "" && isDir(runTmp) ? runTmp : tmpdir3();
|
|
7646
7423
|
try {
|
|
7647
|
-
configDir = mkdtempSync2(
|
|
7424
|
+
configDir = mkdtempSync2(join27(root, "loki-gh-config-"));
|
|
7648
7425
|
} catch {
|
|
7649
7426
|
return null;
|
|
7650
7427
|
}
|
|
@@ -7685,7 +7462,7 @@ function hardenCredentialEnv(env, fresh = false) {
|
|
|
7685
7462
|
}
|
|
7686
7463
|
var GITHUB_TOKEN_VARS, SENTINEL_PREFIX = "ghp_LOKIWITHHELDsentinel", sentinel = null, configDir = null, exitHooked = false, sigtermHooked = false, isDir = (p) => {
|
|
7687
7464
|
try {
|
|
7688
|
-
return !lstatSync4(p).isSymbolicLink() &&
|
|
7465
|
+
return !lstatSync4(p).isSymbolicLink() && statSync11(p).isDirectory();
|
|
7689
7466
|
} catch {
|
|
7690
7467
|
return false;
|
|
7691
7468
|
}
|
|
@@ -7799,17 +7576,21 @@ var init_safe_git = __esm(() => {
|
|
|
7799
7576
|
OPT_WITH_VALUE = new Set(["-C", "-c", "--git-dir", "--work-tree", "--namespace", "--exec-path", "--config-env", "--attr-source"]);
|
|
7800
7577
|
SECRET_VARS = ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "SSH_AUTH_SOCK"];
|
|
7801
7578
|
});
|
|
7579
|
+
// ../../loki-ts/src/util/yaml_key.ts
|
|
7580
|
+
var init_yaml_key = () => {};
|
|
7581
|
+
|
|
7802
7582
|
// ../../loki-ts/src/util/run_cap.ts
|
|
7803
7583
|
var MAX_SCOPE_BYTES;
|
|
7804
7584
|
var init_run_cap = __esm(() => {
|
|
7805
7585
|
init_types();
|
|
7586
|
+
init_yaml_key();
|
|
7806
7587
|
MAX_SCOPE_BYTES = 256 * 1024;
|
|
7807
7588
|
});
|
|
7808
7589
|
|
|
7809
7590
|
// ../../loki-ts/src/util/mutation_proof.ts
|
|
7810
|
-
import { existsSync as
|
|
7591
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync3, readFileSync as readFileSync18, rmSync as rmSync5, symlinkSync, writeFileSync as writeFileSync8 } from "fs";
|
|
7811
7592
|
import { tmpdir as tmpdir4 } from "os";
|
|
7812
|
-
import { basename as basename8, dirname as
|
|
7593
|
+
import { basename as basename8, dirname as dirname7, isAbsolute as isAbsolute2, join as join28, relative as relative2 } from "path";
|
|
7813
7594
|
function mutationProof(i) {
|
|
7814
7595
|
const rels = i.wallFiles.map((f) => isAbsolute2(f.path) ? relative2(i.repoDir, f.path) : f.path);
|
|
7815
7596
|
if (rels.length === 0)
|
|
@@ -7827,26 +7608,26 @@ function mutationProof(i) {
|
|
|
7827
7608
|
const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
|
|
7828
7609
|
let parent = null, wt = null, added = false;
|
|
7829
7610
|
try {
|
|
7830
|
-
parent = mkdtempSync3(
|
|
7831
|
-
wt =
|
|
7611
|
+
parent = mkdtempSync3(join28(tmpdir4(), "loki-mutproof-"));
|
|
7612
|
+
wt = join28(parent, "wt");
|
|
7832
7613
|
const add2 = git(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
|
|
7833
|
-
added =
|
|
7614
|
+
added = existsSync15(wt) || add2.status === 0;
|
|
7834
7615
|
if (add2.status !== 0)
|
|
7835
7616
|
return np("could not create the base worktree");
|
|
7836
7617
|
for (const rel of rels) {
|
|
7837
|
-
const sealed =
|
|
7838
|
-
if (!
|
|
7618
|
+
const sealed = join28(i.runDir, "wall", basename8(rel)), src = existsSync15(sealed) ? sealed : join28(i.repoDir, rel);
|
|
7619
|
+
if (!existsSync15(src))
|
|
7839
7620
|
return np(`Wall file missing: ${rel}`);
|
|
7840
|
-
mkdirSync5(
|
|
7841
|
-
writeFileSync8(
|
|
7621
|
+
mkdirSync5(dirname7(join28(wt, rel)), { recursive: true });
|
|
7622
|
+
writeFileSync8(join28(wt, rel), readFileSync18(src));
|
|
7842
7623
|
}
|
|
7843
7624
|
for (const rel of rels) {
|
|
7844
7625
|
const parts = rel.split("/").slice(0, -1);
|
|
7845
7626
|
for (let n2 = 0;n2 <= parts.length; n2++) {
|
|
7846
7627
|
const anc = parts.slice(0, n2).join("/");
|
|
7847
7628
|
for (const d of DEP_DIRS) {
|
|
7848
|
-
const src =
|
|
7849
|
-
if (
|
|
7629
|
+
const src = join28(i.repoDir, anc, d), dst = join28(wt, anc, d);
|
|
7630
|
+
if (existsSync15(src) && !existsSync15(dst)) {
|
|
7850
7631
|
try {
|
|
7851
7632
|
symlinkSync(src, dst);
|
|
7852
7633
|
} catch {}
|
|
@@ -7904,7 +7685,7 @@ var init_lean_prefix = __esm(() => {
|
|
|
7904
7685
|
|
|
7905
7686
|
// ../../loki-ts/src/features/wall_manifest.ts
|
|
7906
7687
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7907
|
-
import { accessSync, constants, statSync as
|
|
7688
|
+
import { accessSync, constants, statSync as statSync12 } from "fs";
|
|
7908
7689
|
import { tmpdir as tmpdir5 } from "os";
|
|
7909
7690
|
function templateEnd(s, i) {
|
|
7910
7691
|
for (let j = i + 1;j < s.length; ) {
|
|
@@ -8638,7 +8419,7 @@ function resolvePython3() {
|
|
|
8638
8419
|
const cand = `${dir}/python3`;
|
|
8639
8420
|
try {
|
|
8640
8421
|
accessSync(cand, constants.X_OK);
|
|
8641
|
-
if (
|
|
8422
|
+
if (statSync12(cand).isFile())
|
|
8642
8423
|
return cand;
|
|
8643
8424
|
} catch {}
|
|
8644
8425
|
}
|
|
@@ -8961,8 +8742,8 @@ var init_wall_manifest = __esm(() => {
|
|
|
8961
8742
|
});
|
|
8962
8743
|
|
|
8963
8744
|
// ../../loki-ts/src/features/wall_manifest_wire.ts
|
|
8964
|
-
import { createHash as
|
|
8965
|
-
import { basename as basename9, dirname as
|
|
8745
|
+
import { createHash as createHash6 } from "crypto";
|
|
8746
|
+
import { basename as basename9, dirname as dirname8 } from "path";
|
|
8966
8747
|
function blobEntries(ls) {
|
|
8967
8748
|
const out2 = [];
|
|
8968
8749
|
for (const raw2 of ls.toString("latin1").split("\x00")) {
|
|
@@ -8992,7 +8773,7 @@ function wallManifestFor(repoDir, tree, task, env = process.env) {
|
|
|
8992
8773
|
return null;
|
|
8993
8774
|
const low = task.toLowerCase().replace(/\\/g, "/");
|
|
8994
8775
|
const token = (n2) => new RegExp(`(?<![A-Za-z0-9_])${n2.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_])`).test(low);
|
|
8995
|
-
const dirModule = (e) => /^(index|__init__|mod|main)\.[^.]+$/.test(basename9(e.path)) && e.path.includes("/") && token(
|
|
8776
|
+
const dirModule = (e) => /^(index|__init__|mod|main)\.[^.]+$/.test(basename9(e.path)) && e.path.includes("/") && token(dirname8(e.path));
|
|
8996
8777
|
const matched = all.filter((e) => SOURCE.test(e.path) && (token(basename9(e.path)) || token(e.path) || token(basename9(e.path).replace(/\.[^.]*$/, "")) || dirModule(e)));
|
|
8997
8778
|
const spans = (p) => [...low.matchAll(new RegExp(`(?<![A-Za-z0-9_])${p.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_])`, "g"))].map((m) => [m.index, m.index + m[0].length]);
|
|
8998
8779
|
const occ = new Map(matched.map((e) => [e, spans(e.path)]));
|
|
@@ -9020,8 +8801,8 @@ function wallManifestFor(repoDir, tree, task, env = process.env) {
|
|
|
9020
8801
|
}
|
|
9021
8802
|
if (at !== cat.length)
|
|
9022
8803
|
return null;
|
|
9023
|
-
const
|
|
9024
|
-
return { text:
|
|
8804
|
+
const text2 = buildWallManifest([...files, ...listed.map((e) => ({ path: e.path, content: "" }))], named.map((e) => e.path), matched.map((e) => e.path));
|
|
8805
|
+
return { text: text2, sha256: createHash6("sha256").update(text2).digest("hex") };
|
|
9025
8806
|
} catch {
|
|
9026
8807
|
return null;
|
|
9027
8808
|
}
|
|
@@ -9053,12 +8834,12 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
|
|
|
9053
8834
|
});
|
|
9054
8835
|
|
|
9055
8836
|
// ../../loki-ts/src/engine10/cache.ts
|
|
9056
|
-
import { createHash as
|
|
9057
|
-
import { existsSync as
|
|
8837
|
+
import { createHash as createHash7 } from "crypto";
|
|
8838
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync9 } from "fs";
|
|
9058
8839
|
import { resolve as resolve8 } from "path";
|
|
9059
8840
|
function repoKey(originUrl, repoDir) {
|
|
9060
8841
|
const basis = originUrl && originUrl.trim() !== "" ? originUrl : resolve8(repoDir);
|
|
9061
|
-
return
|
|
8842
|
+
return createHash7("sha256").update(basis).digest("hex");
|
|
9062
8843
|
}
|
|
9063
8844
|
function defaultCacheRoot() {
|
|
9064
8845
|
return resolve8(homeLokiDir(), "cache", "v10");
|
|
@@ -9066,11 +8847,11 @@ function defaultCacheRoot() {
|
|
|
9066
8847
|
function repoCacheDir(key, cacheRoot = defaultCacheRoot()) {
|
|
9067
8848
|
return resolve8(cacheRoot, key);
|
|
9068
8849
|
}
|
|
9069
|
-
function
|
|
9070
|
-
if (!
|
|
8850
|
+
function readJson3(path, isValid = (_v) => true) {
|
|
8851
|
+
if (!existsSync16(path))
|
|
9071
8852
|
return null;
|
|
9072
8853
|
try {
|
|
9073
|
-
const parsed = JSON.parse(
|
|
8854
|
+
const parsed = JSON.parse(readFileSync19(path, "utf8"));
|
|
9074
8855
|
return isValid(parsed) ? parsed : null;
|
|
9075
8856
|
} catch {
|
|
9076
8857
|
return null;
|
|
@@ -9080,7 +8861,7 @@ function isRepoMap(v) {
|
|
|
9080
8861
|
return typeof v === "object" && v !== null && Array.isArray(v.files) && Array.isArray(v.entries);
|
|
9081
8862
|
}
|
|
9082
8863
|
function readRepoMapCache(dir, tree) {
|
|
9083
|
-
return
|
|
8864
|
+
return readJson3(resolve8(dir, `repomap-${tree}.json`), isRepoMap);
|
|
9084
8865
|
}
|
|
9085
8866
|
var init_cache = __esm(() => {
|
|
9086
8867
|
init_paths();
|
|
@@ -9105,7 +8886,7 @@ function selectSpecificFiles(task, repoMap, max = MAX_RELEVANT_FILES) {
|
|
|
9105
8886
|
const scored = sets.map((toks, idx) => ({ path: entries[idx].path, score: specific.reduce((n2, w) => n2 + (toks.has(w) ? 1 : 0), 0), idx }));
|
|
9106
8887
|
return scored.filter((s) => s.score > 0).sort((a, b) => b.score - a.score || a.idx - b.idx).slice(0, max).map((s) => s.path);
|
|
9107
8888
|
}
|
|
9108
|
-
var MAX_RELEVANT_FILES = 8, haystack = (entry) => `${entry.path} ${entry.symbols.join(" ")}`.toLowerCase(), wordTokens = (
|
|
8889
|
+
var MAX_RELEVANT_FILES = 8, haystack = (entry) => `${entry.path} ${entry.symbols.join(" ")}`.toLowerCase(), wordTokens = (text2) => text2.toLowerCase().match(/[a-z0-9_]+/g) ?? [];
|
|
9109
8890
|
|
|
9110
8891
|
// ../../loki-ts/src/features/speed/lean_select.ts
|
|
9111
8892
|
function speedLikelyFiles(task, map, env = process.env) {
|
|
@@ -9120,12 +8901,12 @@ function speedLikelyFiles(task, map, env = process.env) {
|
|
|
9120
8901
|
var init_lean_select = () => {};
|
|
9121
8902
|
|
|
9122
8903
|
// ../../loki-ts/src/util/claude_model.ts
|
|
9123
|
-
import { readFileSync as
|
|
8904
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
9124
8905
|
import { resolve as resolve9 } from "path";
|
|
9125
8906
|
function resolveClaudeModel(want) {
|
|
9126
8907
|
try {
|
|
9127
8908
|
const path = process.env["LOKI_MODEL_CATALOG"] || resolve9(REPO_ROOT, "providers/model_catalog.json");
|
|
9128
|
-
return JSON.parse(
|
|
8909
|
+
return JSON.parse(readFileSync20(path, "utf8")).providers?.claude?.cli_aliases?.[want] ?? want;
|
|
9129
8910
|
} catch {
|
|
9130
8911
|
return want;
|
|
9131
8912
|
}
|
|
@@ -9173,17 +8954,28 @@ var init_hooks = __esm(() => {
|
|
|
9173
8954
|
hooks = {};
|
|
9174
8955
|
});
|
|
9175
8956
|
|
|
8957
|
+
// ../../loki-ts/src/runner/router/flag.ts
|
|
8958
|
+
function routerMode(env = process.env) {
|
|
8959
|
+
const v = (env.LOKI_ROUTER ?? "").trim().toLowerCase();
|
|
8960
|
+
if (v === "0" || v === "false" || v === "off")
|
|
8961
|
+
return "opt-out";
|
|
8962
|
+
if (v === "1" || v === "true" || v === "on")
|
|
8963
|
+
return "on";
|
|
8964
|
+
return "off";
|
|
8965
|
+
}
|
|
8966
|
+
var routerEnabled = (env = process.env) => routerMode(env) === "on";
|
|
8967
|
+
|
|
9176
8968
|
// ../../loki-ts/src/engine10/cost.ts
|
|
9177
|
-
import { mkdirSync as mkdirSync7, readdirSync as
|
|
9178
|
-
import { join as
|
|
8969
|
+
import { mkdirSync as mkdirSync7, readdirSync as readdirSync9, readFileSync as readFileSync21, writeFileSync as writeFileSync10 } from "fs";
|
|
8970
|
+
import { join as join29 } from "path";
|
|
9179
8971
|
function routerTelemetryOn(env = process.env) {
|
|
9180
8972
|
return routerEnabled(env);
|
|
9181
8973
|
}
|
|
9182
|
-
function
|
|
8974
|
+
function num3(v) {
|
|
9183
8975
|
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
9184
8976
|
}
|
|
9185
8977
|
function resultCostPath(lokiRoot, iteration) {
|
|
9186
|
-
return
|
|
8978
|
+
return join29(lokiRoot, "metrics", `result-cost-${iteration}.json`);
|
|
9187
8979
|
}
|
|
9188
8980
|
function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
9189
8981
|
const out2 = {
|
|
@@ -9214,7 +9006,7 @@ function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
|
9214
9006
|
const parsed = new Map;
|
|
9215
9007
|
for (const iter of iterations) {
|
|
9216
9008
|
try {
|
|
9217
|
-
parsed.set(iter, JSON.parse(
|
|
9009
|
+
parsed.set(iter, JSON.parse(readFileSync21(resultCostPath(lokiRoot, iter), "utf8")));
|
|
9218
9010
|
} catch {}
|
|
9219
9011
|
}
|
|
9220
9012
|
const own = new Set(iterations);
|
|
@@ -9223,15 +9015,15 @@ function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
|
9223
9015
|
if (own.has(iter))
|
|
9224
9016
|
continue;
|
|
9225
9017
|
try {
|
|
9226
|
-
lookup.push({ iter, rec: JSON.parse(
|
|
9018
|
+
lookup.push({ iter, rec: JSON.parse(readFileSync21(resultCostPath(lokiRoot, iter), "utf8")) });
|
|
9227
9019
|
} catch {}
|
|
9228
9020
|
}
|
|
9229
9021
|
const verdicts = hooks.costRecords?.resumeVerdicts(lookup) ?? { ambiguous: [], separate: [] };
|
|
9230
9022
|
const rv = { ambiguous: verdicts.ambiguous.filter((i) => own.has(i)), separate: verdicts.separate.filter((i) => own.has(i)) };
|
|
9231
9023
|
for (const iter of iterations) {
|
|
9232
9024
|
const path = resultCostPath(lokiRoot, iter);
|
|
9233
|
-
const
|
|
9234
|
-
if (!
|
|
9025
|
+
const rec = parsed.get(iter);
|
|
9026
|
+
if (!rec) {
|
|
9235
9027
|
out2.missing.push(iter);
|
|
9236
9028
|
continue;
|
|
9237
9029
|
}
|
|
@@ -9241,45 +9033,45 @@ function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
|
9241
9033
|
continue;
|
|
9242
9034
|
}
|
|
9243
9035
|
tokenSessions++;
|
|
9244
|
-
const inTok =
|
|
9245
|
-
const outTok =
|
|
9246
|
-
const cacheR =
|
|
9247
|
-
const cacheC =
|
|
9036
|
+
const inTok = num3(rec["input_tokens"]);
|
|
9037
|
+
const outTok = num3(rec["output_tokens"]);
|
|
9038
|
+
const cacheR = num3(rec["cache_read_tokens"]);
|
|
9039
|
+
const cacheC = num3(rec["cache_creation_tokens"]);
|
|
9248
9040
|
out2.input_tokens += inTok;
|
|
9249
9041
|
out2.output_tokens += outTok;
|
|
9250
9042
|
out2.cache_read_tokens += cacheR;
|
|
9251
9043
|
out2.cache_creation_tokens += cacheC;
|
|
9252
|
-
if (typeof
|
|
9044
|
+
if (typeof rec["cache_read_tokens"] === "number")
|
|
9253
9045
|
readSeen++;
|
|
9254
|
-
if (typeof
|
|
9046
|
+
if (typeof rec["cache_creation_tokens"] === "number")
|
|
9255
9047
|
creationSeen++;
|
|
9256
|
-
if (typeof
|
|
9257
|
-
out2.duration_ms = (out2.duration_ms ?? 0) +
|
|
9048
|
+
if (typeof rec["duration_ms"] === "number" && Number.isFinite(rec["duration_ms"])) {
|
|
9049
|
+
out2.duration_ms = (out2.duration_ms ?? 0) + rec["duration_ms"];
|
|
9258
9050
|
durSeen++;
|
|
9259
9051
|
}
|
|
9260
9052
|
if (out2.router)
|
|
9261
|
-
out2.router["requests_total"] +=
|
|
9053
|
+
out2.router["requests_total"] += num3(rec["requests_total"]);
|
|
9262
9054
|
if (out2.router)
|
|
9263
|
-
out2.router["requests_over_100k"] +=
|
|
9055
|
+
out2.router["requests_over_100k"] += num3(rec["requests_over_100k"]);
|
|
9264
9056
|
if (out2.router)
|
|
9265
|
-
out2.router["over_100k_input_tokens"] +=
|
|
9057
|
+
out2.router["over_100k_input_tokens"] += num3(rec["over_100k_input_tokens"]);
|
|
9266
9058
|
if (out2.router)
|
|
9267
|
-
out2.router["over_100k_output_tokens"] +=
|
|
9059
|
+
out2.router["over_100k_output_tokens"] += num3(rec["over_100k_output_tokens"]);
|
|
9268
9060
|
if (out2.router)
|
|
9269
|
-
out2.router["advisor_calls"] +=
|
|
9061
|
+
out2.router["advisor_calls"] += num3(rec["advisor_calls"]);
|
|
9270
9062
|
if (out2.router)
|
|
9271
|
-
out2.router["advisor_input_tokens"] +=
|
|
9063
|
+
out2.router["advisor_input_tokens"] += num3(rec["advisor_input_tokens"]);
|
|
9272
9064
|
if (out2.router)
|
|
9273
|
-
out2.router["advisor_output_tokens"] +=
|
|
9274
|
-
if (typeof
|
|
9275
|
-
out2.model =
|
|
9065
|
+
out2.router["advisor_output_tokens"] += num3(rec["advisor_output_tokens"]);
|
|
9066
|
+
if (typeof rec["model"] === "string" && rec["model"])
|
|
9067
|
+
out2.model = rec["model"];
|
|
9276
9068
|
sources2.push(path);
|
|
9277
|
-
recs.push({ iter, rec
|
|
9278
|
-
const c =
|
|
9279
|
-
const unmetered =
|
|
9069
|
+
recs.push({ iter, rec });
|
|
9070
|
+
const c = rec["total_cost_usd"];
|
|
9071
|
+
const unmetered = rec["source"] === UNMETERED;
|
|
9280
9072
|
if (unmetered)
|
|
9281
9073
|
out2.unmetered = true;
|
|
9282
|
-
if (
|
|
9074
|
+
if (rec["estimated"] === true)
|
|
9283
9075
|
out2.estimated = true;
|
|
9284
9076
|
const noUsage = !unmetered && inTok === 0 && outTok === 0 && cacheR === 0 && cacheC === 0;
|
|
9285
9077
|
if (typeof c !== "number" || !Number.isFinite(c) || noUsage) {
|
|
@@ -9315,20 +9107,75 @@ function sumResultCosts(lokiRoot, iterations, context = []) {
|
|
|
9315
9107
|
out2.usd = usd;
|
|
9316
9108
|
return out2;
|
|
9317
9109
|
}
|
|
9318
|
-
var UNMETERED = "cli-invoker-unmetered";
|
|
9319
|
-
var init_cost = __esm(() => {
|
|
9320
|
-
init_hooks();
|
|
9110
|
+
var UNMETERED = "cli-invoker-unmetered";
|
|
9111
|
+
var init_cost = __esm(() => {
|
|
9112
|
+
init_hooks();
|
|
9113
|
+
});
|
|
9114
|
+
|
|
9115
|
+
// ../../loki-ts/src/util/atomic.ts
|
|
9116
|
+
import {
|
|
9117
|
+
closeSync as closeSync5,
|
|
9118
|
+
fstatSync as fstatSync4,
|
|
9119
|
+
fsyncSync as fsyncSync2,
|
|
9120
|
+
lstatSync as lstatSync5,
|
|
9121
|
+
mkdirSync as mkdirSync8,
|
|
9122
|
+
openSync as openSync5,
|
|
9123
|
+
readSync as readSync4,
|
|
9124
|
+
renameSync as renameSync4,
|
|
9125
|
+
rmSync as rmSync6,
|
|
9126
|
+
statSync as statSync13,
|
|
9127
|
+
unlinkSync as unlinkSync3,
|
|
9128
|
+
writeFileSync as writeFileSync11,
|
|
9129
|
+
writeSync as writeSync3
|
|
9130
|
+
} from "fs";
|
|
9131
|
+
import { dirname as dirname9 } from "path";
|
|
9132
|
+
function durableWriteThenRename(target, body) {
|
|
9133
|
+
mkdirSync8(dirname9(target), { recursive: true });
|
|
9134
|
+
const tmp = tmpPathFor(target);
|
|
9135
|
+
const fd = openSync5(tmp, "w");
|
|
9136
|
+
try {
|
|
9137
|
+
writeSync3(fd, body);
|
|
9138
|
+
fsyncSync2(fd);
|
|
9139
|
+
} finally {
|
|
9140
|
+
closeSync5(fd);
|
|
9141
|
+
}
|
|
9142
|
+
renameSync4(tmp, target);
|
|
9143
|
+
fsyncParentDir(target);
|
|
9144
|
+
}
|
|
9145
|
+
function fsyncParentDir(target) {
|
|
9146
|
+
let dfd = null;
|
|
9147
|
+
try {
|
|
9148
|
+
dfd = openSync5(dirname9(target), "r");
|
|
9149
|
+
fsyncSync2(dfd);
|
|
9150
|
+
} catch {} finally {
|
|
9151
|
+
if (dfd !== null) {
|
|
9152
|
+
try {
|
|
9153
|
+
closeSync5(dfd);
|
|
9154
|
+
} catch {}
|
|
9155
|
+
}
|
|
9156
|
+
}
|
|
9157
|
+
}
|
|
9158
|
+
function atomicWriteJson(target, data) {
|
|
9159
|
+
durableWriteThenRename(target, `${JSON.stringify(data, null, 2)}
|
|
9160
|
+
`);
|
|
9161
|
+
}
|
|
9162
|
+
function tmpPathFor(target) {
|
|
9163
|
+
return `${target}.tmp.${process.pid}.${++_tmpCounter}`;
|
|
9164
|
+
}
|
|
9165
|
+
var _tmpCounter = 0, _appendChains;
|
|
9166
|
+
var init_atomic = __esm(() => {
|
|
9167
|
+
_appendChains = new Map;
|
|
9321
9168
|
});
|
|
9322
9169
|
|
|
9323
9170
|
// ../../loki-ts/src/runner/budget.ts
|
|
9324
|
-
import { existsSync as
|
|
9325
|
-
import { dirname as dirname10, join as
|
|
9171
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync9, readdirSync as readdirSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync12 } from "fs";
|
|
9172
|
+
import { dirname as dirname10, join as join30, resolve as resolve10 } from "path";
|
|
9326
9173
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9327
9174
|
function loadDefaultMaxCostUsd() {
|
|
9328
9175
|
const here = dirname10(fileURLToPath2(import.meta.url));
|
|
9329
9176
|
for (const rel of [["..", "..", "data"], ["..", "data"]]) {
|
|
9330
9177
|
try {
|
|
9331
|
-
const j = JSON.parse(
|
|
9178
|
+
const j = JSON.parse(readFileSync22(resolve10(here, ...rel, "model-pricing.json"), "utf8"));
|
|
9332
9179
|
if (typeof j.default_max_cost_usd === "number" && Number.isFinite(j.default_max_cost_usd) && j.default_max_cost_usd > 0)
|
|
9333
9180
|
return j.default_max_cost_usd;
|
|
9334
9181
|
} catch {}
|
|
@@ -9339,9 +9186,9 @@ function _loadPricing() {
|
|
|
9339
9186
|
try {
|
|
9340
9187
|
const moduleDir = dirname10(fileURLToPath2(import.meta.url));
|
|
9341
9188
|
const jsonPath = resolve10(moduleDir, "..", "..", "data", "model-pricing.json");
|
|
9342
|
-
if (!
|
|
9189
|
+
if (!existsSync17(jsonPath))
|
|
9343
9190
|
return _FALLBACK_PRICING;
|
|
9344
|
-
const raw2 = JSON.parse(
|
|
9191
|
+
const raw2 = JSON.parse(readFileSync22(jsonPath, "utf8"));
|
|
9345
9192
|
const pricing2 = raw2["pricing"];
|
|
9346
9193
|
if (!pricing2 || typeof pricing2 !== "object")
|
|
9347
9194
|
return _FALLBACK_PRICING;
|
|
@@ -9371,6 +9218,7 @@ function _loadPricing() {
|
|
|
9371
9218
|
}
|
|
9372
9219
|
var DEFAULT_FALLBACK_USD = 100, _FALLBACK_PRICING, PRICING;
|
|
9373
9220
|
var init_budget = __esm(() => {
|
|
9221
|
+
init_atomic();
|
|
9374
9222
|
init_paths();
|
|
9375
9223
|
init_cost();
|
|
9376
9224
|
_FALLBACK_PRICING = {
|
|
@@ -9470,7 +9318,7 @@ var init_model_rank = __esm(() => {
|
|
|
9470
9318
|
});
|
|
9471
9319
|
|
|
9472
9320
|
// ../../loki-ts/src/engine10/sizing.ts
|
|
9473
|
-
import { existsSync as
|
|
9321
|
+
import { existsSync as existsSync18, readFileSync as readFileSync23 } from "fs";
|
|
9474
9322
|
import { basename as basename10 } from "path";
|
|
9475
9323
|
function namedFiles(task, map) {
|
|
9476
9324
|
return (map?.files ?? []).filter((f) => task.toLowerCase().includes(basename10(f).toLowerCase()));
|
|
@@ -9489,10 +9337,10 @@ function sizeTask(task, map, tests) {
|
|
|
9489
9337
|
return why.length ? { size: "normal", reasons: why } : { size: "small", reasons: [`task ${task.length} chars, names ${named} files`] };
|
|
9490
9338
|
}
|
|
9491
9339
|
function loadRepoMap(repomapRef) {
|
|
9492
|
-
if (!repomapRef || !
|
|
9340
|
+
if (!repomapRef || !existsSync18(repomapRef))
|
|
9493
9341
|
return null;
|
|
9494
9342
|
try {
|
|
9495
|
-
return JSON.parse(
|
|
9343
|
+
return JSON.parse(readFileSync23(repomapRef, "utf8"));
|
|
9496
9344
|
} catch {
|
|
9497
9345
|
return null;
|
|
9498
9346
|
}
|
|
@@ -9523,8 +9371,8 @@ var init_sizing = __esm(() => {
|
|
|
9523
9371
|
});
|
|
9524
9372
|
|
|
9525
9373
|
// ../../loki-ts/src/project_model/schema.ts
|
|
9526
|
-
import { existsSync as
|
|
9527
|
-
import { isAbsolute as isAbsolute3, join as
|
|
9374
|
+
import { existsSync as existsSync19, lstatSync as lstatSync6, realpathSync as realpathSync14, statSync as statSync14 } from "fs";
|
|
9375
|
+
import { isAbsolute as isAbsolute3, join as join32, normalize, sep as sep9 } from "path";
|
|
9528
9376
|
function safeRel(p) {
|
|
9529
9377
|
const n2 = normalize(p.trim()).split(sep9).join("/").replace(/\/$/, "");
|
|
9530
9378
|
if (n2 === "" || isAbsolute3(n2) || n2 === ".." || n2.startsWith("../"))
|
|
@@ -9533,7 +9381,7 @@ function safeRel(p) {
|
|
|
9533
9381
|
}
|
|
9534
9382
|
function insideRepo(repoDir, rel) {
|
|
9535
9383
|
try {
|
|
9536
|
-
const real2 = realpathSync14(
|
|
9384
|
+
const real2 = realpathSync14(join32(repoDir, rel));
|
|
9537
9385
|
const base = realpathSync14(repoDir);
|
|
9538
9386
|
return real2 === base || real2.startsWith(base + sep9);
|
|
9539
9387
|
} catch {
|
|
@@ -9546,8 +9394,8 @@ function checkCitation(repoDir, raw2) {
|
|
|
9546
9394
|
const rel = safeRel(raw2.replace(/:\d+(?:-\d+)?$/, ""));
|
|
9547
9395
|
if (rel === null)
|
|
9548
9396
|
return `citation "${raw2}" is not a repo-relative path`;
|
|
9549
|
-
const abs =
|
|
9550
|
-
if (!
|
|
9397
|
+
const abs = join32(repoDir, rel);
|
|
9398
|
+
if (!existsSync19(abs) || !statSync14(abs).isFile() || !insideRepo(repoDir, rel))
|
|
9551
9399
|
return `citation "${raw2}" names a file that does not exist`;
|
|
9552
9400
|
return null;
|
|
9553
9401
|
}
|
|
@@ -9558,7 +9406,7 @@ function checkFingerprint(repoDir, raw2) {
|
|
|
9558
9406
|
if (rel === null)
|
|
9559
9407
|
return `fingerprint "${raw2}" is not a repo-relative path`;
|
|
9560
9408
|
try {
|
|
9561
|
-
if (!
|
|
9409
|
+
if (!lstatSync6(join32(repoDir, rel)).isFile() || !insideRepo(repoDir, rel))
|
|
9562
9410
|
return `fingerprint "${raw2}" is not a regular file inside the repo`;
|
|
9563
9411
|
} catch {
|
|
9564
9412
|
return `fingerprint "${raw2}" names a file that does not exist`;
|
|
@@ -9586,8 +9434,8 @@ function checkDir(repoDir, v, where, errs) {
|
|
|
9586
9434
|
errs.push(`${where}: must be a repo-relative directory ("." for the repo root)`);
|
|
9587
9435
|
return ".";
|
|
9588
9436
|
}
|
|
9589
|
-
const abs =
|
|
9590
|
-
if (!
|
|
9437
|
+
const abs = join32(repoDir, rel);
|
|
9438
|
+
if (!existsSync19(abs) || !statSync14(abs).isDirectory() || !insideRepo(repoDir, rel))
|
|
9591
9439
|
errs.push(`${where}: directory "${rel}" does not exist`);
|
|
9592
9440
|
return rel;
|
|
9593
9441
|
}
|
|
@@ -9689,9 +9537,9 @@ var init_schema = __esm(() => {
|
|
|
9689
9537
|
});
|
|
9690
9538
|
|
|
9691
9539
|
// ../../loki-ts/src/project_model/gather.ts
|
|
9692
|
-
import { createHash as
|
|
9693
|
-
import { closeSync as
|
|
9694
|
-
import { dirname as dirname11, join as
|
|
9540
|
+
import { createHash as createHash8 } from "crypto";
|
|
9541
|
+
import { closeSync as closeSync6, lstatSync as lstatSync7, openSync as openSync6, readFileSync as readFileSync24, readSync as readSync5 } from "fs";
|
|
9542
|
+
import { dirname as dirname11, join as join33 } from "path";
|
|
9695
9543
|
function listShallow(repoDir) {
|
|
9696
9544
|
try {
|
|
9697
9545
|
const out2 = safeGit(repoDir, ["ls-files", "-z"], { maxBuffer: 256 * 1024 * 1024 });
|
|
@@ -9704,7 +9552,7 @@ function shallowDirs(repoDir) {
|
|
|
9704
9552
|
return [...new Set(listShallow(repoDir).map((p) => dirname11(p)))].sort();
|
|
9705
9553
|
}
|
|
9706
9554
|
function computeKey(repoDir, fingerprintFiles, dirs, committedHash = null) {
|
|
9707
|
-
const h =
|
|
9555
|
+
const h = createHash8("sha256");
|
|
9708
9556
|
h.update(`${MODEL_REV}
|
|
9709
9557
|
`);
|
|
9710
9558
|
if (committedHash !== null)
|
|
@@ -9717,9 +9565,9 @@ function computeKey(repoDir, fingerprintFiles, dirs, committedHash = null) {
|
|
|
9717
9565
|
if (checkFingerprint(repoDir, f) !== null)
|
|
9718
9566
|
h.update("invalid");
|
|
9719
9567
|
else {
|
|
9720
|
-
const abs =
|
|
9721
|
-
const size =
|
|
9722
|
-
h.update(size <= GATHER_CAPS.maxHashBytes ?
|
|
9568
|
+
const abs = join33(repoDir, f);
|
|
9569
|
+
const size = lstatSync7(abs).size;
|
|
9570
|
+
h.update(size <= GATHER_CAPS.maxHashBytes ? readFileSync24(abs) : `too-large:${size}`);
|
|
9723
9571
|
}
|
|
9724
9572
|
} catch {
|
|
9725
9573
|
h.update("missing");
|
|
@@ -9744,7 +9592,7 @@ function committedModelHash(raw2) {
|
|
|
9744
9592
|
if (typeof raw2 !== "object" || raw2 === null || Array.isArray(raw2))
|
|
9745
9593
|
return null;
|
|
9746
9594
|
const { key: _key, expiresAt: _exp, ...rest } = raw2;
|
|
9747
|
-
return
|
|
9595
|
+
return createHash8("sha256").update(JSON.stringify(rest)).digest("hex");
|
|
9748
9596
|
}
|
|
9749
9597
|
var GATHER_CAPS, depthOf = (p) => p.split("/").length, MODEL_REV = "model-rev:2";
|
|
9750
9598
|
var init_gather = __esm(() => {
|
|
@@ -9762,14 +9610,14 @@ var init_gather = __esm(() => {
|
|
|
9762
9610
|
});
|
|
9763
9611
|
|
|
9764
9612
|
// ../../loki-ts/src/project_model/discover.ts
|
|
9765
|
-
import { existsSync as
|
|
9766
|
-
import { join as
|
|
9613
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync10, readFileSync as readFileSync25, rmSync as rmSync7, writeFileSync as writeFileSync13 } from "fs";
|
|
9614
|
+
import { join as join34 } from "path";
|
|
9767
9615
|
function projectModelEnabled(env = process.env) {
|
|
9768
9616
|
return env["LOKI_E10_PROJECT_MODEL"] !== "0";
|
|
9769
9617
|
}
|
|
9770
9618
|
function loadCached(repoDir, now2 = Date.now()) {
|
|
9771
9619
|
try {
|
|
9772
|
-
return parseCached(repoDir, JSON.parse(
|
|
9620
|
+
return parseCached(repoDir, JSON.parse(readFileSync25(join34(repoDir, PROJECT_FILE), "utf8")), now2);
|
|
9773
9621
|
} catch {
|
|
9774
9622
|
return null;
|
|
9775
9623
|
}
|
|
@@ -9784,7 +9632,7 @@ function loadCommitted(repoDir) {
|
|
|
9784
9632
|
};
|
|
9785
9633
|
let raw2;
|
|
9786
9634
|
try {
|
|
9787
|
-
raw2 = JSON.parse(
|
|
9635
|
+
raw2 = JSON.parse(readFileSync25(join34(repoDir, PROJECT_FILE), "utf8"));
|
|
9788
9636
|
} catch (e) {
|
|
9789
9637
|
return ignore(`unreadable JSON (${e instanceof Error ? e.message : String(e)})`);
|
|
9790
9638
|
}
|
|
@@ -9857,7 +9705,7 @@ var clean2 = (p) => typeof p === "string" ? posix.normalize(p.replace(/\\/g, "/"
|
|
|
9857
9705
|
var init_api = () => {};
|
|
9858
9706
|
|
|
9859
9707
|
// ../../loki-ts/src/project_model/resolve.ts
|
|
9860
|
-
import { join as
|
|
9708
|
+
import { join as join35 } from "path";
|
|
9861
9709
|
function loadProjectApi(repoDir, env = process.env) {
|
|
9862
9710
|
if (!projectModelEnabled(env))
|
|
9863
9711
|
return null;
|
|
@@ -9879,7 +9727,7 @@ function siteFor(api, repoDir, file) {
|
|
|
9879
9727
|
const rel = api.relativeToRoot(file);
|
|
9880
9728
|
if (!pkg || pkg.root === "." || rel === null)
|
|
9881
9729
|
return null;
|
|
9882
|
-
return { pkg, root: pkg.root, cwd:
|
|
9730
|
+
return { pkg, root: pkg.root, cwd: join35(repoDir, pkg.root), file: rel };
|
|
9883
9731
|
}
|
|
9884
9732
|
function groupByPackage(api, repoDir, files) {
|
|
9885
9733
|
const out2 = new Map;
|
|
@@ -9912,9 +9760,9 @@ var init_scope = __esm(() => {
|
|
|
9912
9760
|
|
|
9913
9761
|
// ../../loki-ts/src/e10ext/assert_delta.ts
|
|
9914
9762
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
9915
|
-
import { mkdtempSync as mkdtempSync4, readFileSync as
|
|
9763
|
+
import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync26, rmSync as rmSync8 } from "fs";
|
|
9916
9764
|
import { tmpdir as tmpdir6 } from "os";
|
|
9917
|
-
import { join as
|
|
9765
|
+
import { join as join36 } from "path";
|
|
9918
9766
|
import { basename as basename11 } from "path";
|
|
9919
9767
|
function classifyAssertDelta(inp) {
|
|
9920
9768
|
const f = basename11(inp.path);
|
|
@@ -9924,7 +9772,7 @@ function classifyAssertDelta(inp) {
|
|
|
9924
9772
|
return WEAKENED;
|
|
9925
9773
|
let cwd = "";
|
|
9926
9774
|
try {
|
|
9927
|
-
cwd = mkdtempSync4(
|
|
9775
|
+
cwd = mkdtempSync4(join36(tmpdir6(), "loki-ad-"));
|
|
9928
9776
|
const raw2 = execFileSync5("python3", ["-I", "-c", PY], {
|
|
9929
9777
|
input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
|
|
9930
9778
|
cwd,
|
|
@@ -9947,7 +9795,7 @@ function classifyAssertDelta(inp) {
|
|
|
9947
9795
|
return WEAKENED;
|
|
9948
9796
|
} finally {
|
|
9949
9797
|
if (cwd)
|
|
9950
|
-
|
|
9798
|
+
rmSync8(cwd, { recursive: true, force: true });
|
|
9951
9799
|
}
|
|
9952
9800
|
}
|
|
9953
9801
|
function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, headCounts) {
|
|
@@ -9955,7 +9803,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
|
|
|
9955
9803
|
return null;
|
|
9956
9804
|
try {
|
|
9957
9805
|
const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
|
|
9958
|
-
const head = headRef ? show(headRef) :
|
|
9806
|
+
const head = headRef ? show(headRef) : readFileSync26(join36(repoDir, path), "utf8");
|
|
9959
9807
|
const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
|
|
9960
9808
|
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;
|
|
9961
9809
|
} catch {
|
|
@@ -10179,7 +10027,7 @@ var init_runner_errors = __esm(() => {
|
|
|
10179
10027
|
});
|
|
10180
10028
|
|
|
10181
10029
|
// ../../loki-ts/src/engine10/testmap.ts
|
|
10182
|
-
import { basename as basename12, extname, join as
|
|
10030
|
+
import { basename as basename12, extname, join as join37, relative as relative3, sep as sep10 } from "path";
|
|
10183
10031
|
function isTestFile(rel) {
|
|
10184
10032
|
const name = basename12(rel);
|
|
10185
10033
|
return JS_TEST_RE.test(name) || PY_TEST_RE.test(name) || GO_TEST_RE.test(name);
|
|
@@ -10209,8 +10057,8 @@ var init_testmap = __esm(() => {
|
|
|
10209
10057
|
});
|
|
10210
10058
|
|
|
10211
10059
|
// ../../loki-ts/src/util/check_result.ts
|
|
10212
|
-
import { mkdirSync as
|
|
10213
|
-
import { basename as basename13, join as
|
|
10060
|
+
import { mkdirSync as mkdirSync11, readFileSync as readFileSync27, renameSync as renameSync5, writeFileSync as writeFileSync14 } from "fs";
|
|
10061
|
+
import { basename as basename13, join as join38 } from "path";
|
|
10214
10062
|
function plainTestEnv(base = process.env) {
|
|
10215
10063
|
const e = {};
|
|
10216
10064
|
for (const [k, v] of Object.entries(tokenFreeEnv(base)))
|
|
@@ -10389,17 +10237,17 @@ function classifyCheck(i) {
|
|
|
10389
10237
|
return { result: "not_run", reason: "timed out or aborted" };
|
|
10390
10238
|
if (i.kind === "static")
|
|
10391
10239
|
return { result: i.ok ? "pass" : "fail" };
|
|
10392
|
-
const
|
|
10240
|
+
const text2 = stripAnsi(i.out);
|
|
10393
10241
|
if (i.runner === "go") {
|
|
10394
10242
|
if (i.ok)
|
|
10395
10243
|
return { result: "not_run", reason: GO_EXIT0_REASON };
|
|
10396
|
-
const j = goJson(
|
|
10244
|
+
const j = goJson(text2);
|
|
10397
10245
|
if (j)
|
|
10398
10246
|
return j.failed ? { result: "fail" } : { result: "not_run", reason: UNCONFIRMED_REASON };
|
|
10399
|
-
return FAIL_EVIDENCE.test(
|
|
10247
|
+
return FAIL_EVIDENCE.test(text2) || GO_FAIL_EVIDENCE.test(text2) ? { result: "fail" } : { result: "not_run", reason: UNCONFIRMED_REASON };
|
|
10400
10248
|
}
|
|
10401
10249
|
const n2 = testCount(i.out, i.path, i.ok);
|
|
10402
|
-
if (!i.ok && FAIL_EVIDENCE.test(
|
|
10250
|
+
if (!i.ok && FAIL_EVIDENCE.test(text2))
|
|
10403
10251
|
return { result: "fail", ...n2 !== null ? { n: n2 } : {} };
|
|
10404
10252
|
if (n2 === 0)
|
|
10405
10253
|
return { result: "not_run", n: 0, reason: `${NO_TESTS_REASON} (ran 0 tests, empty or all skipped)` };
|
|
@@ -10502,7 +10350,7 @@ function diffFiles(repoDir, baseSha) {
|
|
|
10502
10350
|
return f;
|
|
10503
10351
|
let n2 = 0;
|
|
10504
10352
|
try {
|
|
10505
|
-
n2 =
|
|
10353
|
+
n2 = readFileSync27(join38(repoDir, path), "utf8").split(`
|
|
10506
10354
|
`).length;
|
|
10507
10355
|
} catch {}
|
|
10508
10356
|
return { path, added: n2, deleted: 0, status: "added" };
|
|
@@ -10510,9 +10358,9 @@ function diffFiles(repoDir, baseSha) {
|
|
|
10510
10358
|
}
|
|
10511
10359
|
function recordRisk(repoDir, a) {
|
|
10512
10360
|
try {
|
|
10513
|
-
const dir =
|
|
10514
|
-
|
|
10515
|
-
|
|
10361
|
+
const dir = join38(repoDir, ".loki", "state"), p = join38(dir, "risk-tier.json");
|
|
10362
|
+
mkdirSync11(dir, { recursive: true });
|
|
10363
|
+
writeFileSync14(`${p}.tmp`, JSON.stringify(a, null, 2) + `
|
|
10516
10364
|
`);
|
|
10517
10365
|
renameSync5(`${p}.tmp`, p);
|
|
10518
10366
|
return p;
|
|
@@ -10553,12 +10401,12 @@ var init_check_result = __esm(() => {
|
|
|
10553
10401
|
|
|
10554
10402
|
// ../../loki-ts/src/runner/load_owner.ts
|
|
10555
10403
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
10556
|
-
import { mkdtempSync as mkdtempSync5, realpathSync as realpathSync15, rmSync as
|
|
10404
|
+
import { mkdtempSync as mkdtempSync5, realpathSync as realpathSync15, rmSync as rmSync9 } from "fs";
|
|
10557
10405
|
import { tmpdir as tmpdir7 } from "os";
|
|
10558
|
-
import { basename as basename14, extname as extname2, join as
|
|
10406
|
+
import { basename as basename14, extname as extname2, join as join39 } from "path";
|
|
10559
10407
|
function changedFilesNamed(out2, repoDir, changed) {
|
|
10560
10408
|
return changed.filter((f) => {
|
|
10561
|
-
if (out2.includes(f) || out2.includes(
|
|
10409
|
+
if (out2.includes(f) || out2.includes(join39(repoDir, f)))
|
|
10562
10410
|
return true;
|
|
10563
10411
|
const segs = f.split("/");
|
|
10564
10412
|
if (suffixes(segs, 2).some((x) => x !== f && bounded(out2, x, "(?![\\w-])")))
|
|
@@ -10669,7 +10517,7 @@ async function loadErrorIsHarnessOwned(i) {
|
|
|
10669
10517
|
return false;
|
|
10670
10518
|
if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
|
|
10671
10519
|
return false;
|
|
10672
|
-
const dir = mkdtempSync5(
|
|
10520
|
+
const dir = mkdtempSync5(join39(tmpdir7(), "e10-loadown-"));
|
|
10673
10521
|
const git3 = (args) => {
|
|
10674
10522
|
safeGit(i.repoDir, args, { stdio: "ignore" });
|
|
10675
10523
|
};
|
|
@@ -10683,7 +10531,7 @@ async function loadErrorIsHarnessOwned(i) {
|
|
|
10683
10531
|
try {
|
|
10684
10532
|
git3(["worktree", "remove", "--force", dir]);
|
|
10685
10533
|
} catch {}
|
|
10686
|
-
|
|
10534
|
+
rmSync9(dir, { recursive: true, force: true });
|
|
10687
10535
|
try {
|
|
10688
10536
|
git3(["worktree", "prune"]);
|
|
10689
10537
|
} catch {}
|
|
@@ -10701,7 +10549,7 @@ var init_load_owner = __esm(() => {
|
|
|
10701
10549
|
});
|
|
10702
10550
|
|
|
10703
10551
|
// ../../loki-ts/src/util/wall_owned.ts
|
|
10704
|
-
import { isAbsolute as isAbsolute4, join as
|
|
10552
|
+
import { isAbsolute as isAbsolute4, join as join40, relative as relative4 } from "path";
|
|
10705
10553
|
function failingLocations(raw2, cwd, repoDir) {
|
|
10706
10554
|
const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
|
|
10707
10555
|
`), files = new Set;
|
|
@@ -10733,7 +10581,7 @@ function failingLocations(raw2, cwd, repoDir) {
|
|
|
10733
10581
|
}
|
|
10734
10582
|
if (errors2 === 0 || located !== errors2)
|
|
10735
10583
|
return null;
|
|
10736
|
-
return [...files].map((f) => relative4(repoDir, isAbsolute4(f) ? f :
|
|
10584
|
+
return [...files].map((f) => relative4(repoDir, isAbsolute4(f) ? f : join40(cwd, f)));
|
|
10737
10585
|
}
|
|
10738
10586
|
function wallOwnedFailure(raw2, cwd, repoDir, wall) {
|
|
10739
10587
|
const locs = failingLocations(raw2, cwd, repoDir);
|
|
@@ -10744,57 +10592,6 @@ var init_wall_owned = __esm(() => {
|
|
|
10744
10592
|
ANSI2 = /\u001b\[[0-9;?]*[ -/]*[@-~]/g;
|
|
10745
10593
|
});
|
|
10746
10594
|
|
|
10747
|
-
// ../../loki-ts/src/util/atomic.ts
|
|
10748
|
-
import {
|
|
10749
|
-
closeSync as closeSync6,
|
|
10750
|
-
fstatSync as fstatSync4,
|
|
10751
|
-
fsyncSync as fsyncSync2,
|
|
10752
|
-
lstatSync as lstatSync7,
|
|
10753
|
-
mkdirSync as mkdirSync11,
|
|
10754
|
-
openSync as openSync6,
|
|
10755
|
-
readSync as readSync5,
|
|
10756
|
-
renameSync as renameSync6,
|
|
10757
|
-
rmSync as rmSync9,
|
|
10758
|
-
statSync as statSync15,
|
|
10759
|
-
unlinkSync as unlinkSync3,
|
|
10760
|
-
writeSync as writeSync3
|
|
10761
|
-
} from "fs";
|
|
10762
|
-
import { dirname as dirname12 } from "path";
|
|
10763
|
-
function durableWriteThenRename(target, body) {
|
|
10764
|
-
mkdirSync11(dirname12(target), { recursive: true });
|
|
10765
|
-
const tmp = `${target}.tmp.${process.pid}.${++_tmpCounter}`;
|
|
10766
|
-
const fd = openSync6(tmp, "w");
|
|
10767
|
-
try {
|
|
10768
|
-
writeSync3(fd, body);
|
|
10769
|
-
fsyncSync2(fd);
|
|
10770
|
-
} finally {
|
|
10771
|
-
closeSync6(fd);
|
|
10772
|
-
}
|
|
10773
|
-
renameSync6(tmp, target);
|
|
10774
|
-
fsyncParentDir(target);
|
|
10775
|
-
}
|
|
10776
|
-
function fsyncParentDir(target) {
|
|
10777
|
-
let dfd = null;
|
|
10778
|
-
try {
|
|
10779
|
-
dfd = openSync6(dirname12(target), "r");
|
|
10780
|
-
fsyncSync2(dfd);
|
|
10781
|
-
} catch {} finally {
|
|
10782
|
-
if (dfd !== null) {
|
|
10783
|
-
try {
|
|
10784
|
-
closeSync6(dfd);
|
|
10785
|
-
} catch {}
|
|
10786
|
-
}
|
|
10787
|
-
}
|
|
10788
|
-
}
|
|
10789
|
-
function atomicWriteJson(target, data) {
|
|
10790
|
-
durableWriteThenRename(target, `${JSON.stringify(data, null, 2)}
|
|
10791
|
-
`);
|
|
10792
|
-
}
|
|
10793
|
-
var _tmpCounter = 0, _appendChains;
|
|
10794
|
-
var init_atomic = __esm(() => {
|
|
10795
|
-
_appendChains = new Map;
|
|
10796
|
-
});
|
|
10797
|
-
|
|
10798
10595
|
// ../../loki-ts/src/runner/state.ts
|
|
10799
10596
|
var TERMINAL_STATUSES;
|
|
10800
10597
|
var init_state = __esm(() => {
|
|
@@ -10813,11 +10610,11 @@ var init_state = __esm(() => {
|
|
|
10813
10610
|
});
|
|
10814
10611
|
|
|
10815
10612
|
// ../../loki-ts/src/runner/repo_profile.ts
|
|
10816
|
-
import { existsSync as
|
|
10817
|
-
import { basename as basename15, join as
|
|
10613
|
+
import { existsSync as existsSync21, readFileSync as readFileSync28, mkdirSync as mkdirSync12, readdirSync as readdirSync11, renameSync as renameSync6, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "fs";
|
|
10614
|
+
import { basename as basename15, join as join41, resolve as resolve11, isAbsolute as isAbsolute5 } from "path";
|
|
10818
10615
|
function loadProfile(repoDir) {
|
|
10819
10616
|
try {
|
|
10820
|
-
const p = JSON.parse(
|
|
10617
|
+
const p = JSON.parse(readFileSync28(commandProfilePath(repoDir), "utf8"));
|
|
10821
10618
|
return p?.version === 1 && Array.isArray(p.commands) && p.baseline ? p : null;
|
|
10822
10619
|
} catch {
|
|
10823
10620
|
return null;
|
|
@@ -10848,7 +10645,7 @@ function attributeFullSuite(repoDir, baseSha, full, blocked, changed) {
|
|
|
10848
10645
|
const block = new Set(blocked);
|
|
10849
10646
|
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))) })));
|
|
10850
10647
|
}
|
|
10851
|
-
var commandProfilePath = (repoDir) =>
|
|
10648
|
+
var commandProfilePath = (repoDir) => join41(repoDir, ".loki", "state", "repo-profile.json");
|
|
10852
10649
|
var init_repo_profile = __esm(() => {
|
|
10853
10650
|
init_failures();
|
|
10854
10651
|
init_check_result();
|
|
@@ -10858,23 +10655,23 @@ var init_repo_profile = __esm(() => {
|
|
|
10858
10655
|
});
|
|
10859
10656
|
|
|
10860
10657
|
// ../../loki-ts/src/project_graph.ts
|
|
10861
|
-
import { createHash as
|
|
10658
|
+
import { createHash as createHash9 } from "crypto";
|
|
10862
10659
|
import {
|
|
10863
|
-
existsSync as
|
|
10864
|
-
readdirSync as
|
|
10865
|
-
readFileSync as
|
|
10866
|
-
statSync as
|
|
10867
|
-
writeFileSync as
|
|
10660
|
+
existsSync as existsSync22,
|
|
10661
|
+
readdirSync as readdirSync12,
|
|
10662
|
+
readFileSync as readFileSync29,
|
|
10663
|
+
statSync as statSync15,
|
|
10664
|
+
writeFileSync as writeFileSync16,
|
|
10868
10665
|
mkdirSync as mkdirSync13
|
|
10869
10666
|
} from "fs";
|
|
10870
|
-
import { basename as basename16, dirname as
|
|
10667
|
+
import { basename as basename16, dirname as dirname12, join as join42, resolve as resolve12 } from "path";
|
|
10871
10668
|
function readManifest(path) {
|
|
10872
|
-
if (!
|
|
10669
|
+
if (!existsSync22(path)) {
|
|
10873
10670
|
return null;
|
|
10874
10671
|
}
|
|
10875
10672
|
let raw2;
|
|
10876
10673
|
try {
|
|
10877
|
-
raw2 =
|
|
10674
|
+
raw2 = readFileSync29(path, "utf8");
|
|
10878
10675
|
} catch {
|
|
10879
10676
|
return null;
|
|
10880
10677
|
}
|
|
@@ -10911,7 +10708,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
10911
10708
|
const seen = new Set;
|
|
10912
10709
|
let children;
|
|
10913
10710
|
try {
|
|
10914
|
-
children =
|
|
10711
|
+
children = readdirSync12(rootDir);
|
|
10915
10712
|
} catch {
|
|
10916
10713
|
children = [];
|
|
10917
10714
|
}
|
|
@@ -10926,12 +10723,12 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
10926
10723
|
for (const child of children) {
|
|
10927
10724
|
if (!matchPattern(name, child))
|
|
10928
10725
|
continue;
|
|
10929
|
-
const full =
|
|
10726
|
+
const full = join42(rootDir, child);
|
|
10930
10727
|
if (seen.has(full))
|
|
10931
10728
|
continue;
|
|
10932
10729
|
let st;
|
|
10933
10730
|
try {
|
|
10934
|
-
st =
|
|
10731
|
+
st = statSync15(full);
|
|
10935
10732
|
} catch {
|
|
10936
10733
|
continue;
|
|
10937
10734
|
}
|
|
@@ -10943,18 +10740,18 @@ function resolveMembers(rootDir, declared, selfBasename) {
|
|
|
10943
10740
|
}
|
|
10944
10741
|
if (declared.length === 0) {
|
|
10945
10742
|
for (const child of children) {
|
|
10946
|
-
const full =
|
|
10743
|
+
const full = join42(rootDir, child);
|
|
10947
10744
|
if (seen.has(full))
|
|
10948
10745
|
continue;
|
|
10949
10746
|
let st;
|
|
10950
10747
|
try {
|
|
10951
|
-
st =
|
|
10748
|
+
st = statSync15(full);
|
|
10952
10749
|
} catch {
|
|
10953
10750
|
continue;
|
|
10954
10751
|
}
|
|
10955
10752
|
if (!st.isDirectory())
|
|
10956
10753
|
continue;
|
|
10957
|
-
if (!
|
|
10754
|
+
if (!existsSync22(join42(full, ".loki", "app.json")))
|
|
10958
10755
|
continue;
|
|
10959
10756
|
seen.add(full);
|
|
10960
10757
|
out2.push(full);
|
|
@@ -10967,34 +10764,34 @@ function cacheKey(manifestPaths) {
|
|
|
10967
10764
|
for (const p of manifestPaths.sort()) {
|
|
10968
10765
|
let mtime = 0;
|
|
10969
10766
|
try {
|
|
10970
|
-
mtime =
|
|
10767
|
+
mtime = statSync15(p).mtimeMs;
|
|
10971
10768
|
} catch {}
|
|
10972
10769
|
parts.push(`${p}:${mtime}`);
|
|
10973
10770
|
}
|
|
10974
|
-
return
|
|
10771
|
+
return createHash9("sha256").update(parts.join("|")).digest("hex");
|
|
10975
10772
|
}
|
|
10976
10773
|
function writeCache(targetDir, key, result) {
|
|
10977
10774
|
try {
|
|
10978
|
-
const cacheDir =
|
|
10775
|
+
const cacheDir = join42(targetDir, ".loki", "state");
|
|
10979
10776
|
mkdirSync13(cacheDir, { recursive: true });
|
|
10980
|
-
const cachePath =
|
|
10981
|
-
|
|
10777
|
+
const cachePath = join42(cacheDir, "project-graph.json");
|
|
10778
|
+
writeFileSync16(cachePath, JSON.stringify({ key, result }, null, 2), "utf8");
|
|
10982
10779
|
} catch {}
|
|
10983
10780
|
}
|
|
10984
10781
|
function discoverProjectGraph(targetDir) {
|
|
10985
10782
|
const absTarget = resolve12(targetDir);
|
|
10986
|
-
const targetManifest =
|
|
10987
|
-
const parentDir =
|
|
10988
|
-
const parentManifest =
|
|
10783
|
+
const targetManifest = join42(absTarget, ".loki", "app.json");
|
|
10784
|
+
const parentDir = dirname12(absTarget);
|
|
10785
|
+
const parentManifest = join42(parentDir, ".loki", "app.json");
|
|
10989
10786
|
const examined = [];
|
|
10990
10787
|
let chosenManifest = null;
|
|
10991
10788
|
let chosenRoot = "";
|
|
10992
|
-
if (
|
|
10789
|
+
if (existsSync22(parentManifest) && parentDir !== absTarget) {
|
|
10993
10790
|
examined.push(parentManifest);
|
|
10994
10791
|
chosenManifest = readManifest(parentManifest);
|
|
10995
10792
|
chosenRoot = parentDir;
|
|
10996
10793
|
}
|
|
10997
|
-
if (!chosenManifest &&
|
|
10794
|
+
if (!chosenManifest && existsSync22(targetManifest)) {
|
|
10998
10795
|
examined.push(targetManifest);
|
|
10999
10796
|
chosenManifest = readManifest(targetManifest);
|
|
11000
10797
|
chosenRoot = absTarget;
|
|
@@ -11005,8 +10802,8 @@ function discoverProjectGraph(targetDir) {
|
|
|
11005
10802
|
const members = resolveMembers(chosenRoot, declared, basename16(absTarget));
|
|
11006
10803
|
const filtered = [];
|
|
11007
10804
|
for (const m of members) {
|
|
11008
|
-
const sibManifestPath =
|
|
11009
|
-
if (
|
|
10805
|
+
const sibManifestPath = join42(m, ".loki", "app.json");
|
|
10806
|
+
if (existsSync22(sibManifestPath)) {
|
|
11010
10807
|
examined.push(sibManifestPath);
|
|
11011
10808
|
const sibManifest = readManifest(sibManifestPath);
|
|
11012
10809
|
if (sibManifest && sibManifest.app_id !== chosenManifest.app_id) {
|
|
@@ -11103,6 +10900,7 @@ var init_shell = __esm(() => {
|
|
|
11103
10900
|
// ../../loki-ts/src/e10ext/budget_cap.ts
|
|
11104
10901
|
var DEFAULT_MAX_COST_USD;
|
|
11105
10902
|
var init_budget_cap = __esm(() => {
|
|
10903
|
+
init_yaml_key();
|
|
11106
10904
|
init_budget();
|
|
11107
10905
|
DEFAULT_MAX_COST_USD = loadDefaultMaxCostUsd();
|
|
11108
10906
|
});
|
|
@@ -11213,14 +11011,14 @@ var init_steer = __esm(() => {
|
|
|
11213
11011
|
});
|
|
11214
11012
|
|
|
11215
11013
|
// ../../loki-ts/src/util/pr_lessons.ts
|
|
11216
|
-
import { existsSync as
|
|
11217
|
-
import { dirname as
|
|
11014
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync14, readFileSync as readFileSync30 } from "fs";
|
|
11015
|
+
import { dirname as dirname13, join as join43 } from "path";
|
|
11218
11016
|
function loadLessons(repoDir) {
|
|
11219
11017
|
const p = lessonsPath(repoDir);
|
|
11220
|
-
if (!
|
|
11018
|
+
if (!existsSync23(p))
|
|
11221
11019
|
return [];
|
|
11222
11020
|
try {
|
|
11223
|
-
const j = JSON.parse(
|
|
11021
|
+
const j = JSON.parse(readFileSync30(p, "utf-8"));
|
|
11224
11022
|
return Array.isArray(j.lessons) ? j.lessons : [];
|
|
11225
11023
|
} catch {
|
|
11226
11024
|
return [];
|
|
@@ -11228,7 +11026,7 @@ function loadLessons(repoDir) {
|
|
|
11228
11026
|
}
|
|
11229
11027
|
function save(repoDir, lessons) {
|
|
11230
11028
|
const p = lessonsPath(repoDir);
|
|
11231
|
-
mkdirSync14(
|
|
11029
|
+
mkdirSync14(dirname13(p), { recursive: true });
|
|
11232
11030
|
atomicWriteJson(p, { version: 2, lessons });
|
|
11233
11031
|
}
|
|
11234
11032
|
function recordRunVerdict(repoDir, runId, verdict) {
|
|
@@ -11243,7 +11041,7 @@ function recordRunVerdict(repoDir, runId, verdict) {
|
|
|
11243
11041
|
if (dirty)
|
|
11244
11042
|
save(repoDir, lessons);
|
|
11245
11043
|
}
|
|
11246
|
-
var lessonsPath = (repoDir) =>
|
|
11044
|
+
var lessonsPath = (repoDir) => join43(repoDir, ".loki", "memory", "semantic", "pr-lessons.json");
|
|
11247
11045
|
var init_pr_lessons = __esm(() => {
|
|
11248
11046
|
init_atomic();
|
|
11249
11047
|
});
|
|
@@ -11258,19 +11056,19 @@ var init_model_downgrades = __esm(() => {
|
|
|
11258
11056
|
var init_mcp_config = () => {};
|
|
11259
11057
|
|
|
11260
11058
|
// ../../loki-ts/src/providers/claude_flags.ts
|
|
11261
|
-
import { existsSync as
|
|
11262
|
-
import { resolve as resolvePath, dirname as
|
|
11059
|
+
import { existsSync as existsSync24, readFileSync as readFileSync31 } from "fs";
|
|
11060
|
+
import { resolve as resolvePath, dirname as dirname14 } from "path";
|
|
11263
11061
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11264
11062
|
function designArchetypesText() {
|
|
11265
11063
|
try {
|
|
11266
|
-
const moduleDir =
|
|
11064
|
+
const moduleDir = dirname14(fileURLToPath3(import.meta.url));
|
|
11267
11065
|
for (const rel of [
|
|
11268
11066
|
["..", "..", "..", "references", "design-archetypes.md"],
|
|
11269
11067
|
["..", "..", "references", "design-archetypes.md"]
|
|
11270
11068
|
]) {
|
|
11271
11069
|
const p = resolvePath(moduleDir, ...rel);
|
|
11272
|
-
if (
|
|
11273
|
-
return
|
|
11070
|
+
if (existsSync24(p))
|
|
11071
|
+
return readFileSync31(p, "utf8");
|
|
11274
11072
|
}
|
|
11275
11073
|
} catch {}
|
|
11276
11074
|
return "";
|
|
@@ -11348,14 +11146,14 @@ var init_providers = __esm(() => {
|
|
|
11348
11146
|
});
|
|
11349
11147
|
|
|
11350
11148
|
// ../../loki-ts/src/runner/router/route_record.ts
|
|
11351
|
-
import { existsSync as
|
|
11352
|
-
import { join as
|
|
11149
|
+
import { existsSync as existsSync25, lstatSync as lstatSync9, mkdirSync as mkdirSync15, readFileSync as readFileSync32, writeFileSync as writeFileSync17 } from "fs";
|
|
11150
|
+
import { join as join44 } from "path";
|
|
11353
11151
|
function loadRouteRecord(runDir) {
|
|
11354
11152
|
try {
|
|
11355
|
-
const p =
|
|
11356
|
-
if (!
|
|
11153
|
+
const p = join44(runDir, ROUTE_RECORD_FILE);
|
|
11154
|
+
if (!existsSync25(p) || !lstatSync9(p).isFile())
|
|
11357
11155
|
return;
|
|
11358
|
-
const v = JSON.parse(
|
|
11156
|
+
const v = JSON.parse(readFileSync32(p, "utf8"));
|
|
11359
11157
|
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
|
|
11360
11158
|
} catch {
|
|
11361
11159
|
return;
|
|
@@ -11365,7 +11163,7 @@ var ROUTE_RECORD_FILE = "route.json";
|
|
|
11365
11163
|
var init_route_record = () => {};
|
|
11366
11164
|
|
|
11367
11165
|
// ../../loki-ts/src/runner/router/history_store.ts
|
|
11368
|
-
import { existsSync as
|
|
11166
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync33, renameSync as renameSync7, rmSync as rmSync11, writeFileSync as writeFileSync18 } from "fs";
|
|
11369
11167
|
import { resolve as resolve13 } from "path";
|
|
11370
11168
|
function validRun(v) {
|
|
11371
11169
|
if (typeof v !== "object" || v === null)
|
|
@@ -11378,10 +11176,10 @@ function historyPath(key, cacheRoot) {
|
|
|
11378
11176
|
}
|
|
11379
11177
|
function readRunHistory(key, cacheRoot) {
|
|
11380
11178
|
const path = historyPath(key, cacheRoot);
|
|
11381
|
-
if (!
|
|
11179
|
+
if (!existsSync26(path))
|
|
11382
11180
|
return [];
|
|
11383
11181
|
try {
|
|
11384
|
-
const parsed = JSON.parse(
|
|
11182
|
+
const parsed = JSON.parse(readFileSync33(path, "utf8"));
|
|
11385
11183
|
const runs2 = parsed?.runs;
|
|
11386
11184
|
return Array.isArray(runs2) ? runs2.filter(validRun) : [];
|
|
11387
11185
|
} catch {
|
|
@@ -11395,8 +11193,8 @@ function appendRunOutcome(key, outcome, cacheRoot) {
|
|
|
11395
11193
|
const target = historyPath(key, cacheRoot);
|
|
11396
11194
|
const tmp = `${target}.${process.pid}.tmp`;
|
|
11397
11195
|
try {
|
|
11398
|
-
|
|
11399
|
-
|
|
11196
|
+
writeFileSync18(tmp, JSON.stringify({ runs: runs2 }));
|
|
11197
|
+
renameSync7(tmp, target);
|
|
11400
11198
|
} catch (e) {
|
|
11401
11199
|
rmSync11(tmp, { force: true, recursive: false });
|
|
11402
11200
|
throw e;
|
|
@@ -11415,7 +11213,7 @@ var init_history_store = __esm(() => {
|
|
|
11415
11213
|
});
|
|
11416
11214
|
|
|
11417
11215
|
// ../../loki-ts/src/runner/router/history.ts
|
|
11418
|
-
import { dirname as
|
|
11216
|
+
import { dirname as dirname15, join as join45, resolve as resolve14 } from "path";
|
|
11419
11217
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
11420
11218
|
function shapeKey(model) {
|
|
11421
11219
|
if (!model || model.status !== "ok")
|
|
@@ -11444,7 +11242,7 @@ var init_history = __esm(() => {
|
|
|
11444
11242
|
init_discover2();
|
|
11445
11243
|
init_gather();
|
|
11446
11244
|
init_history_store();
|
|
11447
|
-
SHAPE_DEFAULTS_FILE = resolve14(
|
|
11245
|
+
SHAPE_DEFAULTS_FILE = resolve14(dirname15(fileURLToPath4(import.meta.url)), "..", "..", "..", "data", "router-shape-defaults.json");
|
|
11448
11246
|
});
|
|
11449
11247
|
|
|
11450
11248
|
// ../../loki-ts/src/runner/router/plan_route.ts
|
|
@@ -11575,7 +11373,7 @@ var init_worker = __esm(() => {
|
|
|
11575
11373
|
});
|
|
11576
11374
|
|
|
11577
11375
|
// ../../loki-ts/src/project_model/package_suite.ts
|
|
11578
|
-
import { join as
|
|
11376
|
+
import { join as join46 } from "path";
|
|
11579
11377
|
async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
11580
11378
|
const api = loadProjectApi(repoDir);
|
|
11581
11379
|
if (!isMultiRoot(api))
|
|
@@ -11586,7 +11384,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
11586
11384
|
for (const pkg of withTests) {
|
|
11587
11385
|
const tc = pkg.commands.test, name = `full suite: ${pkg.name}`, cmd = `(cd ${tc.cwd} && ${tc.cmd})`;
|
|
11588
11386
|
const started = Date.now();
|
|
11589
|
-
const r = await run(["bash", "-c", tc.cmd], { cwd:
|
|
11387
|
+
const r = await run(["bash", "-c", tc.cmd], { cwd: join46(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
11590
11388
|
const duration_s = (Date.now() - started) / 1000;
|
|
11591
11389
|
if (signal.aborted) {
|
|
11592
11390
|
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
@@ -11595,7 +11393,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
|
|
|
11595
11393
|
}
|
|
11596
11394
|
const out2 = `${r.stdout}
|
|
11597
11395
|
${r.stderr}`;
|
|
11598
|
-
const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd:
|
|
11396
|
+
const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join46(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
|
|
11599
11397
|
if (lr) {
|
|
11600
11398
|
checks.push({ name, cmd, result: "not_run", duration_s });
|
|
11601
11399
|
notProven.add(`${lr} (${name}; harness-owned)`);
|
|
@@ -11628,8 +11426,8 @@ __export(exports_deep, {
|
|
|
11628
11426
|
DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH,
|
|
11629
11427
|
DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH
|
|
11630
11428
|
});
|
|
11631
|
-
import { existsSync as
|
|
11632
|
-
import { join as
|
|
11429
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync17, writeFileSync as writeFileSync19 } from "fs";
|
|
11430
|
+
import { join as join47 } from "path";
|
|
11633
11431
|
async function runFullSuite(ctx, signal, opts, checks, notProven) {
|
|
11634
11432
|
if (await runPackageSuites(ctx.repoDir, signal, { path: opts.path, timeoutMs: opts.fullSuiteTimeoutMs ?? FULL_SUITE_TIMEOUT_MS, baseSha: ctx.baseSha }, checks, notProven))
|
|
11635
11433
|
return;
|
|
@@ -11715,7 +11513,7 @@ async function runCouncilCheck(ctx, changed, baseSha, signal, opts, checks, notP
|
|
|
11715
11513
|
async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
11716
11514
|
const scriptPath = opts.secretScanShPath ?? DEFAULT_SECRET_SCAN_SH;
|
|
11717
11515
|
const name = "security scan";
|
|
11718
|
-
if (!
|
|
11516
|
+
if (!existsSync27(scriptPath)) {
|
|
11719
11517
|
checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: 0 });
|
|
11720
11518
|
notProven.add(`not run: ${name} (secret-scan.sh not found)`);
|
|
11721
11519
|
return;
|
|
@@ -11726,7 +11524,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
|
|
|
11726
11524
|
}
|
|
11727
11525
|
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"';
|
|
11728
11526
|
const started = Date.now();
|
|
11729
|
-
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) =>
|
|
11527
|
+
const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join47(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
|
|
11730
11528
|
const durationS = (Date.now() - started) / 1000;
|
|
11731
11529
|
if (r.exitCode === 3) {
|
|
11732
11530
|
checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: durationS });
|
|
@@ -11767,8 +11565,8 @@ async function postResults(ctx, opts, checks, notProven, statusState) {
|
|
|
11767
11565
|
const prNumber = prUrl ? PR_NUMBER_RE.exec(prUrl)?.[1] : undefined;
|
|
11768
11566
|
if (prNumber) {
|
|
11769
11567
|
mkdirSync17(ctx.runDir, { recursive: true });
|
|
11770
|
-
const bodyFile =
|
|
11771
|
-
|
|
11568
|
+
const bodyFile = join47(ctx.runDir, "deep-comment.md");
|
|
11569
|
+
writeFileSync19(bodyFile, buildCommentBody(checks, notProven, statusState), "utf8");
|
|
11772
11570
|
const commentResult = await run(["bash", scriptPath, ...commentArgv(prNumber, bodyFile)], { cwd: ctx.repoDir, env, timeoutMs: 30000 });
|
|
11773
11571
|
if (commentResult.exitCode !== 0)
|
|
11774
11572
|
out2.push(`deep comment not posted (engine10-push.sh exit ${commentResult.exitCode})`);
|
|
@@ -11821,7 +11619,7 @@ async function runDeep(ctx, signal, opts = {}) {
|
|
|
11821
11619
|
const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
|
|
11822
11620
|
const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
11823
11621
|
mkdirSync17(ctx.runDir, { recursive: true });
|
|
11824
|
-
|
|
11622
|
+
writeFileSync19(join47(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
|
|
11825
11623
|
`);
|
|
11826
11624
|
const pushNotProven = await postResults(ctx, opts, checks, notProvenList, statusState);
|
|
11827
11625
|
const allNotProven = [...notProvenList, ...pushNotProven];
|
|
@@ -11864,9 +11662,9 @@ var init_deep = __esm(() => {
|
|
|
11864
11662
|
});
|
|
11865
11663
|
|
|
11866
11664
|
// ../../loki-ts/src/engine10/stages/verify.ts
|
|
11867
|
-
import { existsSync as
|
|
11665
|
+
import { existsSync as existsSync28, mkdtempSync as mkdtempSync6, realpathSync as realpathSync17, rmSync as rmSync12 } from "fs";
|
|
11868
11666
|
import { tmpdir as tmpdir8 } from "os";
|
|
11869
|
-
import { dirname as
|
|
11667
|
+
import { dirname as dirname16, isAbsolute as isAbsolute6, join as join48, relative as relative5 } from "path";
|
|
11870
11668
|
function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
11871
11669
|
const inRepo = (p) => {
|
|
11872
11670
|
try {
|
|
@@ -11877,7 +11675,7 @@ function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
|
|
|
11877
11675
|
}
|
|
11878
11676
|
};
|
|
11879
11677
|
const venvEnv = process.env["VIRTUAL_ENV"];
|
|
11880
|
-
const project = [
|
|
11678
|
+
const project = [join48(repoDir, ".venv", "bin", bin), join48(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join48(venvEnv, "bin", bin)] : []].find(existsSync28);
|
|
11881
11679
|
return project ? [project, "project"] : [Bun.which(fallback) ? fallback : lastResort, "system"];
|
|
11882
11680
|
}
|
|
11883
11681
|
function runnerCmd(t, repoDir) {
|
|
@@ -11897,7 +11695,7 @@ function runnerCmd(t, repoDir) {
|
|
|
11897
11695
|
case "npm":
|
|
11898
11696
|
return ["npm", ["test", "--silent"]];
|
|
11899
11697
|
case "go":
|
|
11900
|
-
return ["go", ["test", "-json", `./${
|
|
11698
|
+
return ["go", ["test", "-json", `./${dirname16(t.path)}`]];
|
|
11901
11699
|
case "cargo":
|
|
11902
11700
|
return ["cargo", ["test"]];
|
|
11903
11701
|
}
|
|
@@ -11995,7 +11793,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
11995
11793
|
const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
|
|
11996
11794
|
if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length) || signal.aborted)
|
|
11997
11795
|
return out2;
|
|
11998
|
-
const dir = mkdtempSync6(
|
|
11796
|
+
const dir = mkdtempSync6(join48(tmpdir8(), "e10-base-"));
|
|
11999
11797
|
const git3 = (args) => {
|
|
12000
11798
|
safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
|
|
12001
11799
|
};
|
|
@@ -12030,7 +11828,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
|
|
|
12030
11828
|
return out2;
|
|
12031
11829
|
}
|
|
12032
11830
|
function isLokiModeRepo(repoDir) {
|
|
12033
|
-
return
|
|
11831
|
+
return existsSync28(join48(repoDir, "scripts", "select-tests.sh"));
|
|
12034
11832
|
}
|
|
12035
11833
|
async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
12036
11834
|
const { api, ...runOpts } = opts;
|
|
@@ -12047,9 +11845,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
|
|
|
12047
11845
|
}
|
|
12048
11846
|
for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
|
|
12049
11847
|
const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
|
|
12050
|
-
if (
|
|
11848
|
+
if (existsSync28(join48(g.cwd, "tsconfig.json")))
|
|
12051
11849
|
await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
|
|
12052
|
-
if (ESLINT_CONFIGS.some((f) =>
|
|
11850
|
+
if (ESLINT_CONFIGS.some((f) => existsSync28(join48(g.cwd, f))))
|
|
12053
11851
|
await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
|
|
12054
11852
|
}
|
|
12055
11853
|
}
|
|
@@ -12181,25 +11979,25 @@ var init_verify = __esm(() => {
|
|
|
12181
11979
|
});
|
|
12182
11980
|
|
|
12183
11981
|
// ../../loki-ts/src/project_model/conventions.ts
|
|
12184
|
-
import { existsSync as
|
|
12185
|
-
import { dirname as
|
|
12186
|
-
function parseJsonc(
|
|
11982
|
+
import { existsSync as existsSync29, readdirSync as readdirSync13, readFileSync as readFileSync34 } from "fs";
|
|
11983
|
+
import { dirname as dirname17, join as join49 } from "path";
|
|
11984
|
+
function parseJsonc(text2) {
|
|
12187
11985
|
let out2 = "", i = 0;
|
|
12188
|
-
while (i <
|
|
12189
|
-
const c =
|
|
11986
|
+
while (i < text2.length) {
|
|
11987
|
+
const c = text2[i], n2 = text2[i + 1];
|
|
12190
11988
|
if (c === '"') {
|
|
12191
11989
|
let j = i + 1;
|
|
12192
|
-
while (j <
|
|
12193
|
-
j +=
|
|
12194
|
-
out2 +=
|
|
11990
|
+
while (j < text2.length && text2[j] !== '"')
|
|
11991
|
+
j += text2[j] === "\\" ? 2 : 1;
|
|
11992
|
+
out2 += text2.slice(i, j + 1);
|
|
12195
11993
|
i = j + 1;
|
|
12196
11994
|
} else if (c === "/" && n2 === "/") {
|
|
12197
|
-
while (i <
|
|
11995
|
+
while (i < text2.length && text2[i] !== `
|
|
12198
11996
|
`)
|
|
12199
11997
|
i++;
|
|
12200
11998
|
} else if (c === "/" && n2 === "*") {
|
|
12201
|
-
const e =
|
|
12202
|
-
i = e < 0 ?
|
|
11999
|
+
const e = text2.indexOf("*/", i + 2);
|
|
12000
|
+
i = e < 0 ? text2.length : e + 2;
|
|
12203
12001
|
} else {
|
|
12204
12002
|
out2 += c;
|
|
12205
12003
|
i++;
|
|
@@ -12208,7 +12006,7 @@ function parseJsonc(text3) {
|
|
|
12208
12006
|
return JSON.parse(out2.replace(/,(\s*[}\]])/g, "$1"));
|
|
12209
12007
|
}
|
|
12210
12008
|
function moduleOf(file, depth = 0) {
|
|
12211
|
-
const j =
|
|
12009
|
+
const j = readJson4(file);
|
|
12212
12010
|
if (!j || depth > 4)
|
|
12213
12011
|
return null;
|
|
12214
12012
|
const m = j.compilerOptions?.module;
|
|
@@ -12217,25 +12015,25 @@ function moduleOf(file, depth = 0) {
|
|
|
12217
12015
|
const ext = typeof j.extends === "string" ? j.extends : null;
|
|
12218
12016
|
if (!ext || !ext.startsWith("."))
|
|
12219
12017
|
return null;
|
|
12220
|
-
const next =
|
|
12221
|
-
return
|
|
12018
|
+
const next = join49(dirname17(file), ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
12019
|
+
return existsSync29(next) ? moduleOf(next, depth + 1) : null;
|
|
12222
12020
|
}
|
|
12223
12021
|
function readPackageConventions(pkgDir, runner = null) {
|
|
12224
12022
|
let names = [];
|
|
12225
12023
|
try {
|
|
12226
|
-
names =
|
|
12024
|
+
names = readdirSync13(pkgDir).filter((f) => f.endsWith(".json")).sort((x, y) => x.length - y.length || x.localeCompare(y));
|
|
12227
12025
|
} catch {
|
|
12228
12026
|
return null;
|
|
12229
12027
|
}
|
|
12230
12028
|
let packageType = null, tsModule = null;
|
|
12231
12029
|
for (const n2 of names) {
|
|
12232
|
-
const j =
|
|
12030
|
+
const j = readJson4(join49(pkgDir, n2));
|
|
12233
12031
|
if (!j)
|
|
12234
12032
|
continue;
|
|
12235
12033
|
if (packageType === null && typeof j.type === "string" && typeof j.name === "string")
|
|
12236
12034
|
packageType = j.type;
|
|
12237
12035
|
if (tsModule === null && j.compilerOptions !== undefined)
|
|
12238
|
-
tsModule = moduleOf(
|
|
12036
|
+
tsModule = moduleOf(join49(pkgDir, n2));
|
|
12239
12037
|
}
|
|
12240
12038
|
if (packageType === null && tsModule === null)
|
|
12241
12039
|
return null;
|
|
@@ -12255,9 +12053,9 @@ function conventionViolation(c, fileName, content) {
|
|
|
12255
12053
|
const code = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1").replace(/(["'`])(?:\\.|(?!\1)[^\\\n])*\1/g, '""');
|
|
12256
12054
|
return /\bimport\.meta\b/.test(code) ? "import.meta is not allowed in a CommonJS package (TS1470)" : null;
|
|
12257
12055
|
}
|
|
12258
|
-
var
|
|
12056
|
+
var readJson4 = (p) => {
|
|
12259
12057
|
try {
|
|
12260
|
-
const v = parseJsonc(
|
|
12058
|
+
const v = parseJsonc(readFileSync34(p, "utf8"));
|
|
12261
12059
|
return v && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
12262
12060
|
} catch {
|
|
12263
12061
|
return null;
|
|
@@ -12267,15 +12065,15 @@ var init_conventions = () => {};
|
|
|
12267
12065
|
|
|
12268
12066
|
// ../../loki-ts/src/engine10/stages/wall.ts
|
|
12269
12067
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
12270
|
-
import { existsSync as
|
|
12068
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync18, mkdtempSync as mkdtempSync7, readFileSync as readFileSync35, readdirSync as readdirSync14, realpathSync as realpathSync18, rmSync as rmSync13, writeFileSync as writeFileSync20 } from "fs";
|
|
12271
12069
|
import { tmpdir as tmpdir9 } from "os";
|
|
12272
|
-
import { dirname as
|
|
12070
|
+
import { dirname as dirname18, isAbsolute as isAbsolute7, join as join50, relative as relative6 } from "path";
|
|
12273
12071
|
function pytestCollectionIsRed(output, repoDir) {
|
|
12274
12072
|
if (/ModuleNotFoundError/.test(output))
|
|
12275
12073
|
return false;
|
|
12276
12074
|
const real2 = (p) => {
|
|
12277
12075
|
try {
|
|
12278
|
-
return realpathSync18(isAbsolute7(p) ? p :
|
|
12076
|
+
return realpathSync18(isAbsolute7(p) ? p : join50(repoDir, p));
|
|
12279
12077
|
} catch {
|
|
12280
12078
|
return null;
|
|
12281
12079
|
}
|
|
@@ -12312,7 +12110,7 @@ function pytestCollectionIsRed(output, repoDir) {
|
|
|
12312
12110
|
}
|
|
12313
12111
|
function moduleUnderRepo(repoDir, name) {
|
|
12314
12112
|
const rel = name.replace(/\./g, "/");
|
|
12315
|
-
return
|
|
12113
|
+
return existsSync30(join50(repoDir, `${rel}.py`)) || existsSync30(join50(repoDir, rel, "__init__.py"));
|
|
12316
12114
|
}
|
|
12317
12115
|
function pytestExit1IsRed(output) {
|
|
12318
12116
|
if (/^!+ _pytest\.outcomes\.Exit\b/m.test(output))
|
|
@@ -12407,22 +12205,22 @@ ${repomapText}`] : [],
|
|
|
12407
12205
|
function loadTaskText(ctx, fromPrior) {
|
|
12408
12206
|
if (fromPrior)
|
|
12409
12207
|
return fromPrior;
|
|
12410
|
-
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ??
|
|
12411
|
-
if (
|
|
12208
|
+
const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join50(ctx.runDir, "issue.json");
|
|
12209
|
+
if (existsSync30(issueJsonPath)) {
|
|
12412
12210
|
try {
|
|
12413
|
-
const issue = JSON.parse(
|
|
12414
|
-
const
|
|
12211
|
+
const issue = JSON.parse(readFileSync35(issueJsonPath, "utf8"));
|
|
12212
|
+
const text2 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
|
|
12415
12213
|
|
|
12416
12214
|
`);
|
|
12417
|
-
if (
|
|
12418
|
-
return
|
|
12215
|
+
if (text2)
|
|
12216
|
+
return text2;
|
|
12419
12217
|
} catch {}
|
|
12420
12218
|
}
|
|
12421
12219
|
return process.env.LOKI_E10_TASK_TEXT ?? "";
|
|
12422
12220
|
}
|
|
12423
12221
|
function wallTargetDir(repoDir, existingTests) {
|
|
12424
12222
|
const first = existingTests[0];
|
|
12425
|
-
return first ?
|
|
12223
|
+
return first ? join50(repoDir, dirname18(first.path)) : join50(repoDir, "tests");
|
|
12426
12224
|
}
|
|
12427
12225
|
function guessRunner(fileName, runners) {
|
|
12428
12226
|
if (fileName.endsWith(".py"))
|
|
@@ -12453,11 +12251,11 @@ async function wallAuthor(ctx, signal) {
|
|
|
12453
12251
|
const tree = prior.intake?.tree;
|
|
12454
12252
|
const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
|
|
12455
12253
|
const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative6(ctx.repoDir, targetDir)}/x`);
|
|
12456
|
-
const conv2 = readPackageConventions(
|
|
12457
|
-
const cwd = mkdtempSync7(
|
|
12254
|
+
const conv2 = readPackageConventions(join50(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
|
|
12255
|
+
const cwd = mkdtempSync7(join50(tmpdir9(), "loki-e15-wall-"));
|
|
12458
12256
|
const wm = wallManifestFor(ctx.repoDir, tree, task);
|
|
12459
12257
|
for (const [n2, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm ? [["wall_manifest.txt", wm.text]] : []])
|
|
12460
|
-
|
|
12258
|
+
writeFileSync20(join50(cwd, n2), c, "utf8");
|
|
12461
12259
|
const session = await ctx.sessions.run({
|
|
12462
12260
|
stage: "wall",
|
|
12463
12261
|
brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2)),
|
|
@@ -12472,15 +12270,15 @@ async function wallAuthor(ctx, signal) {
|
|
|
12472
12270
|
rmSync13(cwd, { recursive: true, force: true });
|
|
12473
12271
|
return done({ status: "failed", data: {}, reason: "wall session aborted, killed, or timed out", killed: true });
|
|
12474
12272
|
}
|
|
12475
|
-
const generated =
|
|
12476
|
-
const sealedDir =
|
|
12273
|
+
const generated = readdirSync14(cwd).filter((f) => f.startsWith(WALL_PREFIX));
|
|
12274
|
+
const sealedDir = join50(ctx.runDir, "wall");
|
|
12477
12275
|
if (generated.length > 0)
|
|
12478
12276
|
mkdirSync18(sealedDir, { recursive: true });
|
|
12479
12277
|
const contents = new Map;
|
|
12480
12278
|
const discarded = [];
|
|
12481
12279
|
for (const name of generated) {
|
|
12482
|
-
const content =
|
|
12483
|
-
|
|
12280
|
+
const content = readFileSync35(join50(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
|
|
12281
|
+
writeFileSync20(join50(sealedDir, name), content, "utf8");
|
|
12484
12282
|
if (bad)
|
|
12485
12283
|
discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
|
|
12486
12284
|
else
|
|
@@ -12500,8 +12298,8 @@ function installWall(ctx, a, baseDir, opts = {}) {
|
|
|
12500
12298
|
const content = contents.get(name);
|
|
12501
12299
|
if (content === undefined)
|
|
12502
12300
|
continue;
|
|
12503
|
-
const dest =
|
|
12504
|
-
|
|
12301
|
+
const dest = join50(targetDir, name), runner = guessRunner(name, runners);
|
|
12302
|
+
writeFileSync20(dest, content, "utf8");
|
|
12505
12303
|
sealedFiles.push({ path: dest, sha256: sha2562(content) });
|
|
12506
12304
|
readOnlyFiles.push({ path: dest, content });
|
|
12507
12305
|
if (runner)
|
|
@@ -12510,7 +12308,7 @@ function installWall(ctx, a, baseDir, opts = {}) {
|
|
|
12510
12308
|
ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
|
|
12511
12309
|
const baseRunner = opts.baseRunner ?? new RealBaseTestRunner, baseRun = { pass: 0, fail: 0, not_run: discarded.length }, notRunFiles = [];
|
|
12512
12310
|
for (const t of wallTests) {
|
|
12513
|
-
const r = baseRunner.run(baseDir, [t]), abs =
|
|
12311
|
+
const r = baseRunner.run(baseDir, [t]), abs = join50(ctx.repoDir, t.path);
|
|
12514
12312
|
baseRun.pass += r.pass;
|
|
12515
12313
|
baseRun.fail += r.fail;
|
|
12516
12314
|
baseRun.not_run += r.not_run ?? 0;
|
|
@@ -12561,15 +12359,15 @@ var init_wall = __esm(() => {
|
|
|
12561
12359
|
});
|
|
12562
12360
|
|
|
12563
12361
|
// ../../loki-ts/src/e10ext/discard.ts
|
|
12564
|
-
import { chmodSync as chmodSync4, closeSync as closeSync8, lstatSync as lstatSync10, mkdirSync as mkdirSync19, openSync as openSync8, readFileSync as
|
|
12565
|
-
import { dirname as
|
|
12362
|
+
import { chmodSync as chmodSync4, closeSync as closeSync8, lstatSync as lstatSync10, mkdirSync as mkdirSync19, openSync as openSync8, readFileSync as readFileSync36, realpathSync as realpathSync19, rmdirSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync21 } from "fs";
|
|
12363
|
+
import { dirname as dirname19, join as join51, relative as relative7, sep as sep11 } from "path";
|
|
12566
12364
|
function safeRestore(repoDir, f, want, mode) {
|
|
12567
|
-
const root = realpathSync19(repoDir), fp =
|
|
12365
|
+
const root = realpathSync19(repoDir), fp = join51(root, f), rel = relative7(root, dirname19(fp));
|
|
12568
12366
|
if (rel.startsWith(".."))
|
|
12569
12367
|
throw new Error("outside repo");
|
|
12570
12368
|
let cur = root;
|
|
12571
12369
|
for (const part of rel === "" ? [] : rel.split(sep11)) {
|
|
12572
|
-
cur =
|
|
12370
|
+
cur = join51(cur, part);
|
|
12573
12371
|
let st2;
|
|
12574
12372
|
try {
|
|
12575
12373
|
st2 = lstatSync10(cur);
|
|
@@ -12586,7 +12384,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
12586
12384
|
} catch {
|
|
12587
12385
|
st = null;
|
|
12588
12386
|
}
|
|
12589
|
-
if (st?.isFile() &&
|
|
12387
|
+
if (st?.isFile() && readFileSync36(fp).equals(want)) {
|
|
12590
12388
|
chmodSync4(fp, mode);
|
|
12591
12389
|
return;
|
|
12592
12390
|
}
|
|
@@ -12598,7 +12396,7 @@ function safeRestore(repoDir, f, want, mode) {
|
|
|
12598
12396
|
}
|
|
12599
12397
|
const fd = openSync8(fp, "wx", mode);
|
|
12600
12398
|
try {
|
|
12601
|
-
|
|
12399
|
+
writeFileSync21(fd, want);
|
|
12602
12400
|
} finally {
|
|
12603
12401
|
closeSync8(fd);
|
|
12604
12402
|
}
|
|
@@ -12608,10 +12406,10 @@ function alreadySatisfied(o) {
|
|
|
12608
12406
|
const b = o.wall?.base_run ?? {};
|
|
12609
12407
|
return o.intake?.already_satisfied === true || o.implement?.exit === "already_done" || typeof b.pass === "number" && b.pass > 0 && b.fail === 0 && (b.not_run ?? 0) === 0;
|
|
12610
12408
|
}
|
|
12611
|
-
function catBlob(repoDir,
|
|
12612
|
-
const r = safeGitSpawn(repoDir, ["cat-file", "blob",
|
|
12409
|
+
function catBlob(repoDir, sha2) {
|
|
12410
|
+
const r = safeGitSpawn(repoDir, ["cat-file", "blob", sha2], { maxBuffer: 1 << 28 });
|
|
12613
12411
|
if (r.error || r.status !== 0)
|
|
12614
|
-
throw r.error ?? new Error(`git cat-file blob ${
|
|
12412
|
+
throw r.error ?? new Error(`git cat-file blob ${sha2} failed`);
|
|
12615
12413
|
return r.stdout;
|
|
12616
12414
|
}
|
|
12617
12415
|
async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
@@ -12624,7 +12422,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
12624
12422
|
return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
|
|
12625
12423
|
const notProven = [];
|
|
12626
12424
|
for (const [f, v] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
|
|
12627
|
-
const fp =
|
|
12425
|
+
const fp = join51(repoDir, f);
|
|
12628
12426
|
try {
|
|
12629
12427
|
if (v.startsWith("!")) {
|
|
12630
12428
|
const st = lstatSync10(fp);
|
|
@@ -12632,7 +12430,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
12632
12430
|
throw new Error("changed, not snapshotted");
|
|
12633
12431
|
continue;
|
|
12634
12432
|
}
|
|
12635
|
-
const [
|
|
12433
|
+
const [sha2, mode] = v.split(" "), want = catBlob(repoDir, sha2);
|
|
12636
12434
|
safeRestore(repoDir, f, want, parseInt(mode ?? "644", 8));
|
|
12637
12435
|
} catch {
|
|
12638
12436
|
notProven.push(f);
|
|
@@ -12643,7 +12441,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
|
|
|
12643
12441
|
try {
|
|
12644
12442
|
let m = 420;
|
|
12645
12443
|
try {
|
|
12646
|
-
const l = lstatSync10(
|
|
12444
|
+
const l = lstatSync10(join51(repoDir, f));
|
|
12647
12445
|
if (l.isFile())
|
|
12648
12446
|
m = l.mode & 511;
|
|
12649
12447
|
} catch {}
|
|
@@ -12676,9 +12474,9 @@ var init_preexisting_dirty = __esm(() => {
|
|
|
12676
12474
|
});
|
|
12677
12475
|
|
|
12678
12476
|
// ../../loki-ts/src/e10ext/commit_filter.ts
|
|
12679
|
-
import { dirname as
|
|
12477
|
+
import { dirname as dirname20 } from "path";
|
|
12680
12478
|
function dropSet(repoDir, staged, preexistingDirty, env = process.env) {
|
|
12681
|
-
return staged.concat(untouchedSinceIntake(repoDir, preexistingDirty, env).map((f) => ({ st: "L", f }))).filter(({ st, f }) => f.startsWith(".loki/") || st === "L" || /(^|\/)loki_wall_[^/]*$/.test(f) || st === "A" && !staged.some(({ f: m }) => /(^|\/)(package\.json|pyproject\.toml|requirements\.txt|Cargo\.toml|go\.mod)$/.test(m) &&
|
|
12479
|
+
return staged.concat(untouchedSinceIntake(repoDir, preexistingDirty, env).map((f) => ({ st: "L", f }))).filter(({ st, f }) => f.startsWith(".loki/") || st === "L" || /(^|\/)loki_wall_[^/]*$/.test(f) || st === "A" && !staged.some(({ f: m }) => /(^|\/)(package\.json|pyproject\.toml|requirements\.txt|Cargo\.toml|go\.mod)$/.test(m) && dirname20(m) === dirname20(f)) && /(^|\/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb?|poetry\.lock|Cargo\.lock|go\.sum)$/.test(f));
|
|
12682
12480
|
}
|
|
12683
12481
|
var parseStaged = (out2) => out2.split("\x00").reduce((a, t, i, all) => i % 2 === 0 && t ? [...a, { st: t, f: all[i + 1] }] : a, []);
|
|
12684
12482
|
var init_commit_filter = __esm(() => {
|
|
@@ -12687,7 +12485,7 @@ var init_commit_filter = __esm(() => {
|
|
|
12687
12485
|
});
|
|
12688
12486
|
|
|
12689
12487
|
// ../../loki-ts/src/e10ext/scope.ts
|
|
12690
|
-
import { basename as basename18, dirname as
|
|
12488
|
+
import { basename as basename18, dirname as dirname21 } from "path";
|
|
12691
12489
|
function contractText(o) {
|
|
12692
12490
|
const c = o.intake?.contract_snapshot?.contract;
|
|
12693
12491
|
return Array.isArray(c?.criteria) ? c.criteria.map((x) => typeof x?.text === "string" ? x.text : "").join(`
|
|
@@ -12698,18 +12496,18 @@ function outsideScope(o, staged) {
|
|
|
12698
12496
|
const plan = typeof o.plan?.plan === "string" ? o.plan.plan : "";
|
|
12699
12497
|
if (rel.length === 0 && plan.trim() === "")
|
|
12700
12498
|
return null;
|
|
12701
|
-
const
|
|
12499
|
+
const text2 = `${plan}
|
|
12702
12500
|
${typeof o.intake?.task === "string" ? o.intake.task : ""}
|
|
12703
12501
|
${contractText(o)}`, pre = o.intake?.preexisting_dirty ?? {};
|
|
12704
|
-
const toks = surfaceTokens(
|
|
12705
|
-
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(
|
|
12502
|
+
const toks = surfaceTokens(text2), plannedDirs = new Set(rel.map((r) => dirname21(r)).filter((d) => d !== "."));
|
|
12503
|
+
return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename18(f)) && !plannedDirs.has(dirname21(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
|
|
12706
12504
|
}
|
|
12707
12505
|
function flagOutsideScope(o, staged) {
|
|
12708
12506
|
const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
|
|
12709
12507
|
const un = outsideScope(o, staged), seen = new Set((unit ?? []).map(outsideNote));
|
|
12710
12508
|
return [...(unit ?? []).map(outsideNote), ...un ? un.map(outsideNote).filter((n2) => !seen.has(n2)) : staged.length > 0 ? [SCOPE_UNDETERMINED] : []];
|
|
12711
12509
|
}
|
|
12712
|
-
var SCOPE_UNDETERMINED = "scope not determined; all edits committed", outsideNote = (f) => `outside stated scope: ${f}`, esc2 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), mentions = (
|
|
12510
|
+
var SCOPE_UNDETERMINED = "scope not determined; all edits committed", outsideNote = (f) => `outside stated scope: ${f}`, esc2 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), mentions = (text2, name) => new RegExp(`(?<![\\w./-])${esc2(name)}(?![\\w-]|\\.\\w)`).test(text2), STOP, stem = (w) => w.length > 3 && w.endsWith("s") ? w.slice(0, -1) : w, surfaceTokens = (text2) => new Set((text2.toLowerCase().match(/[a-z][a-z0-9_-]{2,}/g) ?? []).filter((w) => !STOP.has(w)).map(stem)), dirSegs = (f) => f.split("/").slice(0, -1).map((d) => stem(d.toLowerCase()));
|
|
12713
12511
|
var init_scope2 = __esm(() => {
|
|
12714
12512
|
init_testmap();
|
|
12715
12513
|
init_unit_mode();
|
|
@@ -12717,10 +12515,10 @@ var init_scope2 = __esm(() => {
|
|
|
12717
12515
|
});
|
|
12718
12516
|
|
|
12719
12517
|
// ../../loki-ts/src/util/receipt_signer.ts
|
|
12720
|
-
import { createHash as
|
|
12721
|
-
import { chmodSync as chmodSync5, linkSync, mkdirSync as mkdirSync20, readFileSync as
|
|
12518
|
+
import { createHash as createHash10, randomBytes as randomBytes3, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, sign } from "crypto";
|
|
12519
|
+
import { chmodSync as chmodSync5, linkSync, mkdirSync as mkdirSync20, readFileSync as readFileSync37, statSync as statSync16, unlinkSync as unlinkSync5, writeFileSync as writeFileSync22 } from "fs";
|
|
12722
12520
|
import { homedir as homedir8 } from "os";
|
|
12723
|
-
import { dirname as
|
|
12521
|
+
import { dirname as dirname22, join as join52 } from "path";
|
|
12724
12522
|
function canonicalJson(x) {
|
|
12725
12523
|
const walk = (v) => {
|
|
12726
12524
|
if (Array.isArray(v))
|
|
@@ -12739,21 +12537,21 @@ function loadSigningKey(generate = true) {
|
|
|
12739
12537
|
let pem = inline ?? "";
|
|
12740
12538
|
if (!inline) {
|
|
12741
12539
|
const given = process.env["LOKI_RECEIPT_SIGNING_KEY_FILE"]?.trim();
|
|
12742
|
-
const file = given ||
|
|
12540
|
+
const file = given || join52(process.env["HOME"] || homedir8(), ".loki", "keys", RECEIPT_SIGNER_BASENAME);
|
|
12743
12541
|
try {
|
|
12744
|
-
pem =
|
|
12542
|
+
pem = readFileSync37(file);
|
|
12745
12543
|
if (!given) {
|
|
12746
|
-
for (const [f, m] of [[file, 384], [
|
|
12747
|
-
if (
|
|
12544
|
+
for (const [f, m] of [[file, 384], [dirname22(file), 448]])
|
|
12545
|
+
if (statSync16(f).mode & 63)
|
|
12748
12546
|
chmodSync5(f, m);
|
|
12749
12547
|
}
|
|
12750
12548
|
} catch (e) {
|
|
12751
12549
|
if (e.code !== "ENOENT" || !generate)
|
|
12752
12550
|
return null;
|
|
12753
|
-
mkdirSync20(
|
|
12754
|
-
mkdirSync20(
|
|
12551
|
+
mkdirSync20(dirname22(dirname22(file)), { recursive: true, mode: 448 });
|
|
12552
|
+
mkdirSync20(dirname22(file), { recursive: true, mode: 448 });
|
|
12755
12553
|
const tmp = `${file}.${randomBytes3(6).toString("hex")}.tmp`;
|
|
12756
|
-
|
|
12554
|
+
writeFileSync22(tmp, generateKeyPairSync("ed25519").privateKey.export({ type: "pkcs8", format: "pem" }), { flag: "wx", mode: 384 });
|
|
12757
12555
|
try {
|
|
12758
12556
|
linkSync(tmp, file);
|
|
12759
12557
|
} catch (l) {
|
|
@@ -12762,7 +12560,7 @@ function loadSigningKey(generate = true) {
|
|
|
12762
12560
|
} finally {
|
|
12763
12561
|
unlinkSync5(tmp);
|
|
12764
12562
|
}
|
|
12765
|
-
pem =
|
|
12563
|
+
pem = readFileSync37(file);
|
|
12766
12564
|
}
|
|
12767
12565
|
}
|
|
12768
12566
|
const k = createPrivateKey(pem);
|
|
@@ -12779,15 +12577,15 @@ function signReceipt(runId, hash) {
|
|
|
12779
12577
|
const input = `${b64u(canonicalJson({ alg: "EdDSA", typ: "JWT", kid }))}.${b64u(canonicalJson({ job_id: runId, run_id: runId, receipt_sha256: hash, iat: Math.floor(Date.now() / 1000) }))}`;
|
|
12780
12578
|
return { jwt: `${input}.${b64u(sign(null, Buffer.from(input), key))}`, kid };
|
|
12781
12579
|
}
|
|
12782
|
-
var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem", b64u = (b) => Buffer.from(b).toString("base64url"), kidOf2 = (pub) => b64u(
|
|
12580
|
+
var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem", b64u = (b) => Buffer.from(b).toString("base64url"), kidOf2 = (pub) => b64u(createHash10("sha256").update(`{"crv":"Ed25519","kty":"OKP","x":"${pub.export({ format: "jwk" }).x}"}`).digest());
|
|
12783
12581
|
var init_receipt_signer = () => {};
|
|
12784
12582
|
|
|
12785
12583
|
// ../../loki-ts/src/features/visual_evidence.ts
|
|
12786
12584
|
import { spawn as spawn7 } from "child_process";
|
|
12787
|
-
import { createHash as
|
|
12788
|
-
import { existsSync as
|
|
12585
|
+
import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
|
|
12586
|
+
import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readdirSync as readdirSync15, readFileSync as readFileSync38, writeFileSync as writeFileSync23 } from "fs";
|
|
12789
12587
|
import { createServer } from "net";
|
|
12790
|
-
import { dirname as
|
|
12588
|
+
import { dirname as dirname23, isAbsolute as isAbsolute8, join as join53, normalize as normalize2, relative as relative8, sep as sep12 } from "path";
|
|
12791
12589
|
function routeFor(file) {
|
|
12792
12590
|
let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
|
|
12793
12591
|
r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
|
|
@@ -12797,7 +12595,7 @@ function hashScreens(runDir, rels) {
|
|
|
12797
12595
|
const out2 = [];
|
|
12798
12596
|
for (const rel of rels) {
|
|
12799
12597
|
try {
|
|
12800
|
-
out2.push({ path: rel, sha256: sha256File(
|
|
12598
|
+
out2.push({ path: rel, sha256: sha256File(join53(runDir, rel)) });
|
|
12801
12599
|
} catch {}
|
|
12802
12600
|
}
|
|
12803
12601
|
return out2;
|
|
@@ -12810,14 +12608,14 @@ function checkScreens(runDir, screens) {
|
|
|
12810
12608
|
return "evidence_screens entry is malformed";
|
|
12811
12609
|
if (isAbsolute8(s.path) || normalize2(s.path).startsWith(".."))
|
|
12812
12610
|
return `evidence screenshot path escapes the evidence dir: ${s.path}`;
|
|
12813
|
-
const file =
|
|
12611
|
+
const file = join53(runDir, s.path);
|
|
12814
12612
|
let cur = runDir;
|
|
12815
12613
|
for (const seg of normalize2(s.path).split(sep12)) {
|
|
12816
|
-
cur =
|
|
12614
|
+
cur = join53(cur, seg);
|
|
12817
12615
|
if (isSymlink(cur))
|
|
12818
12616
|
return `evidence screenshot path is a symlink: ${s.path}`;
|
|
12819
12617
|
}
|
|
12820
|
-
if (!
|
|
12618
|
+
if (!existsSync31(file))
|
|
12821
12619
|
return `evidence screenshot is missing: ${s.path}`;
|
|
12822
12620
|
if (!isRegularFile(file))
|
|
12823
12621
|
return `evidence screenshot is not a regular file: ${s.path}`;
|
|
@@ -12860,11 +12658,11 @@ async function waitUp(url, ms, signal) {
|
|
|
12860
12658
|
}
|
|
12861
12659
|
function openapiPaths(repoDir) {
|
|
12862
12660
|
for (const f of ["openapi.json", "openapi.yaml", "openapi.yml", "swagger.json"]) {
|
|
12863
|
-
const p =
|
|
12864
|
-
if (!
|
|
12661
|
+
const p = join53(repoDir, f);
|
|
12662
|
+
if (!existsSync31(p))
|
|
12865
12663
|
continue;
|
|
12866
12664
|
try {
|
|
12867
|
-
const txt =
|
|
12665
|
+
const txt = readFileSync38(p, "utf8");
|
|
12868
12666
|
const paths = f.endsWith(".json") ? Object.keys(JSON.parse(txt).paths ?? {}) : [...txt.matchAll(/^ {2}(\/[^\s:]*):\s*$/gm)].map((m) => m[1]);
|
|
12869
12667
|
return paths.filter((x) => !x.includes("{")).slice(0, 10);
|
|
12870
12668
|
} catch {
|
|
@@ -12878,24 +12676,24 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
|
|
|
12878
12676
|
if (!pw || !pkg)
|
|
12879
12677
|
return { rels: [], skipped: "playwright e2e video and trace skipped: @playwright/test is not installed in the repo" };
|
|
12880
12678
|
try {
|
|
12881
|
-
const dir =
|
|
12679
|
+
const dir = join53(runDir, relDir, "e2e");
|
|
12882
12680
|
mkdirSync21(dir, { recursive: true });
|
|
12883
|
-
|
|
12884
|
-
|
|
12681
|
+
writeFileSync23(join53(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
|
|
12682
|
+
writeFileSync23(join53(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
|
|
12885
12683
|
`);
|
|
12886
|
-
if (!await shoot(pw, ["test", "--config",
|
|
12684
|
+
if (!await shoot(pw, ["test", "--config", join53(dir, "playwright.config.cjs")], repoDir, ms, signal))
|
|
12887
12685
|
return { rels: [], skipped: "playwright e2e video and trace skipped: the run failed or timed out" };
|
|
12888
12686
|
const rels = [];
|
|
12889
12687
|
const walk = (d) => {
|
|
12890
|
-
for (const e of
|
|
12891
|
-
const full =
|
|
12688
|
+
for (const e of readdirSync15(d, { withFileTypes: true })) {
|
|
12689
|
+
const full = join53(d, e.name);
|
|
12892
12690
|
if (e.isDirectory())
|
|
12893
12691
|
walk(full);
|
|
12894
12692
|
else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
|
|
12895
|
-
rels.push(
|
|
12693
|
+
rels.push(join53(relDir, "e2e", relative8(dir, full)));
|
|
12896
12694
|
}
|
|
12897
12695
|
};
|
|
12898
|
-
walk(
|
|
12696
|
+
walk(join53(dir, "out"));
|
|
12899
12697
|
return rels.length > 0 ? { rels, skipped: null } : { rels, skipped: "playwright e2e video and trace skipped: no video or trace was produced" };
|
|
12900
12698
|
} catch (e) {
|
|
12901
12699
|
return { rels: [], skipped: `playwright e2e video and trace skipped: ${String(e?.message ?? e).slice(0, 120)}` };
|
|
@@ -12964,13 +12762,13 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
12964
12762
|
if (!visualEvidenceEnabled(opts.env))
|
|
12965
12763
|
return skip("LOKI_VISUAL_EVIDENCE is 0");
|
|
12966
12764
|
const api = loadProjectApi(repoDir), boot = isMultiRoot(api) ? api.uiBoot() : null;
|
|
12967
|
-
const appDir = boot ?
|
|
12968
|
-
const pkgPath =
|
|
12765
|
+
const appDir = boot ? join53(repoDir, boot.boot.cwd) : repoDir;
|
|
12766
|
+
const pkgPath = join53(appDir, "package.json");
|
|
12969
12767
|
let script = null;
|
|
12970
12768
|
if (!boot) {
|
|
12971
|
-
if (!
|
|
12769
|
+
if (!existsSync31(pkgPath))
|
|
12972
12770
|
return skip("no package.json");
|
|
12973
|
-
script = pickScript(JSON.parse(
|
|
12771
|
+
script = pickScript(JSON.parse(readFileSync38(pkgPath, "utf8")));
|
|
12974
12772
|
if (!script)
|
|
12975
12773
|
return skip("no dev, preview or start script");
|
|
12976
12774
|
}
|
|
@@ -12997,20 +12795,20 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
12997
12795
|
}
|
|
12998
12796
|
if (!await waitUp(base, left(), signal))
|
|
12999
12797
|
return skip(aborted() ? "aborted" : `${script} server did not answer within ${Math.round(budget / 1000)}s`);
|
|
13000
|
-
const evRoot =
|
|
12798
|
+
const evRoot = join53(runDir, "evidence");
|
|
13001
12799
|
if (isSymlink(evRoot))
|
|
13002
12800
|
return skip("evidence dir is a symlink");
|
|
13003
12801
|
mkdirSync21(evRoot, { recursive: true });
|
|
13004
12802
|
if (pages.length > 0) {
|
|
13005
|
-
const rel0 =
|
|
13006
|
-
mkdirSync21(
|
|
12803
|
+
const rel0 = join53("evidence", randomBytes4(6).toString("hex"));
|
|
12804
|
+
mkdirSync21(join53(runDir, rel0));
|
|
13007
12805
|
const rels = [];
|
|
13008
12806
|
for (const route of [...new Set(pages.map(routeFor))].slice(0, opts.maxRoutes ?? MAX_ROUTES)) {
|
|
13009
12807
|
if (aborted() || left() <= 0)
|
|
13010
12808
|
break;
|
|
13011
|
-
const rel =
|
|
13012
|
-
const ok = await shoot(pw, ["screenshot", `${base}${route}`,
|
|
13013
|
-
if (ok && !aborted() && !isSymlink(
|
|
12809
|
+
const rel = join53(rel0, `${screenName(route)}.png`);
|
|
12810
|
+
const ok = await shoot(pw, ["screenshot", `${base}${route}`, join53(runDir, rel)], appDir, left(), signal);
|
|
12811
|
+
if (ok && !aborted() && !isSymlink(join53(runDir, rel)) && existsSync31(join53(runDir, rel)))
|
|
13014
12812
|
rels.push(rel);
|
|
13015
12813
|
}
|
|
13016
12814
|
if (aborted())
|
|
@@ -13035,9 +12833,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
|
|
|
13035
12833
|
}
|
|
13036
12834
|
if (aborted())
|
|
13037
12835
|
return skip("aborted");
|
|
13038
|
-
const hdir =
|
|
12836
|
+
const hdir = join53(evRoot, randomBytes4(6).toString("hex"));
|
|
13039
12837
|
mkdirSync21(hdir);
|
|
13040
|
-
|
|
12838
|
+
writeFileSync23(join53(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
|
|
13041
12839
|
`);
|
|
13042
12840
|
return { screens: [], http: true, skipped: null };
|
|
13043
12841
|
} catch (e) {
|
|
@@ -13060,14 +12858,14 @@ async function sealEvidence(repoDir, runDir, o, notProven, signal, emit) {
|
|
|
13060
12858
|
return ev.screens.length > 0 ? { evidence_screens: ev.screens } : {};
|
|
13061
12859
|
}
|
|
13062
12860
|
function receiptScreensProblem(receiptPath, receipt) {
|
|
13063
|
-
return receipt["evidence_screens"] === undefined ? null : checkScreens(
|
|
12861
|
+
return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname23(receiptPath), receipt["evidence_screens"]);
|
|
13064
12862
|
}
|
|
13065
|
-
var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) =>
|
|
13066
|
-
const bin =
|
|
13067
|
-
return
|
|
12863
|
+
var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash11("sha256").update(readFileSync38(p)).digest("hex"), playwrightBin = (repoDir) => {
|
|
12864
|
+
const bin = join53(repoDir, "node_modules", ".bin", "playwright");
|
|
12865
|
+
return existsSync31(bin) ? bin : null;
|
|
13068
12866
|
}, playwrightTestPkg = (repoDir) => {
|
|
13069
|
-
const d =
|
|
13070
|
-
return
|
|
12867
|
+
const d = join53(repoDir, "node_modules", "@playwright", "test");
|
|
12868
|
+
return existsSync31(join53(d, "package.json")) ? d : null;
|
|
13071
12869
|
}, e2eSpecSource = (pkgDir, base, routes) => `const { test } = require(${JSON.stringify(pkgDir)});
|
|
13072
12870
|
test("loki e2e walkthrough", async ({ page }) => {
|
|
13073
12871
|
for (const r of ${JSON.stringify(routes)}) { await page.goto(${JSON.stringify(base)} + r); await page.waitForLoadState("load"); }
|
|
@@ -13098,14 +12896,14 @@ var init_visual_evidence = __esm(() => {
|
|
|
13098
12896
|
});
|
|
13099
12897
|
|
|
13100
12898
|
// ../../loki-ts/src/council/role_agents.ts
|
|
13101
|
-
import { existsSync as
|
|
12899
|
+
import { existsSync as existsSync32, readdirSync as readdirSync16, readFileSync as readFileSync39 } from "fs";
|
|
13102
12900
|
import { homedir as homedir9 } from "os";
|
|
13103
|
-
import { join as
|
|
12901
|
+
import { join as join54 } from "path";
|
|
13104
12902
|
function agentDirs(repoDir, env = process.env) {
|
|
13105
|
-
return [env["LOKI_AGENTS_PROJECT_DIR"] ||
|
|
12903
|
+
return [env["LOKI_AGENTS_PROJECT_DIR"] || join54(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join54(env["XDG_CONFIG_HOME"] || join54(homedir9(), ".config"), "loki", "agents")];
|
|
13106
12904
|
}
|
|
13107
12905
|
function parseAgent(file, stem2) {
|
|
13108
|
-
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(
|
|
12906
|
+
const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync39(file, "utf8"));
|
|
13109
12907
|
if (!m)
|
|
13110
12908
|
return null;
|
|
13111
12909
|
const body = m[2].trim();
|
|
@@ -13119,18 +12917,18 @@ function parseAgent(file, stem2) {
|
|
|
13119
12917
|
}
|
|
13120
12918
|
function loadRoleAgent(repoDir, role, env = process.env) {
|
|
13121
12919
|
for (const d of agentDirs(repoDir, env)) {
|
|
13122
|
-
if (!
|
|
12920
|
+
if (!existsSync32(d))
|
|
13123
12921
|
continue;
|
|
13124
12922
|
let names;
|
|
13125
12923
|
try {
|
|
13126
|
-
names =
|
|
12924
|
+
names = readdirSync16(d).filter((n2) => n2.endsWith(".md") && !n2.startsWith(".")).sort();
|
|
13127
12925
|
} catch {
|
|
13128
12926
|
continue;
|
|
13129
12927
|
}
|
|
13130
12928
|
const ordered = [...names.filter((n2) => n2 === `${role}.md`), ...names.filter((n2) => n2 !== `${role}.md`)];
|
|
13131
12929
|
for (const n2 of ordered) {
|
|
13132
12930
|
try {
|
|
13133
|
-
const a = parseAgent(
|
|
12931
|
+
const a = parseAgent(join54(d, n2), n2.slice(0, -3));
|
|
13134
12932
|
if (a && a.role === role)
|
|
13135
12933
|
return a;
|
|
13136
12934
|
} catch {}
|
|
@@ -13147,8 +12945,8 @@ var init_role_agents = __esm(() => {
|
|
|
13147
12945
|
});
|
|
13148
12946
|
|
|
13149
12947
|
// ../../loki-ts/src/engine10/stages/xreview.ts
|
|
13150
|
-
import { existsSync as
|
|
13151
|
-
import { join as
|
|
12948
|
+
import { existsSync as existsSync33, readFileSync as readFileSync40 } from "fs";
|
|
12949
|
+
import { join as join55 } from "path";
|
|
13152
12950
|
function minVerdict(verdict, review) {
|
|
13153
12951
|
const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
|
|
13154
12952
|
return RANK3[ceiling] < RANK3[verdict] ? ceiling : verdict;
|
|
@@ -13161,11 +12959,11 @@ function explicitReview(repoDir, env) {
|
|
|
13161
12959
|
if (flag && isOff(ev))
|
|
13162
12960
|
return "off";
|
|
13163
12961
|
for (const f of ["loki.yaml", "loki.yml"]) {
|
|
13164
|
-
const p =
|
|
13165
|
-
if (!
|
|
12962
|
+
const p = join55(repoDir, f);
|
|
12963
|
+
if (!existsSync33(p))
|
|
13166
12964
|
continue;
|
|
13167
12965
|
try {
|
|
13168
|
-
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(
|
|
12966
|
+
const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync40(p, "utf8"));
|
|
13169
12967
|
const v = asProvider(m?.[1]);
|
|
13170
12968
|
if (v)
|
|
13171
12969
|
return v;
|
|
@@ -13254,6 +13052,88 @@ var init_xreview = __esm(() => {
|
|
|
13254
13052
|
RANK3 = { FAILED: 0, SPEC_CONFLICT: 0, PARTIAL: 1, ALREADY_SATISFIED: 2, VERIFIED: 2 };
|
|
13255
13053
|
});
|
|
13256
13054
|
|
|
13055
|
+
// ../../loki-ts/src/runner/router/route_block.ts
|
|
13056
|
+
function advisorUnavailableReason(env, provider) {
|
|
13057
|
+
if (provider !== "claude")
|
|
13058
|
+
return `provider ${provider} has no advisor tool`;
|
|
13059
|
+
if (env["CLAUDE_CODE_USE_BEDROCK"] || env["CLAUDE_CODE_USE_VERTEX"] || env["CLAUDE_CODE_USE_FOUNDRY"])
|
|
13060
|
+
return "advisor tool is unsupported on Bedrock, Vertex and Foundry";
|
|
13061
|
+
if ((env["LOKI_ROUTER_ADVISOR"] ?? "").trim().toLowerCase() === "off")
|
|
13062
|
+
return "LOKI_ROUTER_ADVISOR=off";
|
|
13063
|
+
return null;
|
|
13064
|
+
}
|
|
13065
|
+
function toEsc(raw2) {
|
|
13066
|
+
const esc3 = Array.isArray(raw2) ? raw2 : [];
|
|
13067
|
+
return esc3.map((e) => ({ trigger: s0(e["trigger"]) ?? "unknown", from: modelLabel(s0(e["from"]) ?? "?"), to: modelLabel(s0(e["to"]) ?? "?"), evidence: s0(e["evidence"]) ?? "none recorded" }));
|
|
13068
|
+
}
|
|
13069
|
+
function buildRouteBlock(env, provider, route, telemetry, runModel) {
|
|
13070
|
+
if (!routerEnabled(env))
|
|
13071
|
+
return null;
|
|
13072
|
+
const applied = route?.["applied"] !== false;
|
|
13073
|
+
const executor = s0(route?.["executor"]);
|
|
13074
|
+
const unavailable = s0(route?.["advisor_unavailable_reason"]) ?? advisorUnavailableReason(env, provider);
|
|
13075
|
+
const total = nN(telemetry?.requests_total);
|
|
13076
|
+
const over = nN(telemetry?.requests_over_100k);
|
|
13077
|
+
const shape = s0(route?.["shape_key"]);
|
|
13078
|
+
const escalations = toEsc(route?.["escalations"]);
|
|
13079
|
+
const source = s0(route?.["source"]);
|
|
13080
|
+
const reason = s0(route?.["reason"]) ?? (executor ? "no reason recorded" : "no route recorded by implement");
|
|
13081
|
+
const rawUnits = Array.isArray(route?.["units"]) ? route["units"] : [];
|
|
13082
|
+
const units = rawUnits.length > 0 ? rawUnits.map((u, i) => ({ id: s0(u["id"]) ?? String(i + 1), executor: modelLabel(s0(u["executor"]) ?? "unknown"), applied, assigned_by: assignedBy(s0(u["source"]) ?? source, u["assigned_by"]), reason: s0(u["reason"]) ?? "no reason recorded", escalations: toEsc(u["escalations"]) })) : executor && route?.["routed"] !== false ? [{ id: "run", executor: modelLabel(executor), applied, assigned_by: assignedBy(source, route?.["assigned_by"]), reason, escalations }] : [];
|
|
13083
|
+
return {
|
|
13084
|
+
routed: route?.["routed"] === false ? false : executor !== null || units.length > 0,
|
|
13085
|
+
units,
|
|
13086
|
+
executor: !applied ? `${runModel ? modelLabel(runModel) : "run model"} (per-unit assignment not applied)` : executor ? modelLabel(executor) : units[0]?.executor ?? null,
|
|
13087
|
+
advisor: unavailable ? null : modelLabel(s0(route?.["advisor"]) ?? "opus"),
|
|
13088
|
+
advisor_unavailable_reason: unavailable,
|
|
13089
|
+
reason,
|
|
13090
|
+
source,
|
|
13091
|
+
shape_key: shape,
|
|
13092
|
+
shape_parity: shape ? `NOT PROVEN (no B9 row for shape ${shape})` : "NOT PROVEN (no shape key recorded)",
|
|
13093
|
+
escalations: units.length > 0 ? units.flatMap((u) => u.escalations) : escalations,
|
|
13094
|
+
requests_total: total,
|
|
13095
|
+
requests_over_100k: over,
|
|
13096
|
+
over_100k_share: total !== null && over !== null && total > 0 ? Math.round(over / total * 1e4) / 1e4 : null,
|
|
13097
|
+
advisor_calls: nN(telemetry?.advisor_calls),
|
|
13098
|
+
advisor_input_tokens: nN(telemetry?.advisor_input_tokens),
|
|
13099
|
+
advisor_output_tokens: nN(telemetry?.advisor_output_tokens),
|
|
13100
|
+
plan_model: s0(route?.["plan_model"]),
|
|
13101
|
+
applied,
|
|
13102
|
+
run_model: runModel ?? null,
|
|
13103
|
+
not_proven: Array.isArray(route?.["route_not_proven"]) ? route["route_not_proven"].filter((x) => typeof x === "string") : []
|
|
13104
|
+
};
|
|
13105
|
+
}
|
|
13106
|
+
function routePrLine(r) {
|
|
13107
|
+
if (!r.routed)
|
|
13108
|
+
return `Route: not routed (${r.reason})`;
|
|
13109
|
+
const adv = r.advisor ? `advisor ${r.advisor}` : "advisor unavailable";
|
|
13110
|
+
return `Route: executor ${r.executor}, ${adv}; advisor tokens ${rec(r.advisor_input_tokens)} in / ${rec(r.advisor_output_tokens)} out; over 100K: ${over(r, " requests")}`;
|
|
13111
|
+
}
|
|
13112
|
+
function routeReceiptLines(r) {
|
|
13113
|
+
if (!r.routed)
|
|
13114
|
+
return [`- Route: not routed (${r.reason})`, `- Route shape_parity: ${r.shape_parity}`];
|
|
13115
|
+
return [
|
|
13116
|
+
`- Route: executor ${r.executor}, ${r.advisor ? `advisor ${r.advisor}` : `advisor unavailable: ${r.advisor_unavailable_reason}`}: ${r.reason}`,
|
|
13117
|
+
`- Route shape_key: ${r.shape_key ?? "unknown"} shape_parity: ${r.shape_parity}`,
|
|
13118
|
+
`- Route escalations: ${r.escalations.length === 0 ? "none" : r.escalations.map((e) => `${e.from} -> ${e.to} (${e.trigger}; evidence ${e.evidence})`).join("; ")}`,
|
|
13119
|
+
`- Route advisor: ${rec(r.advisor_calls)} calls, ${rec(r.advisor_input_tokens)} in / ${rec(r.advisor_output_tokens)} out tokens`,
|
|
13120
|
+
...r.units.map((u) => `- Route unit ${u.id}: executor ${u.applied ? u.executor : `not applied (assigned ${u.executor})`}, assigned by ${u.assigned_by}: ${u.reason}; escalation: ${u.escalations.length === 0 ? "none" : u.escalations.map((e) => `${e.from} -> ${e.to} (${e.trigger})`).join(", ")}`),
|
|
13121
|
+
`- Route requests over 100K: ${over(r, "")}`
|
|
13122
|
+
];
|
|
13123
|
+
}
|
|
13124
|
+
function routeNotProven(r) {
|
|
13125
|
+
return [
|
|
13126
|
+
...r.advisor_unavailable_reason ? [`advisor: NOT PROVEN (owner provider): ${r.advisor_unavailable_reason}`] : [],
|
|
13127
|
+
`route.shape_parity: ${r.shape_parity}`,
|
|
13128
|
+
...r.applied ? [] : [`route.executor: NOT PROVEN (owner engine): per-unit executor assignment is not applied (R1-11); every stage ran ${r.run_model ?? "the run model"}`],
|
|
13129
|
+
...r.not_proven
|
|
13130
|
+
];
|
|
13131
|
+
}
|
|
13132
|
+
var ALIAS, modelLabel = (m) => ALIAS[m] ?? m, nN = (v) => typeof v === "number" && Number.isFinite(v) ? v : null, rec = (v) => v === null ? "not recorded" : String(v), s0 = (v) => typeof v === "string" && v.trim() ? v.trim() : null, assignedBy = (src, explicit) => s0(explicit) ?? (src === null || src === "opus" ? "opus" : src), over = (r, unit) => r.requests_total === null || r.requests_over_100k === null ? "not recorded" : `${r.requests_over_100k} of ${r.requests_total}${unit} (${pct(r)})`, pct = (r) => r.over_100k_share === null ? "n/a (no requests)" : `${(r.over_100k_share * 100).toFixed(1)}%`;
|
|
13133
|
+
var init_route_block = __esm(() => {
|
|
13134
|
+
ALIAS = { haiku: "haiku-5.5", sonnet: "sonnet-5.5", opus: "opus-5.5" };
|
|
13135
|
+
});
|
|
13136
|
+
|
|
13257
13137
|
// ../../loki-ts/src/util/engine_origin.ts
|
|
13258
13138
|
function readOriginUrl(repoDir) {
|
|
13259
13139
|
try {
|
|
@@ -13264,6 +13144,7 @@ function readOriginUrl(repoDir) {
|
|
|
13264
13144
|
}
|
|
13265
13145
|
}
|
|
13266
13146
|
var init_engine_origin = __esm(() => {
|
|
13147
|
+
init_atomic();
|
|
13267
13148
|
init_safe_git();
|
|
13268
13149
|
});
|
|
13269
13150
|
|
|
@@ -13300,9 +13181,9 @@ var init_cost_preview = __esm(() => {
|
|
|
13300
13181
|
});
|
|
13301
13182
|
|
|
13302
13183
|
// ../../loki-ts/src/features/contract.ts
|
|
13303
|
-
import { existsSync as
|
|
13304
|
-
import { dirname as
|
|
13305
|
-
import { createHash as
|
|
13184
|
+
import { existsSync as existsSync34, lstatSync as lstatSync12, mkdirSync as mkdirSync22, readFileSync as readFileSync41, rmSync as rmSync14, writeFileSync as writeFileSync24 } from "fs";
|
|
13185
|
+
import { dirname as dirname24, join as join56 } from "path";
|
|
13186
|
+
import { createHash as createHash12 } from "crypto";
|
|
13306
13187
|
function contractEnabled(env = process.env) {
|
|
13307
13188
|
return env["LOKI_CONTRACT"] !== "0";
|
|
13308
13189
|
}
|
|
@@ -13333,7 +13214,7 @@ function untracedLines(trace) {
|
|
|
13333
13214
|
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)}`);
|
|
13334
13215
|
}
|
|
13335
13216
|
function contractPath(repoDir) {
|
|
13336
|
-
return
|
|
13217
|
+
return join56(repoDir, ".loki", "contract.json");
|
|
13337
13218
|
}
|
|
13338
13219
|
function readContract(repoDir) {
|
|
13339
13220
|
const p = contractPath(repoDir);
|
|
@@ -13349,11 +13230,11 @@ function readContract(repoDir) {
|
|
|
13349
13230
|
return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
|
|
13350
13231
|
let raw2;
|
|
13351
13232
|
try {
|
|
13352
|
-
raw2 =
|
|
13233
|
+
raw2 = readFileSync41(p);
|
|
13353
13234
|
} catch {
|
|
13354
13235
|
return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
|
|
13355
13236
|
}
|
|
13356
|
-
const sha2563 =
|
|
13237
|
+
const sha2563 = createHash12("sha256").update(raw2).digest("hex");
|
|
13357
13238
|
let j;
|
|
13358
13239
|
try {
|
|
13359
13240
|
j = JSON.parse(raw2.toString("utf8"));
|
|
@@ -13418,10 +13299,146 @@ var init_contract = __esm(() => {
|
|
|
13418
13299
|
init_safe_git();
|
|
13419
13300
|
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"]);
|
|
13420
13301
|
MAX_CONTRACT_BYTES = 1024 * 1024;
|
|
13421
|
-
REQ_MAP_REL =
|
|
13302
|
+
REQ_MAP_REL = join56(".loki", "state", "requirements-map.json");
|
|
13422
13303
|
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"]);
|
|
13423
13304
|
});
|
|
13424
13305
|
|
|
13306
|
+
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
13307
|
+
import { createHash as createHash13 } from "crypto";
|
|
13308
|
+
import { existsSync as existsSync35, readdirSync as readdirSync17, readFileSync as readFileSync42, statSync as statSync17 } from "fs";
|
|
13309
|
+
import { dirname as dirname25, join as join57 } from "path";
|
|
13310
|
+
function sealGroup(runDir, rh) {
|
|
13311
|
+
const manifestPath = join57(runDir, "group", "manifest.json");
|
|
13312
|
+
if (!existsSync35(manifestPath))
|
|
13313
|
+
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
13314
|
+
const notProven = [];
|
|
13315
|
+
let problems = 0;
|
|
13316
|
+
const fail = (m2) => {
|
|
13317
|
+
problems++;
|
|
13318
|
+
notProven.push(`group: ${m2}`);
|
|
13319
|
+
};
|
|
13320
|
+
const m = readJson5(manifestPath);
|
|
13321
|
+
const list = isObj10(m) && Array.isArray(m["units"]) ? m["units"] : [];
|
|
13322
|
+
if (!isObj10(m) || !ID_RE.test(String(m["group_id"] ?? "")) || list.length === 0) {
|
|
13323
|
+
fail("manifest missing, unreadable or empty");
|
|
13324
|
+
return { section: undefined, notProven, problems, allUnitsPass: false };
|
|
13325
|
+
}
|
|
13326
|
+
const units = [];
|
|
13327
|
+
const seen = new Set, seenLower = new Set;
|
|
13328
|
+
let allUnitsPass = true;
|
|
13329
|
+
list.forEach((raw2, index2) => {
|
|
13330
|
+
const u = isObj10(raw2) ? raw2 : {};
|
|
13331
|
+
const id = String(u["unit_id"] ?? "");
|
|
13332
|
+
if (!ID_RE.test(id) || seen.has(id) || seenLower.has(id.toLowerCase()))
|
|
13333
|
+
return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
13334
|
+
seen.add(id);
|
|
13335
|
+
seenLower.add(id.toLowerCase());
|
|
13336
|
+
const dir = join57(unitsDir(runDir), id), rp = join57(dir, "receipt.json"), ep = join57(dir, "events.jsonl");
|
|
13337
|
+
let bytes;
|
|
13338
|
+
try {
|
|
13339
|
+
bytes = readFileSync42(rp);
|
|
13340
|
+
} catch {
|
|
13341
|
+
return fail(`unit ${id} sub-receipt missing`);
|
|
13342
|
+
}
|
|
13343
|
+
const sub = readJson5(rp);
|
|
13344
|
+
if (!isObj10(sub) || typeof sub["receipt_sha256"] !== "string" || rh(sub) !== sub["receipt_sha256"])
|
|
13345
|
+
return fail(`unit ${id} sub-receipt unreadable or its hash does not recompute`);
|
|
13346
|
+
const verdict = String(sub["verdict"] ?? "");
|
|
13347
|
+
if (!PASSING.has(verdict)) {
|
|
13348
|
+
allUnitsPass = false;
|
|
13349
|
+
notProven.push(`group: unit ${id} verdict ${verdict || "unknown"}`);
|
|
13350
|
+
}
|
|
13351
|
+
units.push({
|
|
13352
|
+
index: index2,
|
|
13353
|
+
unit_id: id,
|
|
13354
|
+
sub_receipt_sha256: sha2(bytes),
|
|
13355
|
+
receipt_sha256: sub["receipt_sha256"],
|
|
13356
|
+
events_file_sha256: existsSync35(ep) ? sha2(readFileSync42(ep)) : null,
|
|
13357
|
+
verdict,
|
|
13358
|
+
goal: text2(u["goal"], 200),
|
|
13359
|
+
files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
|
|
13360
|
+
tests: num4(u["tests"]),
|
|
13361
|
+
tokens: num4(u["tokens"]),
|
|
13362
|
+
model: text2(u["model"], 64)
|
|
13363
|
+
});
|
|
13364
|
+
});
|
|
13365
|
+
const extra = (dirNames(unitsDir(runDir)) ?? []).filter((n2) => !seen.has(n2));
|
|
13366
|
+
for (const n2 of extra)
|
|
13367
|
+
fail(`unit directory ${text2(n2, 64)} is not in the manifest`);
|
|
13368
|
+
return { section: problems === 0 ? { group_id: String(m["group_id"]), units } : undefined, notProven, problems, allUnitsPass: allUnitsPass && problems === 0 };
|
|
13369
|
+
}
|
|
13370
|
+
function capGroupVerdict(v, g) {
|
|
13371
|
+
if (g.problems > 0)
|
|
13372
|
+
return v === "SPEC_CONFLICT" ? v : "FAILED";
|
|
13373
|
+
return !g.allUnitsPass && (v === "VERIFIED" || v === "ALREADY_SATISFIED") ? "PARTIAL" : v;
|
|
13374
|
+
}
|
|
13375
|
+
async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
13376
|
+
const runDir = dirname25(receiptPath);
|
|
13377
|
+
const signed = isObj10(receipt["verification"]) && typeof receipt["verification"]["jwt"] === "string";
|
|
13378
|
+
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
13379
|
+
const g = receipt["group"];
|
|
13380
|
+
if (g === undefined)
|
|
13381
|
+
return existsSync35(join57(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
13382
|
+
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
13383
|
+
return bad("group section malformed");
|
|
13384
|
+
const entries = g["units"];
|
|
13385
|
+
const ids = entries.map((e) => isObj10(e) ? String(e["unit_id"] ?? "") : "");
|
|
13386
|
+
if (ids.some((id) => !ID_RE.test(id)) || new Set(ids.map((i) => i.toLowerCase())).size !== ids.length)
|
|
13387
|
+
return bad("unit ids invalid, duplicated or case-colliding");
|
|
13388
|
+
const onDisk = dirNames(unitsDir(runDir));
|
|
13389
|
+
if (onDisk === null || onDisk.join("\x00") !== [...ids].sort().join("\x00"))
|
|
13390
|
+
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
13391
|
+
let unchecked = null;
|
|
13392
|
+
for (let i = 0;i < entries.length; i++) {
|
|
13393
|
+
const e = entries[i], id = ids[i], dir = join57(unitsDir(runDir), id), rp = join57(dir, "receipt.json"), ep = join57(dir, "events.jsonl");
|
|
13394
|
+
if (e["index"] !== i)
|
|
13395
|
+
return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
|
|
13396
|
+
let bytes;
|
|
13397
|
+
try {
|
|
13398
|
+
if (!statSync17(dir).isDirectory())
|
|
13399
|
+
return bad(`unit ${id} is not a directory`);
|
|
13400
|
+
bytes = readFileSync42(rp);
|
|
13401
|
+
} catch {
|
|
13402
|
+
return bad(`unit ${id} sub-receipt missing`);
|
|
13403
|
+
}
|
|
13404
|
+
if (sha2(bytes) !== e["sub_receipt_sha256"])
|
|
13405
|
+
return bad(`unit ${id} sub-receipt does not match its recorded hash`);
|
|
13406
|
+
const evSha = existsSync35(ep) ? sha2(readFileSync42(ep)) : null;
|
|
13407
|
+
if (evSha !== (e["events_file_sha256"] ?? null))
|
|
13408
|
+
return bad(`unit ${id} events.jsonl does not match its recorded hash`);
|
|
13409
|
+
const sub = readJson5(rp);
|
|
13410
|
+
if (!isObj10(sub) || sub["receipt_sha256"] !== e["receipt_sha256"] || rh(sub) !== e["receipt_sha256"])
|
|
13411
|
+
return bad(`unit ${id} sub-receipt hash does not recompute`);
|
|
13412
|
+
if (String(sub["verdict"] ?? "") !== e["verdict"])
|
|
13413
|
+
return bad(`unit ${id} verdict differs from the combined receipt`);
|
|
13414
|
+
const r = await verifyOne(rp, deps);
|
|
13415
|
+
if (r.verdict === "UNSIGNED" && signed)
|
|
13416
|
+
unchecked ??= `unit ${id} sub-receipt is unsigned under a signed combined receipt`;
|
|
13417
|
+
if (r.verdict === "TAMPERED")
|
|
13418
|
+
return bad(`unit ${id} sub-receipt failed verify: ${r.reasons.join("; ")}`);
|
|
13419
|
+
if (r.verdict === "UNCHECKED")
|
|
13420
|
+
unchecked ??= `unit ${id} sub-receipt not checked: ${r.reasons.join("; ")}`;
|
|
13421
|
+
}
|
|
13422
|
+
return unchecked ? { verdict: "UNCHECKED", reason: `group: ${unchecked}` } : null;
|
|
13423
|
+
}
|
|
13424
|
+
var ID_RE, PASSING, sha2 = (b) => createHash13("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) => join57(runDir, "group", "units"), readJson5 = (p) => {
|
|
13425
|
+
try {
|
|
13426
|
+
return JSON.parse(readFileSync42(p, "utf8"));
|
|
13427
|
+
} catch {
|
|
13428
|
+
return;
|
|
13429
|
+
}
|
|
13430
|
+
}, dirNames = (d) => {
|
|
13431
|
+
try {
|
|
13432
|
+
return readdirSync17(d).filter((n2) => !n2.startsWith(".")).sort();
|
|
13433
|
+
} catch {
|
|
13434
|
+
return null;
|
|
13435
|
+
}
|
|
13436
|
+
};
|
|
13437
|
+
var init_seal_group = __esm(() => {
|
|
13438
|
+
ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
13439
|
+
PASSING = new Set(["VERIFIED", "ALREADY_SATISFIED"]);
|
|
13440
|
+
});
|
|
13441
|
+
|
|
13425
13442
|
// ../../loki-ts/src/supply/supply_guard.ts
|
|
13426
13443
|
import { existsSync as existsSync36, readFileSync as readFileSync43, statSync as statSync18 } from "fs";
|
|
13427
13444
|
import { basename as basename19, join as join58 } from "path";
|
|
@@ -13668,7 +13685,7 @@ var init_supply_guard = __esm(() => {
|
|
|
13668
13685
|
|
|
13669
13686
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
13670
13687
|
import { createHash as createHash14 } from "crypto";
|
|
13671
|
-
import { existsSync as existsSync37, readdirSync as readdirSync18, mkdirSync as mkdirSync23, readFileSync as readFileSync44, writeFileSync as
|
|
13688
|
+
import { existsSync as existsSync37, readdirSync as readdirSync18, mkdirSync as mkdirSync23, readFileSync as readFileSync44, writeFileSync as writeFileSync25 } from "fs";
|
|
13672
13689
|
import { basename as basename20, isAbsolute as isAbsolute9, join as join59, relative as relative9 } from "path";
|
|
13673
13690
|
function sanitizeReason(s) {
|
|
13674
13691
|
const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
|
|
@@ -13749,7 +13766,6 @@ var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usab
|
|
|
13749
13766
|
}, commitStage, sealStage;
|
|
13750
13767
|
var init_seal = __esm(() => {
|
|
13751
13768
|
init_spec_file();
|
|
13752
|
-
init_pr_body();
|
|
13753
13769
|
init_mutation_proof();
|
|
13754
13770
|
init_wall();
|
|
13755
13771
|
init_assert_delta();
|
|
@@ -13985,9 +14001,9 @@ var init_seal = __esm(() => {
|
|
|
13985
14001
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
13986
14002
|
mkdirSync23(ctx.runDir, { recursive: true });
|
|
13987
14003
|
const path = join59(ctx.runDir, "receipt.json");
|
|
13988
|
-
|
|
14004
|
+
writeFileSync25(path, JSON.stringify(receipt, null, 2) + `
|
|
13989
14005
|
`);
|
|
13990
|
-
|
|
14006
|
+
writeFileSync25(join59(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
13991
14007
|
recordRun(process.env, ctx.repoDir, ctx.model, verdict, cost.usd, cost.unmetered === true, totalS);
|
|
13992
14008
|
const signed = sig.jwt !== null;
|
|
13993
14009
|
const data = { receipt_path: path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven, ...mp ? { mutation_line: mp.line } : {}, ...routeBlock ? { route_line: routePrLine(routeBlock) } : {} };
|
|
@@ -14093,7 +14109,7 @@ var init_keys_cmd = __esm(() => {
|
|
|
14093
14109
|
});
|
|
14094
14110
|
|
|
14095
14111
|
// ../../loki-ts/src/engine10/verify_cmd.ts
|
|
14096
|
-
import { existsSync as existsSync38,
|
|
14112
|
+
import { existsSync as existsSync38, readFileSync as readFileSync46, statSync as statSync20 } from "fs";
|
|
14097
14113
|
import { dirname as dirname27, join as join60 } from "path";
|
|
14098
14114
|
import { createHash as createHash15, createPublicKey as createPublicKey4, verify as verify3 } from "crypto";
|
|
14099
14115
|
function pubFor(kid, given) {
|
|
@@ -14221,6 +14237,7 @@ async function verifyReceipt(receiptPath, deps = {}) {
|
|
|
14221
14237
|
var computeReceiptHash = (receipt) => receiptSha256(receipt);
|
|
14222
14238
|
var init_verify_cmd = __esm(() => {
|
|
14223
14239
|
init_paths();
|
|
14240
|
+
init_run_status();
|
|
14224
14241
|
init_events();
|
|
14225
14242
|
init_seal();
|
|
14226
14243
|
init_receipt_dsse();
|