loki-mode 11.54.4 → 11.55.1

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 (68) 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 +10 -0
  7. package/loki-ts/dist/loki.js +1223 -1219
  8. package/mcp/__init__.py +1 -1
  9. package/package.json +2 -2
  10. package/packages/control-plane/dist/server.js +44 -25
  11. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  12. package/web-app/dist/assets/{AdminPage-rWS7P1Ao.js → AdminPage-DMrl-JpA.js} +1 -1
  13. package/web-app/dist/assets/{Avatar-DSk6ksIr.js → Avatar-BEP3MBdR.js} +1 -1
  14. package/web-app/dist/assets/{Badge-CISgXS_G.js → Badge-DL38qqW8.js} +1 -1
  15. package/web-app/dist/assets/{Button-CUUSKCZJ.js → Button-CSqHYv_2.js} +1 -1
  16. package/web-app/dist/assets/{CockpitPage-CcVbcX-V.js → CockpitPage-CwGbI42u.js} +1 -1
  17. package/web-app/dist/assets/{ComparePage-CQcrhvFy.js → ComparePage-CMJ8t-EA.js} +1 -1
  18. package/web-app/dist/assets/{ErrorBoundary-CqSoPFhw.js → ErrorBoundary-DSTIh94K.js} +1 -1
  19. package/web-app/dist/assets/{EvidenceReceiptPanel-IiFZFavc.js → EvidenceReceiptPanel-AKX31N5q.js} +1 -1
  20. package/web-app/dist/assets/{GitHubIssuesPanel-DM8gr5N8.js → GitHubIssuesPanel-pxyIQhC-.js} +1 -1
  21. package/web-app/dist/assets/{GitHubPRsPanel-CuHK7nUF.js → GitHubPRsPanel-3P-i0RU2.js} +1 -1
  22. package/web-app/dist/assets/{HomePage-Xtz2jLmp.js → HomePage-Vy2-dR_0.js} +2 -2
  23. package/web-app/dist/assets/{LoginPage-SDxZNv7B.js → LoginPage-DCBS0q1A.js} +1 -1
  24. package/web-app/dist/assets/{MagicPage-Brb5n_Cj.js → MagicPage-Cw9nNSZR.js} +1 -1
  25. package/web-app/dist/assets/{MetricsPage-aAUVsDHB.js → MetricsPage-B-BoYL0s.js} +1 -1
  26. package/web-app/dist/assets/{NotFoundPage-ChEVzk0P.js → NotFoundPage-ConLcIC5.js} +1 -1
  27. package/web-app/dist/assets/{ProjectPage-tO0cI771.js → ProjectPage-_RJqqa7r.js} +3 -3
  28. package/web-app/dist/assets/{ProjectsPage-DKO0sQwJ.js → ProjectsPage-rsQ4CNaI.js} +1 -1
  29. package/web-app/dist/assets/{SettingsPage-Dm14Yboo.js → SettingsPage-_K8L0Yp6.js} +1 -1
  30. package/web-app/dist/assets/{ShowcasePage-pmpgINEv.js → ShowcasePage-BmNNR8Pk.js} +1 -1
  31. package/web-app/dist/assets/{SystemSettingsPage-D3vaCRPS.js → SystemSettingsPage-BVcLLBR_.js} +1 -1
  32. package/web-app/dist/assets/{TeamsPage-DmnKx4Y2.js → TeamsPage-CYQkxno7.js} +1 -1
  33. package/web-app/dist/assets/{TemplatesPage-Cbj-ePbO.js → TemplatesPage-KBctkp_5.js} +1 -1
  34. package/web-app/dist/assets/{TerminalOutput-DncIMq8c.js → TerminalOutput-zJu55vzo.js} +1 -1
  35. package/web-app/dist/assets/{activity-BE-AgOv1.js → activity-DQJZXRVQ.js} +1 -1
  36. package/web-app/dist/assets/{bell-D_r8abu7.js → bell-DXKmkNZn.js} +1 -1
  37. package/web-app/dist/assets/{bot-BBC3O3VF.js → bot-Cq4UXZAk.js} +1 -1
  38. package/web-app/dist/assets/{check-BhkAUzf6.js → check-8RS3WM0W.js} +1 -1
  39. package/web-app/dist/assets/{chevron-left-D8ksaSPd.js → chevron-left-BfNrm41n.js} +1 -1
  40. package/web-app/dist/assets/{circle-alert-Do3VEpwg.js → circle-alert-Rmo6xwSG.js} +1 -1
  41. package/web-app/dist/assets/{clock-Bu8DUp0v.js → clock-BIovJVE7.js} +1 -1
  42. package/web-app/dist/assets/{cloud-DvCR2PA8.js → cloud-CPACkQj6.js} +1 -1
  43. package/web-app/dist/assets/{code-xml-D3IdN8cp.js → code-xml-By_Axt1q.js} +1 -1
  44. package/web-app/dist/assets/{database-jOdnNbz-.js → database-7Y7ophDy.js} +1 -1
  45. package/web-app/dist/assets/{dollar-sign-Bq2Arvlt.js → dollar-sign-CeuNG_0y.js} +1 -1
  46. package/web-app/dist/assets/{file-code-corner-Dx57oNjY.js → file-code-corner-Cxpa7IqK.js} +1 -1
  47. package/web-app/dist/assets/{file-plus-DT6ln-0k.js → file-plus-CTPHdwOk.js} +1 -1
  48. package/web-app/dist/assets/{globe-j79rR76R.js → globe-DsU2fmWc.js} +1 -1
  49. package/web-app/dist/assets/{hammer-QWDU7JhP.js → hammer-CSB9UcY6.js} +1 -1
  50. package/web-app/dist/assets/{index-DanBjSJ8.js → index-CfxxQ2Rb.js} +3 -3
  51. package/web-app/dist/assets/{layers-FaIaHoxY.js → layers-D0X4BPSq.js} +1 -1
  52. package/web-app/dist/assets/{loader-circle-Bvvku0wP.js → loader-circle-C2ErTM1m.js} +1 -1
  53. package/web-app/dist/assets/{lock-1YFDik7V.js → lock-JLrpk0hT.js} +1 -1
  54. package/web-app/dist/assets/{package-BHnW3nO4.js → package-CNuSANZE.js} +1 -1
  55. package/web-app/dist/assets/{plus-CYsPyD5V.js → plus-B0DxJd7a.js} +1 -1
  56. package/web-app/dist/assets/{refresh-cw-CugB71N2.js → refresh-cw-DjnL9E0A.js} +1 -1
  57. package/web-app/dist/assets/{rotate-ccw-BwG818Ni.js → rotate-ccw-CCFbC5Rz.js} +1 -1
  58. package/web-app/dist/assets/{scroll-text-CCTi2-TZ.js → scroll-text-MtLqgV7M.js} +1 -1
  59. package/web-app/dist/assets/{server-B5Kn_IXa.js → server-BZkj8U3T.js} +1 -1
  60. package/web-app/dist/assets/{shield-alert-9fSMvTZE.js → shield-alert-waWUzfuX.js} +1 -1
  61. package/web-app/dist/assets/{thumbs-up-DSZfhFU7.js → thumbs-up-C5rKskeM.js} +1 -1
  62. package/web-app/dist/assets/{trash-2-C0GKJdOD.js → trash-2-CUYMWFR7.js} +1 -1
  63. package/web-app/dist/assets/{trending-down-CE_quih9.js → trending-down-C8lnBmnC.js} +1 -1
  64. package/web-app/dist/assets/{trending-up-CsIqCh6c.js → trending-up-BLvUoFes.js} +1 -1
  65. package/web-app/dist/assets/{upload-C6v2mC_1.js → upload-DzL0hG7s.js} +1 -1
  66. package/web-app/dist/assets/{usePolling-Cizk5SL0.js → usePolling-DnG782KN.js} +1 -1
  67. package/web-app/dist/assets/{user-D_AwTTHl.js → user-g2NM3Uhg.js} +1 -1
  68. 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.54.4'
78
+ __version__ = '11.55.1'
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.54.4",
4
+ "version": "11.55.1",
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": "afa5b736fad88912c9fca347167ab1e2efd5a1a5"
163
+ "gitHead": "ec115d31f687266b6d3920e989e1822f123c098d"
164
164
  }
@@ -10616,6 +10616,7 @@ var init_base_guard = __esm(() => {
10616
10616
  });
10617
10617
 
10618
10618
  // ../../loki-ts/src/features/speed/unit_mode.ts
10619
+ import { createHash as createHash10 } from "crypto";
10619
10620
  import { closeSync as closeSync7, constants, fstatSync as fstatSync5, lstatSync as lstatSync9, openSync as openSync7, readSync as readSync6, realpathSync as realpathSync18 } from "fs";
10620
10621
  function readBounded(path) {
10621
10622
  const l = lstatSync9(path);
@@ -10672,11 +10673,27 @@ function unitSpec(env = process.env) {
10672
10673
  memo2.set(path, parseSpec(path));
10673
10674
  return memo2.get(path) ?? null;
10674
10675
  }
10676
+ function unitSpecSha256(s) {
10677
+ return createHash10("sha256").update(JSON.stringify({ id: typeof s.id === "string" ? s.id : "", items: arr2(s.items), acceptance: arr2(s.acceptance), writeSet: arr2(s.writeSet), base: typeof s.base === "string" ? s.base : "" })).digest("hex");
10678
+ }
10679
+ function unitSpecReceiptBlock(env = process.env) {
10680
+ const path = env["LOKI_UNIT_SPEC"], frozen = env["LOKI_UNIT_SPEC_FROZEN"];
10681
+ if (env["LOKI_SPEED"] === "0" || !path)
10682
+ return {};
10683
+ try {
10684
+ const txt = frozen !== undefined ? frozen : readBounded(path);
10685
+ if (txt === null || txt.length > MAX_SPEC_BYTES)
10686
+ return {};
10687
+ return { unit_spec: { sha256: unitSpecSha256(JSON.parse(txt)) } };
10688
+ } catch {
10689
+ return {};
10690
+ }
10691
+ }
10675
10692
  function unitFlags(staged, env = process.env, pre = {}) {
10676
10693
  const s = unitSpec(env);
10677
10694
  return s ? staged.filter(({ f }) => !inWriteSet(s, f) && !Object.hasOwn(pre, f)).map(({ f }) => f) : null;
10678
10695
  }
10679
- var MAX_SPEC_BYTES, MAX_TOKEN_BUDGET = 1e9, norm2 = (p) => p.replace(/^\.\//, ""), CTRL, strs = (v) => Array.isArray(v) && v.every((x) => typeof x === "string" && !CTRL.test(x)) ? v.map(norm2) : null, memo2, inWriteSet = (spec, f) => spec.writeSet.some((w) => w.endsWith("/") ? f.startsWith(w) : f === w);
10696
+ var MAX_SPEC_BYTES, MAX_TOKEN_BUDGET = 1e9, norm2 = (p) => p.replace(/^\.\//, ""), CTRL, strs = (v) => Array.isArray(v) && v.every((x) => typeof x === "string" && !CTRL.test(x)) ? v.map(norm2) : null, memo2, arr2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [], inWriteSet = (spec, f) => spec.writeSet.some((w) => w.endsWith("/") ? f.startsWith(w) : f === w);
10680
10697
  var init_unit_mode = __esm(() => {
10681
10698
  MAX_SPEC_BYTES = 1024 * 1024;
10682
10699
  CTRL = /[\x00-\x1f\x7f]/;
@@ -11651,7 +11668,7 @@ var init_context = __esm(() => {
11651
11668
 
11652
11669
  // ../../loki-ts/src/util/steer.ts
11653
11670
  import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync17, lstatSync as lstatSync11, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync34, readSync as readSync7, renameSync as renameSync10, statSync as statSync16, lutimesSync, rmSync as rmSync10, unlinkSync as unlinkSync6, writeFileSync as writeFileSync18, existsSync as existsSync27 } from "fs";
11654
- import { createHash as createHash10, randomBytes as randomBytes4 } from "crypto";
11671
+ import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
11655
11672
  import { basename as basename15, join as join41 } from "path";
11656
11673
  function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
11657
11674
  for (let i = 0;; i++) {
@@ -11890,7 +11907,7 @@ function recordRevisions(repoDir, text2, archived, at) {
11890
11907
  `).trim();
11891
11908
  if (p.rev === null && body === "")
11892
11909
  continue;
11893
- const rev = p.rev !== null && p.rev > last ? p.rev : last + 1, sha2 = createHash10("sha256").update(body).digest("hex");
11910
+ const rev = p.rev !== null && p.rev > last ? p.rev : last + 1, sha2 = createHash11("sha256").update(body).digest("hex");
11894
11911
  last = rev;
11895
11912
  recs.push({ rev, source: p.source, actor: p.actor, sha: sha2, at: at.getTime() });
11896
11913
  out2.push(JSON.stringify({ rev, ts: p.ts, actor: p.actor, source: p.source, chars: body.length, sha256: sha2, consumed_at: at.toISOString(), archived }));
@@ -11933,7 +11950,7 @@ var init_steer = __esm(() => {
11933
11950
  });
11934
11951
 
11935
11952
  // ../../loki-ts/src/util/run_outputs.ts
11936
- import { createHash as createHash11 } from "crypto";
11953
+ import { createHash as createHash12 } from "crypto";
11937
11954
  import { existsSync as existsSync28, mkdirSync as mkdirSync16, readdirSync as readdirSync18, readFileSync as readFileSync35, statSync as statSync17, writeFileSync as writeFileSync19 } from "fs";
11938
11955
  import { join as join42, resolve as resolve16 } from "path";
11939
11956
  function intentRevisionsBlock(revs) {
@@ -11943,7 +11960,7 @@ function intentRevisionsBlock(revs) {
11943
11960
  function seededCorpusBlock(env = process.env) {
11944
11961
  const dir = env["LOKI_SEEDED_DEFECTS_DIR"] || join42(REPO_ROOT, "benchmarks", "seeded-defects");
11945
11962
  try {
11946
- const bytes = readFileSync35(join42(dir, "manifest.json")), version2 = createHash11("sha256").update(bytes).digest("hex");
11963
+ const bytes = readFileSync35(join42(dir, "manifest.json")), version2 = createHash12("sha256").update(bytes).digest("hex");
11947
11964
  const ids = (JSON.parse(bytes.toString("utf8")).defects ?? []).map((d) => d.id);
11948
11965
  let rate = null;
11949
11966
  try {
@@ -12367,11 +12384,11 @@ var init_run_status = __esm(() => {
12367
12384
  });
12368
12385
 
12369
12386
  // ../../loki-ts/src/util/seal_drift.ts
12370
- import { createHash as createHash12 } from "crypto";
12387
+ import { createHash as createHash13 } from "crypto";
12371
12388
  var EMPTY_SHA;
12372
12389
  var init_seal_drift = __esm(() => {
12373
12390
  init_safe_git();
12374
- EMPTY_SHA = createHash12("sha256").digest("hex");
12391
+ EMPTY_SHA = createHash13("sha256").digest("hex");
12375
12392
  });
12376
12393
 
12377
12394
  // ../../loki-ts/src/util/spec_file.ts
@@ -12884,7 +12901,7 @@ var init_wall_manifest = __esm(() => {
12884
12901
  });
12885
12902
 
12886
12903
  // ../../loki-ts/src/features/wall_manifest_wire.ts
12887
- import { createHash as createHash13 } from "crypto";
12904
+ import { createHash as createHash14 } from "crypto";
12888
12905
  import { basename as basename17, dirname as dirname18 } from "path";
12889
12906
  function blobEntries(ls) {
12890
12907
  const out2 = [];
@@ -12944,7 +12961,7 @@ function wallManifestFor(repoDir, tree, task, env = process.env) {
12944
12961
  if (at !== cat.length)
12945
12962
  return null;
12946
12963
  const text2 = buildWallManifest([...files, ...listed.map((e) => ({ path: e.path, content: "" }))], named.map((e) => e.path), matched.map((e) => e.path));
12947
- return { text: text2, sha256: createHash13("sha256").update(text2).digest("hex") };
12964
+ return { text: text2, sha256: createHash14("sha256").update(text2).digest("hex") };
12948
12965
  } catch {
12949
12966
  return null;
12950
12967
  }
@@ -12976,7 +12993,7 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
12976
12993
  });
12977
12994
 
12978
12995
  // ../../loki-ts/src/util/holdout.ts
12979
- import { createHash as createHash14 } from "crypto";
12996
+ import { createHash as createHash15 } from "crypto";
12980
12997
  import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync39, rmSync as rmSync13, writeFileSync as writeFileSync21 } from "fs";
12981
12998
  import { tmpdir as tmpdir6 } from "os";
12982
12999
  import { basename as basename18, join as join45, relative as relative6 } from "path";
@@ -13049,7 +13066,7 @@ function recordHoldoutTriage(runDir, entry) {
13049
13066
  `, { mode: 384 });
13050
13067
  } catch {}
13051
13068
  }
13052
- var sha2 = (s) => createHash14("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId2, repoDir) => join45(tmpdir6(), `loki-e10-holdout-${sha2(`${runId2}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
13069
+ var sha2 = (s) => createHash15("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId2, repoDir) => join45(tmpdir6(), `loki-e10-holdout-${sha2(`${runId2}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
13053
13070
  var init_holdout = () => {};
13054
13071
 
13055
13072
  // ../../loki-ts/src/util/lock_ecosystems.ts
@@ -14884,7 +14901,7 @@ var init_route_block = __esm(() => {
14884
14901
 
14885
14902
  // ../../loki-ts/src/features/visual_evidence.ts
14886
14903
  import { spawn as spawn8 } from "child_process";
14887
- import { createHash as createHash15, randomBytes as randomBytes6 } from "crypto";
14904
+ import { createHash as createHash16, randomBytes as randomBytes6 } from "crypto";
14888
14905
  import { existsSync as existsSync35, lstatSync as lstatSync12, mkdirSync as mkdirSync21, readdirSync as readdirSync20, readFileSync as readFileSync45, writeFileSync as writeFileSync24 } from "fs";
14889
14906
  import { createServer } from "net";
14890
14907
  import { dirname as dirname23, isAbsolute as isAbsolute10, join as join54, normalize as normalize3, relative as relative10, sep as sep13 } from "path";
@@ -15185,7 +15202,7 @@ function receiptScreensProblem(receiptPath, receipt) {
15185
15202
  return `visual evidence failed (LOKI_VISUAL_GATE=1): ${receipt["evidence_failed"]}`;
15186
15203
  return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname23(receiptPath), receipt["evidence_screens"]);
15187
15204
  }
15188
- var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash15("sha256").update(readFileSync45(p)).digest("hex"), playwrightBin = (repoDir) => {
15205
+ var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash16("sha256").update(readFileSync45(p)).digest("hex"), playwrightBin = (repoDir) => {
15189
15206
  const bin = join54(repoDir, "node_modules", ".bin", "playwright");
15190
15207
  return existsSync35(bin) ? bin : null;
15191
15208
  }, playwrightTestPkg = (repoDir) => {
@@ -15264,7 +15281,7 @@ var init_pr = __esm(() => {
15264
15281
  // ../../loki-ts/src/util/pr_lessons.ts
15265
15282
  import { existsSync as existsSync36, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync8, readFileSync as readFileSync46, rmSync as rmSync17, writeFileSync as writeFileSync25 } from "fs";
15266
15283
  import { dirname as dirname24, join as join56 } from "path";
15267
- import { createHash as createHash16 } from "crypto";
15284
+ import { createHash as createHash17 } from "crypto";
15268
15285
  function loadLessons(repoDir) {
15269
15286
  const p = lessonsPath(repoDir);
15270
15287
  if (!existsSync36(p))
@@ -15282,7 +15299,7 @@ function save(repoDir, lessons) {
15282
15299
  atomicWriteJson(p, { version: 2, lessons });
15283
15300
  }
15284
15301
  function appendReceiptFact(repoDir, f, now2 = () => new Date) {
15285
- const id = `rcp-${createHash16("sha256").update(f.runId).digest("hex").slice(0, 12)}`;
15302
+ const id = `rcp-${createHash17("sha256").update(f.runId).digest("hex").slice(0, 12)}`;
15286
15303
  const lessons = loadLessons(repoDir);
15287
15304
  if (lessons.some((l) => l.id === id))
15288
15305
  return false;
@@ -16850,7 +16867,7 @@ See also: loki cost --detail (what a run ALREADY spent)
16850
16867
  // ../../loki-ts/src/features/contract.ts
16851
16868
  import { existsSync as existsSync44, lstatSync as lstatSync16, mkdirSync as mkdirSync29, readFileSync as readFileSync53, rmSync as rmSync21, writeFileSync as writeFileSync31 } from "fs";
16852
16869
  import { dirname as dirname29, join as join66 } from "path";
16853
- import { createHash as createHash17 } from "crypto";
16870
+ import { createHash as createHash18 } from "crypto";
16854
16871
  function contractEnabled(env = process.env) {
16855
16872
  return env["LOKI_CONTRACT"] !== "0";
16856
16873
  }
@@ -16901,7 +16918,7 @@ function readContract(repoDir) {
16901
16918
  } catch {
16902
16919
  return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
16903
16920
  }
16904
- const sha2563 = createHash17("sha256").update(raw2).digest("hex");
16921
+ const sha2563 = createHash18("sha256").update(raw2).digest("hex");
16905
16922
  let j;
16906
16923
  try {
16907
16924
  j = JSON.parse(raw2.toString("utf8"));
@@ -16971,7 +16988,7 @@ var init_contract = __esm(() => {
16971
16988
  });
16972
16989
 
16973
16990
  // ../../loki-ts/src/features/speed/seal_group.ts
16974
- import { createHash as createHash18 } from "crypto";
16991
+ import { createHash as createHash19 } from "crypto";
16975
16992
  import { existsSync as existsSync45, mkdirSync as mkdirSync30, readdirSync as readdirSync23, readFileSync as readFileSync54, renameSync as renameSync13, statSync as statSync21, writeFileSync as writeFileSync32 } from "fs";
16976
16993
  import { dirname as dirname30, join as join67 } from "path";
16977
16994
  function sealGroup(runDir, rh) {
@@ -17093,7 +17110,7 @@ function compositeVerdict(childVerdicts) {
17093
17110
  const failed2 = childVerdicts.filter((v) => v === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v)).length;
17094
17111
  return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v) => PASSING.has(v)) });
17095
17112
  }
17096
- var ID_RE, PASSING, sha3 = (b) => createHash18("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join67(runDir, "group", "units"), readJson6 = (p) => {
17113
+ var ID_RE, PASSING, sha3 = (b) => createHash19("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join67(runDir, "group", "units"), readJson6 = (p) => {
17097
17114
  try {
17098
17115
  return JSON.parse(readFileSync54(p, "utf8"));
17099
17116
  } catch {
@@ -17357,7 +17374,7 @@ var init_supply_guard = __esm(() => {
17357
17374
  });
17358
17375
 
17359
17376
  // ../../loki-ts/src/engine10/stages/seal.ts
17360
- import { createHash as createHash19 } from "crypto";
17377
+ import { createHash as createHash20 } from "crypto";
17361
17378
  import { existsSync as existsSync47, readdirSync as readdirSync24, mkdirSync as mkdirSync31, readFileSync as readFileSync56 } from "fs";
17362
17379
  import { basename as basename26, isAbsolute as isAbsolute13, join as join69, relative as relative14 } from "path";
17363
17380
  function receiptSha256(r) {
@@ -17433,7 +17450,7 @@ function renderReceiptMd(r) {
17433
17450
  ].join(`
17434
17451
  `);
17435
17452
  }
17436
- var SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", WALL_GREEN_ON_BASE_REASON = "Wall green on base: no Wall test discriminates the change", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash19("sha256").update(s).digest("hex"), str4 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], g = (ctx) => (a) => git4(ctx, a), receiptRel = (ctx) => {
17453
+ var SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", AGENT_ONLY_REASON = "only agent-authored tests executed (no agent-independent proof)", WALL_GREEN_ON_BASE_REASON = "Wall green on base: no Wall test discriminates the change", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash20("sha256").update(s).digest("hex"), str4 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], g = (ctx) => (a) => git4(ctx, a), receiptRel = (ctx) => {
17437
17454
  const r = relative14(ctx.repoDir, join69(ctx.runDir, "receipt.json"));
17438
17455
  return r.startsWith("..") || isAbsolute13(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
17439
17456
  }, commitStage, wallGreenOnBaseOf = (o) => {
@@ -17445,6 +17462,7 @@ var init_seal = __esm(() => {
17445
17462
  init_spec_file();
17446
17463
  init_steer();
17447
17464
  init_run_outputs();
17465
+ init_unit_mode();
17448
17466
  init_pr_body();
17449
17467
  init_mutation_proof();
17450
17468
  init_wall();
@@ -17694,6 +17712,7 @@ var init_seal = __esm(() => {
17694
17712
  ...routeBlock ? { route: routeBlock } : {},
17695
17713
  ...supply.block ? { supply: supply.block } : {},
17696
17714
  ...specReceiptBlock(process.env),
17715
+ ...unitSpecReceiptBlock(process.env),
17697
17716
  ...intentRevisionsBlock(ctx.intentRevisions),
17698
17717
  ...seededCorpusBlock()
17699
17718
  };
@@ -17864,7 +17883,7 @@ var init_keys_cmd = __esm(() => {
17864
17883
  // ../../loki-ts/src/engine10/verify_cmd.ts
17865
17884
  import { existsSync as existsSync49, readFileSync as readFileSync58, renameSync as renameSync14, statSync as statSync24, writeFileSync as writeFileSync34 } from "fs";
17866
17885
  import { basename as basename28, dirname as dirname33, join as join71 } from "path";
17867
- import { createHash as createHash20, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
17886
+ import { createHash as createHash21, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
17868
17887
  function pubFor(kid, given) {
17869
17888
  if (given)
17870
17889
  return kidOf2(given) === kid ? given : undefined;
@@ -17910,7 +17929,7 @@ function checkEventLog(receiptPath, receipt) {
17910
17929
  }
17911
17930
  if (typeof bound !== "string")
17912
17931
  return null;
17913
- if (bound === createHash20("sha256").digest("hex")) {
17932
+ if (bound === createHash21("sha256").digest("hex")) {
17914
17933
  const st = receipt["time"]?.stages;
17915
17934
  const claims = st !== null && typeof st === "object" && Object.keys(st).length > 0;
17916
17935
  return claims ? "the receipt records stages but binds the empty-log hash, so no events.jsonl can back it (missing, empty or non-empty); the receipt is forged or was sealed without a log. Re-run the task to produce a fresh receipt" : null;
@@ -17924,7 +17943,7 @@ function checkEventLog(receiptPath, receipt) {
17924
17943
  return "events.jsonl has a forged, edited or missing line";
17925
17944
  if (events2.some((e) => e.type === "tamper.detected"))
17926
17945
  return "the supervisor detected events.jsonl being modified during the run";
17927
- const h = createHash20("sha256");
17946
+ const h = createHash21("sha256");
17928
17947
  for (const l of lines2) {
17929
17948
  if (h.copy().digest("hex") === bound)
17930
17949
  return null;
@@ -17943,7 +17962,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
17943
17962
  if (!d)
17944
17963
  return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
17945
17964
  const lines2 = readFileSync58(path, "utf8").split(`
17946
- `).filter((l) => l.trim() !== ""), sha4 = createHash20("sha256").update(lines2.slice(0, done + 1).join(`
17965
+ `).filter((l) => l.trim() !== ""), sha4 = createHash21("sha256").update(lines2.slice(0, done + 1).join(`
17947
17966
  `) + `
17948
17967
  `).digest("hex");
17949
17968
  const pub = d["kid"] === kid ? pubFor(kid, given) : undefined;
@@ -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.54.4",
5
+ "version": "11.55.1",
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-DanBjSJ8.js";import{B as C}from"./Button-CUUSKCZJ.js";import{T as $e}from"./trending-up-CsIqCh6c.js";import{C as z}from"./clock-Bu8DUp0v.js";import{A as Be,U as ue,M as De}from"./Avatar-DSk6ksIr.js";import{A as J}from"./activity-BE-AgOv1.js";import{R as pe}from"./refresh-cw-CugB71N2.js";import{G as ze}from"./globe-j79rR76R.js";import{C as Le}from"./chevron-left-D8ksaSPd.js";import{C as je}from"./check-BhkAUzf6.js";import{D as Y}from"./dollar-sign-Bq2Arvlt.js";import{U as Te}from"./user-D_AwTTHl.js";import{D as Me}from"./database-jOdnNbz-.js";import{L as Ue}from"./lock-1YFDik7V.js";import{S as Re}from"./scroll-text-CCTi2-TZ.js";import{S as Ie}from"./shield-alert-9fSMvTZE.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-CfxxQ2Rb.js";import{B as C}from"./Button-CSqHYv_2.js";import{T as $e}from"./trending-up-BLvUoFes.js";import{C as z}from"./clock-BIovJVE7.js";import{A as Be,U as ue,M as De}from"./Avatar-BEP3MBdR.js";import{A as J}from"./activity-DQJZXRVQ.js";import{R as pe}from"./refresh-cw-DjnL9E0A.js";import{G as ze}from"./globe-DsU2fmWc.js";import{C as Le}from"./chevron-left-BfNrm41n.js";import{C as je}from"./check-8RS3WM0W.js";import{D as Y}from"./dollar-sign-CeuNG_0y.js";import{U as Te}from"./user-g2NM3Uhg.js";import{D as Me}from"./database-7Y7ophDy.js";import{L as Ue}from"./lock-JLrpk0hT.js";import{S as Re}from"./scroll-text-MtLqgV7M.js";import{S as Ie}from"./shield-alert-waWUzfuX.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-DanBjSJ8.js";/**
1
+ import{c as l,j as s}from"./index-CfxxQ2Rb.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-DanBjSJ8.js";import{C as r}from"./clock-Bu8DUp0v.js";import{C as a}from"./circle-alert-Do3VEpwg.js";import{C as l}from"./check-BhkAUzf6.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-CfxxQ2Rb.js";import{C as r}from"./clock-BIovJVE7.js";import{C as a}from"./circle-alert-Rmo6xwSG.js";import{C as l}from"./check-8RS3WM0W.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-DanBjSJ8.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-CfxxQ2Rb.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-DanBjSJ8.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-CqSoPFhw.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-DSZfhFU7.js";import{C as oe}from"./check-BhkAUzf6.js";import{C as Ye}from"./clock-Bu8DUp0v.js";import{D as Xe}from"./dollar-sign-Bq2Arvlt.js";import{U as Ze}from"./upload-C6v2mC_1.js";import{L as V}from"./loader-circle-Bvvku0wP.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-CfxxQ2Rb.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DSTIh94K.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-C5rKskeM.js";import{C as oe}from"./check-8RS3WM0W.js";import{C as Ye}from"./clock-BIovJVE7.js";import{D as Xe}from"./dollar-sign-CeuNG_0y.js";import{U as Ze}from"./upload-DzL0hG7s.js";import{L as V}from"./loader-circle-C2ErTM1m.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-DanBjSJ8.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-CfxxQ2Rb.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-DanBjSJ8.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-CfxxQ2Rb.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-DanBjSJ8.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-CfxxQ2Rb.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-DanBjSJ8.js";import{B as N}from"./Button-CUUSKCZJ.js";import{C as y}from"./thumbs-up-DSZfhFU7.js";import{R as S}from"./refresh-cw-CugB71N2.js";import{C as z}from"./circle-alert-Do3VEpwg.js";import{U as D}from"./user-D_AwTTHl.js";import{L as G}from"./loader-circle-Bvvku0wP.js";import{R as T}from"./rotate-ccw-BwG818Ni.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-CfxxQ2Rb.js";import{B as N}from"./Button-CSqHYv_2.js";import{C as y}from"./thumbs-up-C5rKskeM.js";import{R as S}from"./refresh-cw-DjnL9E0A.js";import{C as z}from"./circle-alert-Rmo6xwSG.js";import{U as D}from"./user-g2NM3Uhg.js";import{L as G}from"./loader-circle-C2ErTM1m.js";import{R as T}from"./rotate-ccw-CCFbC5Rz.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-DanBjSJ8.js";import{B as y}from"./Button-CUUSKCZJ.js";import{C as ge}from"./chevron-left-D8ksaSPd.js";import{G as P}from"./thumbs-up-DSZfhFU7.js";import{R as $}from"./refresh-cw-CugB71N2.js";import{C as Ne}from"./circle-alert-Do3VEpwg.js";import{L as Q,S as je}from"./ProjectPage-tO0cI771.js";import{S as se}from"./shield-alert-9fSMvTZE.js";import{F as ye}from"./file-code-corner-Dx57oNjY.js";import{C as V}from"./clock-Bu8DUp0v.js";import{C as re}from"./check-BhkAUzf6.js";import"./ErrorBoundary-CqSoPFhw.js";import"./TerminalOutput-DncIMq8c.js";import"./lock-1YFDik7V.js";import"./package-BHnW3nO4.js";import"./file-plus-DT6ln-0k.js";import"./activity-BE-AgOv1.js";import"./scroll-text-CCTi2-TZ.js";import"./bot-BBC3O3VF.js";import"./loader-circle-Bvvku0wP.js";import"./hammer-QWDU7JhP.js";import"./dollar-sign-Bq2Arvlt.js";import"./globe-j79rR76R.js";import"./trash-2-C0GKJdOD.js";import"./upload-C6v2mC_1.js";import"./plus-CYsPyD5V.js";import"./rotate-ccw-BwG818Ni.js";import"./code-xml-D3IdN8cp.js";import"./trending-up-CsIqCh6c.js";import"./layers-FaIaHoxY.js";import"./trending-down-CE_quih9.js";import"./server-B5Kn_IXa.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-CfxxQ2Rb.js";import{B as y}from"./Button-CSqHYv_2.js";import{C as ge}from"./chevron-left-BfNrm41n.js";import{G as P}from"./thumbs-up-C5rKskeM.js";import{R as $}from"./refresh-cw-DjnL9E0A.js";import{C as Ne}from"./circle-alert-Rmo6xwSG.js";import{L as Q,S as je}from"./ProjectPage-_RJqqa7r.js";import{S as se}from"./shield-alert-waWUzfuX.js";import{F as ye}from"./file-code-corner-Cxpa7IqK.js";import{C as V}from"./clock-BIovJVE7.js";import{C as re}from"./check-8RS3WM0W.js";import"./ErrorBoundary-DSTIh94K.js";import"./TerminalOutput-zJu55vzo.js";import"./lock-JLrpk0hT.js";import"./package-CNuSANZE.js";import"./file-plus-CTPHdwOk.js";import"./activity-DQJZXRVQ.js";import"./scroll-text-MtLqgV7M.js";import"./bot-Cq4UXZAk.js";import"./loader-circle-C2ErTM1m.js";import"./hammer-CSB9UcY6.js";import"./dollar-sign-CeuNG_0y.js";import"./globe-DsU2fmWc.js";import"./trash-2-CUYMWFR7.js";import"./upload-DzL0hG7s.js";import"./plus-B0DxJd7a.js";import"./rotate-ccw-CCFbC5Rz.js";import"./code-xml-By_Axt1q.js";import"./trending-up-BLvUoFes.js";import"./layers-D0X4BPSq.js";import"./trending-down-C8lnBmnC.js";import"./server-BZkj8U3T.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.