loki-mode 11.2.0 → 11.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/skill-link-heal.sh +54 -0
- package/autonomy/loki +156 -1201
- package/autonomy/provider-offer.sh +4 -4
- package/autonomy/run.sh +11 -3
- package/bin/loki +22 -0
- package/bin/loki-postinstall.js +3 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/KNOWN-ISSUES.md +0 -1
- package/docs/v10/ADOPTION-PLAN.md +2 -2
- package/docs/v10/DECISIONS.md +2 -0
- package/docs/v10/FAILURE-CLASSES.md +37 -1
- package/loki-ts/dist/loki.js +729 -704
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/packages/control-plane/dist/server.js +252 -65
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-Bs4Vyd9R.js → AdminPage-C-iMLNxe.js} +1 -1
- package/web-app/dist/assets/{Avatar-Dmf_rtmv.js → Avatar-C7VUvwsO.js} +1 -1
- package/web-app/dist/assets/{Badge-DCEdgEN8.js → Badge-tGvQEhnw.js} +1 -1
- package/web-app/dist/assets/{Button-BpGXXEPk.js → Button-_iHlH_yL.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-CzssVmim.js → CockpitPage-J_nNjbcR.js} +1 -1
- package/web-app/dist/assets/{ComparePage-BU4XtB9F.js → ComparePage-B05ui6Xt.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-Bkjf4KP2.js → ErrorBoundary-Bxex6DLn.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-CcGMfaq7.js → EvidenceReceiptPanel-BsgWfdD1.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-D53leEFJ.js → GitHubIssuesPanel-DZBhZ8_X.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-UVsPtV3-.js → GitHubPRsPanel-BaxlAl6R.js} +1 -1
- package/web-app/dist/assets/{HomePage-D9wO-XTX.js → HomePage-mVJvzqbF.js} +2 -2
- package/web-app/dist/assets/{LoginPage-ChxBSele.js → LoginPage-B0zd4A_G.js} +1 -1
- package/web-app/dist/assets/{MagicPage-BqQDKX2L.js → MagicPage-DXLQ-y_R.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-CA22NkPl.js → MetricsPage-CLS34Xvr.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-oYt5qdHQ.js → NotFoundPage-BXG8PbNV.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-tSAdI6A6.js → ProjectPage-D3kFFC0F.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Dk22bicF.js → ProjectsPage-2bFn-gnC.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-CwDSvMn6.js → SettingsPage-CBM0ziWE.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-By3IMy9k.js → ShowcasePage-BTaXhjI3.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-DcWNR28_.js → SystemSettingsPage-BrC2hyAr.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-CFawyYQg.js → TeamsPage-oqxdbVbY.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-D7pCD-63.js → TemplatesPage-CEbUIY21.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-CT2v1Vm2.js → TerminalOutput-aIoWLbJA.js} +1 -1
- package/web-app/dist/assets/{activity-DW6jRbjj.js → activity-CPyi45gt.js} +1 -1
- package/web-app/dist/assets/{bell-CJOu9IIM.js → bell-BhaNBaJp.js} +1 -1
- package/web-app/dist/assets/{bot-dVt0Xw_X.js → bot-Da8REaEP.js} +1 -1
- package/web-app/dist/assets/{check-BVC4A8YK.js → check-DPj99ArM.js} +1 -1
- package/web-app/dist/assets/{chevron-left-Djgr5pg-.js → chevron-left-CkxonN0X.js} +1 -1
- package/web-app/dist/assets/{circle-alert-OE2reifn.js → circle-alert-C0JkB1y5.js} +1 -1
- package/web-app/dist/assets/{clock-BUUN5rWU.js → clock-COzFIiWi.js} +1 -1
- package/web-app/dist/assets/{cloud-CzPIksNz.js → cloud-bjkac4kn.js} +1 -1
- package/web-app/dist/assets/{code-xml-DlE7vlGY.js → code-xml-hlKlvXUJ.js} +1 -1
- package/web-app/dist/assets/{database-DUauMcIC.js → database-D555S5Km.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-CBx9DWbM.js → dollar-sign-CVcApzcD.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-hTmaP9Mz.js → file-code-corner-UORaMIcO.js} +1 -1
- package/web-app/dist/assets/{file-plus-DimFEqtO.js → file-plus-ALJtDoI2.js} +1 -1
- package/web-app/dist/assets/{globe-BV7yxcQ_.js → globe-CPlrM_IC.js} +1 -1
- package/web-app/dist/assets/{hammer-CW6Ol_ju.js → hammer-qaGZHpja.js} +1 -1
- package/web-app/dist/assets/{index-83w75NC1.js → index-BcXljIAO.js} +3 -3
- package/web-app/dist/assets/{layers-DMAqCHxh.js → layers-BV8R9VUK.js} +1 -1
- package/web-app/dist/assets/{loader-circle-B-TJNPo5.js → loader-circle-6TlDS9Tu.js} +1 -1
- package/web-app/dist/assets/{lock-DbvZW7dV.js → lock-B9t6oWI0.js} +1 -1
- package/web-app/dist/assets/{package-BWFcV2kS.js → package-2gEUAtZJ.js} +1 -1
- package/web-app/dist/assets/{plus-CjPzASFv.js → plus-DXocxPjU.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DJL2nFq0.js → refresh-cw-D3dWHBd6.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-Bq3vK-Tu.js → rotate-ccw-CvuWqaSB.js} +1 -1
- package/web-app/dist/assets/{scroll-text-CAMgtDYH.js → scroll-text-ktmD_xJY.js} +1 -1
- package/web-app/dist/assets/{server-D71_Bywf.js → server-E7pZtj5A.js} +1 -1
- package/web-app/dist/assets/{shield-alert-DqQ5wzQ6.js → shield-alert-968j9z0V.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-DXE_IT36.js → thumbs-up-Tz_8rpU_.js} +1 -1
- package/web-app/dist/assets/{trash-2-VYAPKajq.js → trash-2-Drh9IIj8.js} +1 -1
- package/web-app/dist/assets/{trending-down-CuE-J2LH.js → trending-down-DCQXtVSL.js} +1 -1
- package/web-app/dist/assets/{trending-up-BvdD9XmQ.js → trending-up-BIiwQbWV.js} +1 -1
- package/web-app/dist/assets/{upload-OM2YFziE.js → upload-sCbPkfmy.js} +1 -1
- package/web-app/dist/assets/{usePolling-Bk39fp_d.js → usePolling-BMIg6ZVT.js} +1 -1
- package/web-app/dist/assets/{user-CWmKQURs.js → user-kGzXC3V2.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -6959,8 +6959,8 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6959
6959
|
});
|
|
6960
6960
|
|
|
6961
6961
|
// src/server/app.ts
|
|
6962
|
-
import { existsSync as existsSync24, readFileSync as
|
|
6963
|
-
import { join as
|
|
6962
|
+
import { existsSync as existsSync24, readFileSync as readFileSync31, statSync as statSync15 } from "fs";
|
|
6963
|
+
import { join as join40, resolve as resolve8, sep as sep14 } from "path";
|
|
6964
6964
|
|
|
6965
6965
|
// node_modules/hono/dist/request/constants.js
|
|
6966
6966
|
var GET_MATCH_RESULT = Symbol();
|
|
@@ -17519,13 +17519,13 @@ function mount20(ctx) {
|
|
|
17519
17519
|
}
|
|
17520
17520
|
|
|
17521
17521
|
// src/server/routes/verify.ts
|
|
17522
|
-
import { readFileSync as
|
|
17522
|
+
import { readFileSync as readFileSync29, realpathSync as realpathSync17 } from "fs";
|
|
17523
17523
|
import { createPublicKey as createPublicKey5 } from "crypto";
|
|
17524
|
-
import { join as
|
|
17524
|
+
import { join as join38, sep as sep13 } from "path";
|
|
17525
17525
|
|
|
17526
17526
|
// ../../loki-ts/src/engine10/verify_cmd.ts
|
|
17527
|
-
import { existsSync as existsSync22, readdirSync as
|
|
17528
|
-
import { dirname as dirname14, join as
|
|
17527
|
+
import { existsSync as existsSync22, readdirSync as readdirSync13, readFileSync as readFileSync28, statSync as statSync14 } from "fs";
|
|
17528
|
+
import { dirname as dirname14, join as join37 } from "path";
|
|
17529
17529
|
import { createHash as createHash10, createPublicKey as createPublicKey4, verify as verify3 } from "crypto";
|
|
17530
17530
|
|
|
17531
17531
|
// ../../loki-ts/src/util/paths.ts
|
|
@@ -17550,9 +17550,9 @@ var REPO_ROOT = findRepoRoot();
|
|
|
17550
17550
|
|
|
17551
17551
|
// ../../loki-ts/src/engine10/stages/seal.ts
|
|
17552
17552
|
import { createHash as createHash9, randomBytes as randomBytes3, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, sign } from "crypto";
|
|
17553
|
-
import { chmodSync as chmodSync5, existsSync as existsSync21, readdirSync as
|
|
17553
|
+
import { chmodSync as chmodSync5, existsSync as existsSync21, readdirSync as readdirSync12, linkSync, mkdirSync as mkdirSync10, readFileSync as readFileSync26, statSync as statSync13, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "fs";
|
|
17554
17554
|
import { homedir as homedir7 } from "os";
|
|
17555
|
-
import { basename as basename11, dirname as dirname13, join as
|
|
17555
|
+
import { basename as basename11, dirname as dirname13, join as join36 } from "path";
|
|
17556
17556
|
|
|
17557
17557
|
// ../../loki-ts/src/e10ext/assert_delta.ts
|
|
17558
17558
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
@@ -18797,6 +18797,187 @@ async function crossReview(ctx, verdict, head) {
|
|
|
18797
18797
|
}
|
|
18798
18798
|
}
|
|
18799
18799
|
|
|
18800
|
+
// ../../loki-ts/src/runner/router/flag.ts
|
|
18801
|
+
function routerMode(env = process.env) {
|
|
18802
|
+
const v = (env.LOKI_ROUTER ?? "").trim().toLowerCase();
|
|
18803
|
+
if (v === "0" || v === "false" || v === "off")
|
|
18804
|
+
return "opt-out";
|
|
18805
|
+
if (v === "1" || v === "true" || v === "on")
|
|
18806
|
+
return "on";
|
|
18807
|
+
return "off";
|
|
18808
|
+
}
|
|
18809
|
+
var routerEnabled = (env = process.env) => routerMode(env) === "on";
|
|
18810
|
+
|
|
18811
|
+
// ../../loki-ts/src/runner/router/route_block.ts
|
|
18812
|
+
var ALIAS = { haiku: "haiku-5.5", sonnet: "sonnet-5.5", opus: "opus-5.5" };
|
|
18813
|
+
var modelLabel = (m) => ALIAS[m] ?? m;
|
|
18814
|
+
function advisorUnavailableReason(env, provider) {
|
|
18815
|
+
if (provider !== "claude")
|
|
18816
|
+
return `provider ${provider} has no advisor tool`;
|
|
18817
|
+
if (env["CLAUDE_CODE_USE_BEDROCK"] || env["CLAUDE_CODE_USE_VERTEX"] || env["CLAUDE_CODE_USE_FOUNDRY"])
|
|
18818
|
+
return "advisor tool is unsupported on Bedrock, Vertex and Foundry";
|
|
18819
|
+
if ((env["LOKI_ROUTER_ADVISOR"] ?? "").trim().toLowerCase() === "off")
|
|
18820
|
+
return "LOKI_ROUTER_ADVISOR=off";
|
|
18821
|
+
return null;
|
|
18822
|
+
}
|
|
18823
|
+
var nN = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
18824
|
+
var rec = (v) => v === null ? "not recorded" : String(v);
|
|
18825
|
+
var s0 = (v) => typeof v === "string" && v.trim() ? v.trim() : null;
|
|
18826
|
+
function toEsc(raw2) {
|
|
18827
|
+
const esc2 = Array.isArray(raw2) ? raw2 : [];
|
|
18828
|
+
return esc2.map((e) => ({ trigger: s0(e["trigger"]) ?? "unknown", from: modelLabel(s0(e["from"]) ?? "?"), to: modelLabel(s0(e["to"]) ?? "?"), evidence: s0(e["evidence"]) ?? "none recorded" }));
|
|
18829
|
+
}
|
|
18830
|
+
var assignedBy = (src, explicit) => s0(explicit) ?? (src === null || src === "opus" ? "opus" : src);
|
|
18831
|
+
function buildRouteBlock(env, provider, route, telemetry) {
|
|
18832
|
+
if (!routerEnabled(env))
|
|
18833
|
+
return null;
|
|
18834
|
+
const executor = s0(route?.["executor"]);
|
|
18835
|
+
const unavailable = s0(route?.["advisor_unavailable_reason"]) ?? advisorUnavailableReason(env, provider);
|
|
18836
|
+
const total = nN(telemetry?.requests_total);
|
|
18837
|
+
const over = nN(telemetry?.requests_over_100k);
|
|
18838
|
+
const shape = s0(route?.["shape_key"]);
|
|
18839
|
+
const escalations = toEsc(route?.["escalations"]);
|
|
18840
|
+
const source = s0(route?.["source"]);
|
|
18841
|
+
const reason = s0(route?.["reason"]) ?? (executor ? "no reason recorded" : "no route recorded by implement");
|
|
18842
|
+
const rawUnits = Array.isArray(route?.["units"]) ? route["units"] : [];
|
|
18843
|
+
const units = rawUnits.length > 0 ? rawUnits.map((u, i) => ({ id: s0(u["id"]) ?? String(i + 1), executor: modelLabel(s0(u["executor"]) ?? "unknown"), assigned_by: assignedBy(s0(u["source"]) ?? source, u["assigned_by"]), reason: s0(u["reason"]) ?? "no reason recorded", escalations: toEsc(u["escalations"]) })) : executor ? [{ id: "run", executor: modelLabel(executor), assigned_by: assignedBy(source, route?.["assigned_by"]), reason, escalations }] : [];
|
|
18844
|
+
return {
|
|
18845
|
+
routed: executor !== null || units.length > 0,
|
|
18846
|
+
units,
|
|
18847
|
+
executor: executor ? modelLabel(executor) : units[0]?.executor ?? null,
|
|
18848
|
+
advisor: unavailable ? null : modelLabel(s0(route?.["advisor"]) ?? "opus"),
|
|
18849
|
+
advisor_unavailable_reason: unavailable,
|
|
18850
|
+
reason,
|
|
18851
|
+
source,
|
|
18852
|
+
shape_key: shape,
|
|
18853
|
+
shape_parity: shape ? `NOT PROVEN (no B9 row for shape ${shape})` : "NOT PROVEN (no shape key recorded)",
|
|
18854
|
+
escalations: units.length > 0 ? units.flatMap((u) => u.escalations) : escalations,
|
|
18855
|
+
requests_total: total,
|
|
18856
|
+
requests_over_100k: over,
|
|
18857
|
+
over_100k_share: total !== null && over !== null && total > 0 ? Math.round(over / total * 1e4) / 1e4 : null,
|
|
18858
|
+
advisor_calls: nN(telemetry?.advisor_calls),
|
|
18859
|
+
advisor_input_tokens: nN(telemetry?.advisor_input_tokens),
|
|
18860
|
+
advisor_output_tokens: nN(telemetry?.advisor_output_tokens)
|
|
18861
|
+
};
|
|
18862
|
+
}
|
|
18863
|
+
var 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)})`;
|
|
18864
|
+
var pct = (r) => r.over_100k_share === null ? "n/a (no requests)" : `${(r.over_100k_share * 100).toFixed(1)}%`;
|
|
18865
|
+
function routePrLine(r) {
|
|
18866
|
+
if (!r.routed)
|
|
18867
|
+
return `Route: not routed (${r.reason})`;
|
|
18868
|
+
const adv = r.advisor ? `advisor ${r.advisor}` : "advisor unavailable";
|
|
18869
|
+
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")}`;
|
|
18870
|
+
}
|
|
18871
|
+
function routeReceiptLines(r) {
|
|
18872
|
+
if (!r.routed)
|
|
18873
|
+
return [`- Route: not routed (${r.reason})`, `- Route shape_parity: ${r.shape_parity}`];
|
|
18874
|
+
return [
|
|
18875
|
+
`- Route: executor ${r.executor}, ${r.advisor ? `advisor ${r.advisor}` : `advisor unavailable: ${r.advisor_unavailable_reason}`}: ${r.reason}`,
|
|
18876
|
+
`- Route shape_key: ${r.shape_key ?? "unknown"} shape_parity: ${r.shape_parity}`,
|
|
18877
|
+
`- Route escalations: ${r.escalations.length === 0 ? "none" : r.escalations.map((e) => `${e.from} -> ${e.to} (${e.trigger}; evidence ${e.evidence})`).join("; ")}`,
|
|
18878
|
+
`- Route advisor: ${rec(r.advisor_calls)} calls, ${rec(r.advisor_input_tokens)} in / ${rec(r.advisor_output_tokens)} out tokens`,
|
|
18879
|
+
...r.units.map((u) => `- Route unit ${u.id}: executor ${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(", ")}`),
|
|
18880
|
+
`- Route requests over 100K: ${over(r, "")}`
|
|
18881
|
+
];
|
|
18882
|
+
}
|
|
18883
|
+
function routeNotProven(r) {
|
|
18884
|
+
return [
|
|
18885
|
+
...r.advisor_unavailable_reason ? [`advisor: NOT PROVEN (owner provider): ${r.advisor_unavailable_reason}`] : [],
|
|
18886
|
+
`route.shape_parity: ${r.shape_parity}`
|
|
18887
|
+
];
|
|
18888
|
+
}
|
|
18889
|
+
|
|
18890
|
+
// ../../loki-ts/src/engine10/cost.ts
|
|
18891
|
+
import { mkdirSync as mkdirSync8, readdirSync as readdirSync10, readFileSync as readFileSync23, writeFileSync as writeFileSync11 } from "fs";
|
|
18892
|
+
import { join as join33 } from "path";
|
|
18893
|
+
var UNMETERED = "cli-invoker-unmetered";
|
|
18894
|
+
function routerTelemetryOn(env = process.env) {
|
|
18895
|
+
return routerEnabled(env);
|
|
18896
|
+
}
|
|
18897
|
+
function num3(v) {
|
|
18898
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
18899
|
+
}
|
|
18900
|
+
function resultCostPath(lokiRoot, iteration) {
|
|
18901
|
+
return join33(lokiRoot, "metrics", `result-cost-${iteration}.json`);
|
|
18902
|
+
}
|
|
18903
|
+
function sumResultCosts(lokiRoot, iterations) {
|
|
18904
|
+
const out2 = {
|
|
18905
|
+
usd: null,
|
|
18906
|
+
partialUsd: 0,
|
|
18907
|
+
measuredCount: 0,
|
|
18908
|
+
totalCount: iterations.length,
|
|
18909
|
+
input_tokens: 0,
|
|
18910
|
+
output_tokens: 0,
|
|
18911
|
+
cache_read_tokens: 0,
|
|
18912
|
+
cache_creation_tokens: 0,
|
|
18913
|
+
...routerTelemetryOn() ? { router: {
|
|
18914
|
+
requests_total: 0,
|
|
18915
|
+
requests_over_100k: 0,
|
|
18916
|
+
over_100k_input_tokens: 0,
|
|
18917
|
+
over_100k_output_tokens: 0,
|
|
18918
|
+
advisor_calls: 0,
|
|
18919
|
+
advisor_input_tokens: 0,
|
|
18920
|
+
advisor_output_tokens: 0
|
|
18921
|
+
} } : {},
|
|
18922
|
+
model: null,
|
|
18923
|
+
source: "",
|
|
18924
|
+
missing: []
|
|
18925
|
+
};
|
|
18926
|
+
const sources2 = [];
|
|
18927
|
+
let usd = 0;
|
|
18928
|
+
for (const iter of iterations) {
|
|
18929
|
+
const path = resultCostPath(lokiRoot, iter);
|
|
18930
|
+
let rec2;
|
|
18931
|
+
try {
|
|
18932
|
+
rec2 = JSON.parse(readFileSync23(path, "utf8"));
|
|
18933
|
+
} catch {
|
|
18934
|
+
out2.missing.push(iter);
|
|
18935
|
+
continue;
|
|
18936
|
+
}
|
|
18937
|
+
const inTok = num3(rec2["input_tokens"]);
|
|
18938
|
+
const outTok = num3(rec2["output_tokens"]);
|
|
18939
|
+
const cacheR = num3(rec2["cache_read_tokens"]);
|
|
18940
|
+
const cacheC = num3(rec2["cache_creation_tokens"]);
|
|
18941
|
+
out2.input_tokens += inTok;
|
|
18942
|
+
out2.output_tokens += outTok;
|
|
18943
|
+
out2.cache_read_tokens += cacheR;
|
|
18944
|
+
out2.cache_creation_tokens += cacheC;
|
|
18945
|
+
if (out2.router)
|
|
18946
|
+
out2.router["requests_total"] += num3(rec2["requests_total"]);
|
|
18947
|
+
if (out2.router)
|
|
18948
|
+
out2.router["requests_over_100k"] += num3(rec2["requests_over_100k"]);
|
|
18949
|
+
if (out2.router)
|
|
18950
|
+
out2.router["over_100k_input_tokens"] += num3(rec2["over_100k_input_tokens"]);
|
|
18951
|
+
if (out2.router)
|
|
18952
|
+
out2.router["over_100k_output_tokens"] += num3(rec2["over_100k_output_tokens"]);
|
|
18953
|
+
if (out2.router)
|
|
18954
|
+
out2.router["advisor_calls"] += num3(rec2["advisor_calls"]);
|
|
18955
|
+
if (out2.router)
|
|
18956
|
+
out2.router["advisor_input_tokens"] += num3(rec2["advisor_input_tokens"]);
|
|
18957
|
+
if (out2.router)
|
|
18958
|
+
out2.router["advisor_output_tokens"] += num3(rec2["advisor_output_tokens"]);
|
|
18959
|
+
if (typeof rec2["model"] === "string" && rec2["model"])
|
|
18960
|
+
out2.model = rec2["model"];
|
|
18961
|
+
sources2.push(path);
|
|
18962
|
+
const c = rec2["total_cost_usd"];
|
|
18963
|
+
const unmetered = rec2["source"] === UNMETERED;
|
|
18964
|
+
if (unmetered)
|
|
18965
|
+
out2.unmetered = true;
|
|
18966
|
+
const noUsage = !unmetered && inTok === 0 && outTok === 0 && cacheR === 0 && cacheC === 0;
|
|
18967
|
+
if (typeof c !== "number" || !Number.isFinite(c) || noUsage) {
|
|
18968
|
+
out2.missing.push(iter);
|
|
18969
|
+
continue;
|
|
18970
|
+
}
|
|
18971
|
+
usd += c;
|
|
18972
|
+
out2.partialUsd += c;
|
|
18973
|
+
out2.measuredCount++;
|
|
18974
|
+
}
|
|
18975
|
+
out2.source = sources2.join(",");
|
|
18976
|
+
if (iterations.length > 0 && out2.missing.length === 0)
|
|
18977
|
+
out2.usd = usd;
|
|
18978
|
+
return out2;
|
|
18979
|
+
}
|
|
18980
|
+
|
|
18800
18981
|
// ../../loki-ts/src/util/check_result.ts
|
|
18801
18982
|
var NO_TESTS_REASON = "no tests executed";
|
|
18802
18983
|
var UNCONFIRMED_REASON = "test count could not be confirmed";
|
|
@@ -18805,8 +18986,8 @@ var isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c
|
|
|
18805
18986
|
var hasExecutedProof = (checks) => checks.some(isExecutedProof);
|
|
18806
18987
|
|
|
18807
18988
|
// ../../loki-ts/src/features/contract.ts
|
|
18808
|
-
import { existsSync as existsSync19, lstatSync as lstatSync8, mkdirSync as
|
|
18809
|
-
import { dirname as dirname11, join as
|
|
18989
|
+
import { existsSync as existsSync19, lstatSync as lstatSync8, mkdirSync as mkdirSync9, readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "fs";
|
|
18990
|
+
import { dirname as dirname11, join as join34 } from "path";
|
|
18810
18991
|
import { createHash as createHash7 } from "crypto";
|
|
18811
18992
|
var MAX_CRITERIA = 50;
|
|
18812
18993
|
var MAX_TEXT = 500;
|
|
@@ -18841,7 +19022,7 @@ function untracedLines(trace) {
|
|
|
18841
19022
|
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)}`);
|
|
18842
19023
|
}
|
|
18843
19024
|
function contractPath(repoDir) {
|
|
18844
|
-
return
|
|
19025
|
+
return join34(repoDir, ".loki", "contract.json");
|
|
18845
19026
|
}
|
|
18846
19027
|
var MAX_CONTRACT_BYTES = 1024 * 1024;
|
|
18847
19028
|
function readContract(repoDir) {
|
|
@@ -18858,7 +19039,7 @@ function readContract(repoDir) {
|
|
|
18858
19039
|
return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
|
|
18859
19040
|
let raw2;
|
|
18860
19041
|
try {
|
|
18861
|
-
raw2 =
|
|
19042
|
+
raw2 = readFileSync24(p);
|
|
18862
19043
|
} catch {
|
|
18863
19044
|
return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
|
|
18864
19045
|
}
|
|
@@ -18922,31 +19103,31 @@ function sealContract(repoDir, body, rawDiff, checks, env = process.env, snap) {
|
|
|
18922
19103
|
|
|
18923
19104
|
// ../../loki-ts/src/features/speed/seal_group.ts
|
|
18924
19105
|
import { createHash as createHash8 } from "crypto";
|
|
18925
|
-
import { existsSync as existsSync20, readdirSync as
|
|
18926
|
-
import { dirname as dirname12, join as
|
|
19106
|
+
import { existsSync as existsSync20, readdirSync as readdirSync11, readFileSync as readFileSync25, statSync as statSync12 } from "fs";
|
|
19107
|
+
import { dirname as dirname12, join as join35 } from "path";
|
|
18927
19108
|
var ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
18928
19109
|
var PASSING = new Set(["VERIFIED", "ALREADY_SATISFIED"]);
|
|
18929
19110
|
var sha2 = (b) => createHash8("sha256").update(b).digest("hex");
|
|
18930
19111
|
var isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
18931
19112
|
var text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "";
|
|
18932
|
-
var
|
|
18933
|
-
var unitsDir = (runDir) =>
|
|
19113
|
+
var num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
|
|
19114
|
+
var unitsDir = (runDir) => join35(runDir, "group", "units");
|
|
18934
19115
|
var readJson3 = (p) => {
|
|
18935
19116
|
try {
|
|
18936
|
-
return JSON.parse(
|
|
19117
|
+
return JSON.parse(readFileSync25(p, "utf8"));
|
|
18937
19118
|
} catch {
|
|
18938
19119
|
return;
|
|
18939
19120
|
}
|
|
18940
19121
|
};
|
|
18941
19122
|
var dirNames = (d) => {
|
|
18942
19123
|
try {
|
|
18943
|
-
return
|
|
19124
|
+
return readdirSync11(d).filter((n2) => !n2.startsWith(".")).sort();
|
|
18944
19125
|
} catch {
|
|
18945
19126
|
return null;
|
|
18946
19127
|
}
|
|
18947
19128
|
};
|
|
18948
19129
|
function sealGroup(runDir, rh) {
|
|
18949
|
-
const manifestPath =
|
|
19130
|
+
const manifestPath = join35(runDir, "group", "manifest.json");
|
|
18950
19131
|
if (!existsSync20(manifestPath))
|
|
18951
19132
|
return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
|
|
18952
19133
|
const notProven = [];
|
|
@@ -18971,10 +19152,10 @@ function sealGroup(runDir, rh) {
|
|
|
18971
19152
|
return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
|
|
18972
19153
|
seen.add(id);
|
|
18973
19154
|
seenLower.add(id.toLowerCase());
|
|
18974
|
-
const dir =
|
|
19155
|
+
const dir = join35(unitsDir(runDir), id), rp = join35(dir, "receipt.json"), ep = join35(dir, "events.jsonl");
|
|
18975
19156
|
let bytes;
|
|
18976
19157
|
try {
|
|
18977
|
-
bytes =
|
|
19158
|
+
bytes = readFileSync25(rp);
|
|
18978
19159
|
} catch {
|
|
18979
19160
|
return fail(`unit ${id} sub-receipt missing`);
|
|
18980
19161
|
}
|
|
@@ -18991,12 +19172,12 @@ function sealGroup(runDir, rh) {
|
|
|
18991
19172
|
unit_id: id,
|
|
18992
19173
|
sub_receipt_sha256: sha2(bytes),
|
|
18993
19174
|
receipt_sha256: sub["receipt_sha256"],
|
|
18994
|
-
events_file_sha256: existsSync20(ep) ? sha2(
|
|
19175
|
+
events_file_sha256: existsSync20(ep) ? sha2(readFileSync25(ep)) : null,
|
|
18995
19176
|
verdict,
|
|
18996
19177
|
goal: text2(u["goal"], 200),
|
|
18997
19178
|
files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
|
|
18998
|
-
tests:
|
|
18999
|
-
tokens:
|
|
19179
|
+
tests: num4(u["tests"]),
|
|
19180
|
+
tokens: num4(u["tokens"]),
|
|
19000
19181
|
model: text2(u["model"], 64)
|
|
19001
19182
|
});
|
|
19002
19183
|
});
|
|
@@ -19016,7 +19197,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
19016
19197
|
const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
|
|
19017
19198
|
const g = receipt["group"];
|
|
19018
19199
|
if (g === undefined)
|
|
19019
|
-
return existsSync20(
|
|
19200
|
+
return existsSync20(join35(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
|
|
19020
19201
|
if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
|
|
19021
19202
|
return bad("group section malformed");
|
|
19022
19203
|
const entries = g["units"];
|
|
@@ -19028,20 +19209,20 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
|
|
|
19028
19209
|
return bad("unit directories do not match the receipt (missing or extra unit)");
|
|
19029
19210
|
let unchecked = null;
|
|
19030
19211
|
for (let i = 0;i < entries.length; i++) {
|
|
19031
|
-
const e = entries[i], id = ids[i], dir =
|
|
19212
|
+
const e = entries[i], id = ids[i], dir = join35(unitsDir(runDir), id), rp = join35(dir, "receipt.json"), ep = join35(dir, "events.jsonl");
|
|
19032
19213
|
if (e["index"] !== i)
|
|
19033
19214
|
return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
|
|
19034
19215
|
let bytes;
|
|
19035
19216
|
try {
|
|
19036
19217
|
if (!statSync12(dir).isDirectory())
|
|
19037
19218
|
return bad(`unit ${id} is not a directory`);
|
|
19038
|
-
bytes =
|
|
19219
|
+
bytes = readFileSync25(rp);
|
|
19039
19220
|
} catch {
|
|
19040
19221
|
return bad(`unit ${id} sub-receipt missing`);
|
|
19041
19222
|
}
|
|
19042
19223
|
if (sha2(bytes) !== e["sub_receipt_sha256"])
|
|
19043
19224
|
return bad(`unit ${id} sub-receipt does not match its recorded hash`);
|
|
19044
|
-
const evSha = existsSync20(ep) ? sha2(
|
|
19225
|
+
const evSha = existsSync20(ep) ? sha2(readFileSync25(ep)) : null;
|
|
19045
19226
|
if (evSha !== (e["events_file_sha256"] ?? null))
|
|
19046
19227
|
return bad(`unit ${id} events.jsonl does not match its recorded hash`);
|
|
19047
19228
|
const sub = readJson3(rp);
|
|
@@ -19096,9 +19277,9 @@ function loadSigningKey(generate = true) {
|
|
|
19096
19277
|
let pem = inline ?? "";
|
|
19097
19278
|
if (!inline) {
|
|
19098
19279
|
const given = process.env["LOKI_RECEIPT_SIGNING_KEY_FILE"]?.trim();
|
|
19099
|
-
const file = given ||
|
|
19280
|
+
const file = given || join36(process.env["HOME"] || homedir7(), ".loki", "keys", RECEIPT_SIGNER_BASENAME);
|
|
19100
19281
|
try {
|
|
19101
|
-
pem =
|
|
19282
|
+
pem = readFileSync26(file);
|
|
19102
19283
|
if (!given) {
|
|
19103
19284
|
for (const [f, m] of [[file, 384], [dirname13(file), 448]])
|
|
19104
19285
|
if (statSync13(f).mode & 63)
|
|
@@ -19107,10 +19288,10 @@ function loadSigningKey(generate = true) {
|
|
|
19107
19288
|
} catch (e) {
|
|
19108
19289
|
if (e.code !== "ENOENT" || !generate)
|
|
19109
19290
|
return null;
|
|
19110
|
-
|
|
19111
|
-
|
|
19291
|
+
mkdirSync10(dirname13(dirname13(file)), { recursive: true, mode: 448 });
|
|
19292
|
+
mkdirSync10(dirname13(file), { recursive: true, mode: 448 });
|
|
19112
19293
|
const tmp = `${file}.${randomBytes3(6).toString("hex")}.tmp`;
|
|
19113
|
-
|
|
19294
|
+
writeFileSync13(tmp, generateKeyPairSync("ed25519").privateKey.export({ type: "pkcs8", format: "pem" }), { flag: "wx", mode: 384 });
|
|
19114
19295
|
try {
|
|
19115
19296
|
linkSync(tmp, file);
|
|
19116
19297
|
} catch (l) {
|
|
@@ -19119,7 +19300,7 @@ function loadSigningKey(generate = true) {
|
|
|
19119
19300
|
} finally {
|
|
19120
19301
|
unlinkSync4(tmp);
|
|
19121
19302
|
}
|
|
19122
|
-
pem =
|
|
19303
|
+
pem = readFileSync26(file);
|
|
19123
19304
|
}
|
|
19124
19305
|
}
|
|
19125
19306
|
const k = createPrivateKey(pem);
|
|
@@ -19215,6 +19396,7 @@ function renderReceiptMd(r) {
|
|
|
19215
19396
|
`- receipt_sha256: ${r.receipt_sha256}`,
|
|
19216
19397
|
`- Signature: ${sig}`,
|
|
19217
19398
|
`- Provider: ${r.provider} (${r.model}) Cost: ${usd} Wall: ${r.time.wall_s}s`,
|
|
19399
|
+
...r.route ? routeReceiptLines(r.route) : [],
|
|
19218
19400
|
"",
|
|
19219
19401
|
"### Checks",
|
|
19220
19402
|
...r.checks.length ? r.checks.map((c) => `- ${c.result}: ${c.name} (\`${c.cmd}\`, ${c.duration_s}s)`) : ["- none"],
|
|
@@ -19263,7 +19445,7 @@ var sealStage = {
|
|
|
19263
19445
|
if (wallNotRun > 0) {
|
|
19264
19446
|
try {
|
|
19265
19447
|
const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename11(String(f.path))));
|
|
19266
|
-
for (const n2 of
|
|
19448
|
+
for (const n2 of readdirSync12(join36(ctx.runDir, "wall")).sort())
|
|
19267
19449
|
if (!kept.has(n2))
|
|
19268
19450
|
notProven.add(`wall test discarded: ${n2} (not_run)`);
|
|
19269
19451
|
} catch {}
|
|
@@ -19326,11 +19508,15 @@ var sealStage = {
|
|
|
19326
19508
|
const cost = ctx.cost.read(ctx.repoDir, iterIds);
|
|
19327
19509
|
if (cost.unmetered)
|
|
19328
19510
|
notProven.add("cost unmetered (CLI invoker; recorded as 0)");
|
|
19329
|
-
const eventsPath =
|
|
19511
|
+
const eventsPath = join36(ctx.runDir, "events.jsonl");
|
|
19330
19512
|
const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
|
|
19331
19513
|
const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
|
|
19332
19514
|
if (wallFiles.length > 0 && wallPassed === null)
|
|
19333
19515
|
notProven.add("wall result not recorded by verify");
|
|
19516
|
+
const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route, cost.router ?? (routerEnabled(process.env) ? sumResultCosts(join36(ctx.repoDir, ".loki"), iterIds).router : undefined));
|
|
19517
|
+
if (routeBlock)
|
|
19518
|
+
for (const l of routeNotProven(routeBlock))
|
|
19519
|
+
notProven.add(l);
|
|
19334
19520
|
const body = {
|
|
19335
19521
|
schema: "loki.v10.receipt/1",
|
|
19336
19522
|
run_id: ctx.runId,
|
|
@@ -19363,9 +19549,10 @@ var sealStage = {
|
|
|
19363
19549
|
provider: ctx.provider,
|
|
19364
19550
|
model: ctx.model,
|
|
19365
19551
|
resumed: o.intake?.resumed === true,
|
|
19366
|
-
events_sha256: sha2562(existsSync21(eventsPath) ?
|
|
19552
|
+
events_sha256: sha2562(existsSync21(eventsPath) ? readFileSync26(eventsPath) : ""),
|
|
19367
19553
|
...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
|
|
19368
|
-
log_seal: true
|
|
19554
|
+
log_seal: true,
|
|
19555
|
+
...routeBlock ? { route: routeBlock } : {}
|
|
19369
19556
|
};
|
|
19370
19557
|
for (const l of sealContract(ctx.repoDir, body, rawDiff, checks, process.env, o.intake?.contract_snapshot))
|
|
19371
19558
|
notProven.add(l);
|
|
@@ -19377,21 +19564,21 @@ var sealStage = {
|
|
|
19377
19564
|
hash = receiptSha256(body);
|
|
19378
19565
|
}
|
|
19379
19566
|
const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
|
|
19380
|
-
|
|
19381
|
-
const path =
|
|
19382
|
-
|
|
19567
|
+
mkdirSync10(ctx.runDir, { recursive: true });
|
|
19568
|
+
const path = join36(ctx.runDir, "receipt.json");
|
|
19569
|
+
writeFileSync13(path, JSON.stringify(receipt, null, 2) + `
|
|
19383
19570
|
`);
|
|
19384
|
-
|
|
19571
|
+
writeFileSync13(join36(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
|
|
19385
19572
|
const signed = sig.jwt !== null;
|
|
19386
|
-
const data = { receipt_path: path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven };
|
|
19387
|
-
ctx.emit("receipt.sealed", "seal", { path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven });
|
|
19573
|
+
const data = { receipt_path: path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven, ...routeBlock ? { route_line: routePrLine(routeBlock) } : {} };
|
|
19574
|
+
ctx.emit("receipt.sealed", "seal", { path, receipt_sha256: hash, signed, kid: sig.kid, verdict, not_proven: receipt.not_proven, ...routeBlock ? { route_line: routePrLine(routeBlock) } : {} });
|
|
19388
19575
|
return { status: "completed", data: { ...data, summary: `${verdict} receipt ${hash.slice(0, 12)} ${signed ? `SIGNED kid ${sig.kid}` : "UNSIGNED"}` } };
|
|
19389
19576
|
}
|
|
19390
19577
|
};
|
|
19391
19578
|
|
|
19392
19579
|
// ../../loki-ts/src/features/receipt_dsse.ts
|
|
19393
19580
|
import { createPublicKey as createPublicKey3, sign as sign2, verify as verify2 } from "crypto";
|
|
19394
|
-
import { readFileSync as
|
|
19581
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
19395
19582
|
var DSSE_PAYLOAD_TYPE = "application/vnd.in-toto+json";
|
|
19396
19583
|
var STATEMENT_TYPE = "https://in-toto.io/Statement/v1";
|
|
19397
19584
|
var PREDICATE_TYPE = "https://autonomi.dev/loki/receipt/v10";
|
|
@@ -19472,7 +19659,7 @@ function verifyDsseReceipt(env, d) {
|
|
|
19472
19659
|
}
|
|
19473
19660
|
function runIdGuard(receiptPath, runId) {
|
|
19474
19661
|
try {
|
|
19475
|
-
return envelopeRunIdProblem(JSON.parse(
|
|
19662
|
+
return envelopeRunIdProblem(JSON.parse(readFileSync27(receiptPath, "utf8")), runId);
|
|
19476
19663
|
} catch {
|
|
19477
19664
|
return null;
|
|
19478
19665
|
}
|
|
@@ -19486,7 +19673,7 @@ function pubFor(kid, given) {
|
|
|
19486
19673
|
const active = loadSigningKey(false);
|
|
19487
19674
|
const pubs = (process.env["LOKI_RECEIPT_RETIRED_PUBKEYS"] ?? "").split(":").map((f) => f.trim()).filter(Boolean).flatMap((f) => {
|
|
19488
19675
|
try {
|
|
19489
|
-
return [createPublicKey4(
|
|
19676
|
+
return [createPublicKey4(readFileSync28(f))];
|
|
19490
19677
|
} catch {
|
|
19491
19678
|
return [];
|
|
19492
19679
|
}
|
|
@@ -19518,10 +19705,10 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
19518
19705
|
const bound = receipt["events_sha256"];
|
|
19519
19706
|
if (typeof bound !== "string" || bound === createHash10("sha256").digest("hex"))
|
|
19520
19707
|
return null;
|
|
19521
|
-
const path =
|
|
19708
|
+
const path = join37(dirname14(receiptPath), "events.jsonl");
|
|
19522
19709
|
if (!existsSync22(path))
|
|
19523
19710
|
return "events.jsonl is missing";
|
|
19524
|
-
const raw2 =
|
|
19711
|
+
const raw2 = readFileSync28(path, "utf8"), events2 = readEvents(path), lines = raw2.split(`
|
|
19525
19712
|
`).filter((l) => l.trim() !== "");
|
|
19526
19713
|
if (events2.length !== lines.length || events2.some((e, i) => e.seq !== i))
|
|
19527
19714
|
return "events.jsonl has a forged, edited or missing line";
|
|
@@ -19537,7 +19724,7 @@ function checkEventLog(receiptPath, receipt) {
|
|
|
19537
19724
|
return h.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
|
|
19538
19725
|
}
|
|
19539
19726
|
function checkLogSeal(receiptPath, hash, kid, given) {
|
|
19540
|
-
const path =
|
|
19727
|
+
const path = join37(dirname14(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
|
|
19541
19728
|
if (!events2.some((e) => e.type === "receipt.sealed" && e.data["receipt_sha256"] === hash))
|
|
19542
19729
|
return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
|
|
19543
19730
|
if (done < 0)
|
|
@@ -19545,7 +19732,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
|
|
|
19545
19732
|
const seal = events2[done + 1], d = seal?.type === "log.sealed" ? seal.data : null;
|
|
19546
19733
|
if (!d)
|
|
19547
19734
|
return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
|
|
19548
|
-
const lines =
|
|
19735
|
+
const lines = readFileSync28(path, "utf8").split(`
|
|
19549
19736
|
`).filter((l) => l.trim() !== ""), sha3 = createHash10("sha256").update(lines.slice(0, done + 1).join(`
|
|
19550
19737
|
`) + `
|
|
19551
19738
|
`).digest("hex");
|
|
@@ -19559,7 +19746,7 @@ async function verifyReceipt(receiptPath, deps = {}) {
|
|
|
19559
19746
|
return { verdict: "UNCHECKED", reasons: [`receipt not found: ${receiptPath}`] };
|
|
19560
19747
|
let receipt;
|
|
19561
19748
|
try {
|
|
19562
|
-
receipt = JSON.parse((deps.read ?? ((p) =>
|
|
19749
|
+
receipt = JSON.parse((deps.read ?? ((p) => readFileSync28(p, "utf8")))(receiptPath));
|
|
19563
19750
|
} catch {
|
|
19564
19751
|
return { verdict: "UNCHECKED", reasons: ["receipt.json is not valid JSON"] };
|
|
19565
19752
|
}
|
|
@@ -19627,11 +19814,11 @@ function mount21(ctx) {
|
|
|
19627
19814
|
return done(404, "receipt not available", "not_found");
|
|
19628
19815
|
let runDir, file;
|
|
19629
19816
|
try {
|
|
19630
|
-
const root = realpathSync17(
|
|
19631
|
-
runDir = realpathSync17(
|
|
19632
|
-
if (runDir !==
|
|
19817
|
+
const root = realpathSync17(join38(repo.p, ".loki", "runs"));
|
|
19818
|
+
runDir = realpathSync17(join38(root, run2));
|
|
19819
|
+
if (runDir !== join38(root, run2))
|
|
19633
19820
|
return done(404, "receipt not found", "not_found");
|
|
19634
|
-
file = realpathSync17(
|
|
19821
|
+
file = realpathSync17(join38(runDir, "receipt.json"));
|
|
19635
19822
|
} catch {
|
|
19636
19823
|
return done(404, "receipt not found", "not_found");
|
|
19637
19824
|
}
|
|
@@ -19650,7 +19837,7 @@ function mount21(ctx) {
|
|
|
19650
19837
|
sha3 = r.receiptSha256 ?? null;
|
|
19651
19838
|
}
|
|
19652
19839
|
try {
|
|
19653
|
-
outcome = outcomeOf(JSON.parse(
|
|
19840
|
+
outcome = outcomeOf(JSON.parse(readFileSync29(file, "utf8")));
|
|
19654
19841
|
} catch {
|
|
19655
19842
|
outcome = "UNREADABLE";
|
|
19656
19843
|
}
|
|
@@ -19712,8 +19899,8 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
|
|
|
19712
19899
|
}
|
|
19713
19900
|
|
|
19714
19901
|
// src/server/legacy/shim.ts
|
|
19715
|
-
import { existsSync as existsSync23, readFileSync as
|
|
19716
|
-
import { join as
|
|
19902
|
+
import { existsSync as existsSync23, readFileSync as readFileSync30 } from "fs";
|
|
19903
|
+
import { join as join39 } from "path";
|
|
19717
19904
|
|
|
19718
19905
|
// src/server/legacy/routes.ts
|
|
19719
19906
|
var LEGACY_ROUTES = [
|
|
@@ -20085,10 +20272,10 @@ var logged = new Set;
|
|
|
20085
20272
|
var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
|
|
20086
20273
|
var NOT_SUPPORTED = "not yet supported by the Control Plane";
|
|
20087
20274
|
var repoVersion = () => {
|
|
20088
|
-
for (const f of [
|
|
20275
|
+
for (const f of [join39(import.meta.dir, "../../../../../VERSION")]) {
|
|
20089
20276
|
try {
|
|
20090
20277
|
if (existsSync23(f))
|
|
20091
|
-
return
|
|
20278
|
+
return readFileSync30(f, "utf8").trim();
|
|
20092
20279
|
} catch {}
|
|
20093
20280
|
}
|
|
20094
20281
|
return "unknown";
|
|
@@ -20270,7 +20457,7 @@ function legacyShim(opts) {
|
|
|
20270
20457
|
|
|
20271
20458
|
// src/server/app.ts
|
|
20272
20459
|
var MAX_BODY2 = 1e6;
|
|
20273
|
-
var defaultUiDir = () => [
|
|
20460
|
+
var defaultUiDir = () => [join40(import.meta.dir, "../../ui/dist"), join40(import.meta.dir, "../ui/dist")].find((d) => existsSync24(join40(d, "index.html")));
|
|
20274
20461
|
function createApp(opts) {
|
|
20275
20462
|
const uiDir = opts.uiDir ?? defaultUiDir();
|
|
20276
20463
|
const { db, sqlite } = openDb(opts.dbPath);
|
|
@@ -20299,10 +20486,10 @@ function createApp(opts) {
|
|
|
20299
20486
|
await next();
|
|
20300
20487
|
});
|
|
20301
20488
|
const readInstalled = () => {
|
|
20302
|
-
for (const f of [process.env.LOKI_VERSION_FILE,
|
|
20489
|
+
for (const f of [process.env.LOKI_VERSION_FILE, join40(import.meta.dir, "../../../../VERSION")]) {
|
|
20303
20490
|
try {
|
|
20304
20491
|
if (f)
|
|
20305
|
-
return
|
|
20492
|
+
return readFileSync31(f, "utf8").trim() || "unknown";
|
|
20306
20493
|
} catch {}
|
|
20307
20494
|
}
|
|
20308
20495
|
return "unknown";
|
|
@@ -20417,7 +20604,7 @@ function createApp(opts) {
|
|
|
20417
20604
|
return new Response(Bun.file(f));
|
|
20418
20605
|
if (/\.[a-z0-9]+$/i.test(p))
|
|
20419
20606
|
return c.json({ error: "not found" }, 404);
|
|
20420
|
-
return new Response(Bun.file(
|
|
20607
|
+
return new Response(Bun.file(join40(root, "index.html")));
|
|
20421
20608
|
});
|
|
20422
20609
|
return { app, db, close: () => {
|
|
20423
20610
|
clearInterval(reconciler);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "loki-mode",
|
|
4
4
|
"displayName": "Loki Mode",
|
|
5
|
-
"version": "11.2.
|
|
5
|
+
"version": "11.2.2",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Autonomi",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-
|
|
1
|
+
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-BcXljIAO.js";import{B as C}from"./Button-_iHlH_yL.js";import{T as $e}from"./trending-up-BIiwQbWV.js";import{C as z}from"./clock-COzFIiWi.js";import{A as Be,U as ue,M as De}from"./Avatar-C7VUvwsO.js";import{A as J}from"./activity-CPyi45gt.js";import{R as pe}from"./refresh-cw-D3dWHBd6.js";import{G as ze}from"./globe-CPlrM_IC.js";import{C as Le}from"./chevron-left-CkxonN0X.js";import{C as je}from"./check-DPj99ArM.js";import{D as Y}from"./dollar-sign-CVcApzcD.js";import{U as Te}from"./user-kGzXC3V2.js";import{D as Me}from"./database-D555S5Km.js";import{L as Ue}from"./lock-B9t6oWI0.js";import{S as Re}from"./scroll-text-ktmD_xJY.js";import{S as Ie}from"./shield-alert-968j9z0V.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|