loki-mode 9.49.2 → 9.49.3

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 (75) hide show
  1. package/.github/workflows/loki-issue-to-pr.yml +1 -1
  2. package/SKILL.md +2 -2
  3. package/VERSION +1 -1
  4. package/autonomy/lib/claude-flags.sh +18 -2
  5. package/autonomy/notification-checker.py +45 -17
  6. package/autonomy/run.sh +43 -4
  7. package/dashboard/__init__.py +1 -1
  8. package/docs/INSTALLATION.md +1 -1
  9. package/docs/cost-controls.md +1 -1
  10. package/docs/environment-variables.md +1 -1
  11. package/loki-ts/dist/loki.js +3 -3
  12. package/mcp/__init__.py +1 -1
  13. package/package.json +1 -1
  14. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  15. package/web-app/dist/assets/{AdminPage-DpV2vW3y.js → AdminPage-BA6etdwL.js} +1 -1
  16. package/web-app/dist/assets/{Avatar-BXeMYK1_.js → Avatar-CAtbcD23.js} +1 -1
  17. package/web-app/dist/assets/{Badge-D8WddQk1.js → Badge-sb_JbKl0.js} +1 -1
  18. package/web-app/dist/assets/{Button-CFzTTVeJ.js → Button-BamXbIWa.js} +1 -1
  19. package/web-app/dist/assets/{CockpitPage-D1eQe9QF.js → CockpitPage-CUYizBtG.js} +1 -1
  20. package/web-app/dist/assets/{ComparePage-uX3OPphr.js → ComparePage-BnmNTggM.js} +1 -1
  21. package/web-app/dist/assets/{ErrorBoundary-wE3oxaG6.js → ErrorBoundary-BjX4_KOW.js} +1 -1
  22. package/web-app/dist/assets/{EvidenceReceiptPanel-B_Wouz6N.js → EvidenceReceiptPanel-Bq6pmNUw.js} +1 -1
  23. package/web-app/dist/assets/{GitHubIssuesPanel-DRlEeFuw.js → GitHubIssuesPanel-DD8c6RVj.js} +1 -1
  24. package/web-app/dist/assets/{GitHubPRsPanel-CCv6_I74.js → GitHubPRsPanel-4NawTXRl.js} +1 -1
  25. package/web-app/dist/assets/{HomePage-EG-jq8nR.js → HomePage-DTREi8OE.js} +1 -1
  26. package/web-app/dist/assets/{LoginPage-CEOnBICH.js → LoginPage-DavfeQxC.js} +1 -1
  27. package/web-app/dist/assets/{MagicPage-DeWaFdsG.js → MagicPage-BIbTFlwh.js} +1 -1
  28. package/web-app/dist/assets/{MetricsPage-CG8CuSSJ.js → MetricsPage-Cn3UPKpU.js} +1 -1
  29. package/web-app/dist/assets/{NotFoundPage-Mz5rOat6.js → NotFoundPage-BVs_nuBv.js} +1 -1
  30. package/web-app/dist/assets/{ProjectPage-D2Fh6tVw.js → ProjectPage-CLplvOHe.js} +25 -25
  31. package/web-app/dist/assets/{ProjectsPage-B8cRWkWa.js → ProjectsPage-BBFzBBG_.js} +1 -1
  32. package/web-app/dist/assets/{SettingsPage-DKpsst6x.js → SettingsPage-WPsJ_K9r.js} +1 -1
  33. package/web-app/dist/assets/{ShowcasePage-qab065PM.js → ShowcasePage-ZaLaJl5J.js} +1 -1
  34. package/web-app/dist/assets/{SystemSettingsPage-9qmEH2Y6.js → SystemSettingsPage-CCORP-uG.js} +1 -1
  35. package/web-app/dist/assets/{TeamsPage-CW6lvW-0.js → TeamsPage-B6IGT_K2.js} +1 -1
  36. package/web-app/dist/assets/{TemplatesPage-B-a61T6a.js → TemplatesPage-RrYYC3CM.js} +1 -1
  37. package/web-app/dist/assets/{TerminalOutput-CJy13rAn.js → TerminalOutput-CeTvKnkl.js} +1 -1
  38. package/web-app/dist/assets/{activity-CA4moIvC.js → activity-CySdOdDP.js} +1 -1
  39. package/web-app/dist/assets/{bell-JyOeobLN.js → bell-BHdr5yat.js} +1 -1
  40. package/web-app/dist/assets/{bot-Cu4UwP5w.js → bot-BaB4q_4m.js} +1 -1
  41. package/web-app/dist/assets/{check-Drzd8-9c.js → check-BAgbzVrK.js} +1 -1
  42. package/web-app/dist/assets/{chevron-left-ClvdXm3Y.js → chevron-left-CrVUY29C.js} +1 -1
  43. package/web-app/dist/assets/{circle-alert-CstyZfKG.js → circle-alert-YrWgH49w.js} +1 -1
  44. package/web-app/dist/assets/{clock-Bnz6tlQN.js → clock-DN8LAN-0.js} +1 -1
  45. package/web-app/dist/assets/{cloud-IPIgE4P3.js → cloud-D6C4b1KY.js} +1 -1
  46. package/web-app/dist/assets/{code-xml-BOZbQiOt.js → code-xml-xBWyKfux.js} +1 -1
  47. package/web-app/dist/assets/{database-CHclPjog.js → database-BYqcS6kn.js} +1 -1
  48. package/web-app/dist/assets/{dollar-sign-D6RFNgdZ.js → dollar-sign--WOh4k_m.js} +1 -1
  49. package/web-app/dist/assets/{file-code-corner-CNayCvOY.js → file-code-corner-B0rLPjW1.js} +1 -1
  50. package/web-app/dist/assets/{file-plus-BmVfFwsX.js → file-plus-BNhUQ1TQ.js} +1 -1
  51. package/web-app/dist/assets/{folder-open-ChzGfLRr.js → folder-open-DliiOgFl.js} +1 -1
  52. package/web-app/dist/assets/{globe-DtXgCG3Z.js → globe-BV-hx0u_.js} +1 -1
  53. package/web-app/dist/assets/{hammer-DCa0I_7V.js → hammer-DhmP4GLw.js} +1 -1
  54. package/web-app/dist/assets/{index-Cu-njJ8o.js → index-x0TESFYr.js} +2 -2
  55. package/web-app/dist/assets/{layers-DxIhn7NZ.js → layers-DXWDMSYj.js} +1 -1
  56. package/web-app/dist/assets/{lightbulb-D7Pzhd06.js → lightbulb-PBw6hhLS.js} +1 -1
  57. package/web-app/dist/assets/{loader-circle-DXgc_u5I.js → loader-circle-B7KiGAVU.js} +1 -1
  58. package/web-app/dist/assets/{lock-qRAVU53b.js → lock-BUTRYdDQ.js} +1 -1
  59. package/web-app/dist/assets/{mail-CHe3KyCw.js → mail-DaLiNrPb.js} +1 -1
  60. package/web-app/dist/assets/{minus-B8p0FoYZ.js → minus-DB_hlGEk.js} +1 -1
  61. package/web-app/dist/assets/{package-C5LDn8SI.js → package-CymmXoiQ.js} +1 -1
  62. package/web-app/dist/assets/{plus-CRd_FHOA.js → plus-Cp4AO4I2.js} +1 -1
  63. package/web-app/dist/assets/{refresh-cw-DKoSN8s3.js → refresh-cw-ygYTmZTE.js} +1 -1
  64. package/web-app/dist/assets/{rotate-ccw-Nf8zB8G0.js → rotate-ccw-Ba3QxM9K.js} +1 -1
  65. package/web-app/dist/assets/{save-B8ytQLgW.js → save-DPm96BnR.js} +1 -1
  66. package/web-app/dist/assets/{server-D_VRDkaD.js → server-BapOz_vf.js} +1 -1
  67. package/web-app/dist/assets/{shield-alert-PsDkSyFD.js → shield-alert-DYzfVqWS.js} +1 -1
  68. package/web-app/dist/assets/{thumbs-up-Da1QQhqo.js → thumbs-up-DxOTplej.js} +1 -1
  69. package/web-app/dist/assets/{trash-2-ChoylpGQ.js → trash-2-Br8dh_6B.js} +1 -1
  70. package/web-app/dist/assets/{trending-down-CX2fUeho.js → trending-down-CxSP6MU3.js} +1 -1
  71. package/web-app/dist/assets/{trending-up-CGyYgZH7.js → trending-up-CXx0ywZb.js} +1 -1
  72. package/web-app/dist/assets/{upload-KkeVyg67.js → upload-CpEO3qNc.js} +1 -1
  73. package/web-app/dist/assets/{usePolling-C5f4xrXD.js → usePolling-BuzXwjmC.js} +1 -1
  74. package/web-app/dist/assets/{user-WCGccIST.js → user-DUUYT47B.js} +1 -1
  75. package/web-app/dist/index.html +1 -1
@@ -61,7 +61,7 @@ jobs:
61
61
  # Pinned to a TAG, not @main. A moving ref would hand every user
62
62
  # whatever main holds at the moment their issue is labeled, including a
63
63
  # half-landed release. Bump this line deliberately.
64
- uses: asklokesh/loki-mode/.github/actions/issue-to-pr@v9.49.2
64
+ uses: asklokesh/loki-mode/.github/actions/issue-to-pr@v9.49.3
65
65
  env:
66
66
  ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
67
67
  with:
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v9.49.2
6
+ # Loki Mode v9.49.3
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -470,4 +470,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
470
470
 
471
471
  ---
472
472
 
473
- **v9.49.2 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
473
+ **v9.49.3 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 9.49.2
1
+ 9.49.3
@@ -51,7 +51,21 @@ loki_effort_for_tier() {
51
51
 
52
52
  # ---------- Remaining budget ----------
53
53
  # Compute remaining budget = LOKI_BUDGET_LIMIT - cumulative spend so far.
54
- # Spend lives in .loki/metrics/budget.json under "current_spend" (per autonomy/run.sh:8167+).
54
+ # Spend lives in .loki/metrics/budget.json under "budget_used".
55
+ #
56
+ # It was read as "current_spend" until v9.50.0, a key NO production writer has
57
+ # ever emitted. All six writers of that file (run.sh:6581,17851,17869,
58
+ # loki-ts/src/runner/budget.ts:267, dashboard/server.py:7953, autonomy/loki)
59
+ # write "budget_used". The old citation pointed at run.sh:8167+, which is
60
+ # per-iteration token parsing and writes no budget key at all.
61
+ #
62
+ # Effect of the bug: spend always read 0, so --max-budget-usd was handed the
63
+ # FULL cap on every call instead of the remainder, and the per-call backstop
64
+ # never tightened as spend accumulated. Only reachable for users who set
65
+ # LOKI_BUDGET_LIMIT explicitly (run.sh sets BUDGET_LIMIT, not LOKI_*), i.e.
66
+ # exactly the cost-conscious users who asked for the cap.
67
+ # "current_spend" is still accepted as a fallback so a budget.json written by
68
+ # an in-flight older run still parses.
55
69
  # Emit empty string when budget is unlimited (LOKI_BUDGET_LIMIT unset or 0).
56
70
  # Emit empty when remaining <= 0 (caller decides what to do; we never emit 0).
57
71
  loki_remaining_budget() {
@@ -71,7 +85,9 @@ import json, os, sys
71
85
  try:
72
86
  with open(os.environ["_LOKI_BUDGET_FILE"]) as f:
73
87
  d = json.load(f)
74
- v = d.get("current_spend", 0)
88
+ v = d.get("budget_used")
89
+ if v is None:
90
+ v = d.get("current_spend", 0)
75
91
  print(float(v))
76
92
  except Exception:
77
93
  print(0)
@@ -165,7 +165,15 @@ def check_budget_threshold(trigger, loki_dir, iteration, notifications):
165
165
  state = json.loads(state_file.read_text())
166
166
  budget = state.get("budget", {})
167
167
  limit = budget.get("limit", 0)
168
- used = budget.get("used", 0)
168
+ # run.sh:7084 nests .loki/metrics/budget.json verbatim under "budget",
169
+ # and that file's spend key is "budget_used". Reading only "used" meant
170
+ # this trigger never fired in production: verified against the exact
171
+ # state run.sh writes, 0 notifications were produced at 85% of cap.
172
+ # "used" stays as a fallback for the /api/cost-shaped payload
173
+ # (autonomy/loki:28122), which does write that key.
174
+ used = budget.get("budget_used")
175
+ if used is None:
176
+ used = budget.get("used", 0)
169
177
  if limit <= 0:
170
178
  return None
171
179
  pct = (used / limit) * 100
@@ -241,24 +249,44 @@ def check_file_access(trigger, loki_dir, iteration, notifications):
241
249
 
242
250
 
243
251
  def check_quality_gate(trigger, loki_dir, iteration, notifications):
244
- """Check for quality gate failures. Reports ALL failed gates, not just first."""
245
- state_file = Path(loki_dir) / "dashboard-state.json"
246
- if not state_file.exists():
247
- return []
248
-
252
+ """Check for quality gate failures. Reports ALL failed gates, not just first.
253
+
254
+ Reads .loki/quality/gate-failures.txt, which is what run.sh actually writes
255
+ (:24100, :24142, :24553) as a comma-terminated list of failing gate names,
256
+ e.g. "mock_integrity,".
257
+
258
+ This previously read state["qualityGates"] out of dashboard-state.json,
259
+ sourced from .loki/state/quality-gates.json (run.sh:6972). NOTHING writes
260
+ that file: all seven repo references are readers, autonomy/hooks/
261
+ quality-gate.sh:12 guards on `[ ! -f ]`, and proof-generator.py:345 records
262
+ the same finding as issue #125 and already works around it by reading these
263
+ per-gate artifacts. The aggregate was therefore always absent, qualityGates
264
+ was always null, and this trigger could never fire -- the same dead-reader
265
+ defect as the budget key, in the same file.
266
+
267
+ gate-failures.txt is the canonical failure source used by
268
+ proof-generator.py:413 and loki-ts build_prompt_helpers.ts:250, so this
269
+ reuses a proven contract rather than introducing a second one.
270
+ """
271
+ failures_file = Path(loki_dir) / "quality" / "gate-failures.txt"
249
272
  results = []
250
273
  try:
251
- state = json.loads(state_file.read_text())
252
- gates = state.get("qualityGates", {})
253
- if isinstance(gates, dict):
254
- for gate_name, gate_data in gates.items():
255
- if isinstance(gate_data, dict) and gate_data.get("status") == "failed":
256
- msg = trigger["message"].format(gate=gate_name)
257
- results.append(make_notification(
258
- trigger["id"], trigger["severity"], msg, iteration,
259
- {"gate": gate_name},
260
- ))
261
- except (json.JSONDecodeError, OSError, KeyError):
274
+ if failures_file.exists():
275
+ # Cap the read: a pathological file must not be loaded whole
276
+ # (same reason as build_prompt.ts:707).
277
+ raw = failures_file.read_text(errors="replace")[:8000]
278
+ seen = set()
279
+ for name in raw.replace("\n", ",").split(","):
280
+ gate_name = name.strip()
281
+ if not gate_name or gate_name in seen:
282
+ continue
283
+ seen.add(gate_name)
284
+ msg = trigger["message"].format(gate=gate_name)
285
+ results.append(make_notification(
286
+ trigger["id"], trigger["severity"], msg, iteration,
287
+ {"gate": gate_name},
288
+ ))
289
+ except (OSError, KeyError):
262
290
  pass
263
291
  return results if results else None
264
292
 
package/autonomy/run.sh CHANGED
@@ -1181,10 +1181,12 @@ PERPETUAL_MODE=${LOKI_PERPETUAL_MODE:-false}
1181
1181
  #
1182
1182
  # MEASURED, not chosen. Real per-iteration wall clock across every recorded run
1183
1183
  # on this machine: median 718s, max 1746s. So the 1000 default is an 8.3-DAY
1184
- # ceiling -- and it is the ONLY backstop, because the other two valves ship
1185
- # disabled: LOKI_BUDGET_LIMIT defaults to "" (check_budget_limit returns
1186
- # immediately) and LOKI_MAX_DURATION defaults to 0 (check_max_duration returns
1187
- # "never stop").
1184
+ # ceiling. When this analysis was written it was also the ONLY backstop,
1185
+ # because the other two valves shipped disabled. That is no longer true of the
1186
+ # budget: since v9.42.0 LOKI_BUDGET_LIMIT defaults to "100.00" (see :527 --
1187
+ # note `-` not `:-`, so only an EXPLICIT "" means unlimited), and breaching it
1188
+ # pauses the run. LOKI_MAX_DURATION does still default to 0 (check_max_duration
1189
+ # returns "never stop" at :18278).
1188
1190
  #
1189
1191
  # It also contradicts our own documentation. SETUP.md tells users to RAISE the
1190
1192
  # budget for large work with LOKI_MAX_ITERATIONS=40, and the demo uses 10 -- so
@@ -17860,6 +17862,43 @@ BUDGETUPD_EOF
17860
17862
  return 0
17861
17863
  fi
17862
17864
 
17865
+ # LIVE COST VISIBILITY. The loop has always computed cumulative spend here,
17866
+ # every iteration, and printed NOTHING until 80% of the cap. That silence is
17867
+ # the "predatory / un-capped" feeling users report about agentic tools: the
17868
+ # enforcement was never missing (the cap pauses at 100.00 by default), only
17869
+ # the visibility was, so spend was discoverable solely after the fact.
17870
+ #
17871
+ # Reuses the $current_cost computed above; deliberately NOT a second reader.
17872
+ # Two readers of one number disagreeing is the exact defect class fixed in
17873
+ # 405da630, and a per-iteration cost line is not worth reintroducing it.
17874
+ #
17875
+ # Safe on stdout: this function has exactly two non-comment references in
17876
+ # the file -- its own definition, and the single loop call site, which
17877
+ # tests the exit code and never captures output. Verified with a
17878
+ # comment-excluding grep plus a positive control.
17879
+ #
17880
+ # This comment deliberately does NOT spell out the call-site expression.
17881
+ # tests/test-max-duration.sh:151 counts that exact string across this file
17882
+ # and asserts there is exactly ONE, so quoting it here made the count 2 and
17883
+ # turned a green suite red -- a text guard firing on prose written to
17884
+ # explain it. Describe the call site; never reproduce it.
17885
+ #
17886
+ # log_info is additionally gated by _loki_log_enabled, so quiet modes stay
17887
+ # quiet.
17888
+ # The zero test must be NUMERIC. `[ "$current_cost" != "0" ]` is a string
17889
+ # compare and the python above emits "0.0", so a run with nothing recorded
17890
+ # would announce "Cost so far: $0.0" -- claiming a measurement we do not
17891
+ # have, which is the exact fabrication this codebase deletes on sight.
17892
+ #
17893
+ # No else-branch: BUDGET_LIMIT empty means unlimited, and check_budget_limit
17894
+ # returns at its first line in that case, so any "no cap set" arm here would
17895
+ # be unreachable code advertising a message that can never print. The
17896
+ # no-cap disclosure already lives at run-start (show_run_start_estimate).
17897
+ if [ -n "$current_cost" ] \
17898
+ && awk -v c="$current_cost" 'BEGIN{exit !(c+0 > 0)}' 2>/dev/null; then
17899
+ log_info "Cost so far: \$${current_cost} of \$${BUDGET_LIMIT} cap (iteration ${ITERATION_COUNT:-0})."
17900
+ fi
17901
+
17863
17902
  # Update budget.json with current usage (not exceeded)
17864
17903
  if [ -n "$current_cost" ] && [ "$current_cost" != "0" ]; then
17865
17904
  cat > ".loki/metrics/budget.json" << BUDGETUPD_EOF
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "9.49.2"
10
+ __version__ = "9.49.3"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v9.49.2
5
+ **Version:** v9.49.3
6
6
 
7
7
  ---
8
8
 
@@ -25,7 +25,7 @@ They bound different things, and a run that stalls needs all three.
25
25
 
26
26
  | Cap | Bounds | Default |
27
27
  |---|---|---|
28
- | `LOKI_BUDGET_LIMIT` | Total spend, in USD | unset (no cap) |
28
+ | `LOKI_BUDGET_LIMIT` | Total spend, in USD | `100.00` (breaching pauses the run) |
29
29
  | `LOKI_MAX_ITERATIONS` | Number of iterations | 1000 |
30
30
  | `LOKI_MAX_DURATION` | Wall-clock time | unset (no cap) |
31
31
 
@@ -23,7 +23,7 @@ with nowhere to look them up.
23
23
  |---|---|---|
24
24
  | `LOKI_PRD_FILE` | none | Path to a spec file, as an alternative to the positional argument. |
25
25
  | `LOKI_MAX_ITERATIONS` | `1000` | Hard cap on iterations. Reaching it is a deterministic terminal failure, not a success. Also in `config schema`. |
26
- | `LOKI_BUDGET_LIMIT` | unset (no cap) | Spend cap in USD. On exhaustion the run stops and reports a terminal failure -- see [exit codes](./exit-codes.md). |
26
+ | `LOKI_BUDGET_LIMIT` | `100.00` | Spend cap in USD. Breaching it **pauses** the run (writes `.loki/PAUSE` and saves state); it never kills work or discards a deliverable. Remove `.loki/PAUSE` to resume, or raise the cap. Set to `""` for no cap. A warning is logged at 80%. |
27
27
  | `LOKI_MAX_DURATION` | unset (no cap) | Wall-clock cap in seconds. Stops cleanly at the next iteration boundary with a `max_duration_reached` terminal status. `loki start --max-duration` also accepts `90m` / `2h`. |
28
28
  | `LOKI_AUTO_CONFIRM` | unset | `true`/`false` to control prompts. Takes precedence over `CI`. |
29
29
  | `LOKI_CONFIG_DUMP` | `0` | `1` prints the resolved configuration and exits **without starting a run or spending anything**. |
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var vt=Object.create;var{getPrototypeOf:ht,defineProperty:jG,getOwnPropertyNames:gt}=Object;var mt=Object.prototype.hasOwnProperty;function ut($){return this[$]}var dt,pt,ct=($,X,Q)=>{var z=$!=null&&typeof $==="object";if(z){var Z=X?dt??=new WeakMap:pt??=new WeakMap,K=Z.get($);if(K)return K}Q=$!=null?vt(ht($)):{};let J=X||!$||!$.__esModule?jG(Q,"default",{value:$,enumerable:!0}):Q;for(let q of gt($))if(!mt.call(J,q))jG(J,q,{get:ut.bind($,q),enumerable:!0});if(z)Z.set($,J);return J};var zq=($,X)=>()=>(X||$((X={exports:{}}).exports,X),X.exports);var lt=($)=>$;function it($,X){this[$]=lt.bind(null,X)}var B1=($,X)=>{for(var Q in X)jG($,Q,{get:X[Q],enumerable:!0,configurable:!0,set:it.bind(X,Q)})};var s=($,X)=>()=>($&&(X=$($=0)),X);var w5=import.meta.require;var HR={};B1(HR,{lokiDir:()=>h0,homeLokiDir:()=>GQ,findRepoRootForVersion:()=>AG,REPO_ROOT:()=>L1});import{resolve as h2,dirname as LG}from"path";import{fileURLToPath as at}from"url";import{existsSync as Zq}from"fs";import{homedir as ot}from"os";function st(){let $=UR;for(let X=0;X<6;X++){if(Zq(h2($,"VERSION"))&&Zq(h2($,"autonomy/run.sh")))return $;let Q=LG($);if(Q===$)break;$=Q}return h2(UR,"..","..","..")}function AG($){let X=$;for(let Q=0;Q<6;Q++){if(Zq(h2(X,"VERSION"))&&Zq(h2(X,"autonomy/run.sh")))return X;let z=LG(X);if(z===X)break;X=z}return h2($,"..","..","..")}function h0(){return process.env.LOKI_DIR??h2(process.cwd(),".loki")}function GQ(){return h2(ot(),".loki")}var UR,L1;var k1=s(()=>{UR=LG(at(import.meta.url));L1=st()});import{readFileSync as nt}from"fs";import{resolve as rt,dirname as tt}from"path";import{fileURLToPath as et}from"url";function j9(){if(n3!==null)return n3;let $="9.49.2";if(typeof $==="string"&&$.length>0)return n3=$,n3;try{let X=tt(et(import.meta.url)),Q=AG(X);n3=nt(rt(Q,"VERSION"),"utf-8").trim()}catch{n3="unknown"}return n3}var n3=null;var Kq=s(()=>{k1()});var jR={};B1(jR,{runOrThrow:()=>Ne,run:()=>$1,readStreamCapped:()=>Jq,commandVersion:()=>Oe,commandExists:()=>g5,ShellError:()=>TG,MAX_STDOUT_BYTES:()=>OR});async function Jq($,X=OR){let Q=$.getReader(),z=new TextDecoder,Z="",K=0;try{while(K<X){let{done:J,value:q}=await Q.read();if(J)break;if(!q)continue;if(K+=q.byteLength,K>X){let V=q.byteLength-(K-X);Z+=z.decode(q.subarray(0,V),{stream:!0});break}Z+=z.decode(q,{stream:!0})}Z+=z.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return Z}async function $1($,X={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),z,Z;if(X.timeoutMs&&X.timeoutMs>0)z=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[K,J,q]=await Promise.all([Jq(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:J,exitCode:q}}finally{if(z)clearTimeout(z);if(Z)clearTimeout(Z)}}async function Ne($,X={}){let Q=await $1($,X);if(Q.exitCode!==0)throw new TG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function g5($){let X=Me($),Q=await $1(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Me($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function Oe($,X="--version"){if(!await g5($))return null;let z=await $1([$,X],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var OR=16777216,TG;var y8=s(()=>{TG=class TG extends Error{message;exitCode;stdout;stderr;constructor($,X,Q,z){super($);this.message=$;this.exitCode=X;this.stdout=Q;this.stderr=z;this.name="ShellError"}}});function g2($){return je?"":$}var je,p0,$5,q1,F61,A1,f1,m5,r;var t7=s(()=>{je=(process.env.NO_COLOR??"").length>0;p0=g2("\x1B[0;31m"),$5=g2("\x1B[0;32m"),q1=g2("\x1B[1;33m"),F61=g2("\x1B[0;34m"),A1=g2("\x1B[0;36m"),f1=g2("\x1B[1m"),m5=g2("\x1B[2m"),r=g2("\x1B[0m")});import{existsSync as Pe}from"fs";async function Z2(){if(BQ!==void 0)return BQ;let $="/opt/homebrew/bin/python3.12";if(Pe($))return BQ=$,$;let X=await g5("python3.12");if(X)return BQ=X,X;let Q=await g5("python3");return BQ=Q,Q}async function I4($,X={}){let Q=await Z2();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return $1([Q,"-c",$],X)}var BQ;var m2=s(()=>{y8()});var hR={};B1(hR,{runStatus:()=>ee});import{existsSync as u5,readFileSync as C9,readdirSync as xR,statSync as kR}from"fs";import{resolve as A5,basename as ce}from"path";import{homedir as le}from"os";function SR($){let X=Math.trunc($);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function yR($,X,Q){if(X===0)return null;let z=Math.trunc($*100/X),Z=Math.trunc($*Vq/X);if(Z>Vq)Z=Vq;let K=Vq-Z,J=$5;if(z>=80)J=p0;else if(z>=50)J=q1;let q="=".repeat(Math.max(0,Z))+" ".repeat(Math.max(0,K)),V=SR($),Y=SR(X);return` ${f1}${Q}${r} ${J}[${q}]${r} ${z}% (${V} / ${Y})`}async function ae(){if(await g5("jq"))return!0;return process.stdout.write(`${p0}Error: jq is required but not installed.${r}
2
+ var vt=Object.create;var{getPrototypeOf:ht,defineProperty:jG,getOwnPropertyNames:gt}=Object;var mt=Object.prototype.hasOwnProperty;function ut($){return this[$]}var dt,pt,ct=($,X,Q)=>{var z=$!=null&&typeof $==="object";if(z){var Z=X?dt??=new WeakMap:pt??=new WeakMap,K=Z.get($);if(K)return K}Q=$!=null?vt(ht($)):{};let J=X||!$||!$.__esModule?jG(Q,"default",{value:$,enumerable:!0}):Q;for(let q of gt($))if(!mt.call(J,q))jG(J,q,{get:ut.bind($,q),enumerable:!0});if(z)Z.set($,J);return J};var zq=($,X)=>()=>(X||$((X={exports:{}}).exports,X),X.exports);var lt=($)=>$;function it($,X){this[$]=lt.bind(null,X)}var B1=($,X)=>{for(var Q in X)jG($,Q,{get:X[Q],enumerable:!0,configurable:!0,set:it.bind(X,Q)})};var s=($,X)=>()=>($&&(X=$($=0)),X);var w5=import.meta.require;var HR={};B1(HR,{lokiDir:()=>h0,homeLokiDir:()=>GQ,findRepoRootForVersion:()=>AG,REPO_ROOT:()=>L1});import{resolve as h2,dirname as LG}from"path";import{fileURLToPath as at}from"url";import{existsSync as Zq}from"fs";import{homedir as ot}from"os";function st(){let $=UR;for(let X=0;X<6;X++){if(Zq(h2($,"VERSION"))&&Zq(h2($,"autonomy/run.sh")))return $;let Q=LG($);if(Q===$)break;$=Q}return h2(UR,"..","..","..")}function AG($){let X=$;for(let Q=0;Q<6;Q++){if(Zq(h2(X,"VERSION"))&&Zq(h2(X,"autonomy/run.sh")))return X;let z=LG(X);if(z===X)break;X=z}return h2($,"..","..","..")}function h0(){return process.env.LOKI_DIR??h2(process.cwd(),".loki")}function GQ(){return h2(ot(),".loki")}var UR,L1;var k1=s(()=>{UR=LG(at(import.meta.url));L1=st()});import{readFileSync as nt}from"fs";import{resolve as rt,dirname as tt}from"path";import{fileURLToPath as et}from"url";function j9(){if(n3!==null)return n3;let $="9.49.3";if(typeof $==="string"&&$.length>0)return n3=$,n3;try{let X=tt(et(import.meta.url)),Q=AG(X);n3=nt(rt(Q,"VERSION"),"utf-8").trim()}catch{n3="unknown"}return n3}var n3=null;var Kq=s(()=>{k1()});var jR={};B1(jR,{runOrThrow:()=>Ne,run:()=>$1,readStreamCapped:()=>Jq,commandVersion:()=>Oe,commandExists:()=>g5,ShellError:()=>TG,MAX_STDOUT_BYTES:()=>OR});async function Jq($,X=OR){let Q=$.getReader(),z=new TextDecoder,Z="",K=0;try{while(K<X){let{done:J,value:q}=await Q.read();if(J)break;if(!q)continue;if(K+=q.byteLength,K>X){let V=q.byteLength-(K-X);Z+=z.decode(q.subarray(0,V),{stream:!0});break}Z+=z.decode(q,{stream:!0})}Z+=z.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return Z}async function $1($,X={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),z,Z;if(X.timeoutMs&&X.timeoutMs>0)z=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[K,J,q]=await Promise.all([Jq(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:J,exitCode:q}}finally{if(z)clearTimeout(z);if(Z)clearTimeout(Z)}}async function Ne($,X={}){let Q=await $1($,X);if(Q.exitCode!==0)throw new TG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function g5($){let X=Me($),Q=await $1(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function Me($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function Oe($,X="--version"){if(!await g5($))return null;let z=await $1([$,X],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var OR=16777216,TG;var y8=s(()=>{TG=class TG extends Error{message;exitCode;stdout;stderr;constructor($,X,Q,z){super($);this.message=$;this.exitCode=X;this.stdout=Q;this.stderr=z;this.name="ShellError"}}});function g2($){return je?"":$}var je,p0,$5,q1,F61,A1,f1,m5,r;var t7=s(()=>{je=(process.env.NO_COLOR??"").length>0;p0=g2("\x1B[0;31m"),$5=g2("\x1B[0;32m"),q1=g2("\x1B[1;33m"),F61=g2("\x1B[0;34m"),A1=g2("\x1B[0;36m"),f1=g2("\x1B[1m"),m5=g2("\x1B[2m"),r=g2("\x1B[0m")});import{existsSync as Pe}from"fs";async function Z2(){if(BQ!==void 0)return BQ;let $="/opt/homebrew/bin/python3.12";if(Pe($))return BQ=$,$;let X=await g5("python3.12");if(X)return BQ=X,X;let Q=await g5("python3");return BQ=Q,Q}async function I4($,X={}){let Q=await Z2();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return $1([Q,"-c",$],X)}var BQ;var m2=s(()=>{y8()});var hR={};B1(hR,{runStatus:()=>ee});import{existsSync as u5,readFileSync as C9,readdirSync as xR,statSync as kR}from"fs";import{resolve as A5,basename as ce}from"path";import{homedir as le}from"os";function SR($){let X=Math.trunc($);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function yR($,X,Q){if(X===0)return null;let z=Math.trunc($*100/X),Z=Math.trunc($*Vq/X);if(Z>Vq)Z=Vq;let K=Vq-Z,J=$5;if(z>=80)J=p0;else if(z>=50)J=q1;let q="=".repeat(Math.max(0,Z))+" ".repeat(Math.max(0,K)),V=SR($),Y=SR(X);return` ${f1}${Q}${r} ${J}[${q}]${r} ${z}% (${V} / ${Y})`}async function ae(){if(await g5("jq"))return!0;return process.stdout.write(`${p0}Error: jq is required but not installed.${r}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -835,7 +835,7 @@ new Anthropic({ apiKey, dangerouslyAllowBrowser: true });
835
835
  `),K.verdict==="accepted"?0:2}}catch(Z){let K=Z instanceof Error?Z.message:String(Z);return process.stderr.write(`exec-manifest: ${K}
836
836
  `),2}return process.stderr.write(`exec-manifest: unknown action "${X}"
837
837
  `),2}var Ak=s(()=>{Ok()});var Ck;var Tk=s(()=>{Ck={now:()=>Date.now(),sleep:($)=>new Promise((X)=>setTimeout(X,$))}});import{resolve as N30,join as rM}from"path";import{existsSync as tM,mkdirSync as M30}from"fs";function O30(){return N30(L1,"autonomy","lib","proof-generator.py")}function j30(){let $=new Date().toISOString().replace(/[-:T]/g,"").slice(0,14),X=Math.floor(Math.random()*32768);return`proof-${$}-${process.pid}-${X}`}async function Dk($){try{if(process.env.LOKI_PROOF==="0")return!1;let X=O30();if(!tM(X))return!1;if(!tM($.lokiDir))return!1;let Q=await Z2();if(!Q)return!1;let z="unknown";try{z=j9()}catch{}let Z=j30(),K=[X,"--loki-dir",$.lokiDir,"--loki-version",z,"--provider",$.provider,"--run-id",Z,"--quiet"],J={ITERATION_COUNT:String($.iterationCount),PROVIDER_NAME:$.provider};if($.prdPath)J.PRD_PATH=$.prdPath;await $1([Q,...K],{cwd:$.cwd,env:J,timeoutMs:30000});let q=rM($.lokiDir,"proofs",Z,"proof.json");if(tM(q))try{let V=rM($.lokiDir,"state");M30(V,{recursive:!0}),T7(rM(V,"last-proof-id.txt"),Z)}catch{}return!0}catch(X){try{$.log(`[runner] proof-of-run generation skipped: ${X.message}`)}catch{}return!1}}var Fk=s(()=>{k1();m2();y8();Kq();w4()});import{existsSync as Rk,readFileSync as Ik,writeFileSync as L30,mkdirSync as A30,statSync as wk}from"fs";import{resolve as C30,join as eM,delimiter as T30}from"path";function F30(){let $=process.env.PATH??"";if(!$)return!1;let X=$.split(T30).filter((Q)=>Q.length>0);for(let Q of D30)for(let z of X){let Z=eM(z,Q);try{if(wk(Z).isFile())return!0}catch{}}return!1}function R30($){let X={"loki-mode":{command:"python3",args:["-m","mcp.server"]}};if($)X["lsp-proxy"]={command:"python3",args:["-m","mcp.lsp_proxy"]};return{mcpServers:X}}function I30($){return JSON.stringify($,null,2)+`
838
- `}function $O($){let X=C30($,".loki"),Q=eM(X,"mcp-config.json"),z=I30(R30(F30())),Z=null;if(Rk(Q))try{Z=Ik(Q,"utf8")}catch{Z=null}if(Z===z)return Q;return A30(X,{recursive:!0}),L30(Q,z,"utf8"),Q}function w30(){let $=process.env.HOME;if(!$)return null;let X=eM($,".claude","mcp.json");if(!Rk(X))return null;try{let Q=wk(X);if(!Q.isFile())return null;if(Q.size>1048576)return console.warn("[mcp_config] ignoring ~/.claude/mcp.json: file exceeds the 1 MiB safety limit."),null;let z=JSON.parse(Ik(X,"utf8"));if(typeof z!=="object"||z===null||!("mcpServers"in z)||typeof z.mcpServers!=="object"||z.mcpServers===null||Array.isArray(z.mcpServers))return console.warn('[mcp_config] ignoring ~/.claude/mcp.json: Claude Code requires a top-level "mcpServers" object; update or remove the legacy/invalid file.'),null;return X}catch{return console.warn('[mcp_config] ignoring ~/.claude/mcp.json: Claude Code requires valid JSON with a top-level "mcpServers" object.'),null}}function Pk($){let Q=["--mcp-config",$O($)],z=w30();if(z!==null)Q.push(z);return Q}var D30;var XO=s(()=>{D30=["typescript-language-server","pylsp","gopls","rust-analyzer"]});import{existsSync as Sk,readFileSync as QO}from"fs";import{resolve as yk,dirname as P30}from"path";import{fileURLToPath as E30}from"url";import{createHash as x30}from"crypto";function L$($,X){let Q;switch($){case"planning":case"best":Q="xhigh";break;case"development":case"balanced":Q="high";break;case"fast":Q="medium";break;case"cheap":Q="low";break;default:Q="high";break}if((X??process.env.LOKI_COMPLEXITY??"standard")==="complex")switch(Q){case"low":Q="medium";break;case"medium":Q="high";break;case"high":Q="xhigh";break}return Q}function Ek(...$){return $.some((X)=>{let Q=process.env[X];return Q!==void 0&&Q!==""})}function zO($,X){if(process.env.LOKI_TIER_ROUTING!=="1")return X;let Q=process.env.LOKI_COMPLEXITY??"standard";switch($){case"planning":if(Q==="complex"&&!Ek("LOKI_CLAUDE_MODEL_PLANNING","LOKI_MODEL_PLANNING"))return"opus";return X;case"fast":if(Q==="simple"&&process.env.LOKI_ALLOW_HAIKU==="true"&&!Ek("LOKI_CLAUDE_MODEL_FAST","LOKI_MODEL_FAST"))return"haiku";return X;default:return X}}function ZO($){let X=process.env.LOKI_BUDGET_LIMIT;if(!X)return null;let Q=parseFloat(X);if(!Number.isFinite(Q)||Q<=0)return null;let z=$??process.env.TARGET_DIR??".",Z=yk(z,".loki","metrics","budget.json"),K=0;if(Sk(Z))try{let V=JSON.parse(QO(Z,"utf8")).current_spend;if(typeof V==="number"&&Number.isFinite(V))K=V;else if(typeof V==="string"){let Y=parseFloat(V);if(Number.isFinite(Y))K=Y}}catch{K=0}let J=Q-K;if(J<=0)return null;return J.toFixed(2)}function KO($,X){if(!$)return null;let Q=X??process.env.LOKI_ALLOW_HAIKU==="true";switch($){case"opus":return"sonnet";case"sonnet":return Q?"haiku":null;default:return null}}function u1($,X){let Q=X??HY;if(Q===null||Q===void 0)return!1;return Q.includes($)}async function w6(){if(HY!==null)return;try{let $=Bun.spawn(["claude","--help"],{stdout:"pipe",stderr:"pipe"}),X=await new Response($.stdout).text();await $.exited,HY=X||""}catch{HY=""}}function bk($){let X=[];if(u1("--effort")){let Q=L$($.tier,$.complexity);X.push("--effort",Q)}if(u1("--max-budget-usd")){let Q=ZO($.targetDir);if(Q!==null)X.push("--max-budget-usd",Q)}if(u1("--fallback-model")){let Q=KO($.primary);if(Q!==null)X.push("--fallback-model",Q)}if((process.env.LOKI_DYNAMIC_PROMPT_SECTIONS??"auto")!=="keep"&&u1("--exclude-dynamic-system-prompt-sections"))X.push("--exclude-dynamic-system-prompt-sections");if(u1("--mcp-config"))try{let Q=$.targetDir??process.env.TARGET_DIR??".",z=Pk(Q);if(X.push(...z),process.env.LOKI_STRICT_MCP!=="0"&&z.length>0&&u1("--strict-mcp-config"))X.push("--strict-mcp-config")}catch(Q){console.warn(`[claude_flags] --mcp-config emit skipped: ${Q.message}`)}if(process.env.LOKI_HOOK_EVENTS!=="off"&&u1("--include-hook-events"))X.push("--include-hook-events");if(process.env.LOKI_AUTONOMY_OVERRIDE!=="off"&&u1("--append-system-prompt"))X.push("--append-system-prompt",JO());if(process.env.LOKI_NO_SESSION_PERSIST==="1"&&u1("--no-session-persistence"))X.push("--no-session-persistence");return X}function JO(){let $=Number.parseInt(process.env.ITERATION_COUNT??"1",10);return process.env.LOKI_FIRST_PASS_EXCELLENCE!=="0"&&(Number.isNaN($)||$<=1)?xk+S30:xk}function fk(){return process.env.LOKI_AUTONOMY_OVERRIDE!=="off"}function k30(){try{let $=P30(E30(import.meta.url));for(let X of[["..","..","..","references","design-archetypes.md"],["..","..","references","design-archetypes.md"]]){let Q=yk($,...X);if(Sk(Q))return QO(Q,"utf8")}}catch{}return""}function b30($){let X=y30.replace(/-/g,""),Q=Uint8Array.from(X.match(/.{2}/g).map((V)=>parseInt(V,16))),z=new TextEncoder().encode($),Z=new Uint8Array(Q.length+z.length);Z.set(Q,0),Z.set(z,Q.length);let J=Uint8Array.from(x30("sha1").update(Z).digest()).subarray(0,16);J[6]=J[6]&15|80,J[8]=J[8]&63|128;let q=Array.from(J).map((V)=>V.toString(16).padStart(2,"0")).join("");return`${q.slice(0,8)}-${q.slice(8,12)}-${q.slice(12,16)}-${q.slice(16,20)}-${q.slice(20)}`}function f30($,X){let Q=$??process.env.LOKI_TRUST_RUN_ID??"";if(!Q)return null;let z=X;if(z===void 0){let Z=parseInt(process.env.ITERATION_COUNT??"0",10);z=Number.isFinite(Z)?Z:0}return b30(`${Q}:${z}`)}function _30(){if(process.env.LOKI_SESSION_STAMP!=="1")return!1;return u1("--session-id")}function _k($,X){if(!_30())return[];let Q=f30($,X);return Q?["--session-id",Q]:[]}function h30(){if(process.env.LOKI_REVIEW_ALLOWLIST==="0")return!1;return u1("--allowedTools")}function qO(){if(!h30())return[];return["--allowedTools",v30]}function vk(){if(process.env.LOKI_RESUME_SESSION!=="1")return!1;return u1("--resume")}function g30(){if(process.env.LOKI_SESSION_FORK!=="1")return!1;if(!vk())return!1;return u1("--fork-session")}function m30($){let X=$??process.env.TARGET_DIR??".",z=`${process.env.LOKI_DIR??`${X}/.loki`}/state/claude-session.json`;try{let Z=QO(z,"utf8"),K=JSON.parse(Z);if(typeof K!=="object"||K===null)return null;let J=K.claude_session_uuid;if(typeof J==="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(J))return J;return null}catch{return null}}function hk($){if(!vk())return[];let X=m30($);if(!X)return[];let Q=["--resume",X];if(g30())Q.push("--fork-session");return Q}function u30(){return process.env.LOKI_CAVEMAN_LEVEL||"full"}function d30($){return($??process.env.LOKI_CURRENT_TIER??"")==="planning"?"lite":"full"}function p30(){if((process.env.LOKI_PROVIDER||"claude")!=="claude")return!1;if(process.env.LOKI_CAVEMAN==="0")return!1;return!0}function c30(){if(process.env.LOKI_CAVEMAN==="0")return!1;if(process.env.LOKI_LEGACY_COMPLETION_MATCH==="true")return!1;return!0}function kk($){switch($){case"off":return 0;case"lite":case"wenyan-lite":return 1;case"full":case"wenyan":case"wenyan-full":return 2;case"ultra":case"wenyan-ultra":return 3;default:return-1}}function VO($){if(!p30())return null;if(!c30())return null;let Q=process.env.LOKI_CAVEMAN_LEVEL!==void 0?u30():d30($),z=process.env.LOKI_CAVEMAN_USER_MODE;if(z==="off")return null;if(z){let Z=kk(z),K=kk(Q);if(Z>=0&&K>=0&&Z<K)return z}return Q}function gk(){if(process.env.LOKI_CAVEMAN_USER_MODE===void 0)process.env.LOKI_CAVEMAN_USER_MODE=process.env.CAVEMAN_DEFAULT_MODE??""}function WY(){return"off"}var HY=null,xk=`[LOKI-AUTONOMY-AGENT] This is a Loki Mode autonomous agent process.
838
+ `}function $O($){let X=C30($,".loki"),Q=eM(X,"mcp-config.json"),z=I30(R30(F30())),Z=null;if(Rk(Q))try{Z=Ik(Q,"utf8")}catch{Z=null}if(Z===z)return Q;return A30(X,{recursive:!0}),L30(Q,z,"utf8"),Q}function w30(){let $=process.env.HOME;if(!$)return null;let X=eM($,".claude","mcp.json");if(!Rk(X))return null;try{let Q=wk(X);if(!Q.isFile())return null;if(Q.size>1048576)return console.warn("[mcp_config] ignoring ~/.claude/mcp.json: file exceeds the 1 MiB safety limit."),null;let z=JSON.parse(Ik(X,"utf8"));if(typeof z!=="object"||z===null||!("mcpServers"in z)||typeof z.mcpServers!=="object"||z.mcpServers===null||Array.isArray(z.mcpServers))return console.warn('[mcp_config] ignoring ~/.claude/mcp.json: Claude Code requires a top-level "mcpServers" object; update or remove the legacy/invalid file.'),null;return X}catch{return console.warn('[mcp_config] ignoring ~/.claude/mcp.json: Claude Code requires valid JSON with a top-level "mcpServers" object.'),null}}function Pk($){let Q=["--mcp-config",$O($)],z=w30();if(z!==null)Q.push(z);return Q}var D30;var XO=s(()=>{D30=["typescript-language-server","pylsp","gopls","rust-analyzer"]});import{existsSync as Sk,readFileSync as QO}from"fs";import{resolve as yk,dirname as P30}from"path";import{fileURLToPath as E30}from"url";import{createHash as x30}from"crypto";function L$($,X){let Q;switch($){case"planning":case"best":Q="xhigh";break;case"development":case"balanced":Q="high";break;case"fast":Q="medium";break;case"cheap":Q="low";break;default:Q="high";break}if((X??process.env.LOKI_COMPLEXITY??"standard")==="complex")switch(Q){case"low":Q="medium";break;case"medium":Q="high";break;case"high":Q="xhigh";break}return Q}function Ek(...$){return $.some((X)=>{let Q=process.env[X];return Q!==void 0&&Q!==""})}function zO($,X){if(process.env.LOKI_TIER_ROUTING!=="1")return X;let Q=process.env.LOKI_COMPLEXITY??"standard";switch($){case"planning":if(Q==="complex"&&!Ek("LOKI_CLAUDE_MODEL_PLANNING","LOKI_MODEL_PLANNING"))return"opus";return X;case"fast":if(Q==="simple"&&process.env.LOKI_ALLOW_HAIKU==="true"&&!Ek("LOKI_CLAUDE_MODEL_FAST","LOKI_MODEL_FAST"))return"haiku";return X;default:return X}}function ZO($){let X=process.env.LOKI_BUDGET_LIMIT;if(!X)return null;let Q=parseFloat(X);if(!Number.isFinite(Q)||Q<=0)return null;let z=$??process.env.TARGET_DIR??".",Z=yk(z,".loki","metrics","budget.json"),K=0;if(Sk(Z))try{let q=JSON.parse(QO(Z,"utf8")),V=q.budget_used??q.current_spend;if(typeof V==="number"&&Number.isFinite(V))K=V;else if(typeof V==="string"){let Y=parseFloat(V);if(Number.isFinite(Y))K=Y}}catch{K=0}let J=Q-K;if(J<=0)return null;return J.toFixed(2)}function KO($,X){if(!$)return null;let Q=X??process.env.LOKI_ALLOW_HAIKU==="true";switch($){case"opus":return"sonnet";case"sonnet":return Q?"haiku":null;default:return null}}function u1($,X){let Q=X??HY;if(Q===null||Q===void 0)return!1;return Q.includes($)}async function w6(){if(HY!==null)return;try{let $=Bun.spawn(["claude","--help"],{stdout:"pipe",stderr:"pipe"}),X=await new Response($.stdout).text();await $.exited,HY=X||""}catch{HY=""}}function bk($){let X=[];if(u1("--effort")){let Q=L$($.tier,$.complexity);X.push("--effort",Q)}if(u1("--max-budget-usd")){let Q=ZO($.targetDir);if(Q!==null)X.push("--max-budget-usd",Q)}if(u1("--fallback-model")){let Q=KO($.primary);if(Q!==null)X.push("--fallback-model",Q)}if((process.env.LOKI_DYNAMIC_PROMPT_SECTIONS??"auto")!=="keep"&&u1("--exclude-dynamic-system-prompt-sections"))X.push("--exclude-dynamic-system-prompt-sections");if(u1("--mcp-config"))try{let Q=$.targetDir??process.env.TARGET_DIR??".",z=Pk(Q);if(X.push(...z),process.env.LOKI_STRICT_MCP!=="0"&&z.length>0&&u1("--strict-mcp-config"))X.push("--strict-mcp-config")}catch(Q){console.warn(`[claude_flags] --mcp-config emit skipped: ${Q.message}`)}if(process.env.LOKI_HOOK_EVENTS!=="off"&&u1("--include-hook-events"))X.push("--include-hook-events");if(process.env.LOKI_AUTONOMY_OVERRIDE!=="off"&&u1("--append-system-prompt"))X.push("--append-system-prompt",JO());if(process.env.LOKI_NO_SESSION_PERSIST==="1"&&u1("--no-session-persistence"))X.push("--no-session-persistence");return X}function JO(){let $=Number.parseInt(process.env.ITERATION_COUNT??"1",10);return process.env.LOKI_FIRST_PASS_EXCELLENCE!=="0"&&(Number.isNaN($)||$<=1)?xk+S30:xk}function fk(){return process.env.LOKI_AUTONOMY_OVERRIDE!=="off"}function k30(){try{let $=P30(E30(import.meta.url));for(let X of[["..","..","..","references","design-archetypes.md"],["..","..","references","design-archetypes.md"]]){let Q=yk($,...X);if(Sk(Q))return QO(Q,"utf8")}}catch{}return""}function b30($){let X=y30.replace(/-/g,""),Q=Uint8Array.from(X.match(/.{2}/g).map((V)=>parseInt(V,16))),z=new TextEncoder().encode($),Z=new Uint8Array(Q.length+z.length);Z.set(Q,0),Z.set(z,Q.length);let J=Uint8Array.from(x30("sha1").update(Z).digest()).subarray(0,16);J[6]=J[6]&15|80,J[8]=J[8]&63|128;let q=Array.from(J).map((V)=>V.toString(16).padStart(2,"0")).join("");return`${q.slice(0,8)}-${q.slice(8,12)}-${q.slice(12,16)}-${q.slice(16,20)}-${q.slice(20)}`}function f30($,X){let Q=$??process.env.LOKI_TRUST_RUN_ID??"";if(!Q)return null;let z=X;if(z===void 0){let Z=parseInt(process.env.ITERATION_COUNT??"0",10);z=Number.isFinite(Z)?Z:0}return b30(`${Q}:${z}`)}function _30(){if(process.env.LOKI_SESSION_STAMP!=="1")return!1;return u1("--session-id")}function _k($,X){if(!_30())return[];let Q=f30($,X);return Q?["--session-id",Q]:[]}function h30(){if(process.env.LOKI_REVIEW_ALLOWLIST==="0")return!1;return u1("--allowedTools")}function qO(){if(!h30())return[];return["--allowedTools",v30]}function vk(){if(process.env.LOKI_RESUME_SESSION!=="1")return!1;return u1("--resume")}function g30(){if(process.env.LOKI_SESSION_FORK!=="1")return!1;if(!vk())return!1;return u1("--fork-session")}function m30($){let X=$??process.env.TARGET_DIR??".",z=`${process.env.LOKI_DIR??`${X}/.loki`}/state/claude-session.json`;try{let Z=QO(z,"utf8"),K=JSON.parse(Z);if(typeof K!=="object"||K===null)return null;let J=K.claude_session_uuid;if(typeof J==="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(J))return J;return null}catch{return null}}function hk($){if(!vk())return[];let X=m30($);if(!X)return[];let Q=["--resume",X];if(g30())Q.push("--fork-session");return Q}function u30(){return process.env.LOKI_CAVEMAN_LEVEL||"full"}function d30($){return($??process.env.LOKI_CURRENT_TIER??"")==="planning"?"lite":"full"}function p30(){if((process.env.LOKI_PROVIDER||"claude")!=="claude")return!1;if(process.env.LOKI_CAVEMAN==="0")return!1;return!0}function c30(){if(process.env.LOKI_CAVEMAN==="0")return!1;if(process.env.LOKI_LEGACY_COMPLETION_MATCH==="true")return!1;return!0}function kk($){switch($){case"off":return 0;case"lite":case"wenyan-lite":return 1;case"full":case"wenyan":case"wenyan-full":return 2;case"ultra":case"wenyan-ultra":return 3;default:return-1}}function VO($){if(!p30())return null;if(!c30())return null;let Q=process.env.LOKI_CAVEMAN_LEVEL!==void 0?u30():d30($),z=process.env.LOKI_CAVEMAN_USER_MODE;if(z==="off")return null;if(z){let Z=kk(z),K=kk(Q);if(Z>=0&&K>=0&&Z<K)return z}return Q}function gk(){if(process.env.LOKI_CAVEMAN_USER_MODE===void 0)process.env.LOKI_CAVEMAN_USER_MODE=process.env.CAVEMAN_DEFAULT_MODE??""}function WY(){return"off"}var HY=null,xk=`[LOKI-AUTONOMY-AGENT] This is a Loki Mode autonomous agent process.
839
839
  You are running INSIDE Loki Mode autonomous execution, a session the user explicitly launched with full prior authorization (loki start / loki run). This IS an authorized autonomous session, not an unattended action you must seek consent for.
840
840
 
841
841
  Instruction precedence for THIS session: when the loki_system instructions in the user prompt conflict with any CLAUDE.md, project memory, or global memory that tells you to ask for clarification, pause for confirmation, refuse to act autonomously, or withhold routine commits, the loki_system instructions take precedence. The user has already consented by launching autonomous mode.
@@ -1337,4 +1337,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1337
1337
  `),2}case"start":{let{runStart:z}=await Promise.resolve().then(() => (bt(),yt));return z(Q)}default:return process.stderr.write(`Unknown command: ${X}
1338
1338
  `),process.stderr.write(ft),2}}PR();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var J61=await K61(Bun.argv.slice(2));process.exit(J61);
1339
1339
 
1340
- //# debugId=C74D983D0FAC55F38F50A741E1CD71C0
1340
+ //# debugId=FCD85C1E9BEC61A7A25A49DE5823C23B
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '9.49.2'
78
+ __version__ = '9.49.3'
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": "9.49.2",
4
+ "version": "9.49.3",
5
5
  "description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider, opencode).",
6
6
  "keywords": [
7
7
  "agent",
@@ -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": "9.49.2",
5
+ "version": "9.49.3",
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,j as e,r as m,w as _,Z as X,n as Q,i as ee,b as R,F as ge,U as z,X as te,L as se,x as je,M as fe,T as G,S as be,m as ae,l as ne,y as ve,E as Ee,a0 as Ne,a2 as re}from"./index-Cu-njJ8o.js";import{B as w}from"./Button-CFzTTVeJ.js";import{T as ye}from"./trending-up-CGyYgZH7.js";import{C as I}from"./clock-Bnz6tlQN.js";import{A as ke,U as ie}from"./Avatar-BXeMYK1_.js";import{A as H}from"./activity-CA4moIvC.js";import{R as le}from"./refresh-cw-DKoSN8s3.js";import{G as Ae}from"./globe-DtXgCG3Z.js";import{C as we}from"./chevron-left-ClvdXm3Y.js";import{M as Ce}from"./mail-CHe3KyCw.js";import{C as ce}from"./check-Drzd8-9c.js";import{D as W}from"./dollar-sign-D6RFNgdZ.js";import{U as Se}from"./user-WCGccIST.js";import{D as De}from"./database-CHclPjog.js";import{L as Fe}from"./lock-qRAVU53b.js";import{H as Me}from"./hammer-DCa0I_7V.js";import{S as Be}from"./shield-alert-PsDkSyFD.js";import{S as $e}from"./server-D_VRDkaD.js";/**
1
+ import{c as L,j as e,r as m,w as _,Z as X,n as Q,i as ee,b as R,F as ge,U as z,X as te,L as se,x as je,M as fe,T as G,S as be,m as ae,l as ne,y as ve,E as Ee,a0 as Ne,a2 as re}from"./index-x0TESFYr.js";import{B as w}from"./Button-BamXbIWa.js";import{T as ye}from"./trending-up-CXx0ywZb.js";import{C as I}from"./clock-DN8LAN-0.js";import{A as ke,U as ie}from"./Avatar-CAtbcD23.js";import{A as H}from"./activity-CySdOdDP.js";import{R as le}from"./refresh-cw-ygYTmZTE.js";import{G as Ae}from"./globe-BV-hx0u_.js";import{C as we}from"./chevron-left-CrVUY29C.js";import{M as Ce}from"./mail-DaLiNrPb.js";import{C as ce}from"./check-BAgbzVrK.js";import{D as W}from"./dollar-sign--WOh4k_m.js";import{U as Se}from"./user-DUUYT47B.js";import{D as De}from"./database-BYqcS6kn.js";import{L as Fe}from"./lock-BUTRYdDQ.js";import{H as Me}from"./hammer-DhmP4GLw.js";import{S as Be}from"./shield-alert-DYzfVqWS.js";import{S as $e}from"./server-BapOz_vf.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 h,j as s}from"./index-Cu-njJ8o.js";/**
1
+ import{c as h,j as s}from"./index-x0TESFYr.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-Cu-njJ8o.js";import{C as r}from"./clock-Bnz6tlQN.js";import{C as a}from"./circle-alert-CstyZfKG.js";import{C as l}from"./check-Drzd8-9c.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-x0TESFYr.js";import{C as r}from"./clock-DN8LAN-0.js";import{C as a}from"./circle-alert-YrWgH49w.js";import{C as l}from"./check-BAgbzVrK.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-Cu-njJ8o.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-x0TESFYr.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 i,j as e,G as fe,Q as ge,F as be,i as ke,T as G,Z as ve,a as j,S as ye,V as je,X as Ne,P as ae,k as we,h as Se,m as Ce,Y as Re,N as I,J as Me,K as Te,O as $e,u as Ee}from"./index-Cu-njJ8o.js";import{P as K,S as Pe,E as Ae}from"./ErrorBoundary-wE3oxaG6.js";import{C as ze,F as Ie,H as _e,a as De,G as Fe,T as Le}from"./thumbs-up-Da1QQhqo.js";import{C as re}from"./check-Drzd8-9c.js";import{C as Oe}from"./clock-Bnz6tlQN.js";import{D as He}from"./dollar-sign-D6RFNgdZ.js";import{M as Be}from"./minus-B8p0FoYZ.js";import{U as qe}from"./upload-KkeVyg67.js";import{L as W}from"./loader-circle-DXgc_u5I.js";/**
1
+ import{c as $,r as i,j as e,G as fe,Q as ge,F as be,i as ke,T as G,Z as ve,a as j,S as ye,V as je,X as Ne,P as ae,k as we,h as Se,m as Ce,Y as Re,N as I,J as Me,K as Te,O as $e,u as Ee}from"./index-x0TESFYr.js";import{P as K,S as Pe,E as Ae}from"./ErrorBoundary-BjX4_KOW.js";import{C as ze,F as Ie,H as _e,a as De,G as Fe,T as Le}from"./thumbs-up-DxOTplej.js";import{C as re}from"./check-BAgbzVrK.js";import{C as Oe}from"./clock-DN8LAN-0.js";import{D as He}from"./dollar-sign--WOh4k_m.js";import{M as Be}from"./minus-DB_hlGEk.js";import{U as qe}from"./upload-CpEO3qNc.js";import{L as W}from"./loader-circle-B7KiGAVU.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 i,j as e}from"./index-Cu-njJ8o.js";function p({value:r,prefix:t="",suffix:s=""}){const[n,a]=i.useState(0),o=i.useRef(0);return i.useEffect(()=>{const c=o.current,d=r-c;if(d===0)return;const x=600,h=performance.now();function u(l){const b=l-h,f=Math.min(b/x,1),g=1-Math.pow(1-f,3),j=Math.round(c+d*g);a(j),o.current=j,f<1&&requestAnimationFrame(u)}requestAnimationFrame(u)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,n.toLocaleString(),s]})}function N(){const[r,t]=i.useState(5),[s,n]=i.useState(30),[a,o]=i.useState(75),x=Math.round(r*s*.4*4.33),h=Math.round(x*a),u=1/0;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=>n(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:["$",a,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:a,onChange:l=>o(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-3 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(p,{value:x,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(p,{value:h,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Cost saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#36342E]",children:u===1/0?"Free":e.jsx(p,{value:u,suffix:"%"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"ROI (self-hosted)"})]})]}),e.jsx("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:["With Loki Mode, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[x.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",h.toLocaleString()]})," ","per month."]})})]})]})}function y({count:r=5}){return e.jsx("div",{className:"flex gap-0.5",children:Array.from({length:r}).map((t,s)=>e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"#553DE9",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"})},s))})}function w(){return e.jsx("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:"text-[#553DE9]/15",children:e.jsx("path",{d:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zm12 0c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",fill:"currentColor"})})}function k({quote:r,name:t,role:s,company:n,avatar:a,rating:o=5}){const c=t.split(" ").map(d=>d[0]).join("").toUpperCase().slice(0,2);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 flex flex-col gap-4 shadow-sm hover:shadow-md transition-shadow",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(w,{}),e.jsx(y,{count:o})]}),e.jsxs("p",{className:"text-[#36342E] text-sm leading-relaxed flex-1",children:['"',r,'"']}),e.jsxs("div",{className:"flex items-center gap-3 pt-2 border-t border-[#ECEAE3]",children:[a?e.jsx("img",{src:a,alt:"",className:"w-10 h-10 rounded-full object-cover"}):e.jsx("div",{className:"w-10 h-10 rounded-full bg-gradient-to-br from-[#553DE9] to-[#7B6BEF] flex items-center justify-center text-white text-sm font-bold flex-shrink-0",children:c}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold text-[#36342E]",children:t}),e.jsxs("p",{className:"text-xs text-[#6B6960]",children:[s,", ",n]})]})]})]})}const E=[{quote:"Loki Mode turned a weekend project into a production app in 45 minutes. The RARV cycle caught bugs I would have shipped. Easily 10x faster than writing everything by hand.",name:"Sarah Chen",role:"Full-Stack Developer",company:"Nimbus Labs"},{quote:"The quality gates are what sold me. Three blind reviewers, anti-sycophancy checks, severity blocking -- it catches issues that even our senior engineers miss in code review.",name:"Marcus Rivera",role:"CTO",company:"Forgepoint Systems"},{quote:"As a solo founder, Loki Mode is like having a senior engineering team on demand. I shipped our MVP in a day instead of two weeks. The autonomous iteration is the real game changer.",name:"Priya Sharma",role:"Founder",company:"Seedcraft"},{quote:"Self-hosted, no data leaves our network, and the multi-provider failover means we never hit rate limits. Exactly what our compliance team needed. Enterprise-ready out of the box.",name:"Daniel Okafor",role:"DevOps Lead",company:"Vaultline Security"}],v=[{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:"Gemini",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"9 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 C(){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 M(){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 m({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(C,{}):e.jsx(M,{})}const A=[{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:"9 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 S(){const r=[...new Set(v.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}`),v.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(m,{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(m,{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(m,{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(m,{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:A.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.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"What developers are saying"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:E.map(t=>e.jsx(k,{...t},t.name))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(N,{})})]})})}export{S as default};
1
+ import{r as i,j as e}from"./index-x0TESFYr.js";function p({value:r,prefix:t="",suffix:s=""}){const[n,a]=i.useState(0),o=i.useRef(0);return i.useEffect(()=>{const c=o.current,d=r-c;if(d===0)return;const x=600,h=performance.now();function u(l){const b=l-h,f=Math.min(b/x,1),g=1-Math.pow(1-f,3),j=Math.round(c+d*g);a(j),o.current=j,f<1&&requestAnimationFrame(u)}requestAnimationFrame(u)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,n.toLocaleString(),s]})}function N(){const[r,t]=i.useState(5),[s,n]=i.useState(30),[a,o]=i.useState(75),x=Math.round(r*s*.4*4.33),h=Math.round(x*a),u=1/0;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=>n(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:["$",a,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:a,onChange:l=>o(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-3 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(p,{value:x,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(p,{value:h,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Cost saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#36342E]",children:u===1/0?"Free":e.jsx(p,{value:u,suffix:"%"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"ROI (self-hosted)"})]})]}),e.jsx("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:["With Loki Mode, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[x.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",h.toLocaleString()]})," ","per month."]})})]})]})}function y({count:r=5}){return e.jsx("div",{className:"flex gap-0.5",children:Array.from({length:r}).map((t,s)=>e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"#553DE9",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"})},s))})}function w(){return e.jsx("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:"text-[#553DE9]/15",children:e.jsx("path",{d:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zm12 0c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",fill:"currentColor"})})}function k({quote:r,name:t,role:s,company:n,avatar:a,rating:o=5}){const c=t.split(" ").map(d=>d[0]).join("").toUpperCase().slice(0,2);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 flex flex-col gap-4 shadow-sm hover:shadow-md transition-shadow",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(w,{}),e.jsx(y,{count:o})]}),e.jsxs("p",{className:"text-[#36342E] text-sm leading-relaxed flex-1",children:['"',r,'"']}),e.jsxs("div",{className:"flex items-center gap-3 pt-2 border-t border-[#ECEAE3]",children:[a?e.jsx("img",{src:a,alt:"",className:"w-10 h-10 rounded-full object-cover"}):e.jsx("div",{className:"w-10 h-10 rounded-full bg-gradient-to-br from-[#553DE9] to-[#7B6BEF] flex items-center justify-center text-white text-sm font-bold flex-shrink-0",children:c}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold text-[#36342E]",children:t}),e.jsxs("p",{className:"text-xs text-[#6B6960]",children:[s,", ",n]})]})]})]})}const E=[{quote:"Loki Mode turned a weekend project into a production app in 45 minutes. The RARV cycle caught bugs I would have shipped. Easily 10x faster than writing everything by hand.",name:"Sarah Chen",role:"Full-Stack Developer",company:"Nimbus Labs"},{quote:"The quality gates are what sold me. Three blind reviewers, anti-sycophancy checks, severity blocking -- it catches issues that even our senior engineers miss in code review.",name:"Marcus Rivera",role:"CTO",company:"Forgepoint Systems"},{quote:"As a solo founder, Loki Mode is like having a senior engineering team on demand. I shipped our MVP in a day instead of two weeks. The autonomous iteration is the real game changer.",name:"Priya Sharma",role:"Founder",company:"Seedcraft"},{quote:"Self-hosted, no data leaves our network, and the multi-provider failover means we never hit rate limits. Exactly what our compliance team needed. Enterprise-ready out of the box.",name:"Daniel Okafor",role:"DevOps Lead",company:"Vaultline Security"}],v=[{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:"Gemini",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"9 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 C(){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 M(){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 m({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(C,{}):e.jsx(M,{})}const A=[{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:"9 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 S(){const r=[...new Set(v.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}`),v.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(m,{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(m,{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(m,{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(m,{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:A.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.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"What developers are saying"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:E.map(t=>e.jsx(k,{...t},t.name))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(N,{})})]})})}export{S as default};
@@ -1,4 +1,4 @@
1
- import{c as o,r as a,j as e,T as n,i,b as c}from"./index-Cu-njJ8o.js";/**
1
+ import{c as o,r as a,j as e,T as n,i,b as c}from"./index-x0TESFYr.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 d,a as x,j as e}from"./index-Cu-njJ8o.js";const j={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"These receipt bytes are unaltered, and they were signed by the holder of the signing key.",notProven:"That the code is correct. 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 receipt is internally consistent with its own integrity hash.",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 integrity hash matches, so nothing is wrong with the contents.",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 recorded hash does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."}};function w(t){const n=t==null?void 0:t.verification;return!n||!n.hash?"unsigned":n.attestation||n.gpg_signature?"unchecked":"unsigned"}const b=[{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 N({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:b.map(({key:a,bar:s})=>{const i=t[a];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${a}`},a):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:b.map(({key:a,label:s,text:i})=>{const l=t[a];return l?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:l})," ",s.toLowerCase()]},a):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function o({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 y({proof:t}){var m,p,g,f;const[n,a]=d.useState(!1),[s,i]=d.useState(null),[l,c]=d.useState(null);d.useEffect(()=>{if(!n||s||l)return;let h=!1;return x.getProof(t.run_id).then(u=>{h||i(u)}).catch(u=>{h||c((u==null?void 0:u.message)||"could not load this receipt")}),()=>{h=!0}},[n,t.run_id,s,l]);const r=j[w(s)],v=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?r.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:()=>a(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?r.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline||t.run_id}),t.final_verdict&&e.jsx("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children: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:[l&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",l]}),!l&&!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(o,{label:"Run",value:s.run_id}),e.jsx(o,{label:"Generated",value:v}),e.jsx(o,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(o,{label:"Cost",value:typeof s.cost_usd=="number"?`$${s.cost_usd.toFixed(2)}`:"unknown"}),e.jsx(o,{label:"Files changed",value:typeof s.files_changed=="number"?String(s.files_changed):"unknown"}),((m=s.verification)==null?void 0:m.hash)&&e.jsx(o,{label:"Integrity hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${r.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:r.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),r.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),r.notProven]})]}),(((p=s.verification)==null?void 0:p.attestation)||((g=s.verification)==null?void 0:g.gpg_signature))&&e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself:"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(f=s.verification)!=null&&f.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 _(){const[t,n]=d.useState(null),[a,s]=d.useState(null),[i,l]=d.useState(null);return d.useEffect(()=>{let c=!1;return x.listProofs().then(r=>{c||n(r.proofs||[])}).catch(r=>{c||l((r==null?void 0:r.message)||"could not load receipts")}),x.proofsSummary().then(r=>{c||s(r)}).catch(()=>{}),()=>{c=!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…"}),a&&e.jsx(N,{summary:a}),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(c=>e.jsx(y,{proof:c},c.run_id))})]})}export{_ as E};
1
+ import{r as d,a as x,j as e}from"./index-x0TESFYr.js";const j={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"These receipt bytes are unaltered, and they were signed by the holder of the signing key.",notProven:"That the code is correct. 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 receipt is internally consistent with its own integrity hash.",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 integrity hash matches, so nothing is wrong with the contents.",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 recorded hash does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."}};function w(t){const n=t==null?void 0:t.verification;return!n||!n.hash?"unsigned":n.attestation||n.gpg_signature?"unchecked":"unsigned"}const b=[{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 N({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:b.map(({key:a,bar:s})=>{const i=t[a];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${a}`},a):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:b.map(({key:a,label:s,text:i})=>{const l=t[a];return l?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:l})," ",s.toLowerCase()]},a):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function o({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 y({proof:t}){var m,p,g,f;const[n,a]=d.useState(!1),[s,i]=d.useState(null),[l,c]=d.useState(null);d.useEffect(()=>{if(!n||s||l)return;let h=!1;return x.getProof(t.run_id).then(u=>{h||i(u)}).catch(u=>{h||c((u==null?void 0:u.message)||"could not load this receipt")}),()=>{h=!0}},[n,t.run_id,s,l]);const r=j[w(s)],v=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?r.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:()=>a(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?r.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline||t.run_id}),t.final_verdict&&e.jsx("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children: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:[l&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",l]}),!l&&!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(o,{label:"Run",value:s.run_id}),e.jsx(o,{label:"Generated",value:v}),e.jsx(o,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(o,{label:"Cost",value:typeof s.cost_usd=="number"?`$${s.cost_usd.toFixed(2)}`:"unknown"}),e.jsx(o,{label:"Files changed",value:typeof s.files_changed=="number"?String(s.files_changed):"unknown"}),((m=s.verification)==null?void 0:m.hash)&&e.jsx(o,{label:"Integrity hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${r.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:r.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),r.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),r.notProven]})]}),(((p=s.verification)==null?void 0:p.attestation)||((g=s.verification)==null?void 0:g.gpg_signature))&&e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself:"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(f=s.verification)!=null&&f.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 _(){const[t,n]=d.useState(null),[a,s]=d.useState(null),[i,l]=d.useState(null);return d.useEffect(()=>{let c=!1;return x.listProofs().then(r=>{c||n(r.proofs||[])}).catch(r=>{c||l((r==null?void 0:r.message)||"could not load receipts")}),x.proofsSummary().then(r=>{c||s(r)}).catch(()=>{}),()=>{c=!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…"}),a&&e.jsx(N,{summary:a}),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(c=>e.jsx(y,{proof:c},c.run_id))})]})}export{_ as E};
@@ -1,4 +1,4 @@
1
- import{c as M,r as o,a as C,j as e,n as P,J as w,N as f,a5 as B,M as R,m as A,E as H}from"./index-Cu-njJ8o.js";import{B as v}from"./Button-CFzTTVeJ.js";import{C as k,G as q}from"./thumbs-up-Da1QQhqo.js";import{R as F}from"./refresh-cw-DKoSN8s3.js";import{C as S}from"./circle-alert-CstyZfKG.js";import{U as D}from"./user-WCGccIST.js";import{R as T}from"./rotate-ccw-Nf8zB8G0.js";import{L as U}from"./loader-circle-DXgc_u5I.js";/**
1
+ import{c as M,r as o,a as C,j as e,n as P,J as w,N as f,a5 as B,M as R,m as A,E as H}from"./index-x0TESFYr.js";import{B as v}from"./Button-BamXbIWa.js";import{C as k,G as q}from"./thumbs-up-DxOTplej.js";import{R as F}from"./refresh-cw-ygYTmZTE.js";import{C as S}from"./circle-alert-YrWgH49w.js";import{U as D}from"./user-DUUYT47B.js";import{R as T}from"./rotate-ccw-Ba3QxM9K.js";import{L as U}from"./loader-circle-B7KiGAVU.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 o,a as b,j as e,G as xe,A as me,S as Z,l as ee,n as ue,i as pe,b as he,X as te,M as fe}from"./index-Cu-njJ8o.js";import{B as y}from"./Button-CFzTTVeJ.js";import{C as be}from"./chevron-left-ClvdXm3Y.js";import{G as P}from"./thumbs-up-Da1QQhqo.js";import{R as L}from"./refresh-cw-DKoSN8s3.js";import{C as ge}from"./circle-alert-CstyZfKG.js";import{L as V,S as Ne}from"./ProjectPage-D2Fh6tVw.js";import{S as se}from"./shield-alert-PsDkSyFD.js";import{F as je}from"./file-code-corner-CNayCvOY.js";import{C as H}from"./clock-Bnz6tlQN.js";import{C as re}from"./check-Drzd8-9c.js";import"./ErrorBoundary-wE3oxaG6.js";import"./TerminalOutput-CJy13rAn.js";import"./lock-qRAVU53b.js";import"./package-C5LDn8SI.js";import"./file-plus-BmVfFwsX.js";import"./activity-CA4moIvC.js";import"./bot-Cu4UwP5w.js";import"./loader-circle-DXgc_u5I.js";import"./hammer-DCa0I_7V.js";import"./dollar-sign-D6RFNgdZ.js";import"./globe-DtXgCG3Z.js";import"./folder-open-ChzGfLRr.js";import"./upload-KkeVyg67.js";import"./plus-CRd_FHOA.js";import"./trash-2-ChoylpGQ.js";import"./rotate-ccw-Nf8zB8G0.js";import"./minus-B8p0FoYZ.js";import"./save-B8ytQLgW.js";import"./code-xml-BOZbQiOt.js";import"./trending-up-CGyYgZH7.js";import"./layers-DxIhn7NZ.js";import"./trending-down-CX2fUeho.js";import"./server-D_VRDkaD.js";/**
1
+ import{c as I,r as o,a as b,j as e,G as xe,A as me,S as Z,l as ee,n as ue,i as pe,b as he,X as te,M as fe}from"./index-x0TESFYr.js";import{B as y}from"./Button-BamXbIWa.js";import{C as be}from"./chevron-left-CrVUY29C.js";import{G as P}from"./thumbs-up-DxOTplej.js";import{R as L}from"./refresh-cw-ygYTmZTE.js";import{C as ge}from"./circle-alert-YrWgH49w.js";import{L as V,S as Ne}from"./ProjectPage-CLplvOHe.js";import{S as se}from"./shield-alert-DYzfVqWS.js";import{F as je}from"./file-code-corner-B0rLPjW1.js";import{C as H}from"./clock-DN8LAN-0.js";import{C as re}from"./check-BAgbzVrK.js";import"./ErrorBoundary-BjX4_KOW.js";import"./TerminalOutput-CeTvKnkl.js";import"./lock-BUTRYdDQ.js";import"./package-CymmXoiQ.js";import"./file-plus-BNhUQ1TQ.js";import"./activity-CySdOdDP.js";import"./bot-BaB4q_4m.js";import"./loader-circle-B7KiGAVU.js";import"./hammer-DhmP4GLw.js";import"./dollar-sign--WOh4k_m.js";import"./globe-BV-hx0u_.js";import"./folder-open-DliiOgFl.js";import"./upload-CpEO3qNc.js";import"./plus-Cp4AO4I2.js";import"./trash-2-Br8dh_6B.js";import"./rotate-ccw-Ba3QxM9K.js";import"./minus-DB_hlGEk.js";import"./save-DPm96BnR.js";import"./code-xml-xBWyKfux.js";import"./trending-up-CXx0ywZb.js";import"./layers-DXWDMSYj.js";import"./trending-down-CxSP6MU3.js";import"./server-BapOz_vf.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 he,j as e,P as We,r as n,a as j,C as Ue,M as fe,R as re,u as ae,b as Ve,A as Qe,S as Ye,d as Ke,U as Ze,e as Je}from"./index-Cu-njJ8o.js";import{u as R}from"./usePolling-C5f4xrXD.js";import{P as Xe,S as et,E as C}from"./ErrorBoundary-wE3oxaG6.js";import{F as tt,T as st}from"./TerminalOutput-CJy13rAn.js";import{E as rt}from"./EvidenceReceiptPanel-B_Wouz6N.js";import{B as at}from"./Badge-D8WddQk1.js";import{P as nt}from"./package-C5LDn8SI.js";import{C as it}from"./cloud-IPIgE4P3.js";import{C as be}from"./code-xml-BOZbQiOt.js";import{H as lt}from"./hammer-DCa0I_7V.js";import{C as ot}from"./chevron-left-ClvdXm3Y.js";import{L as ct}from"./layers-DxIhn7NZ.js";import{C as dt}from"./check-Drzd8-9c.js";import{M as mt}from"./mail-CHe3KyCw.js";import{B as xt}from"./bell-JyOeobLN.js";import{F as ut}from"./file-code-corner-CNayCvOY.js";import"./lock-qRAVU53b.js";import"./clock-Bnz6tlQN.js";import"./circle-alert-CstyZfKG.js";/**
1
+ import{c as he,j as e,P as We,r as n,a as j,C as Ue,M as fe,R as re,u as ae,b as Ve,A as Qe,S as Ye,d as Ke,U as Ze,e as Je}from"./index-x0TESFYr.js";import{u as R}from"./usePolling-BuzXwjmC.js";import{P as Xe,S as et,E as C}from"./ErrorBoundary-BjX4_KOW.js";import{F as tt,T as st}from"./TerminalOutput-CeTvKnkl.js";import{E as rt}from"./EvidenceReceiptPanel-Bq6pmNUw.js";import{B as at}from"./Badge-sb_JbKl0.js";import{P as nt}from"./package-CymmXoiQ.js";import{C as it}from"./cloud-D6C4b1KY.js";import{C as be}from"./code-xml-xBWyKfux.js";import{H as lt}from"./hammer-DhmP4GLw.js";import{C as ot}from"./chevron-left-CrVUY29C.js";import{L as ct}from"./layers-DXWDMSYj.js";import{C as dt}from"./check-BAgbzVrK.js";import{M as mt}from"./mail-DaLiNrPb.js";import{B as xt}from"./bell-BHdr5yat.js";import{F as ut}from"./file-code-corner-B0rLPjW1.js";import"./lock-BUTRYdDQ.js";import"./clock-DN8LAN-0.js";import"./circle-alert-YrWgH49w.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.