loki-mode 11.17.47 → 11.17.48

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 (73) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/loki +32 -4
  4. package/autonomy/run.sh +16 -6
  5. package/completions/_loki +8 -0
  6. package/completions/loki.bash +1 -1
  7. package/dashboard/__init__.py +1 -1
  8. package/docs/CLI-REFERENCE.md +1 -1
  9. package/docs/INSTALLATION.md +1 -1
  10. package/docs/v10/BOARD.md +31 -31
  11. package/docs/v10/PROGRESS.md +3 -0
  12. package/loki-ts/dist/loki.js +1294 -1266
  13. package/mcp/__init__.py +1 -1
  14. package/package.json +2 -2
  15. package/packages/control-plane/dist/server.js +76 -36
  16. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  17. package/web-app/dist/assets/{AdminPage-CUwePM-U.js → AdminPage-BPJVaCEf.js} +1 -1
  18. package/web-app/dist/assets/{Avatar-CgaFfyso.js → Avatar-Bw7MMGi1.js} +1 -1
  19. package/web-app/dist/assets/{Badge-CobXGTUy.js → Badge-CEFAS_Xj.js} +1 -1
  20. package/web-app/dist/assets/{Button-DMRfh5W0.js → Button-CzQvJaSb.js} +1 -1
  21. package/web-app/dist/assets/{CockpitPage-BmV-CvaY.js → CockpitPage-uWZUV5vU.js} +1 -1
  22. package/web-app/dist/assets/{ComparePage-CGTEosOm.js → ComparePage-B8K52Bob.js} +1 -1
  23. package/web-app/dist/assets/{ErrorBoundary-CcJne7Ux.js → ErrorBoundary-mmBzw79w.js} +1 -1
  24. package/web-app/dist/assets/{EvidenceReceiptPanel-t7H7yPy1.js → EvidenceReceiptPanel-D-C_9v67.js} +1 -1
  25. package/web-app/dist/assets/{GitHubIssuesPanel-Ddg8AH1O.js → GitHubIssuesPanel-D01lFHnc.js} +1 -1
  26. package/web-app/dist/assets/{GitHubPRsPanel-Dpkz6xml.js → GitHubPRsPanel-Bje_NQB0.js} +1 -1
  27. package/web-app/dist/assets/{HomePage-DNNpULKb.js → HomePage-C8OEDRTr.js} +2 -2
  28. package/web-app/dist/assets/{LoginPage-DhYy51rG.js → LoginPage-Cool7Iw_.js} +1 -1
  29. package/web-app/dist/assets/{MagicPage-C6rjuz1S.js → MagicPage-DMvhVDyI.js} +1 -1
  30. package/web-app/dist/assets/{MetricsPage-Ca32CVTG.js → MetricsPage-CzYARc4t.js} +1 -1
  31. package/web-app/dist/assets/{NotFoundPage-BoxZzhCd.js → NotFoundPage-CLuI0jCU.js} +1 -1
  32. package/web-app/dist/assets/{ProjectPage-DxVUZNMc.js → ProjectPage-BxhIhhVe.js} +3 -3
  33. package/web-app/dist/assets/{ProjectsPage-CkIWNsOA.js → ProjectsPage-D_hclu0C.js} +1 -1
  34. package/web-app/dist/assets/{SettingsPage-D8A23FW8.js → SettingsPage-Dau5TMP3.js} +1 -1
  35. package/web-app/dist/assets/{ShowcasePage-Cqttc_ey.js → ShowcasePage-D560cP-Z.js} +1 -1
  36. package/web-app/dist/assets/{SystemSettingsPage-ClL-v9yl.js → SystemSettingsPage-ek9P-k4X.js} +1 -1
  37. package/web-app/dist/assets/{TeamsPage-ClAYMb0Y.js → TeamsPage-e1RGxUiS.js} +1 -1
  38. package/web-app/dist/assets/{TemplatesPage-CYZdjIhP.js → TemplatesPage-C5O7u6Yl.js} +1 -1
  39. package/web-app/dist/assets/{TerminalOutput-83CRSw0t.js → TerminalOutput-_UWCGfD0.js} +1 -1
  40. package/web-app/dist/assets/{activity-Bsvd74sO.js → activity-BcHzPz-Z.js} +1 -1
  41. package/web-app/dist/assets/{bell-BXY-QQ2u.js → bell-D5IPRWzy.js} +1 -1
  42. package/web-app/dist/assets/{bot--nwTc41X.js → bot-B_5hZVKx.js} +1 -1
  43. package/web-app/dist/assets/{check-CtpgmnRS.js → check-Dn2f9AXR.js} +1 -1
  44. package/web-app/dist/assets/{chevron-left-gRqAwE_C.js → chevron-left-DF2PtK7-.js} +1 -1
  45. package/web-app/dist/assets/{circle-alert-ch2xsEEk.js → circle-alert-B_4ZRu8m.js} +1 -1
  46. package/web-app/dist/assets/{clock-D-5jWbZZ.js → clock-7CFKor-w.js} +1 -1
  47. package/web-app/dist/assets/{cloud-DEoaJd5k.js → cloud-CGYN9-6_.js} +1 -1
  48. package/web-app/dist/assets/{code-xml-3bA_SNyD.js → code-xml-DqBxYuk4.js} +1 -1
  49. package/web-app/dist/assets/{database-D9xzmMKg.js → database-CiOULELf.js} +1 -1
  50. package/web-app/dist/assets/{dollar-sign-DiakXRz8.js → dollar-sign-DijBsvLO.js} +1 -1
  51. package/web-app/dist/assets/{file-code-corner-DfVAbxzi.js → file-code-corner-BNEtGVfX.js} +1 -1
  52. package/web-app/dist/assets/{file-plus-B_MYtTUf.js → file-plus-DtUmw4Kz.js} +1 -1
  53. package/web-app/dist/assets/{globe-Dy8IUkH2.js → globe-CmWPNrp3.js} +1 -1
  54. package/web-app/dist/assets/{hammer-s0wolu4P.js → hammer-CnrZECeT.js} +1 -1
  55. package/web-app/dist/assets/{index-BTuyie41.js → index-B9oYaFMU.js} +3 -3
  56. package/web-app/dist/assets/{layers-BSiiXNtI.js → layers-Lxxu1F99.js} +1 -1
  57. package/web-app/dist/assets/{loader-circle-B7E55O_p.js → loader-circle-Dp9seYEV.js} +1 -1
  58. package/web-app/dist/assets/{lock-CUNgslvM.js → lock-Ej10h0El.js} +1 -1
  59. package/web-app/dist/assets/{package-CEwAH9Cq.js → package-nzNsxPvu.js} +1 -1
  60. package/web-app/dist/assets/{plus-Cl4dYXk4.js → plus-Bohfac84.js} +1 -1
  61. package/web-app/dist/assets/{refresh-cw-DyF0eHsk.js → refresh-cw-D28TMjNP.js} +1 -1
  62. package/web-app/dist/assets/{rotate-ccw-Dvm8sAXO.js → rotate-ccw-EydLVFHV.js} +1 -1
  63. package/web-app/dist/assets/{scroll-text-3myN2XZ3.js → scroll-text-CqJ7dpQH.js} +1 -1
  64. package/web-app/dist/assets/{server-BlGLvr0P.js → server-UHZ1Mk-a.js} +1 -1
  65. package/web-app/dist/assets/{shield-alert-C-9nW2ch.js → shield-alert-a-XlrS3P.js} +1 -1
  66. package/web-app/dist/assets/{thumbs-up-F1HQBWou.js → thumbs-up-QHDAqKhY.js} +1 -1
  67. package/web-app/dist/assets/{trash-2-ON8ACmt9.js → trash-2-CJ8uIX7e.js} +1 -1
  68. package/web-app/dist/assets/{trending-down-h1X1KCc-.js → trending-down-CQ1Ofr8H.js} +1 -1
  69. package/web-app/dist/assets/{trending-up-DlrPtYg6.js → trending-up-jG23a3L-.js} +1 -1
  70. package/web-app/dist/assets/{upload-RRiIUPVC.js → upload-CsZ15cCI.js} +1 -1
  71. package/web-app/dist/assets/{usePolling-OFW8TEeh.js → usePolling-C2ztQasf.js} +1 -1
  72. package/web-app/dist/assets/{user-B15Az6V5.js → user-B1RCExaJ.js} +1 -1
  73. 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.47'
78
+ __version__ = '11.17.48'
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.47",
4
+ "version": "11.17.48",
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": "cbded275937b96d1fb4970c473b8bb5b526474e4"
163
+ "gitHead": "f2771105528cd6b39f1a38dd9e93add76a9ba957"
164
164
  }
@@ -8213,7 +8213,7 @@ function pushArgv(a) {
8213
8213
  function taskBlock(task) {
8214
8214
  return ["Task (untrusted, quoted verbatim):", "<<<TASK", task, "TASK"];
8215
8215
  }
8216
- var STAGE_BUDGETS;
8216
+ var STAGE_BUDGETS, warnedCap;
8217
8217
  var init_types = __esm(() => {
8218
8218
  STAGE_BUDGETS = {
8219
8219
  intake: { targetS: 15, limitS: 60 },
@@ -8227,6 +8227,7 @@ var init_types = __esm(() => {
8227
8227
  pr: { targetS: 15, limitS: 60 },
8228
8228
  deep: { targetS: null, limitS: 2700 }
8229
8229
  };
8230
+ warnedCap = new Set;
8230
8231
  });
8231
8232
 
8232
8233
  // ../../loki-ts/src/runner/router/decision.ts
@@ -8882,7 +8883,7 @@ var init_test_file_text = __esm(() => {
8882
8883
  });
8883
8884
 
8884
8885
  // ../../loki-ts/src/engine10/testmap.ts
8885
- import { existsSync as existsSync22, readdirSync as readdirSync12, readFileSync as readFileSync27, realpathSync as realpathSync15 } from "fs";
8886
+ import { existsSync as existsSync22, lstatSync as lstatSync8, readdirSync as readdirSync12, readFileSync as readFileSync27, realpathSync as realpathSync15 } from "fs";
8886
8887
  import { basename as basename10, extname, isAbsolute as isAbsolute2, join as join36, relative, sep as sep10 } from "path";
8887
8888
  function projectInterpreter(root) {
8888
8889
  const ve = process.env["VIRTUAL_ENV"], inRepo = (p) => {
@@ -8897,6 +8898,7 @@ function projectInterpreter(root) {
8897
8898
  }
8898
8899
  var SKIP_DIRS;
8899
8900
  var init_testmap = __esm(() => {
8901
+ init_safe_git();
8900
8902
  init_resolve();
8901
8903
  init_scope();
8902
8904
  init_test_file_text();
@@ -9486,6 +9488,8 @@ function canonicalJson(x) {
9486
9488
  return walk(x).replace(/[\u0080-\uFFFF]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
9487
9489
  }
9488
9490
  function loadSigningKey(generate = true) {
9491
+ lastProblem = null;
9492
+ let stage = "read";
9489
9493
  try {
9490
9494
  const inline = process.env["LOKI_RECEIPT_SIGNING_KEY"]?.trim();
9491
9495
  let pem = inline ?? "";
@@ -9500,6 +9504,8 @@ function loadSigningKey(generate = true) {
9500
9504
  chmodSync4(f, m);
9501
9505
  }
9502
9506
  } catch (e) {
9507
+ if (e.code !== "ENOENT")
9508
+ lastProblem = `signing key file unreadable (${e.code ?? "error"})`;
9503
9509
  if (e.code !== "ENOENT" || !generate)
9504
9510
  return null;
9505
9511
  mkdirSync13(dirname12(dirname12(file)), { recursive: true, mode: 448 });
@@ -9517,16 +9523,25 @@ function loadSigningKey(generate = true) {
9517
9523
  pem = readFileSync29(file);
9518
9524
  }
9519
9525
  }
9526
+ stage = "parse";
9520
9527
  const k = createPrivateKey(pem);
9521
- return k.asymmetricKeyType === "ed25519" ? k : null;
9528
+ if (k.asymmetricKeyType === "ed25519")
9529
+ return k;
9530
+ lastProblem = `signing key is not ed25519 (found ${k.asymmetricKeyType ?? "unknown"})`;
9531
+ return null;
9522
9532
  } catch {
9533
+ lastProblem ??= stage === "parse" ? "signing key is not a valid PEM private key" : "signing key could not be read or created";
9523
9534
  return null;
9524
9535
  }
9525
9536
  }
9526
9537
  function signReceipt(runId, hash) {
9527
9538
  const key = loadSigningKey();
9528
- if (!key)
9539
+ if (!key) {
9540
+ if (lastProblem)
9541
+ process.stderr.write(`loki: receipt left UNSIGNED: ${lastProblem}
9542
+ `);
9529
9543
  return { jwt: null, kid: null };
9544
+ }
9530
9545
  const kid = kidOf2(createPublicKey2(key));
9531
9546
  const input = `${b64u(canonicalJson({ alg: "EdDSA", typ: "JWT", kid }))}.${b64u(canonicalJson({ job_id: runId, run_id: runId, receipt_sha256: hash, iat: Math.floor(Date.now() / 1000) }))}`;
9532
9547
  return { jwt: `${input}.${b64u(sign(null, Buffer.from(input), key))}`, kid };
@@ -9539,7 +9554,31 @@ function toolVersion(bin) {
9539
9554
  return null;
9540
9555
  }
9541
9556
  }
9542
- var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem", b64u = (b) => Buffer.from(b).toString("base64url"), kidOf2 = (pub) => b64u(createHash8("sha256").update(`{"crv":"Ed25519","kty":"OKP","x":"${pub.export({ format: "jwk" }).x}"}`).digest()), TOOLCHAIN_KEYS, collectToolchain = (probe = toolVersion) => ({ bun: process.versions["bun"] ?? probe("bun"), node: probe("node"), python3: probe("python3"), git: probe("git") });
9557
+ function probeAll() {
9558
+ const out2 = { node: null, python3: null, git: null };
9559
+ probeRuns++;
9560
+ const job = (b) => `(v=$(${b} --version 2>/dev/null) && printf '${b}=%s\\n' "$(printf %s "$v" | head -n 1)") &`;
9561
+ try {
9562
+ const r = spawnSync2("/bin/sh", ["-c", `${job("node")} ${job("python3")} ${job("git")} wait`], { env: plainTestEnv(), encoding: "utf8", timeout: 5000, killSignal: "SIGKILL", stdio: ["ignore", "pipe", "ignore"] });
9563
+ for (const line2 of String(r.stdout ?? "").split(`
9564
+ `)) {
9565
+ const i = line2.indexOf("=");
9566
+ if (i > 0 && line2.slice(0, i) in out2)
9567
+ out2[line2.slice(0, i)] = /\d+(\.\d+)+\S*/.exec(line2.slice(i + 1))?.[0] ?? null;
9568
+ }
9569
+ } catch {}
9570
+ return out2;
9571
+ }
9572
+ function collectToolchain(probe) {
9573
+ if (probe)
9574
+ return { bun: process.versions["bun"] ?? probe("bun"), node: probe("node"), python3: probe("python3"), git: probe("git") };
9575
+ if (!memo) {
9576
+ const p = probeAll();
9577
+ memo = { bun: process.versions["bun"] ?? toolVersion("bun"), node: p["node"], python3: p["python3"], git: p["git"] };
9578
+ }
9579
+ return { ...memo };
9580
+ }
9581
+ var RECEIPT_SIGNER_BASENAME = "receipt-ed25519.pem", b64u = (b) => Buffer.from(b).toString("base64url"), kidOf2 = (pub) => b64u(createHash8("sha256").update(`{"crv":"Ed25519","kty":"OKP","x":"${pub.export({ format: "jwk" }).x}"}`).digest()), lastProblem = null, TOOLCHAIN_KEYS, probeRuns = 0, memo = null;
9543
9582
  var init_receipt_signer = __esm(() => {
9544
9583
  init_check_result();
9545
9584
  TOOLCHAIN_KEYS = ["bun", "node", "python3", "git"];
@@ -9567,9 +9606,9 @@ var init_base_guard = __esm(() => {
9567
9606
  });
9568
9607
 
9569
9608
  // ../../loki-ts/src/features/speed/unit_mode.ts
9570
- import { closeSync as closeSync7, constants, fstatSync as fstatSync5, lstatSync as lstatSync8, openSync as openSync7, readSync as readSync6, realpathSync as realpathSync17 } from "fs";
9609
+ import { closeSync as closeSync7, constants, fstatSync as fstatSync5, lstatSync as lstatSync9, openSync as openSync7, readSync as readSync6, realpathSync as realpathSync17 } from "fs";
9571
9610
  function readBounded(path) {
9572
- const l = lstatSync8(path);
9611
+ const l = lstatSync9(path);
9573
9612
  if (l.isSymbolicLink() || !l.isFile() || l.size > MAX_SPEC_BYTES)
9574
9613
  return null;
9575
9614
  const fd = openSync7(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
@@ -9619,19 +9658,19 @@ function unitSpec(env = process.env) {
9619
9658
  return null;
9620
9659
  if (frozen !== undefined)
9621
9660
  return frozen.length <= MAX_SPEC_BYTES ? parseText(frozen) : null;
9622
- if (!memo.has(path))
9623
- memo.set(path, parseSpec(path));
9624
- return memo.get(path) ?? null;
9661
+ if (!memo2.has(path))
9662
+ memo2.set(path, parseSpec(path));
9663
+ return memo2.get(path) ?? null;
9625
9664
  }
9626
9665
  function unitFlags(staged, env = process.env, pre = {}) {
9627
9666
  const s = unitSpec(env);
9628
9667
  return s ? staged.filter(({ f }) => !inWriteSet(s, f) && !Object.hasOwn(pre, f)).map(({ f }) => f) : null;
9629
9668
  }
9630
- 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, memo, inWriteSet = (spec, f) => spec.writeSet.some((w) => w.endsWith("/") ? f.startsWith(w) : f === w);
9669
+ 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);
9631
9670
  var init_unit_mode = __esm(() => {
9632
9671
  MAX_SPEC_BYTES = 1024 * 1024;
9633
9672
  CTRL = /[\x00-\x1f\x7f]/;
9634
- memo = new Map;
9673
+ memo2 = new Map;
9635
9674
  });
9636
9675
 
9637
9676
  // ../../loki-ts/src/util/ts_signatures.ts
@@ -10416,7 +10455,7 @@ var init_state = __esm(() => {
10416
10455
 
10417
10456
  // ../../loki-ts/src/runner/repo_profile.ts
10418
10457
  import { spawnSync as spawnSync3 } from "child_process";
10419
- import { existsSync as existsSync24, lstatSync as lstatSync9, readFileSync as readFileSync30, mkdirSync as mkdirSync14, readdirSync as readdirSync14, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
10458
+ import { existsSync as existsSync24, lstatSync as lstatSync10, readFileSync as readFileSync30, mkdirSync as mkdirSync14, readdirSync as readdirSync14, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
10420
10459
  import { basename as basename12, join as join39, resolve as resolve13, isAbsolute as isAbsolute4 } from "path";
10421
10460
  function detectFormatters(repoDir) {
10422
10461
  const out2 = [];
@@ -10443,7 +10482,7 @@ function runFormatters(repoDir, files, env) {
10443
10482
  const fmts = detectFormatters(repoDir);
10444
10483
  const mine = fmts.length ? files.filter((f) => {
10445
10484
  try {
10446
- return lstatSync9(join39(repoDir, f)).isFile();
10485
+ return lstatSync10(join39(repoDir, f)).isFile();
10447
10486
  } catch {
10448
10487
  return false;
10449
10488
  }
@@ -10595,7 +10634,7 @@ var init_context = __esm(() => {
10595
10634
  });
10596
10635
 
10597
10636
  // ../../loki-ts/src/util/steer.ts
10598
- import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync15, lstatSync as lstatSync10, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync31, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync25 } from "fs";
10637
+ import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync15, lstatSync as lstatSync11, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync31, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync25 } from "fs";
10599
10638
  import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
10600
10639
  import { basename as basename13, join as join40 } from "path";
10601
10640
  function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
@@ -10622,7 +10661,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
10622
10661
  }
10623
10662
  }
10624
10663
  function orphanAlreadyArchived(logs, claim) {
10625
- const c = lstatSync10(claim);
10664
+ const c = lstatSync11(claim);
10626
10665
  if (!c.isFile())
10627
10666
  return false;
10628
10667
  for (const a of readdirSync15(logs)) {
@@ -10724,7 +10763,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10724
10763
  hooks2?.beforeRestore?.();
10725
10764
  let restored = false;
10726
10765
  try {
10727
- if (lstatSync10(claimed).isDirectory())
10766
+ if (lstatSync11(claimed).isDirectory())
10728
10767
  renameSync10(claimed, f);
10729
10768
  else
10730
10769
  (hooks2?.link ?? linkSync2)(claimed, f);
@@ -10733,7 +10772,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10733
10772
  if (!restored)
10734
10773
  return reject("NOTFILE", "not a regular file");
10735
10774
  try {
10736
- if (!lstatSync10(claimed, { throwIfNoEntry: false })?.isDirectory())
10775
+ if (!lstatSync11(claimed, { throwIfNoEntry: false })?.isDirectory())
10737
10776
  unlinkSync5(claimed);
10738
10777
  } catch {}
10739
10778
  claimed = "";
@@ -10743,7 +10782,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10743
10782
  try {
10744
10783
  fd = openSync8(claimed, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
10745
10784
  } catch (e) {
10746
- const l = lstatSync10(claimed, { throwIfNoEntry: false });
10785
+ const l = lstatSync11(claimed, { throwIfNoEntry: false });
10747
10786
  if (!l)
10748
10787
  throw e;
10749
10788
  if (l.isSymbolicLink() || e.code === "ELOOP") {
@@ -10798,7 +10837,7 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10798
10837
  }
10799
10838
  } else
10800
10839
  try {
10801
- if (lstatSync10(f, { throwIfNoEntry: false }))
10840
+ if (lstatSync11(f, { throwIfNoEntry: false }))
10802
10841
  unapplied("logs dir unwritable or file unreadable");
10803
10842
  } catch {}
10804
10843
  return null;
@@ -13124,7 +13163,7 @@ var init_route_block = __esm(() => {
13124
13163
  // ../../loki-ts/src/features/visual_evidence.ts
13125
13164
  import { spawn as spawn7 } from "child_process";
13126
13165
  import { createHash as createHash14, randomBytes as randomBytes5 } from "crypto";
13127
- import { existsSync as existsSync32, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readdirSync as readdirSync17, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
13166
+ import { existsSync as existsSync32, lstatSync as lstatSync12, mkdirSync as mkdirSync21, readdirSync as readdirSync17, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
13128
13167
  import { createServer } from "net";
13129
13168
  import { dirname as dirname17, isAbsolute as isAbsolute8, join as join51, normalize as normalize3, relative as relative6, sep as sep12 } from "path";
13130
13169
  function routeFor(file) {
@@ -13436,13 +13475,13 @@ test("loki e2e walkthrough", async ({ page }) => {
13436
13475
  });
13437
13476
  `, DEFAULT_BUDGET_MS = 25000, MAX_ROUTES = 5, isSymlink = (p) => {
13438
13477
  try {
13439
- return lstatSync11(p).isSymbolicLink();
13478
+ return lstatSync12(p).isSymbolicLink();
13440
13479
  } catch {
13441
13480
  return false;
13442
13481
  }
13443
13482
  }, isRegularFile = (p) => {
13444
13483
  try {
13445
- return lstatSync11(p).isFile();
13484
+ return lstatSync12(p).isFile();
13446
13485
  } catch {
13447
13486
  return false;
13448
13487
  }
@@ -13709,12 +13748,12 @@ var init_providers = __esm(() => {
13709
13748
  });
13710
13749
 
13711
13750
  // ../../loki-ts/src/runner/router/route_record.ts
13712
- import { existsSync as existsSync35, lstatSync as lstatSync12, mkdirSync as mkdirSync23, readFileSync as readFileSync44, writeFileSync as writeFileSync26 } from "fs";
13751
+ import { existsSync as existsSync35, lstatSync as lstatSync13, mkdirSync as mkdirSync23, readFileSync as readFileSync44, writeFileSync as writeFileSync26 } from "fs";
13713
13752
  import { join as join54 } from "path";
13714
13753
  function loadRouteRecord(runDir) {
13715
13754
  try {
13716
13755
  const p = join54(runDir, ROUTE_RECORD_FILE);
13717
- if (!existsSync35(p) || !lstatSync12(p).isFile())
13756
+ if (!existsSync35(p) || !lstatSync13(p).isFile())
13718
13757
  return;
13719
13758
  const v = JSON.parse(readFileSync44(p, "utf8"));
13720
13759
  return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
@@ -13899,7 +13938,7 @@ __export(exports_deep, {
13899
13938
  DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH,
13900
13939
  DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
13901
13940
  });
13902
- import { copyFileSync as copyFileSync3, existsSync as existsSync36, lstatSync as lstatSync13, mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync9, rmSync as rmSync17, writeFileSync as writeFileSync27 } from "fs";
13941
+ import { copyFileSync as copyFileSync3, existsSync as existsSync36, lstatSync as lstatSync14, mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync9, rmSync as rmSync17, writeFileSync as writeFileSync27 } from "fs";
13903
13942
  import { tmpdir as tmpdir10 } from "os";
13904
13943
  import { dirname as dirname20, join as join56 } from "path";
13905
13944
  function sessionCouncil(sessions) {
@@ -14021,7 +14060,7 @@ async function secureScanChanged(repoDir, changed, opts) {
14021
14060
  const dir = mkdtempSync9(join56(tmpdir10(), "loki-deep-secure-"));
14022
14061
  try {
14023
14062
  for (const f of changed)
14024
- if (existsSync36(join56(repoDir, f)) && lstatSync13(join56(repoDir, f)).isFile()) {
14063
+ if (existsSync36(join56(repoDir, f)) && lstatSync14(join56(repoDir, f)).isFile()) {
14025
14064
  mkdirSync24(dirname20(join56(dir, f)), { recursive: true });
14026
14065
  copyFileSync3(join56(repoDir, f), join56(dir, f));
14027
14066
  }
@@ -14881,7 +14920,7 @@ var init_wall = __esm(() => {
14881
14920
  });
14882
14921
 
14883
14922
  // ../../loki-ts/src/e10ext/discard.ts
14884
- import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync14, mkdirSync as mkdirSync26, openSync as openSync9, readFileSync as readFileSync47, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync29 } from "fs";
14923
+ import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync15, mkdirSync as mkdirSync26, openSync as openSync9, readFileSync as readFileSync47, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync29 } from "fs";
14885
14924
  import { dirname as dirname24, join as join60, relative as relative9, sep as sep13 } from "path";
14886
14925
  function safeRestore(repoDir, f, want, mode) {
14887
14926
  const root = realpathSync23(repoDir), fp = join60(root, f), rel = relative9(root, dirname24(fp));
@@ -14892,7 +14931,7 @@ function safeRestore(repoDir, f, want, mode) {
14892
14931
  cur = join60(cur, part);
14893
14932
  let st2;
14894
14933
  try {
14895
- st2 = lstatSync14(cur);
14934
+ st2 = lstatSync15(cur);
14896
14935
  } catch {
14897
14936
  mkdirSync26(cur);
14898
14937
  continue;
@@ -14902,7 +14941,7 @@ function safeRestore(repoDir, f, want, mode) {
14902
14941
  }
14903
14942
  let st;
14904
14943
  try {
14905
- st = lstatSync14(fp);
14944
+ st = lstatSync15(fp);
14906
14945
  } catch {
14907
14946
  st = null;
14908
14947
  }
@@ -14947,7 +14986,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
14947
14986
  const fp = join60(repoDir, f);
14948
14987
  try {
14949
14988
  if (v.startsWith("!")) {
14950
- const st = lstatSync14(fp);
14989
+ const st = lstatSync15(fp);
14951
14990
  if (`!${st.size}:${st.mtimeMs}:${st.ctimeMs}` !== v)
14952
14991
  throw new Error("changed, not snapshotted");
14953
14992
  continue;
@@ -14963,7 +15002,7 @@ async function discardIfSatisfied(git4, base, o, staged, keep, repoDir) {
14963
15002
  try {
14964
15003
  let m = 420;
14965
15004
  try {
14966
- const l = lstatSync14(join60(repoDir, f));
15005
+ const l = lstatSync15(join60(repoDir, f));
14967
15006
  if (l.isFile())
14968
15007
  m = l.mode & 511;
14969
15008
  } catch {}
@@ -15350,7 +15389,7 @@ function recordRun(env, repoDir, model, verdict, usd, unmetered, wallS, cacheRoo
15350
15389
  const row = outcomeFor(shape, model, verdict, usd, wallS);
15351
15390
  return row !== null && appendRunOutcome(repoKey(readOriginUrl(repoDir), repoDir), row, cacheRoot);
15352
15391
  }
15353
- var MIN_RUNS = 3, NOT_RECORDED = "NOT RECORDED", previewOn = (env) => env["LOKI_COST_PREVIEW"] !== "0", ESTIMATE_HELP;
15392
+ var MIN_RUNS = 3, NOT_RECORDED = "NOT RECORDED", previewOn = (env) => env["LOKI_COST_PREVIEW"] !== "0", ESTIMATE_HELP, VALID_PROVIDERS;
15354
15393
  var init_cost_preview = __esm(() => {
15355
15394
  init_cache();
15356
15395
  init_session();
@@ -15380,10 +15419,11 @@ Examples:
15380
15419
 
15381
15420
  See also: loki cost --detail (what a run ALREADY spent)
15382
15421
  `;
15422
+ VALID_PROVIDERS = new Set(["claude", "codex", "cline", "aider", "opencode"]);
15383
15423
  });
15384
15424
 
15385
15425
  // ../../loki-ts/src/features/contract.ts
15386
- import { existsSync as existsSync43, lstatSync as lstatSync15, mkdirSync as mkdirSync29, readFileSync as readFileSync51, rmSync as rmSync20, writeFileSync as writeFileSync31 } from "fs";
15426
+ import { existsSync as existsSync43, lstatSync as lstatSync16, mkdirSync as mkdirSync29, readFileSync as readFileSync51, rmSync as rmSync20, writeFileSync as writeFileSync31 } from "fs";
15387
15427
  import { dirname as dirname27, join as join65 } from "path";
15388
15428
  import { createHash as createHash16 } from "crypto";
15389
15429
  function contractEnabled(env = process.env) {
@@ -15422,7 +15462,7 @@ function readContract(repoDir) {
15422
15462
  const p = contractPath(repoDir);
15423
15463
  let st;
15424
15464
  try {
15425
- st = lstatSync15(p);
15465
+ st = lstatSync16(p);
15426
15466
  } catch {
15427
15467
  return { contract: null, notes: [], sha256: null };
15428
15468
  }
@@ -15467,7 +15507,7 @@ function sealContract(repoDir, body, rawDiff, checks, env = process.env, snap) {
15467
15507
  const live2 = readContract(repoDir);
15468
15508
  let exists2 = true;
15469
15509
  try {
15470
- lstatSync15(contractPath(repoDir));
15510
+ lstatSync16(contractPath(repoDir));
15471
15511
  } catch {
15472
15512
  exists2 = false;
15473
15513
  }
@@ -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.47",
5
+ "version": "11.17.48",
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-BTuyie41.js";import{B as C}from"./Button-DMRfh5W0.js";import{T as $e}from"./trending-up-DlrPtYg6.js";import{C as z}from"./clock-D-5jWbZZ.js";import{A as Be,U as ue,M as De}from"./Avatar-CgaFfyso.js";import{A as J}from"./activity-Bsvd74sO.js";import{R as pe}from"./refresh-cw-DyF0eHsk.js";import{G as ze}from"./globe-Dy8IUkH2.js";import{C as Le}from"./chevron-left-gRqAwE_C.js";import{C as je}from"./check-CtpgmnRS.js";import{D as Y}from"./dollar-sign-DiakXRz8.js";import{U as Te}from"./user-B15Az6V5.js";import{D as Me}from"./database-D9xzmMKg.js";import{L as Ue}from"./lock-CUNgslvM.js";import{S as Re}from"./scroll-text-3myN2XZ3.js";import{S as Ie}from"./shield-alert-C-9nW2ch.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-B9oYaFMU.js";import{B as C}from"./Button-CzQvJaSb.js";import{T as $e}from"./trending-up-jG23a3L-.js";import{C as z}from"./clock-7CFKor-w.js";import{A as Be,U as ue,M as De}from"./Avatar-Bw7MMGi1.js";import{A as J}from"./activity-BcHzPz-Z.js";import{R as pe}from"./refresh-cw-D28TMjNP.js";import{G as ze}from"./globe-CmWPNrp3.js";import{C as Le}from"./chevron-left-DF2PtK7-.js";import{C as je}from"./check-Dn2f9AXR.js";import{D as Y}from"./dollar-sign-DijBsvLO.js";import{U as Te}from"./user-B1RCExaJ.js";import{D as Me}from"./database-CiOULELf.js";import{L as Ue}from"./lock-Ej10h0El.js";import{S as Re}from"./scroll-text-CqJ7dpQH.js";import{S as Ie}from"./shield-alert-a-XlrS3P.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-BTuyie41.js";/**
1
+ import{c as l,j as s}from"./index-B9oYaFMU.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-BTuyie41.js";import{C as r}from"./clock-D-5jWbZZ.js";import{C as a}from"./circle-alert-ch2xsEEk.js";import{C as l}from"./check-CtpgmnRS.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-B9oYaFMU.js";import{C as r}from"./clock-7CFKor-w.js";import{C as a}from"./circle-alert-B_4ZRu8m.js";import{C as l}from"./check-Dn2f9AXR.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-BTuyie41.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-B9oYaFMU.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-BTuyie41.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-CcJne7Ux.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-F1HQBWou.js";import{C as oe}from"./check-CtpgmnRS.js";import{C as Ye}from"./clock-D-5jWbZZ.js";import{D as Xe}from"./dollar-sign-DiakXRz8.js";import{U as Ze}from"./upload-RRiIUPVC.js";import{L as V}from"./loader-circle-B7E55O_p.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-B9oYaFMU.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-mmBzw79w.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-QHDAqKhY.js";import{C as oe}from"./check-Dn2f9AXR.js";import{C as Ye}from"./clock-7CFKor-w.js";import{D as Xe}from"./dollar-sign-DijBsvLO.js";import{U as Ze}from"./upload-CsZ15cCI.js";import{L as V}from"./loader-circle-Dp9seYEV.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-BTuyie41.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-B9oYaFMU.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-BTuyie41.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-B9oYaFMU.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-BTuyie41.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-B9oYaFMU.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-BTuyie41.js";import{B as N}from"./Button-DMRfh5W0.js";import{C as y}from"./thumbs-up-F1HQBWou.js";import{R as S}from"./refresh-cw-DyF0eHsk.js";import{C as z}from"./circle-alert-ch2xsEEk.js";import{U as D}from"./user-B15Az6V5.js";import{L as G}from"./loader-circle-B7E55O_p.js";import{R as T}from"./rotate-ccw-Dvm8sAXO.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-B9oYaFMU.js";import{B as N}from"./Button-CzQvJaSb.js";import{C as y}from"./thumbs-up-QHDAqKhY.js";import{R as S}from"./refresh-cw-D28TMjNP.js";import{C as z}from"./circle-alert-B_4ZRu8m.js";import{U as D}from"./user-B1RCExaJ.js";import{L as G}from"./loader-circle-Dp9seYEV.js";import{R as T}from"./rotate-ccw-EydLVFHV.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-BTuyie41.js";import{B as y}from"./Button-DMRfh5W0.js";import{C as ge}from"./chevron-left-gRqAwE_C.js";import{G as P}from"./thumbs-up-F1HQBWou.js";import{R as $}from"./refresh-cw-DyF0eHsk.js";import{C as Ne}from"./circle-alert-ch2xsEEk.js";import{L as Q,S as je}from"./ProjectPage-DxVUZNMc.js";import{S as se}from"./shield-alert-C-9nW2ch.js";import{F as ye}from"./file-code-corner-DfVAbxzi.js";import{C as V}from"./clock-D-5jWbZZ.js";import{C as re}from"./check-CtpgmnRS.js";import"./ErrorBoundary-CcJne7Ux.js";import"./TerminalOutput-83CRSw0t.js";import"./lock-CUNgslvM.js";import"./package-CEwAH9Cq.js";import"./file-plus-B_MYtTUf.js";import"./activity-Bsvd74sO.js";import"./scroll-text-3myN2XZ3.js";import"./bot--nwTc41X.js";import"./loader-circle-B7E55O_p.js";import"./hammer-s0wolu4P.js";import"./dollar-sign-DiakXRz8.js";import"./globe-Dy8IUkH2.js";import"./trash-2-ON8ACmt9.js";import"./upload-RRiIUPVC.js";import"./plus-Cl4dYXk4.js";import"./rotate-ccw-Dvm8sAXO.js";import"./code-xml-3bA_SNyD.js";import"./trending-up-DlrPtYg6.js";import"./layers-BSiiXNtI.js";import"./trending-down-h1X1KCc-.js";import"./server-BlGLvr0P.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-B9oYaFMU.js";import{B as y}from"./Button-CzQvJaSb.js";import{C as ge}from"./chevron-left-DF2PtK7-.js";import{G as P}from"./thumbs-up-QHDAqKhY.js";import{R as $}from"./refresh-cw-D28TMjNP.js";import{C as Ne}from"./circle-alert-B_4ZRu8m.js";import{L as Q,S as je}from"./ProjectPage-BxhIhhVe.js";import{S as se}from"./shield-alert-a-XlrS3P.js";import{F as ye}from"./file-code-corner-BNEtGVfX.js";import{C as V}from"./clock-7CFKor-w.js";import{C as re}from"./check-Dn2f9AXR.js";import"./ErrorBoundary-mmBzw79w.js";import"./TerminalOutput-_UWCGfD0.js";import"./lock-Ej10h0El.js";import"./package-nzNsxPvu.js";import"./file-plus-DtUmw4Kz.js";import"./activity-BcHzPz-Z.js";import"./scroll-text-CqJ7dpQH.js";import"./bot-B_5hZVKx.js";import"./loader-circle-Dp9seYEV.js";import"./hammer-CnrZECeT.js";import"./dollar-sign-DijBsvLO.js";import"./globe-CmWPNrp3.js";import"./trash-2-CJ8uIX7e.js";import"./upload-CsZ15cCI.js";import"./plus-Bohfac84.js";import"./rotate-ccw-EydLVFHV.js";import"./code-xml-DqBxYuk4.js";import"./trending-up-jG23a3L-.js";import"./layers-Lxxu1F99.js";import"./trending-down-CQ1Ofr8H.js";import"./server-UHZ1Mk-a.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.