loki-mode 11.17.102 → 11.18.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.
Files changed (70) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/dashboard/__init__.py +1 -1
  4. package/docs/CLI-REFERENCE.md +1 -1
  5. package/docs/INSTALLATION.md +1 -1
  6. package/docs/v10/FAILURE-CLASSES.md +19 -0
  7. package/docs/v10/PROGRESS.md +12 -0
  8. package/loki-ts/dist/cockpit.js +1 -1
  9. package/loki-ts/dist/loki.js +1283 -1281
  10. package/mcp/__init__.py +1 -1
  11. package/package.json +2 -2
  12. package/packages/control-plane/dist/server.js +39 -21
  13. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  14. package/web-app/dist/assets/{AdminPage-vDT6jaWl.js → AdminPage-Ccl4YEiK.js} +1 -1
  15. package/web-app/dist/assets/{Avatar-BdSscJ5J.js → Avatar-CNr3zMt9.js} +1 -1
  16. package/web-app/dist/assets/{Badge-BCufY0Ud.js → Badge-BvHGigQF.js} +1 -1
  17. package/web-app/dist/assets/{Button-DfTDN0WV.js → Button-BPOUvGtk.js} +1 -1
  18. package/web-app/dist/assets/{CockpitPage-DfRqj4xs.js → CockpitPage-CaQew8Gv.js} +1 -1
  19. package/web-app/dist/assets/{ComparePage-v_2-2cfi.js → ComparePage-BR3EinOa.js} +1 -1
  20. package/web-app/dist/assets/{ErrorBoundary-DWjDhnb-.js → ErrorBoundary-_w7Oyx3U.js} +1 -1
  21. package/web-app/dist/assets/{EvidenceReceiptPanel-D137NBb7.js → EvidenceReceiptPanel-CzMl43Ae.js} +1 -1
  22. package/web-app/dist/assets/{GitHubIssuesPanel-nrs-6UM3.js → GitHubIssuesPanel-DG_OioDO.js} +1 -1
  23. package/web-app/dist/assets/{GitHubPRsPanel-ztLmI7PF.js → GitHubPRsPanel-B6LqESL1.js} +1 -1
  24. package/web-app/dist/assets/{HomePage-D7ardTQS.js → HomePage-CNsoKByl.js} +2 -2
  25. package/web-app/dist/assets/{LoginPage-BBh8oD42.js → LoginPage-aP55S_EK.js} +1 -1
  26. package/web-app/dist/assets/{MagicPage-Bif9DbRZ.js → MagicPage-CtYd65MA.js} +1 -1
  27. package/web-app/dist/assets/{MetricsPage-BNs9yjcQ.js → MetricsPage-4cghRPlD.js} +1 -1
  28. package/web-app/dist/assets/{NotFoundPage-C36t4wL8.js → NotFoundPage-BQ1L2OHR.js} +1 -1
  29. package/web-app/dist/assets/{ProjectPage-wRtrbDO6.js → ProjectPage-CWZw_DTd.js} +3 -3
  30. package/web-app/dist/assets/{ProjectsPage-DO4A0M2F.js → ProjectsPage-CTqLKk01.js} +1 -1
  31. package/web-app/dist/assets/{SettingsPage-BKWXl4Np.js → SettingsPage-W7Ntgwvx.js} +1 -1
  32. package/web-app/dist/assets/{ShowcasePage-UNZcXiHr.js → ShowcasePage-Bnb-SpWP.js} +1 -1
  33. package/web-app/dist/assets/{SystemSettingsPage-CW2mOuWl.js → SystemSettingsPage-DmkyMEEf.js} +1 -1
  34. package/web-app/dist/assets/{TeamsPage-Cxk0bCsu.js → TeamsPage-BDg_dylr.js} +1 -1
  35. package/web-app/dist/assets/{TemplatesPage-iYNF5yYL.js → TemplatesPage-zwUCIEOg.js} +1 -1
  36. package/web-app/dist/assets/{TerminalOutput-Dg_Xdxmz.js → TerminalOutput-Raof8c5U.js} +1 -1
  37. package/web-app/dist/assets/{activity-CsJcnEkv.js → activity-IB3YlI9q.js} +1 -1
  38. package/web-app/dist/assets/{bell-Dj1eV0sE.js → bell-BDzVZvca.js} +1 -1
  39. package/web-app/dist/assets/{bot-SdhbB-yI.js → bot-DsRGUgID.js} +1 -1
  40. package/web-app/dist/assets/{check-qfdE8z-n.js → check-C7E0WGL4.js} +1 -1
  41. package/web-app/dist/assets/{chevron-left-BZTvZw6M.js → chevron-left-D-ICnF5T.js} +1 -1
  42. package/web-app/dist/assets/{circle-alert-C0ZCdZKV.js → circle-alert-CZqV3x2-.js} +1 -1
  43. package/web-app/dist/assets/{clock-BoLle2Q_.js → clock-BIEgg_GJ.js} +1 -1
  44. package/web-app/dist/assets/{cloud-B62-AI50.js → cloud-DRzjdYzI.js} +1 -1
  45. package/web-app/dist/assets/{code-xml-BJ6VEWJ2.js → code-xml-BQYPTsLd.js} +1 -1
  46. package/web-app/dist/assets/{database-CJWmI9K6.js → database-gBcDKVfn.js} +1 -1
  47. package/web-app/dist/assets/{dollar-sign-CHkKo4JL.js → dollar-sign-Bnsh4Jq8.js} +1 -1
  48. package/web-app/dist/assets/{file-code-corner-Cak0xMzn.js → file-code-corner-BhXnk7-V.js} +1 -1
  49. package/web-app/dist/assets/{file-plus-KcuuGUvs.js → file-plus-l1DKdi2E.js} +1 -1
  50. package/web-app/dist/assets/{globe-RYkFQXqZ.js → globe-D8W2cVH_.js} +1 -1
  51. package/web-app/dist/assets/{hammer-CqZmiYoP.js → hammer-DFPCUfHe.js} +1 -1
  52. package/web-app/dist/assets/{index-V8ZcLtYm.js → index-BMB47fiQ.js} +3 -3
  53. package/web-app/dist/assets/{layers-CmUGOLSC.js → layers-Dlu05krU.js} +1 -1
  54. package/web-app/dist/assets/{loader-circle-CUbu3dVo.js → loader-circle-BGagtH3f.js} +1 -1
  55. package/web-app/dist/assets/{lock-Cyp2Z2pp.js → lock-DBl7GNrr.js} +1 -1
  56. package/web-app/dist/assets/{package-xTUAKlLM.js → package-BsZzFTn1.js} +1 -1
  57. package/web-app/dist/assets/{plus-S1HlIoRX.js → plus-D1iwT9Vz.js} +1 -1
  58. package/web-app/dist/assets/{refresh-cw-D-8F6vP5.js → refresh-cw-WqyzmGbv.js} +1 -1
  59. package/web-app/dist/assets/{rotate-ccw-D0ddZ4wZ.js → rotate-ccw-BiOYJbPr.js} +1 -1
  60. package/web-app/dist/assets/{scroll-text-gqL8lJfM.js → scroll-text-r-VNmnk_.js} +1 -1
  61. package/web-app/dist/assets/{server-DEK4ac2b.js → server-B-gocXVg.js} +1 -1
  62. package/web-app/dist/assets/{shield-alert-DYk3CMCo.js → shield-alert-CU9Diuka.js} +1 -1
  63. package/web-app/dist/assets/{thumbs-up-CsujEA-F.js → thumbs-up-Ds9MPsEN.js} +1 -1
  64. package/web-app/dist/assets/{trash-2-CN1t155F.js → trash-2-CUqmSInK.js} +1 -1
  65. package/web-app/dist/assets/{trending-down-Co40Z73C.js → trending-down-CIvvdZtN.js} +1 -1
  66. package/web-app/dist/assets/{trending-up-Dn7lt32C.js → trending-up-CXVZ5vkw.js} +1 -1
  67. package/web-app/dist/assets/{upload-DvHTb05g.js → upload-DiB_d7Yc.js} +1 -1
  68. package/web-app/dist/assets/{usePolling-ZAgszFZ5.js → usePolling-DNrz_v7v.js} +1 -1
  69. package/web-app/dist/assets/{user-CpJHdCRI.js → user-CSnRzMEQ.js} +1 -1
  70. package/web-app/dist/index.html +1 -1
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '11.17.102'
78
+ __version__ = '11.18.0'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "11.17.102",
4
+ "version": "11.18.0",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -160,5 +160,5 @@
160
160
  "dependencies": {
161
161
  "@resvg/resvg-wasm": "^2.6.2"
162
162
  },
163
- "gitHead": "00bc53d72a5c7f07c6be061f85dd418ba5809d5b"
163
+ "gitHead": "96bf456ce704b32f454588206efa07da8f46ebf8"
164
164
  }
@@ -9292,6 +9292,14 @@ function isExitCodedScript(cmd) {
9292
9292
  }
9293
9293
  return script;
9294
9294
  }
9295
+ function exitCodedId(cmd, out2, repoDir = "") {
9296
+ const roots = repoDir ? [`/private${repoDir}/`, `${repoDir}/`, `/private${repoDir}`, repoDir] : [];
9297
+ const norm2 = (x) => roots.reduce((t, r) => t.split(r).join(""), x).replace(/(?<=\.[A-Za-z0-9]+):\d+(?::\d+)?/g, "").replace(/\s+/g, " ").trim();
9298
+ const lines = stripAnsi(out2).split(`
9299
+ `).map(norm2).filter(Boolean).sort();
9300
+ return lines.length ? `exit-coded:${cmd.trim()}:${createHash8("sha256").update(lines.join(`
9301
+ `)).digest("hex")}` : null;
9302
+ }
9295
9303
  function classifyCheck(i) {
9296
9304
  if (i.missing)
9297
9305
  return { result: "not_run", reason: "tool not found on PATH" };
@@ -9299,8 +9307,6 @@ function classifyCheck(i) {
9299
9307
  return { result: "not_run", reason: "timed out or aborted" };
9300
9308
  if (i.kind === "static")
9301
9309
  return { result: i.ok ? "pass" : "fail" };
9302
- if (i.exitCoded)
9303
- return { result: i.ok ? "pass" : "fail", count: EXIT_CODED_COUNT };
9304
9310
  const text2 = stripAnsi(i.out);
9305
9311
  if (i.runner === "go") {
9306
9312
  if (i.ok)
@@ -9311,6 +9317,8 @@ function classifyCheck(i) {
9311
9317
  return FAIL_EVIDENCE.test(text2) || GO_FAIL_EVIDENCE.test(text2) ? { result: "fail" } : { result: "not_run", reason: UNCONFIRMED_REASON };
9312
9318
  }
9313
9319
  const n2 = testCount(i.out, i.path, i.ok);
9320
+ if (i.exitCoded && n2 === null)
9321
+ return { result: i.ok ? "pass" : "fail", count: EXIT_CODED_COUNT };
9314
9322
  if (!i.ok && FAIL_EVIDENCE.test(text2))
9315
9323
  return { result: "fail", ...n2 !== null ? { n: n2 } : {} };
9316
9324
  if (n2 === 0)
@@ -9819,7 +9827,7 @@ var NO_TESTS_REASON = "no tests executed", GO_EXIT0_REASON = "test count could n
9819
9827
  }, EXCERPT_GROUP_CAP = 1500, EXCERPT_TOTAL_CAP = 6144, verifyJobs = () => {
9820
9828
  const n2 = Number.parseInt(process.env["LOKI_E10_VERIFY_JOBS"] ?? "", 10);
9821
9829
  return Number.isFinite(n2) && n2 >= 1 ? Math.min(n2, 8) : 1;
9822
- }, FULL_SUITE_CMD, ALREADY_FAILING_ON_BASE = "already failing on base, not caused by this change", checkResultLabel = (result, preRed) => result === "fail" && preRed ? `fail (${ALREADY_FAILING_ON_BASE})` : result, blobSha = (b, hex) => createHash8(hex === 64 ? "sha256" : "sha1").update(Buffer.concat([Buffer.from(`blob ${b.length}\x00`), b])).digest("hex");
9830
+ }, FULL_SUITE_CMD, ALREADY_FAILING_ON_BASE = "already failing on base, not caused by this change", SKIPPED_BY_REPO = "skipped by the repo on base and head", checkResultLabel = (result, preRed, repoSkipped = false) => result === "fail" && preRed ? `fail (${ALREADY_FAILING_ON_BASE})` : result === "not_run" && repoSkipped ? `not_run (${SKIPPED_BY_REPO})` : result, blobSha = (b, hex) => createHash8(hex === 64 ? "sha256" : "sha1").update(Buffer.concat([Buffer.from(`blob ${b.length}\x00`), b])).digest("hex");
9823
9831
  var init_check_result = __esm(() => {
9824
9832
  init_resolve();
9825
9833
  init_testmap();
@@ -10027,7 +10035,7 @@ function collapseNotProven(lines) {
10027
10035
  }
10028
10036
  var FLOOD_PREFIXES, FLOOD_CAP = 8, PRE_RED_CAP = 3, PRE_RED = "pre red: ", COLLAPSED_PRE_RED;
10029
10037
  var init_term_width = __esm(() => {
10030
- FLOOD_PREFIXES = ["not run: ", "flaky test: ", "skipped on base (excused): ", "changed, untested after limit: ", "reverted test edit: ", "wall test discarded: ", "Wall test not executed: ", "weakened test: "];
10038
+ FLOOD_PREFIXES = ["not run: ", "flaky test: ", "skipped by the repo on base and head: ", "changed, untested after limit: ", "reverted test edit: ", "wall test discarded: ", "Wall test not executed: ", "weakened test: "];
10031
10039
  COLLAPSED_PRE_RED = /^pre red: \d+ tests already failing on base/;
10032
10040
  });
10033
10041
 
@@ -10135,15 +10143,18 @@ async function zeroOnBase(cands, baseDir, repoDir, run, note) {
10135
10143
  symlinkSync(join39(src, d), join39(c.cwd, d));
10136
10144
  } catch {}
10137
10145
  }
10138
- const b = await run(c), last = c.args[c.args.length - 1] ?? "";
10139
- const k = classifyCheck({ kind: "test", ok: b.ok, cut: b.cut, missing: b.missing, out: b.out, ...goRunner(c.cmd, c.args), path: /\.[cm]?[jt]s$/.test(last) ? last : undefined });
10140
- if (k.result === "not_run" && k.n === 0 && !b.cut && !b.missing) {
10146
+ if (isZeroRun(c, await run(c))) {
10141
10147
  zero.push(c.name);
10142
10148
  note(c.name);
10143
10149
  }
10144
10150
  }
10145
10151
  return zero;
10146
10152
  }
10153
+ function isZeroRun(c, b) {
10154
+ const last = c.args[c.args.length - 1] ?? "";
10155
+ const k = classifyCheck({ kind: "test", ok: b.ok, cut: b.cut, missing: b.missing, out: b.out, ...goRunner(c.cmd, c.args), path: /\.[cm]?[jt]s$/.test(last) ? last : undefined });
10156
+ return k.result === "not_run" && k.n === 0 && !b.cut && !b.missing;
10157
+ }
10147
10158
  function addedSymlinkNotes(rawDiff, planText) {
10148
10159
  const asks = (w) => [...(planText ?? "").matchAll(new RegExp(`\\b${w}s?\\b`, "gi"))].some((m) => !/\b(?:no|not|never|without|avoid|don'?t|cannot|can'?t)\b[^.\n]{0,40}$/i.test(planText.slice(Math.max(0, m.index - 45), m.index)));
10149
10160
  const out2 = [];
@@ -12970,16 +12981,21 @@ ${r.stderr}`);
12970
12981
  continue;
12971
12982
  }
12972
12983
  const cls = classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out2, ...goRunner(line2), exitCoded: isExitCodedScript(line2) });
12973
- checks.push({ name, cmd: cmd2, result: cls.result, duration_s, ...cls.count ? { count: cls.count } : {}, ...cls.result === "fail" ? { ids: failIds(out2), excerpt: failureExcerpt(out2, repoDir) } : {} });
12984
+ checks.push({ name, cmd: cmd2, result: cls.result, duration_s, ...cls.count ? { count: cls.count } : {}, ...cls.result === "fail" ? { ids: cls.count ? [exitCodedId(line2, out2, repoDir) ?? []].flat() : failIds(out2), excerpt: failureExcerpt(out2, repoDir) } : {} });
12974
12985
  if (cls.result === "not_run")
12975
12986
  notProven.add(`not run: ${name} (${cls.reason ?? NO_TESTS_REASON})`);
12976
12987
  }
12977
12988
  const ran2 = checks.some((c) => c.result === "pass" || c.result === "fail"), rel = (f) => isAbsolute7(f) ? relative7(repoDir, f) : f, wallOwn = new Set((opts.proofFiles ?? []).map(rel));
12978
12989
  const product = opts.changed?.filter((f) => !wallOwn.has(rel(f)));
12979
- for (const pkg of api.packages().filter((p) => !p.commands.test)) {
12990
+ const testless = api.packages().filter((p) => !p.commands.test), isRoot = (p) => p.root === "." || p.root === "";
12991
+ const unowned = (product ?? []).filter((f) => !f.startsWith('"') && !api.packageOf(f)), unprovenFiles = execProves(repoDir, opts, (f) => !api.packageOf(f)) ? [] : unowned;
12992
+ if (testless.length)
12993
+ for (const f of unprovenFiles)
12994
+ notProven.add(`changed file ${f} belongs to no package and no passing check exercised it`);
12995
+ for (const pkg of testless) {
12980
12996
  const note = `full suite: package ${pkg.name} defines no test command`, owns = !product || product.length === 0 || product.some((f) => {
12981
12997
  const o = api.packageOf(f);
12982
- return !o || f.startsWith('"') || o.root === pkg.root;
12998
+ return f.startsWith('"') || (o ? o.root === pkg.root : isRoot(pkg));
12983
12999
  });
12984
13000
  const proven = (opts.proofFiles ?? []).some((f) => api.packageOf(f)?.root === pkg.root) || execProves(repoDir, opts, (c) => api.packageOf(c)?.root === pkg.root);
12985
13001
  notProven.add(ran2 && !(owns && !proven) ? NA_PREFIX + note : note);
@@ -15646,7 +15662,7 @@ async function runCheck(ctx, name, cmd2, args, signal, checks, opts = {}) {
15646
15662
  ctx.emit("test.result", "verify", opts.opaque ? { ...pubHold(check) } : { ...check });
15647
15663
  return check;
15648
15664
  }
15649
- async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true) {
15665
+ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal, zeroOk = true, zeroIntake = new Set) {
15650
15666
  const out2 = { ids: [], names: [], weak: [], zero: [], cnt: {} };
15651
15667
  const pairs = checks.flatMap((c) => {
15652
15668
  const t = tests.find((x) => testCheckName(x) === c.name);
@@ -15654,7 +15670,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
15654
15670
  });
15655
15671
  const un = pairs.filter(({ t }) => !changed.includes(t.path));
15656
15672
  const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
15657
- const zc = zeroOk ? un.filter(({ c, t }) => c.result === "not_run" && !c.owner && (c.reason ?? "").startsWith(NO_TESTS_REASON) && !wall.has(c.name) && !rel.has(c.name) && !isHoldoutCheck(c.name) && !changed.includes(t.path)) : [];
15673
+ const zc = zeroOk ? un.filter(({ c, t }) => c.result === "not_run" && !c.owner && (c.reason ?? "").startsWith(NO_TESTS_REASON) && !wall.has(c.name) && !isHoldoutCheck(c.name) && !changed.includes(t.path) && zeroIntake.has(c.name)) : [];
15658
15674
  if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length || zc.length) || signal.aborted)
15659
15675
  return out2;
15660
15676
  const dir = mkdtempSync10(join59(tmpdir11(), "e10-base-"));
@@ -15833,7 +15849,7 @@ var init_verify = __esm(() => {
15833
15849
  }
15834
15850
  const targetNames = new Set([...[...wallTests, ...relevant2].map(testCheckName), ...checks.filter(isHold).map((c) => c.name)]);
15835
15851
  const cfgChanged = testConfigChanged(ctx.repoDir, ctx.baseSha, changed);
15836
- const preRed = await subtractBase(ctx, api, checks, tests, changed, new Set(wallTests.map(testCheckName)), new Set(relevant2.map(testCheckName)), signal, cfgChanged.length === 0 && changed.every(isTestFile));
15852
+ const preRed = await subtractBase(ctx, api, checks, tests, changed, new Set(wallTests.map(testCheckName)), new Set(relevant2.map(testCheckName)), signal, cfgChanged.length === 0, new Set(ctx.outputs().intake?.zero_baseline?.zero ?? []));
15837
15853
  const attr = attribute(ctx.repoDir, ctx.baseSha, checks.filter((c) => c.result === "fail" && !preRed.names.includes(c.name)).map((c) => ({ name: c.name, ids: c.ids, eligible: !targetNames.has(c.name) && !changed.includes(c.name.slice(c.name.indexOf(":") + 1)) })));
15838
15854
  attr.introducedChecks = [...new Set(attr.introducedChecks.map((n2) => isHoldoutCheck(n2) ? "holdout" : n2))];
15839
15855
  preRed.names.push(...attr.preExistingChecks);
@@ -17213,7 +17229,7 @@ function targetProofOf(v) {
17213
17229
  const names = new Set(strs2(v?.target_checks)), raw2 = Array.isArray(v?.checks) ? v.checks : [];
17214
17230
  return raw2.some((c) => names.has(String(c.name)) && hasExecutedProof([c]));
17215
17231
  }
17216
- function checksOf(v, pc, preRed = []) {
17232
+ function checksOf(v, pc, preRed = [], repoSkipped = []) {
17217
17233
  if (!Array.isArray(v))
17218
17234
  return [];
17219
17235
  return v.filter((c) => !!c && typeof c === "object").map((c) => ({
@@ -17224,11 +17240,12 @@ function checksOf(v, pc, preRed = []) {
17224
17240
  provenance: checkProvenance(String(c.name ?? ""), pc),
17225
17241
  ...typeof c.n === "number" ? { n: c.n } : {},
17226
17242
  ...typeof c.count === "string" ? { count: c.count } : {},
17227
- ...c.result === "fail" && preRed.includes(String(c.name ?? "")) ? { pre_red: true } : {}
17243
+ ...c.result === "fail" && preRed.includes(String(c.name ?? "")) ? { pre_red: true } : {},
17244
+ ...c.result !== "pass" && c.result !== "fail" && repoSkipped.includes(String(c.name ?? "")) ? { repo_skipped: true } : {}
17228
17245
  }));
17229
17246
  }
17230
17247
  function renderReceiptMd(r) {
17231
- const sig = r.verification.jwt ? `SIGNED (kid ${r.verification.kid})` : "UNSIGNED", ln = (c) => `- ${checkResultLabel(c.result, c.pre_red === true)}: ${c.name} (\`${c.cmd}\`, ${c.duration_s}s)`, sec = (h, cs) => [h, ...cs.length ? cs.map(ln) : ["- none"]], indep = (c) => c.provenance === "exogenous" || c.provenance === "independent";
17248
+ const sig = r.verification.jwt ? `SIGNED (kid ${r.verification.kid})` : "UNSIGNED", ln = (c) => `- ${checkResultLabel(c.result, c.pre_red === true, c.repo_skipped === true)}: ${c.name} (\`${c.cmd}\`, ${c.duration_s}s)`, sec = (h, cs) => [h, ...cs.length ? cs.map(ln) : ["- none"]], indep = (c) => c.provenance === "exogenous" || c.provenance === "independent";
17232
17249
  const usd = r.cost.usd !== null ? `$${r.cost.usd.toFixed(4)}` : r.cost.measured_sessions > 0 ? `partial: $${r.cost.partial_usd.toFixed(4)} for ${r.cost.measured_sessions} of ${r.cost.total_sessions} sessions` : "not measured";
17233
17250
  return [
17234
17251
  `## Loki receipt: ${r.verdict}`,
@@ -17343,7 +17360,8 @@ var init_seal = __esm(() => {
17343
17360
  const wallNotRun = typeof base.not_run === "number" ? base.not_run : 0;
17344
17361
  const wallGreenOnBase = wallGreenOnBaseOf(o);
17345
17362
  const preRedChecks = strs2(o.verify?.pre_red_checks);
17346
- const rawDiff = diffOk ? diff.stdout.split("\x00").filter(Boolean) : [], pctx = { addedFiles: rawDiff.flatMap((m, i) => i % 2 === 0 && m.trim().split(" ").pop() === "A" && rawDiff[i + 1] ? [rawDiff[i + 1]] : []), wallFiles: Array.isArray(o.wall?.files) ? o.wall.files.map((f) => String(f.path)) : [], modifiedFiles: rawDiff.flatMap((m, i) => i % 2 === 0 && m.trim().split(" ").pop() !== "A" && rawDiff[i + 1] && isTestFile(rawDiff[i + 1]) ? [rawDiff[i + 1]] : []) }, checks = checksOf(o.verify?.checks, pctx, preRedChecks);
17363
+ const wallRel = (Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => String(f.path)), repoSkipped = strs2(o.verify?.skipped_on_base).filter((n3) => !wallRel.some((w) => w === n3.slice(n3.indexOf(":") + 1) || w.endsWith(`/${n3.slice(n3.indexOf(":") + 1)}`)));
17364
+ const rawDiff = diffOk ? diff.stdout.split("\x00").filter(Boolean) : [], pctx = { addedFiles: rawDiff.flatMap((m, i) => i % 2 === 0 && m.trim().split(" ").pop() === "A" && rawDiff[i + 1] ? [rawDiff[i + 1]] : []), wallFiles: Array.isArray(o.wall?.files) ? o.wall.files.map((f) => String(f.path)) : [], modifiedFiles: rawDiff.flatMap((m, i) => i % 2 === 0 && m.trim().split(" ").pop() !== "A" && rawDiff[i + 1] && isTestFile(rawDiff[i + 1]) ? [rawDiff[i + 1]] : []) }, checks = checksOf(o.verify?.checks, pctx, preRedChecks, repoSkipped);
17347
17365
  const weakTests = [];
17348
17366
  for (let i = 0;i + 1 < rawDiff.length; i += 2)
17349
17367
  if ((rawDiff[i].trim().split(" ").pop() ?? "") !== "A" && isTestFile(rawDiff[i + 1]))
@@ -17352,7 +17370,7 @@ var init_seal = __esm(() => {
17352
17370
  const grp = sealGroup(ctx.runDir, receiptSha256);
17353
17371
  const vraw = Array.isArray(o.verify?.checks) ? o.verify.checks : [], executed = hasExecutedProof(vraw), proof = process.env["LOKI_EXOGENOUS_PROOF"] === "0" ? executed : hasExogenousProof(vraw, pctx);
17354
17372
  const uncoveredAfterLimit = o.implement?.exit === "killed" ? strs2(o.verify?.uncovered_changed) : [];
17355
- const verdict0 = capGroupVerdict(verdictOf2(o, checks.filter((c) => !(c.result === "fail" && preRedChecks.includes(c.name))), !diffOk || diff.stdout === "", verifyNotProven.length > 0 || weakTests.length > 0 || rcNotes.length > 0, wallGreenOnBase, proof, targetProofOf(o.verify), uncoveredAfterLimit), grp);
17373
+ const verdict0 = capGroupVerdict(verdictOf2(o, checks.filter((c) => !(c.result === "fail" && preRedChecks.includes(c.name)) && c.repo_skipped !== true), !diffOk || diff.stdout === "", verifyNotProven.length > 0 || weakTests.length > 0 || rcNotes.length > 0, wallGreenOnBase, proof, targetProofOf(o.verify), uncoveredAfterLimit), grp);
17356
17374
  const supply = await supplyGuard(ctx.repoDir, rawDiff.filter((_, i) => i % 2 === 1), readDeclared(ctx.repoDir), process.env);
17357
17375
  const verdict1 = supplyVerdict(verdict0, supply);
17358
17376
  const xr = await crossReview(ctx, verdict1, head, signal), verdict2 = minVerdict(verdict1, xr);
@@ -17412,10 +17430,10 @@ var init_seal = __esm(() => {
17412
17430
  for (const f of uncoveredAfterLimit)
17413
17431
  notProven.add(`changed, untested after limit: ${f}`);
17414
17432
  for (const c of checks)
17415
- if (c.result === "not_run" && !strs2(o.verify?.skipped_on_base).includes(c.name))
17433
+ if (c.result === "not_run" && c.repo_skipped !== true)
17416
17434
  notProven.add(`not run: ${c.name}`);
17417
- for (const n3 of strs2(o.verify?.skipped_on_base))
17418
- notProven.add(`skipped on base (excused): ${n3}`);
17435
+ for (const n3 of repoSkipped)
17436
+ notProven.add(`${SKIPPED_BY_REPO}: ${n3}`);
17419
17437
  for (const f of strs2(o.verify?.flaky))
17420
17438
  notProven.add(`flaky test: ${f}`);
17421
17439
  for (const n3 of verifyNotProven)
@@ -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.17.102",
5
+ "version": "11.18.0",
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-V8ZcLtYm.js";import{B as C}from"./Button-DfTDN0WV.js";import{T as $e}from"./trending-up-Dn7lt32C.js";import{C as z}from"./clock-BoLle2Q_.js";import{A as Be,U as ue,M as De}from"./Avatar-BdSscJ5J.js";import{A as J}from"./activity-CsJcnEkv.js";import{R as pe}from"./refresh-cw-D-8F6vP5.js";import{G as ze}from"./globe-RYkFQXqZ.js";import{C as Le}from"./chevron-left-BZTvZw6M.js";import{C as je}from"./check-qfdE8z-n.js";import{D as Y}from"./dollar-sign-CHkKo4JL.js";import{U as Te}from"./user-CpJHdCRI.js";import{D as Me}from"./database-CJWmI9K6.js";import{L as Ue}from"./lock-Cyp2Z2pp.js";import{S as Re}from"./scroll-text-gqL8lJfM.js";import{S as Ie}from"./shield-alert-DYk3CMCo.js";/**
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-BMB47fiQ.js";import{B as C}from"./Button-BPOUvGtk.js";import{T as $e}from"./trending-up-CXVZ5vkw.js";import{C as z}from"./clock-BIEgg_GJ.js";import{A as Be,U as ue,M as De}from"./Avatar-CNr3zMt9.js";import{A as J}from"./activity-IB3YlI9q.js";import{R as pe}from"./refresh-cw-WqyzmGbv.js";import{G as ze}from"./globe-D8W2cVH_.js";import{C as Le}from"./chevron-left-D-ICnF5T.js";import{C as je}from"./check-C7E0WGL4.js";import{D as Y}from"./dollar-sign-Bnsh4Jq8.js";import{U as Te}from"./user-CSnRzMEQ.js";import{D as Me}from"./database-gBcDKVfn.js";import{L as Ue}from"./lock-DBl7GNrr.js";import{S as Re}from"./scroll-text-r-VNmnk_.js";import{S as Ie}from"./shield-alert-CU9Diuka.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as l,j as s}from"./index-V8ZcLtYm.js";/**
1
+ import{c as l,j as s}from"./index-BMB47fiQ.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as e}from"./index-V8ZcLtYm.js";import{C as r}from"./clock-BoLle2Q_.js";import{C as a}from"./circle-alert-C0ZCdZKV.js";import{C as l}from"./check-qfdE8z-n.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
1
+ import{j as e}from"./index-BMB47fiQ.js";import{C as r}from"./clock-BIEgg_GJ.js";import{C as a}from"./circle-alert-CZqV3x2-.js";import{C as l}from"./check-C7E0WGL4.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
@@ -1 +1 @@
1
- import{r as p,j as t}from"./index-V8ZcLtYm.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
1
+ import{r as p,j as t}from"./index-BMB47fiQ.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
@@ -1,4 +1,4 @@
1
- import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-V8ZcLtYm.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DWjDhnb-.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-CsujEA-F.js";import{C as oe}from"./check-qfdE8z-n.js";import{C as Ye}from"./clock-BoLle2Q_.js";import{D as Xe}from"./dollar-sign-CHkKo4JL.js";import{U as Ze}from"./upload-DvHTb05g.js";import{L as V}from"./loader-circle-CUbu3dVo.js";/**
1
+ import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-BMB47fiQ.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-_w7Oyx3U.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-Ds9MPsEN.js";import{C as oe}from"./check-C7E0WGL4.js";import{C as Ye}from"./clock-BIEgg_GJ.js";import{D as Xe}from"./dollar-sign-Bnsh4Jq8.js";import{U as Ze}from"./upload-DiB_d7Yc.js";import{L as V}from"./loader-circle-BGagtH3f.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as o,j as e}from"./index-V8ZcLtYm.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
1
+ import{r as o,j as e}from"./index-BMB47fiQ.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
@@ -1,4 +1,4 @@
1
- import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-V8ZcLtYm.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-BMB47fiQ.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as l,a as x,j as e}from"./index-V8ZcLtYm.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
1
+ import{r as l,a as x,j as e}from"./index-BMB47fiQ.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
@@ -1,4 +1,4 @@
1
- import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-V8ZcLtYm.js";import{B as N}from"./Button-DfTDN0WV.js";import{C as y}from"./thumbs-up-CsujEA-F.js";import{R as S}from"./refresh-cw-D-8F6vP5.js";import{C as z}from"./circle-alert-C0ZCdZKV.js";import{U as D}from"./user-CpJHdCRI.js";import{L as G}from"./loader-circle-CUbu3dVo.js";import{R as T}from"./rotate-ccw-D0ddZ4wZ.js";/**
1
+ import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-BMB47fiQ.js";import{B as N}from"./Button-BPOUvGtk.js";import{C as y}from"./thumbs-up-Ds9MPsEN.js";import{R as S}from"./refresh-cw-WqyzmGbv.js";import{C as z}from"./circle-alert-CZqV3x2-.js";import{U as D}from"./user-CSnRzMEQ.js";import{L as G}from"./loader-circle-BGagtH3f.js";import{R as T}from"./rotate-ccw-BiOYJbPr.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-V8ZcLtYm.js";import{B as y}from"./Button-DfTDN0WV.js";import{C as ge}from"./chevron-left-BZTvZw6M.js";import{G as P}from"./thumbs-up-CsujEA-F.js";import{R as $}from"./refresh-cw-D-8F6vP5.js";import{C as Ne}from"./circle-alert-C0ZCdZKV.js";import{L as Q,S as je}from"./ProjectPage-wRtrbDO6.js";import{S as se}from"./shield-alert-DYk3CMCo.js";import{F as ye}from"./file-code-corner-Cak0xMzn.js";import{C as V}from"./clock-BoLle2Q_.js";import{C as re}from"./check-qfdE8z-n.js";import"./ErrorBoundary-DWjDhnb-.js";import"./TerminalOutput-Dg_Xdxmz.js";import"./lock-Cyp2Z2pp.js";import"./package-xTUAKlLM.js";import"./file-plus-KcuuGUvs.js";import"./activity-CsJcnEkv.js";import"./scroll-text-gqL8lJfM.js";import"./bot-SdhbB-yI.js";import"./loader-circle-CUbu3dVo.js";import"./hammer-CqZmiYoP.js";import"./dollar-sign-CHkKo4JL.js";import"./globe-RYkFQXqZ.js";import"./trash-2-CN1t155F.js";import"./upload-DvHTb05g.js";import"./plus-S1HlIoRX.js";import"./rotate-ccw-D0ddZ4wZ.js";import"./code-xml-BJ6VEWJ2.js";import"./trending-up-Dn7lt32C.js";import"./layers-CmUGOLSC.js";import"./trending-down-Co40Z73C.js";import"./server-DEK4ac2b.js";/**
1
+ import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-BMB47fiQ.js";import{B as y}from"./Button-BPOUvGtk.js";import{C as ge}from"./chevron-left-D-ICnF5T.js";import{G as P}from"./thumbs-up-Ds9MPsEN.js";import{R as $}from"./refresh-cw-WqyzmGbv.js";import{C as Ne}from"./circle-alert-CZqV3x2-.js";import{L as Q,S as je}from"./ProjectPage-CWZw_DTd.js";import{S as se}from"./shield-alert-CU9Diuka.js";import{F as ye}from"./file-code-corner-BhXnk7-V.js";import{C as V}from"./clock-BIEgg_GJ.js";import{C as re}from"./check-C7E0WGL4.js";import"./ErrorBoundary-_w7Oyx3U.js";import"./TerminalOutput-Raof8c5U.js";import"./lock-DBl7GNrr.js";import"./package-BsZzFTn1.js";import"./file-plus-l1DKdi2E.js";import"./activity-IB3YlI9q.js";import"./scroll-text-r-VNmnk_.js";import"./bot-DsRGUgID.js";import"./loader-circle-BGagtH3f.js";import"./hammer-DFPCUfHe.js";import"./dollar-sign-Bnsh4Jq8.js";import"./globe-D8W2cVH_.js";import"./trash-2-CUqmSInK.js";import"./upload-DiB_d7Yc.js";import"./plus-D1iwT9Vz.js";import"./rotate-ccw-BiOYJbPr.js";import"./code-xml-BQYPTsLd.js";import"./trending-up-CXVZ5vkw.js";import"./layers-Dlu05krU.js";import"./trending-down-CIvvdZtN.js";import"./server-B-gocXVg.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.