loki-mode 10.5.22 → 10.5.24

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 (72) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/dashboard/__init__.py +1 -1
  4. package/docs/INSTALLATION.md +1 -1
  5. package/docs/enterprise/integration-cookbook.md +4 -7
  6. package/docs/enterprise/migration.md +1 -0
  7. package/docs/v10/BOARD.md +10 -6
  8. package/docs/v10/FOUNDER-QUEUE.md +1 -0
  9. package/docs/v10/GUARDS.md +22 -0
  10. package/docs/v10/PROGRESS.md +29 -1
  11. package/loki-ts/dist/loki.js +2 -2
  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/src/integrations/sync-subscriber.js +7 -2
  16. package/web-app/dist/assets/{AdminPage-D8w0ab3X.js → AdminPage-C1qX6Aj-.js} +1 -1
  17. package/web-app/dist/assets/{Avatar-DdlzHGiT.js → Avatar-CPKsZYTu.js} +1 -1
  18. package/web-app/dist/assets/{Badge-CsOY5IHf.js → Badge-C7MnPRej.js} +1 -1
  19. package/web-app/dist/assets/{Button-OEb0K5fU.js → Button-B1u8l20V.js} +1 -1
  20. package/web-app/dist/assets/{CockpitPage-P1_J2yY7.js → CockpitPage-CBvW9cvQ.js} +1 -1
  21. package/web-app/dist/assets/{ComparePage-Dz0OF3rY.js → ComparePage-BymGvr_b.js} +1 -1
  22. package/web-app/dist/assets/{ErrorBoundary-BG1SdbI9.js → ErrorBoundary-DMvaiN2_.js} +1 -1
  23. package/web-app/dist/assets/{EvidenceReceiptPanel-qXiSbX0T.js → EvidenceReceiptPanel-Dt7XbGbK.js} +1 -1
  24. package/web-app/dist/assets/{GitHubIssuesPanel-kZVIqzjB.js → GitHubIssuesPanel-D_uQgusi.js} +1 -1
  25. package/web-app/dist/assets/{GitHubPRsPanel-A0svwIEt.js → GitHubPRsPanel-F-J3qQ34.js} +1 -1
  26. package/web-app/dist/assets/{HomePage-BTxHfUUb.js → HomePage-BEnIeTKw.js} +2 -2
  27. package/web-app/dist/assets/{LoginPage-BWWcRTXF.js → LoginPage-DARBOPra.js} +1 -1
  28. package/web-app/dist/assets/{MagicPage-CKNpFDUR.js → MagicPage-CGh4tmzh.js} +1 -1
  29. package/web-app/dist/assets/{MetricsPage-DE7UEUGs.js → MetricsPage-Dlz2VzRy.js} +1 -1
  30. package/web-app/dist/assets/{NotFoundPage-CKIOD5Ys.js → NotFoundPage-Di51TJZs.js} +1 -1
  31. package/web-app/dist/assets/{ProjectPage-BDryei4O.js → ProjectPage-D7_H_qgT.js} +3 -3
  32. package/web-app/dist/assets/{ProjectsPage-D4JoaMkL.js → ProjectsPage-BcNGDjve.js} +1 -1
  33. package/web-app/dist/assets/{SettingsPage-BQYk2vHL.js → SettingsPage-Bz6BBBXL.js} +1 -1
  34. package/web-app/dist/assets/{ShowcasePage-CXRhoXei.js → ShowcasePage-BKJaSExm.js} +1 -1
  35. package/web-app/dist/assets/{SystemSettingsPage-dapwsrQo.js → SystemSettingsPage-BkGKzto3.js} +1 -1
  36. package/web-app/dist/assets/{TeamsPage-Co5_ARDw.js → TeamsPage-Bdn33jjm.js} +1 -1
  37. package/web-app/dist/assets/{TemplatesPage-CnCLNDS8.js → TemplatesPage-Bl5b9d-C.js} +1 -1
  38. package/web-app/dist/assets/{TerminalOutput-BZxTHYwT.js → TerminalOutput-jOfxyPFJ.js} +1 -1
  39. package/web-app/dist/assets/{activity-B43aIno-.js → activity-CKvd8U1b.js} +1 -1
  40. package/web-app/dist/assets/{bell-DMzWO8la.js → bell-B7ZVJqrp.js} +1 -1
  41. package/web-app/dist/assets/{bot-B8WyaOPt.js → bot-C_jRLKqH.js} +1 -1
  42. package/web-app/dist/assets/{check-DfMG8EL7.js → check-B-xfD1pQ.js} +1 -1
  43. package/web-app/dist/assets/{chevron-left-DqQV0gcd.js → chevron-left-d1OZMSD2.js} +1 -1
  44. package/web-app/dist/assets/{circle-alert-7GFVd60S.js → circle-alert-BDPtB3PN.js} +1 -1
  45. package/web-app/dist/assets/{clock-BDKw1_R8.js → clock-Cq-zj0ZJ.js} +1 -1
  46. package/web-app/dist/assets/{cloud-D3s4vkR1.js → cloud-CyblNtCQ.js} +1 -1
  47. package/web-app/dist/assets/{code-xml-V_GOUJ82.js → code-xml-BadEEBt6.js} +1 -1
  48. package/web-app/dist/assets/{database-B9oHux-i.js → database-hJAIBBOu.js} +1 -1
  49. package/web-app/dist/assets/{dollar-sign-C2JeiZKd.js → dollar-sign-NAaKHtUp.js} +1 -1
  50. package/web-app/dist/assets/{file-code-corner-CkqFpKah.js → file-code-corner-D7XBEpP-.js} +1 -1
  51. package/web-app/dist/assets/{file-plus-DbNKpj5U.js → file-plus-KZyMeKo5.js} +1 -1
  52. package/web-app/dist/assets/{globe-NgUZ94HR.js → globe-CVl8_kt5.js} +1 -1
  53. package/web-app/dist/assets/{hammer-BMDwR3rq.js → hammer-NhQB95s9.js} +1 -1
  54. package/web-app/dist/assets/{index-DqLaggNg.js → index-r93xpUon.js} +3 -3
  55. package/web-app/dist/assets/{layers-JrA9gfn-.js → layers-N-hCKTPD.js} +1 -1
  56. package/web-app/dist/assets/{loader-circle-D3Re-zBz.js → loader-circle-BkL9W5Mv.js} +1 -1
  57. package/web-app/dist/assets/{lock-Dzt5MqiP.js → lock-BxBPSPk_.js} +1 -1
  58. package/web-app/dist/assets/{package-dKDrYcHV.js → package-BO4fpgTO.js} +1 -1
  59. package/web-app/dist/assets/{plus-P6H35lZz.js → plus-CQZ1XzjX.js} +1 -1
  60. package/web-app/dist/assets/{refresh-cw-DpmPbMhN.js → refresh-cw-CWDIiQWB.js} +1 -1
  61. package/web-app/dist/assets/{rotate-ccw-DdkhV-ED.js → rotate-ccw-BgVXIVTU.js} +1 -1
  62. package/web-app/dist/assets/{scroll-text-C7dHDNJR.js → scroll-text-ghD5rTL5.js} +1 -1
  63. package/web-app/dist/assets/{server-D7SziIKB.js → server-kP2j3KGS.js} +1 -1
  64. package/web-app/dist/assets/{shield-alert-B86sjYoT.js → shield-alert-qDqPANTP.js} +1 -1
  65. package/web-app/dist/assets/{thumbs-up-C5Y3O7Ik.js → thumbs-up-MLrmE9p8.js} +1 -1
  66. package/web-app/dist/assets/{trash-2-ByEJRbuH.js → trash-2-7s8w8-_n.js} +1 -1
  67. package/web-app/dist/assets/{trending-down-Dc44T-Va.js → trending-down-fhZdmlgX.js} +1 -1
  68. package/web-app/dist/assets/{trending-up-DwB8jgl2.js → trending-up-Cm4s3m48.js} +1 -1
  69. package/web-app/dist/assets/{upload-DyaOVrs9.js → upload-DjdbK3Je.js} +1 -1
  70. package/web-app/dist/assets/{usePolling-B4pACToJ.js → usePolling-Dvpf8Bxp.js} +1 -1
  71. package/web-app/dist/assets/{user-BgUGFZBV.js → user-Be2fDa0U.js} +1 -1
  72. package/web-app/dist/index.html +1 -1
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v10.5.22
6
+ # Loki Mode v10.5.24
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
- **v10.5.22 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
473
+ **v10.5.24 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 10.5.22
1
+ 10.5.24
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "10.5.22"
10
+ __version__ = "10.5.24"
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:** v10.5.22
5
+ **Version:** v10.5.24
6
6
 
7
7
  ---
8
8
 
@@ -173,16 +173,12 @@ curl -X POST "$LOKI_TEAMS_WEBHOOK_URL" \
173
173
  | Variable | Required | Description |
174
174
  |----------|----------|-------------|
175
175
  | `LOKI_JIRA_URL` | Yes | Jira Cloud base URL |
176
+ | `LOKI_JIRA_EMAIL` | Yes | Email of the Jira user that owns the API token |
176
177
  | `LOKI_JIRA_TOKEN` | Yes | Jira API token |
177
178
  | `LOKI_JIRA_EPIC_KEY` | No | Epic that run events are synced to |
178
179
 
179
- These are read by `src/integrations/sync-subscriber.js`. The Jira user email is
180
- passed to `JiraApiClient` in code (see below); no environment variable carries it.
181
-
182
- Known issue on main: `src/integrations/sync-subscriber.js` constructs `JiraApiClient`
183
- without the `email` and `apiToken` it requires, so Jira auto-sync from these
184
- variables does not start. Construct `JiraApiClient({ baseUrl, email, apiToken })`
185
- in code until that is fixed.
180
+ These are read by `src/integrations/sync-subscriber.js`. If only some of the
181
+ three required variables are set, it logs one line naming the missing ones.
186
182
 
187
183
  ### Configuration
188
184
 
@@ -194,6 +190,7 @@ in code until that is fixed.
194
190
 
195
191
  ```bash
196
192
  export LOKI_JIRA_URL="https://company.atlassian.net"
193
+ export LOKI_JIRA_EMAIL="user@company.com"
197
194
  export LOKI_JIRA_TOKEN="your-api-token"
198
195
  ```
199
196
 
@@ -98,6 +98,7 @@ These variables from v5.50.0 continue to work identically:
98
98
  | `LOKI_TLS_CERT` | (unset) | TLS certificate path |
99
99
  | `LOKI_TLS_KEY` | (unset) | TLS key path |
100
100
  | `LOKI_JIRA_URL` | (unset) | Jira Cloud base URL |
101
+ | `LOKI_JIRA_EMAIL` | (unset) | Jira user email for the API token |
101
102
  | `LOKI_JIRA_TOKEN` | (unset) | Jira API token |
102
103
  | `LOKI_JIRA_EPIC_KEY` | (unset) | Jira epic that run events sync to |
103
104
  | `LOKI_LINEAR_TOKEN` | (unset) | Linear API key |
package/docs/v10/BOARD.md CHANGED
@@ -459,14 +459,14 @@ set is declared to avoid overlap with those and with each other.
459
459
  | E-129 | BACKLOG 117 remainder: WhatsNew.tsx hardcodes a stale CURRENT_VERSION (9.55.0) that drifts from the shipped release | web-app/src/components/WhatsNew.tsx, tests/test-whatsnew-version-sync.sh | LOW | bash tests/test-whatsnew-version-sync.sh | released@2026-09-30T18:50Z | Source: BACKLOG 117. Evidence: WhatsNew.tsx:5 against VERSION 10.5.3. Released in v10.5.7 (merge 0c9daffc is an ancestor of v10.5.7). |
460
460
  | E-130 | D41 item 4 (speed): cache dependency install by lockfile hash in the bash parallel-worktree bootstrap | autonomy/run.sh (create_worktree only), tests/test-worktree-install-cache.sh | MEDIUM | bash tests/test-worktree-install-cache.sh | released@2026-09-30T18:50Z | Source: D41 item 4. Evidence: run.sh:6298-6304 installs unconditionally on every worktree. Released in v10.5.7 (merge 17af0439 is an ancestor of v10.5.7). |
461
461
  | E-131 | BACKLOG 146: P7 sink regex misses a computed or bracket-indexed sink name, for example window[sinkName](rows) | tests/moat/p7-no-fabricated-data.sh | HIGH | bash tests/moat/p7-no-fabricated-data.sh | merged@2026-09-30T18:11Z | Source: BACKLOG 146. Evidence: SETTER regex at p7-no-fabricated-data.sh:771 matches only literal names. Same engineer as E-128. |
462
- | E-132 | Wall classifier: a missing test runner (python -m pytest exits 1 with No module named pytest) reads as red, not not_run; D42 red requires the runner to start and at least one test to fail, so require a pytest summary line with failed before red | loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/wall.test.ts | HIGH | cd loki-ts and bun test tests/engine10/wall.test.ts with a pytest-less python first on PATH | ready@2026-09-28T22:47Z | Source: main red on 04d3ac9c and 708c2907 (CI Bun job had no pytest); reproduced locally with a pytest-less venv, tests (3b) and (4) read fail 1. Seal still refuses later (not_run), so no false VERIFIED, but the Wall mis-seals. Coordinate with E-125 (same classifier). Core budget binds. |
462
+ | E-132 | Wall classifier: a missing test runner (python -m pytest exits 1 with No module named pytest) reads as red, not not_run; D42 red requires the runner to start and at least one test to fail, so require a pytest summary line with failed before red | loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/wall.test.ts | HIGH | cd loki-ts and bun test tests/engine10/wall.test.ts with a pytest-less python first on PATH | merged@2026-10-01T06:47Z | Source: main red on 04d3ac9c and 708c2907 (CI Bun job had no pytest); reproduced locally with a pytest-less venv, tests (3b) and (4) read fail 1. Seal still refuses later (not_run), so no false VERIFIED, but the Wall mis-seals. Coordinate with E-125 (same classifier). Core budget binds. |
463
463
  | E-133 | release.sh guard: refuse to commit dist maps that contain an absolute path (a node_modules symlink in a release worktree wrote 133 /Users paths into loki.js.map and one into cockpit.js.map at v10.5.4) | scripts/release.sh, tests/test-release-dist-guard.sh | MEDIUM | bash tests/test-release-dist-guard.sh | released@2026-09-30T18:50Z | Source: v10.5.4 cut 2026-09-28, caught by hand before commit (paths rewritten to ../node_modules/). Guard: grep the dist maps for an absolute or home-directory path after the bump and exit nonzero. Released in v10.5.7 (merge 53918a30 is an ancestor of v10.5.7). |
464
464
  | E-134 | spawn_env_fsmonitor.test.ts positive control fails on Bun 1.4.2 (Nightly red 2026-09-29 and 09-30, both OSes): Bun no longer inherits the START env for a spawn with no env option, so the bare control call stops leaking the canary and the test proves nothing there. Keep the product assertions unconditional; add a control that passes the canary explicitly so the hook is proven to record env on any Bun; report which inheritance mode the running Bun has | loki-ts/tests/runner/spawn_env_fsmonitor.test.ts | HIGH | cd loki-ts and bun test tests/runner/spawn_env_fsmonitor.test.ts on Bun 1.3.13 and on latest | released@2026-09-30T18:50Z | Source: Nightly run 36719756873 job 109901555421 (bun-v1.4.2): control record held the withheld sentinel, not the canary. Product calls still did not leak. Security guard, opus review. Released in v10.5.7 (merge f0ba0d4d is an ancestor of v10.5.7). |
465
465
  | E-135 | Post-Release Smoke PyPI install gives up after about 10.5 min (6 attempts, 30s steps) while the published version is still propagating; v10.5.5 failed this way though PyPI now has it. Add --no-cache-dir and widen the window | .github/workflows/post-release-smoke.yml | LOW | bash -n on the step script; a rerun of the smoke on the next release | released@2026-09-30T18:50Z | Source: Post-Release Smoke run 36497082408 job 109179083720 (FATAL loki-mode-sdk==10.5.5 not installable after retries); PyPI shows 10.5.5 on 2026-09-30. Rerun of the failed jobs requested. Released in v10.5.7 (merge 1d4975a1 is an ancestor of v10.5.7). |
466
466
  | E-136 | measure-size.py counts any touched non-test .py file, so a docstring-only or typing-only second file makes a one-file fix read as medium (click-3449 utils.py, marshmallow-2170, pluggy-442); count only files whose change alters code, not comments or docstrings | eval/loki10/measure-size.py, its test | MEDIUM | the measure-size self test plus a fixture diff with a docstring-only second file reading small | released@2026-09-30T18:50Z | Source: S41-20a opus review 2026-09-30 (criterion 7 cannot stand in for criterion 1). Use the Python ast module to compare function bodies with docstrings stripped. Released in v10.5.7 (merge d116c91b is an ancestor of v10.5.7). |
467
467
  | E-137 | S41-18 interrupt test (legA in eval/loki10/test-scorecard-run.sh) leaks an orphaned run.sh plus harness.py (tasks rt1,rt2) when the run is torn down: two groups found reparented to PID 1 after 18 and 32 min on 2026-09-30, from a removed worktree and a reviewer probe dir | eval/loki10/test-scorecard-run.sh | MEDIUM | bash eval/loki10/test-scorecard-run.sh twice, then no run.sh or harness.py with --tasks rt1,rt2 remains | released@2026-09-30T19:22Z | Source: pulse Orphan worktree/run.sh processes 2 at 17:30Z; PIDs 56770/56781 and 96302/96310 stopped by literal PID after inspection (the python harness ignored SIGTERM). Fix: trap EXIT in the test that stops the recorded group, and assert no survivors. Released in v10.5.8 (merge 030cd521 is an ancestor of v10.5.8). |
468
468
  | E-138 | P7 scanner misses optional-call sinks and one-hop aliasing: setRows?.([...]), window[k]?.(rows), const s = setRows; s(rows), and a memo or local that forwards a fabricator result; accept an optional ?. before the call in the three sink heads and follow one alias hop | tests/moat/p7-no-fabricated-data.sh | HIGH | bash tests/moat/p7-no-fabricated-data.sh with red and green fixtures per form | parked@2026-09-30T20:04Z | Source: E-128/E-131 opus review 2026-09-30 (lines 776, 1067, 1172 use a (?=[(<]) or \s*\( lookahead); pre-existing at base, not opened by E-131. PARKED 20:05Z by the adoption directive (docs/v10/PROGRESS.md 20:05Z); resumes after Tier 0 is green. |
469
- | E-139 | spawn_env_fsmonitor.test.ts follow-ups from E-134 review: comments at lines 16-17 and 114 overstate Bun 1.4.2 (Bun.spawn and Bun.spawnSync with no env still inherit the START env; only node:child_process inherits current), name spawn_env_guard.test.ts as the guard for them; line 94 driver should run process.execPath, not the bun on PATH | loki-ts/tests/runner/spawn_env_fsmonitor.test.ts | LOW | cd loki-ts and bun test tests/runner/spawn_env_fsmonitor.test.ts | ready@2026-09-30T18:08Z | Source: E-134 opus review 2026-09-30 (probe: Bun.spawn on 1.4.2 printed START env). |
469
+ | E-139 | spawn_env_fsmonitor.test.ts follow-ups from E-134 review: comments at lines 16-17 and 114 overstate Bun 1.4.2 (Bun.spawn and Bun.spawnSync with no env still inherit the START env; only node:child_process inherits current), name spawn_env_guard.test.ts as the guard for them; line 94 driver should run process.execPath, not the bun on PATH | loki-ts/tests/runner/spawn_env_fsmonitor.test.ts | LOW | cd loki-ts and bun test tests/runner/spawn_env_fsmonitor.test.ts | released@2026-09-30T23:00Z | Source: E-134 opus review 2026-09-30 (probe: Bun.spawn on 1.4.2 printed START env). |
470
470
  | E-140 | Something deletes run-owned loki-run.* directories under TMPDIR while another agent is using them (an opus reviewer's dir and its Bun 1.4.2 binary vanished mid-review on 2026-09-30; unfamiliar dirs with e10ext subdirs appeared inside). Find the sweeper (a test cleanup, a trap, or a script removing loki-run.* by pattern) and make it remove only its own validated dir | the offending script or test (to locate), plus a guard test | HIGH | a guard that plants two run-owned dirs and runs the suspected cleanup, asserting the foreign one survives | released@2026-09-30T19:22Z | Source: E-134 opus review cleanup note 2026-09-30. CLAUDE.md forbids sweeping TMPDIR by pattern. Released in v10.5.8 (merge 98eadf90 is an ancestor of v10.5.8). |
471
471
  | E-141 | treeswap passes an explicit env to its git spawns (spawn_env_guard, BACKLOG 149) | loki-ts/src/e10ext/treeswap.ts and its test | MEDIUM | bun test tests/e10ext | released@2026-09-30T18:50Z | Merged c2305c99 via 0bf98fd0. S41-13 binding note records the scrubbed-env requirement. Released in v10.5.7 (merge 0bf98fd0 is an ancestor of v10.5.7). |
472
472
  | E-142 | D44-C follow-ups: structural-checks changed_chars diffs against the merge-base (committed dashes/emoji caught), typecheck prints SKIP without node_modules, register test-v10-ops.sh and fix the IGNORE comment (slow, not hanging) | scripts/structural-checks.sh, tests/test-structural-checks.sh, tests/test-registration-coverage.sh, tests/run-all-tests.sh, tests/shard-durations.tsv | LOW | bash tests/test-structural-checks.sh; each check under 10s | merged@2026-09-30T18:49Z | Source: D44-C TL review (APPROVE with notes). |
@@ -478,7 +478,7 @@ set is declared to avoid overlap with those and with each other.
478
478
  | E-148 | Review follow-ups: test-stop-process-group.sh still kills by `pkill -f "loki-$PGTEST_TAG"` (pattern kill, forbidden by CLAUDE.md): replace with recorded PIDs or a process-group kill; test-audit-chain-cross-file.sh test 1 reads the real ~/.loki/dashboard/audit (fails on hosts with old tampered data): make it hermetic; E-147 timeout message says "after all cases passed" when there was zero output: say "no PASS output (possible hang before the first case)" | tests/test-stop-process-group.sh, tests/test-audit-chain-cross-file.sh, tests/test-trust-core-probe-isolation.sh | LOW | each suite passes on a host with a tampered ~/.loki audit file; no pkill -f remains | merged@2026-09-30T19:53Z | Source: E-143 and E-147 TL reviews (APPROVE with notes). |
479
479
  | E-149 | loki-ts/tests/engine10/modernize/java_capture.test.ts "unitClassesFromGraph (M-04 integration)" times out at bun's 5s default under CI load (5169ms, Coverage run 36764748814 on train/5 1cd5feac; also failed on train/2 and in a local full run): measure, make it cheaper or set an explicit measured timeout; sweep modernize tests over 2.5s | loki-ts/tests/engine10/modernize/*.test.ts | LOW | before/after durations under 3x load; bun test tests/engine10/modernize 0 fail | released@2026-09-30T20:08Z | Source: D44 train/5 red (Coverage). Rerun of the failed job in flight. Released in v10.5.10 (merge 2394dc4a is an ancestor of v10.5.10). |
480
480
  | E-151 | Release blocker guard: v10.5.10 (69ebc03e) shipped loki-ts/dist/loki.js.map stale because the bump changed it (version literal 10.5.9 to 10.5.10 changed length, shifting mappings) and the release commit staged a fixed file list. scripts/release.sh --bump-only should print every file it changed (including dist maps), and a check (in release.sh or a pre-push rule for "release: v*" commits) should refuse a release commit that leaves a stamped tracked file modified in the worktree | scripts/release.sh, tests/test-release-dist-guard.sh | LOW | fixture: a bump that changes the map, commit without it, check refuses; with it, passes | released@2026-09-30T21:23Z | Source: v10.5.10 release; interim procedure: assert `git status --porcelain` is empty after the release commit before pushing. Map corrected on the next train. Released in v10.5.11 (merge bd5834a9 is an ancestor of v10.5.11). |
481
- | E-152 | release.sh --bump-only "stage these files:" list must print a copy-paste command that works: loki-ts/dist is gitignored, so `git add loki-ts/dist/loki.js` refuses (seen 19:58Z on train/7); print `git add -f` for paths under an ignored directory (git check-ignore) and plain `git add` otherwise | scripts/release.sh, tests/test-release-dist-guard.sh | LOW | fixture with an ignored-but-tracked dist file: the printed command stages it | ready@2026-09-30T19:58Z | Source: first live use of E-151 --check-clean caught the unstaged dist (rc=1). |
481
+ | E-152 | release.sh --bump-only "stage these files:" list must print a copy-paste command that works: loki-ts/dist is gitignored, so `git add loki-ts/dist/loki.js` refuses (seen 19:58Z on train/7); print `git add -f` for paths under an ignored directory (git check-ignore) and plain `git add` otherwise | scripts/release.sh, tests/test-release-dist-guard.sh | LOW | fixture with an ignored-but-tracked dist file: the printed command stages it | released@2026-10-01T06:40Z | Source: first live use of E-151 --check-clean caught the unstaged dist (rc=1). |
482
482
  | E-153 | Incident 20:16Z: a reviewer's fixture setup ran `git commit` with the MAIN CHECKOUT as cwd, committing author `t <t@t>` "init" that replaced the real package.json with a fixture and added sum.js/sum.test.js (local only, never pushed; undone with `git reset --keep 1c96ab16`). Guard: a pre-commit hook in .githooks refusing any commit in this repository whose author email is not the repo-local identity (git config user.email) unless LOKI_ALLOW_FOREIGN_AUTHOR=1, so fixture commits made in the wrong cwd fail loudly; fixture commits in real temp repos are unaffected | .githooks/pre-commit, tests/test-pre-commit-author-guard.sh | LOW | red first: in a scratch clone with the hook installed, `git -c user.email=t@t commit` is refused; the repo identity commits | ready@2026-09-30T20:17Z | Source: loki-seal r2 review fixture (agent stopped at 20:17Z). Reviewer prompts now require `git -C "$FIXTURE"` and a pwd check under LOKI_RUN_TMP. |
483
483
  | S41-10b | Static-first fixed-rules block for the implement and fix briefs (S41-10 card remainder): a byte-identical rules block in the cache-stable prefix, per-task context after it; drive-letter and ~ plan paths filtered like absolute ones | loki-ts/src/engine10/stages/implement.ts, fix.ts (prefix only), loki-ts/src/e10ext/context.ts and tests | MEDIUM | red first: two different tasks produce byte-identical prefix bytes; core net-zero lines | merged@2026-09-30T19:19Z | Source: S41-10 reviews (APPROVE r2, remainder). |
484
484
  | S41-20h | Medium-task MINING pass (no task building): shortlist 12 candidate merged PRs whose shape survives the one-file probe (a semantic or signature change in file A that an independently tested caller in file B must match; not helper extraction, parameter threading, moved classes or typing-only files), each with a written one-file-fix attempt run against the upstream tests and its result | eval/loki10/tasks/CANDIDATES.md (new) | MEDIUM | every shortlisted PR has a failing one-file attempt recorded with command and rc | merged@2026-09-30T19:19Z | Source: S41-20b/c/d/e/f: 11 of 16 candidates fell to a reviewer one-file fix; S41-20f built 0. |
@@ -628,10 +628,14 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
628
628
  | E-157 | D46: Security Audit verdict reuse. (a) security-audit.yml also runs on push to train/** so every train tip gets the full --all gitleaks scan before main is fast-forwarded; (b) required-ci reuses the parent Security Audit verdict for an eligible VERSION-only bump under the existing eligibility rule (diff is VERSION plus generated version stamps only, parent run success at that exact SHA). Moat test: a non-VERSION-only bump still re-runs Security Audit. Supersedes FOUNDER-QUEUE 14 | .github/workflows/security-audit.yml, release.yml (required-ci), tests | HIGH | non-VERSION-only bump re-runs the scan | merged@2026-10-01T03:03Z | after slice-D46-ci; r3 opus APPROVE 57b511d2; DROPPED from train/21 (D46): STEP 1 re-indent broke S-132 normalizer parity (test-version-bump-only 28/1), reverted 7d1a0f15, r4 with CI-health |
629
629
  | E-159 | Pre-existing secret-scan gaps found by the E-157 r2 opus reviewer: (a) an evil merge, a merge commit whose OWN content adds a secret (merge -s ours --no-commit, token in the merge commit), is invisible to both the PARENT..SHA range scan and the --all scan (only `gitleaks dir` found it); (b) pinned gitleaks 8.30.0 exits 0 when its internal git log fails (invalid range), a latent fail-open. Fix: --diff-merges=first-parent (or -m) in --log-opts for both modes or a working-tree scan at the release SHA; guard `git rev-list RANGE` success or treat `[git] fatal` as failure | scripts/security-audit-gitleaks.sh, workflows, tests | HIGH | evil-merge and bad-range fixtures fail the scan | merged@2026-10-01T03:03Z | CI-health engineer after E-157 r3; r1 opus REJECT 5f33451d: stdin merge scan false-positives on real history (v10.5.13..14 rc 1), Wall checks skip in CI |
630
630
  | E-160 | D46 runner contention (peer steer 02:11Z): a green train SHA fast-forwarded to main re-runs Tests (8 shards), Bun Parity, Security Audit and First-run gate on the identical SHA, doubling runner load and queueing the next train. Proposal: on push to main, a first job checks for a successful run of the same workflow at the same SHA from a train/** push and, if found, exits success recording the reused run id (D28: same SHA = same tree); any SHA not train-tested runs in full. CTO call FIRST: OPERATING-MODEL says "Tier B full verification on every main commit (never cancelled on main)"; confirm reuse does not weaken Release required-ci, branch-conditional steps (train vs main), or the Security Audit range (base tag config). Sequence after E-157 r4 (same files) | .github/workflows/test.yml, bun-parity.yml, security-audit.yml, tests/test_release_required_ci.py | HIGH | main push of a train-green SHA records reuse and finishes in under 1 min; an untested SHA runs in full; a train-red SHA is not reused | ready@2026-10-01T02:10Z | CTO decision first; after E-157 |
631
- | E-161 | INCIDENT 02:46Z: an opus reviewer ran `git checkout --detach <tag>` x7 plus a `.gitleaksignore` overwrite in the SHARED main checkout (reflog 02:46:04Z to 02:46:38Z). Cause: its run-owned clone dir was deleted, the next `cd` into a new clone failed, and the shell cwd fell back to the main checkout; every later command ran there. Restored by the Chief of Staff (`git checkout main`, fafe50dd, clean). Guard: v10-guard.sh (PreToolUse) blocks `git checkout`/`git switch`/`git reset`/`git worktree remove` and writes to tracked files when cwd resolves to the main checkout and the caller is an agent (not the leader session); agent prompts use `cd DIR` followed by an exit-on-failure check. Test: a hook test with cwd=main checkout blocks a detached checkout and allows it in a worktree | scripts/v10-guard.sh, tests | HIGH | detached checkout in main checkout blocked; same in a worktree allowed | ready@2026-10-01T02:47Z | GUARDS.md entry |
631
+ | E-161 | INCIDENT 02:46Z: an opus reviewer ran `git checkout --detach <tag>` x7 plus a `.gitleaksignore` overwrite in the SHARED main checkout (reflog 02:46:04Z to 02:46:38Z). Cause: its run-owned clone dir was deleted, the next `cd` into a new clone failed, and the shell cwd fell back to the main checkout; every later command ran there. Restored by the Chief of Staff (`git checkout main`, fafe50dd, clean). Guard: v10-guard.sh (PreToolUse) blocks `git checkout`/`git switch`/`git reset`/`git worktree remove` and writes to tracked files when cwd resolves to the main checkout and the caller is an agent (not the leader session); agent prompts use `cd DIR` followed by an exit-on-failure check. Test: a hook test with cwd=main checkout blocks a detached checkout and allows it in a worktree | scripts/v10-guard.sh, tests | HIGH | detached checkout in main checkout blocked; same in a worktree allowed | merged@2026-10-01T06:47Z | GUARDS.md entry |
632
632
  | E-162 | Founder "faster" (03:05Z): slice CI runs only Tier A plus diff-selected suites (the existing Tier A selection), Bun Parity and the structural guards; the full 8-shard Tests stays on train/** and main, and the train stays the release verdict. Frees runners and targets about 2 min slice CI | .github/workflows/test.yml (slice-* job matrix only), tests | HIGH | slice-* push runs no 8-shard matrix; train/** and main still run all 8 shards; a slice touching a suite runs that suite | merged@2026-10-01T05:22Z | after E-157 r4 (same file) |
633
- | E-165 | tests/test-mirofish-integration.sh line 413 runs `autonomy/loki start --no-mirofish` in the repo root: a live autonomous build that ran about 45 min, switched a worktree branch to loki/session-* and committed a docs change (found by DOC-02). Guard: the test must run against a run-owned fixture repo with a stub provider and LOKI_NO_BROWSER=1, never the repo root; add a structural guard that no test launches start/run against REPO_ROOT | tests/test-mirofish-integration.sh, a structural guard | HIGH | the test never runs loki start in the repo root; guard catches a planted case | ready@2026-10-01T04:07Z | P0 guard (D26) |
634
- | E-166 | Jira auto-sync never starts: src/integrations/sync-subscriber.js builds JiraApiClient without the required email and apiToken, so LOKI_JIRA_URL plus LOKI_JIRA_TOKEN do nothing (DOC-02 added a known-issue note to the setup docs). Fix the wiring or remove the advertised auto-sync | src/integrations/sync-subscriber.js, tests | MEDIUM | with env set, the subscriber constructs a working client (mocked API) | ready@2026-10-01T04:07Z | none |
633
+ | E-165 | tests/test-mirofish-integration.sh line 413 runs `autonomy/loki start --no-mirofish` in the repo root: a live autonomous build that ran about 45 min, switched a worktree branch to loki/session-* and committed a docs change (found by DOC-02). Guard: the test must run against a run-owned fixture repo with a stub provider and LOKI_NO_BROWSER=1, never the repo root; add a structural guard that no test launches start/run against REPO_ROOT | tests/test-mirofish-integration.sh, a structural guard | HIGH | the test never runs loki start in the repo root; guard catches a planted case | merged@2026-10-01T06:52Z | P0 guard (D26) |
634
+ | E-166 | Jira auto-sync never starts: src/integrations/sync-subscriber.js builds JiraApiClient without the required email and apiToken, so LOKI_JIRA_URL plus LOKI_JIRA_TOKEN do nothing (DOC-02 added a known-issue note to the setup docs). Fix the wiring or remove the advertised auto-sync | src/integrations/sync-subscriber.js, tests | MEDIUM | with env set, the subscriber constructs a working client (mocked API) | merged@2026-10-01T06:43Z | none |
635
+ | P0-promote-bun | Auto-promote of 10.5.22 failed: promote.yml ran the first-run gate without bun, the installed CLI fell back to legacy, 7 v10 checks failed and the cost check crashed (IndexError). Install bun before the gate; cost check fails closed; explicit engine-fallback check | .github/workflows/promote.yml, scripts/first-run-gate.sh, tests/test-first-run-gate.sh | test-first-run-gate 56/0 incl. fallback fixture; gate --stub 0 failed | HIGH | merged@2026-10-01T07:09Z | opus CTO APPROVE 5bdfe2f8 |
636
+ | E-167 | Gate the no-bun path end to end (CTO follow-up to P0-promote-bun): run the default entry with bun absent from PATH and assert the legacy receipt, NOT VERIFIED on a skipped target and the documented exit codes, with the legacy 15-line budget and legacy verify (the v10 leg keeps 8 lines; scripts/first-run-gate.sh:123 forces LOKI_ENGINE=v10 for verify, which is why a bun-less run failed digest, verify and signed); the promote gate currently proves only the bun path | scripts/first-run-gate.sh, tests/test-first-run-gate.sh | no-bun stub run fails closed on a skipped test; clean no-bun run reads its legacy receipt | MEDIUM | ready@2026-10-01T07:09Z | none |
637
+ | E-161b | E-161 false block: the hook judges a detaching checkout by the hook cwd (the main checkout) and ignores a preceding checked cd into a linked worktree; at 07:20Z a cd into the release worktree followed by git checkout --detach was blocked (RULE8), and the release only proceeded via git -C. Resolve the effective directory from a leading checked cd or from git -C before applying RULE8 | scripts/v10-guard.sh, tests/test-v10-guard.sh | checked cd into a linked worktree then detach: allowed; cwd main with no cd: blocked; git -C linked: allowed | HIGH | ready@2026-10-01T07:22Z | none |
638
+ | P0-nobun | D48 flip does nothing on a bun-less npm install: bin/loki falls back to legacy without bun, and loki-ts/dist/loki.js is built for target bun (node gives ReferenceError: Bun is not defined). Make the Loki 10 engine run without a preinstalled bun (node-runnable build, or bun shipped as an npm dependency) and, when neither works, say so plainly on the start line. Architect plan first | bin/loki, loki-ts/scripts/build.ts, package.json (per plan) | bun-less host runs the v10 default or prints the plain cannot-run line; promote gate no-bun leg (E-167) passes | HIGH | ready@2026-10-01T07:31Z | opus architect plan in progress |
635
639
  | D49-auto | Auto-promote to latest on Post-Release Smoke success (founder D49) | .github/workflows/promote.yml, tests/test_release_next_tag.py | HIGH | smoke-success from Release promotes; manual smoke never promotes; not-lower guard | merged@2026-10-01T03:03Z | opus APPROVE 5510b8c8. Follow-ups (D49-auto-b): not-lower guard fails OPEN on an npm error (make it fail closed); loki-mode-sdk latest has no not-lower guard; a newer queued promote can replace a pending one in a release burst |
636
640
  | D51-A3 | Headless `loki backlog owner/repo --all/--label/--issues` plus loki.yaml (schema, validator, env overrides) | autonomy/lib/backlog.py, autonomy/lib/loki_yaml.py, autonomy/loki, schemas/loki-yaml.schema.json, tests/test-backlog.sh | HIGH | backlog 47/0 | merged@2026-10-01T03:11Z | sonnet APPROVE 14ff9ae2; follow-up D51-A3b: `loki_yaml.py show` echoes a token pasted into git.token_env (redact x-secret-ref fields); no-parser test case; re-run of a failed issue discards its kept worktree |
637
641
  | D51-A4 | Slack on the v10 path (PR opened, BLOCKED, finished), webhook from the env var named by LOKI_SLACK_WEBHOOK_ENV, URL redacted, 5s bounded post | loki-ts/src/e10ext/slack_events.ts, engine10/supervisor.ts, tests | MEDIUM | slack tests 40/0 | merged@2026-10-01T03:11Z | sonnet APPROVE adb838b2; one labelled test message after it ships |
@@ -21,3 +21,4 @@ this file; each item says what the loop does meanwhile.
21
21
  | 14 | 2026-10-01 | Move the full-history `gitleaks --all` scan out of the Release path (to nightly plus every push to main, still blocking there), keeping a base-tag-to-tip range scan in Release. Relayed by the steering session as part of D46. | Weakens a release-blocking security gate; needs the founder directly, not a relay. | Release keeps the `--all` scan; E-156 removes the recurring false positive at the source. | SUPERSEDED 2026-10-01T00:30Z: Security Audit verdict reuse for VERSION-only bumps keeps the full --all scan scope (steering session 00:28Z); filed for the CI-health engineer. |
22
22
  | 15 | 2026-10-01 | Run the REAL-provider first-run gate on the published `next` build: `CLAUDE_CODE_OAUTH_TOKEN=<token from "claude setup-token"> bash scripts/first-run-gate.sh --real --installed loki-mode@10.5.13` (or ANTHROPIC_API_KEY). The swarm has no provider credential in its environment and does not read stored secrets; the gate's throwaway HOME cannot use the keychain login. Stub mode on the installed npm package runs meanwhile. | Credential only the founder holds. | The promote milestone (real gate pass on a `next` version) stays blocked; stub-mode evidence only. |
23
23
  | 16 | 2026-10-01 | A Slack incoming-webhook URL for testing D51 item 4 (notify.sh on the v10 path: PR opened, BLOCKED, backlog finished). Provide it as an env var (for example `LOKI_SLACK_WEBHOOK_URL`) in the Release Manager session, never in a file or chat. | Needs a credential only the founder holds. | Until then notify.sh is tested against a local mock webhook; the real end-to-end check runs once the env var is set. | open |
24
+ | 17 | 2026-10-01 | Ship bun with the npm package so `npm install -g loki-mode` runs the Loki 10 default without a separate bun install (P0-nobun, architect option B): add `"bun": "1.4.2"` as an optionalDependency. Cost: each install grows from 26.6MB to about 90-110MB (platform binary 62MB darwin-arm64, 80MB linux-x64, 86MB win-x64); `--omit=optional` and unsupported platforms keep the legacy engine with a plain message. The alternative (rewrite engine10 to run under node) is about 14 files and 300-450 lines, breaks the engine10 line budget and needs a third Bun Parity runtime. | Install size and dependency policy. | Builds only the resolver and the plain cannot-run message (both useful either way); npm users without bun keep getting legacy, and promote stays paused until the two-leg gate (E-167) lands. DECIDED B 07:35Z by peer relay (autonomi-dev-dc, citing the founder's 03:30Z delegation): the Loki 10 default is the product; a bigger install costs less than an inert default for most npm users; same pattern as esbuild and biome. Conditions: per-platform optional packages only; measured delta reported and held if above about 60MB per platform (architect figures 62-86MB exceed it; 07:35Z follow-up relay: decided (i) accept about 62-86MB, or (iii) bun's baseline build if smaller and Bun Parity passes; not (ii), since a first-run consent step breaks the one-command bar; record measured deltas in the CHANGELOG; document --omit=optional as the slim legacy path); --version probe plus plain start line when bun cannot run; Docker and Homebrew use the same resolver; E-167 two-leg gate stays. Founder may reverse. |
@@ -797,3 +797,25 @@ previously mismarked two merged guards (S-16, S-74) as PENDING.
797
797
  no-op (`return dict(row)`) reproduces the incident directly: the planted
798
798
  secret and the log paths both survive.
799
799
  Run: `bash tests/test-prune-worktrees.sh && bash tests/test-eval-archive.sh`.
800
+
801
+ ## 21. A failed `cd` let an agent detach the shared main checkout (E-161)
802
+
803
+ - **Incident:** an agent ran `cd <temp clone>` which failed, then fell back
804
+ to the shared main checkout and ran `git checkout --detach <tag>` there 7
805
+ times, leaving the founder's checkout detached each time.
806
+ - **Guard:** RULE8 in `scripts/v10-guard.sh` (PreToolUse Bash hook). In the
807
+ primary worktree (git-dir equals git-common-dir) it blocks `git checkout
808
+ --detach`, `git checkout <tag|sha|remote-ref>` and `git switch --detach`
809
+ for every caller. When the hook input carries `agent_id` (set only for
810
+ subagents; the leader has none) it also blocks all `git checkout`/`switch`,
811
+ `reset --hard`, `stash`, `clean` and `worktree remove` of the main
812
+ checkout. A dangerous git command after a `cd` not followed by `&&`/`||`
813
+ is blocked when the hook cwd is the primary worktree. The leader keeps
814
+ `git checkout main`, merge, revert and commit.
815
+ - **Limit:** `cd X || true; git ...` counts as handled. If a host stops
816
+ sending `agent_id`, only the always-on detach forms remain.
817
+ - **The test that proves it fires:** `tests/test-v10-guard.sh` (Rule 8
818
+ section): detached checkout in the main checkout blocked, same in a linked
819
+ worktree allowed, leader `git checkout main` allowed, subagent forms and
820
+ the unchecked-`cd` case blocked.
821
+ Run: `bash tests/test-v10-guard.sh`.
@@ -1754,9 +1754,37 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
1754
1754
  - D46 drop: reverted c2c43fd10 on main (5d25b205; reverted paths identical to aad61f9a; local test-first-run-gate rc=0, 0 FAIL). train/34 5d25b205 pushed with E-163 r3 (haiku fix; env parse probes abc/-5/nan/inf/0 -> 20, 46/0), A-134b r4, E-162.
1755
1755
  - D48-flip r4 (fixture fix) building; D48-r2b (pubkey, null-jwt exits 3 under --pubkey) built, in opus re-review; it needs the flip re-landed first.
1756
1756
 
1757
- ## 2026-10-01T06:07Z v10.5.20 promoted; v10.5.21 (D48 engine flip) released; train/39
1757
+ ## 2026-10-01T06:07Z v10.5.20 promoted; v10.5.21 (D48 engine flip) cut, Release FAILED, NOT published (see 06:30Z); train/39
1758
1758
  - v10.5.20 240f3285: Release success; npm gitHead 240f3285f42b matches; dist-tags latest=10.5.20 next=10.5.20 (auto-promote, watcher bybzbhat6). Contents A-134b, E-162, E-163.
1759
1759
  - train/35 RED (Tests shard 1/8: "1 command(s) absent from 'loki help': keys"). D46 drop of D48-r2b (76e3d25c, revert clean vs flip-r4 merge). Fix r2c 2e7c68a3 (one help line), re-landed as 3eade3d4; train/37 green on Tests, Bun Parity, Coverage, Security Audit.
1760
1760
  - train/36 76e3d25c green (all four); main fast-forwarded; v10.5.21 189f347e pushed (--check-clean rc=0, parent == origin/main). CHANGELOG corrected: the flip's Unreleased notes said "loki verify unchanged"; r3 routes bare verify to v10 when the newest run is a v10 run (bin/loki:296-305), exit 4 for a non-VERIFIED outcome. Watcher bpighrue2.
1761
1761
  - Tier A red on every train since train/33: E-162 ran tests/test-shard-coverage.sh before the Python deps install; two pytest-gated suites (run-all-tests.sh:782-787) were not registered, 666 of 668. Fix 55d559ea moves the step after pip install (train/38).
1762
1762
  - train/39 c34511e5 = flip + keys (D48 rows 2, 7-9) + Tier A fix + 10.5.21 merge; local help, registration, shard-coverage, docs-drift, v10-ops all rc=0.
1763
+
1764
+ ## 2026-10-01T06:29Z CORRECTION: v10.5.21 not published (P0, fix forward)
1765
+ - v10.5.21 189f347e: Release run completed failure. Tests at that SHA failed in shard 6/8: "CHANGELOG Unreleased does not record the v10 default flip" (tests/test-engine10-legacy-notice.sh). The release CHANGELOG moved the flip note from Unreleased into the v10.5.21 section. Post-Release Smoke and Promote skipped; npm dist-tags latest=next=10.5.20. The 06:07Z entry's "released" was premature and is corrected above; rows say released only once npm has the version.
1766
+ - Moat suite passed at 189f347e, so the train/39 P2.checklist-verify-not-shadowed failure did not recur on the same code (local p2 run on c34511e5 also PASS); still treated as unconfirmed until train/40.
1767
+ - Fix baf5e2c8: the test now requires 'Loki 10.*now the default' anywhere in CHANGELOG. Intent kept: a copy of CHANGELOG with that line removed fails the pattern, the real file passes. train/40 baf5e2c8 in CI; on green, fast-forward and cut 10.5.22 (flip, keys, Tier A fix), CHANGELOG stating 10.5.21 was never published.
1768
+
1769
+ ## 2026-10-01T07:03Z v10.5.22 published to next; auto-promote FAILED (P0)
1770
+ - v10.5.22 9b22a347: Release success; npm view loki-mode@10.5.22 gitHead 9b22a3477072 matches; dist-tags next=10.5.22, latest=10.5.20 (UNCHANGED). Release body 11 lines. Contents: D48 flip (rows 7-9), keys export and verify --pubkey (row 2), Tier A fix, E-35 test fix. v10.5.21 was never published.
1771
+ - promote.yml run at 07:00Z: completed failure, correctly refused to move latest. first-run-gate.sh --installed loki-mode@10.5.22 ran on ubuntu-latest WITHOUT bun; the installed CLI fell back to the legacy engine ("the Loki 10 engine needs bun"), so 7 v10 checks failed (digest-matches, verify-ok, receipt-signed, output-lines 13>8, engine-start-line, cost-non-null, skip-bare-verify) and the cost check crashed with IndexError (no v10 run dir).
1772
+ - P0 fix slice-P0-promote-bun building: setup-bun in promote (and any other gate job on an installed package), cost check fails closed instead of crashing, explicit "engine fell back to legacy" check. CTO (opus) review before merge; release-gate change.
1773
+ - train/42 73dbe61b (E-166, E-161, E-132 test, E-165) in CI.
1774
+
1775
+ ## 2026-10-01T07:21Z v10.5.23 cut (E-166, E-161, P0-promote-bun, E-132 test); E-165 on train/45
1776
+ - train/44 a3dd76e6 green on Tests, Bun Parity, Coverage, Security Audit, Tier A; main fast-forwarded; v10.5.23 0b27f4a1 pushed (--check-clean rc=0, parent == origin/main, map sources clean, version embedded once). Watcher b120po3q0 covers the Release run, npm and the promote run, which is the first promote with the bun fix; if its gate passes, latest moves to 10.5.23 and the manual 10.5.22 promote is moot.
1777
+ - E-161 false block found during the cut: a cd into the release worktree then git checkout --detach was blocked as if in the main checkout; git -C worked. Row E-161b (HIGH) added.
1778
+ - train/45 33bbdb75 (adds E-165 r3: funnel-privacy counts only off-machine egress; caller was run.sh:24659 POST to 127.0.0.1/api/focus) in CI.
1779
+ - E-168 r2 (Tier A selects only runnable test files; train/43 range replay) finishing; E-168 r1 2a83f272 rejected by me: helpers fell through to bash execution.
1780
+
1781
+ ## 2026-10-01T07:31Z P0-nobun: the D48 flip does nothing without bun (peer relay)
1782
+ - Evidence: bin/loki:329-331 falls back to legacy when bun is absent; loki-ts/scripts/build.ts:162,206 build target "bun"; node loki-ts/dist/loki.js --version gives "ReferenceError: Bun is not defined" (dist line 1569). Most npm users have no bun.
1783
+ - The bun-less gate failures on 10.5.22 (digest, verify, signed) come from scripts/first-run-gate.sh:123 forcing LOKI_ENGINE=v10 for verify, not from a legacy regression since 10.5.16; output-lines 13 is legacy quick against the new 8-line cap (legacy budget is 15). E-167 extended to a no-bun leg with legacy expectations.
1784
+ - Opus architect comparing a node-runnable engine10 with shipping bun as an npm dependency; slices follow. The flip is not described as done for npm users until this lands.
1785
+
1786
+ ## 2026-10-01T07:34Z Promote PAUSED until the two-leg gate lands
1787
+ - gh workflow disable promote.yml at 07:33Z (state disabled_manually), while 10.5.23's Post-Release Smoke ran. Reason: the promote gate now proves only the bun path; a plain npm install has no bun and gets legacy, which no gate leg checks. latest stays 10.5.20 (gate working); next 10.5.22, 10.5.23 Release success. Re-enable after E-167 (two legs, both must pass) is merged and on main.
1788
+ - Architect (opus): option B (bun@1.4.2 optionalDependency, resolver to node_modules/@oven/bun-*/bin/bun with a --version probe) over A (node build: about 14 files, 300-450 lines, breaks the engine10 budget). Install size 26.6MB to about 90-110MB: FOUNDER-QUEUE 17.
1789
+ - Building: E-167 (two-leg promote gate), P0-nobun-S2 (resolver plus plain cannot-run start line; no dependency added).
1790
+ - train/46 bb82c599 (E-165 r3, E-168 r2) in CI; train/45 was green.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var Jr=Object.create;var{getPrototypeOf:Kr,defineProperty:cG,getOwnPropertyNames:Yr}=Object;var zr=Object.prototype.hasOwnProperty;function Vr($){return this[$]}var Wr,qr,Gr=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?Wr??=new WeakMap:qr??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?Jr(Kr($)):{};let Y=Z||!$||!$.__esModule?cG(Q,"default",{value:$,enumerable:!0}):Q;for(let z of Yr($))if(!zr.call(Y,z))cG(Y,z,{get:Vr.bind($,z),enumerable:!0});if(X)J.set($,Y);return Y};var AK=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var Hr=($)=>$;function Br($,Z){this[$]=Hr.bind(null,Z)}var R0=($,Z)=>{for(var Q in Z)cG($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:Br.bind(Z,Q)})};var v=($,Z)=>()=>($&&(Z=$($=0)),Z);var x4=import.meta.require;var aT={};R0(aT,{lokiDir:()=>T0,homeLokiDir:()=>m7,findRepoRootForVersion:()=>iG,REPO_ROOT:()=>i0});import{resolve as S4,dirname as lG}from"path";import{fileURLToPath as Ur}from"url";import{existsSync as CK}from"fs";import{homedir as Or}from"os";function Nr(){let $=iT;for(let Z=0;Z<6;Z++){if(CK(S4($,"VERSION"))&&CK(S4($,"autonomy/run.sh")))return $;let Q=lG($);if(Q===$)break;$=Q}return S4(iT,"..","..","..")}function iG($){let Z=$;for(let Q=0;Q<6;Q++){if(CK(S4(Z,"VERSION"))&&CK(S4(Z,"autonomy/run.sh")))return Z;let X=lG(Z);if(X===Z)break;Z=X}return S4($,"..","..","..")}function T0(){return process.env.LOKI_DIR??S4(process.cwd(),".loki")}function m7(){return S4(Or(),".loki")}var iT,i0;var J8=v(()=>{iT=lG(Ur(import.meta.url));i0=Nr()});import{readFileSync as Mr}from"fs";import{resolve as jr,dirname as Lr}from"path";import{fileURLToPath as Ar}from"url";function b4(){if(u7!==null)return u7;let $="10.5.22";if(typeof $==="string"&&$.length>0)return u7=$,u7;try{let Z=Lr(Ar(import.meta.url)),Q=iG(Z);u7=Mr(jr(Q,"VERSION"),"utf-8").trim()}catch{u7="unknown"}return u7}var u7=null;var h$=v(()=>{J8()});var $D={};R0($D,{runOrThrow:()=>fr,run:()=>D0,readStreamCapped:()=>TK,commandVersion:()=>hr,commandExists:()=>O9,ShellError:()=>oG,MAX_STDOUT_BYTES:()=>eT});async function TK($,Z=eT){let Q=$.getReader(),X=new TextDecoder,J="",K=0;try{while(K<Z){let{done:Y,value:z}=await Q.read();if(Y)break;if(!z)continue;if(K+=z.byteLength,K>Z){let V=z.byteLength-(K-Z);J+=X.decode(z.subarray(0,V),{stream:!0});break}J+=X.decode(z,{stream:!0})}J+=X.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function D0($,Z={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Z.env?{...process.env,...Z.env}:process.env,cwd:Z.cwd}),X,J;if(Z.timeoutMs&&Z.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},Z.timeoutMs);try{let[K,Y,z]=await Promise.all([TK(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:Y,exitCode:z}}finally{if(X)clearTimeout(X);if(J)clearTimeout(J)}}async function fr($,Z={}){let Q=await D0($,Z);if(Q.exitCode!==0)throw new oG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function O9($){let Z=vr($),Q=await D0(["sh","-c",`command -v ${Z}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function vr($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function hr($,Z="--version"){if(!await O9($))return null;let X=await D0([$,Z],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var eT=16777216,oG;var J9=v(()=>{oG=class oG extends Error{message;exitCode;stdout;stderr;constructor($,Z,Q,X){super($);this.message=$;this.exitCode=Z;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function y4($){return gr?"":$}var gr,k0,P8,p0,XZ8,K8,L8,K9,c;var o5=v(()=>{gr=(process.env.NO_COLOR??"").length>0;k0=y4("\x1B[0;31m"),P8=y4("\x1B[0;32m"),p0=y4("\x1B[1;33m"),XZ8=y4("\x1B[0;34m"),K8=y4("\x1B[0;36m"),L8=y4("\x1B[1m"),K9=y4("\x1B[2m"),c=y4("\x1B[0m")});import{accessSync as nr,constants as sr,existsSync as rr,statSync as tr}from"fs";async function n5(){if(g$!==void 0)return g$;let $="/opt/homebrew/bin/python3.12";if(rr($))return g$=$,$;let Z=await O9("python3.12");if(Z)return g$=Z,Z;let Q=await O9("python3");return g$=Q,Q}async function T6($,Z={}){let Q=await n5();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return D0([Q,"-c",$],Z)}async function XD(){let $=(process.env.PATH??"").split(":").filter((Z)=>Z.startsWith("/"));for(let Z of[...$t,...$.map((Q)=>`${Q}/python3`)])try{if(!tr(Z).isFile())continue;if(nr(Z,sr.X_OK),(await D0([Z,"-I","-S","-c",""],{timeoutMs:1e4})).exitCode===0)return Z}catch{}return null}var g$,er,$t;var D6=v(()=>{J9();er=["/usr/bin/python3","/bin/python3"],$t=er});var CD={};R0(CD,{runStatus:()=>Ft});import{existsSync as Y9,readFileSync as W2,readdirSync as BD,statSync as UD}from"fs";import{resolve as u8,basename as Nt}from"path";import{homedir as Mt}from"os";function OD($){let Z=Math.trunc($);if(Z>=1e6)return`${(Math.trunc(Z/1e6*10)/10).toFixed(1)}M`;if(Z>=1000)return`${(Math.trunc(Z/1000*10)/10).toFixed(1)}K`;return String(Z)}function ND($,Z,Q){if(Z===0)return null;let X=Math.trunc($*100/Z),J=Math.trunc($*IK/Z);if(J>IK)J=IK;let K=IK-J,Y=P8;if(X>=80)Y=k0;else if(X>=50)Y=p0;let z="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,K)),V=OD($),W=OD(Z);return` ${L8}${Q}${c} ${Y}[${z}]${c} ${X}% (${V} / ${W})`}async function Lt(){if(await O9("jq"))return!0;return process.stdout.write(`${k0}Error: jq is required but not installed.${c}
2
+ var Jr=Object.create;var{getPrototypeOf:Kr,defineProperty:cG,getOwnPropertyNames:Yr}=Object;var zr=Object.prototype.hasOwnProperty;function Vr($){return this[$]}var Wr,qr,Gr=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?Wr??=new WeakMap:qr??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?Jr(Kr($)):{};let Y=Z||!$||!$.__esModule?cG(Q,"default",{value:$,enumerable:!0}):Q;for(let z of Yr($))if(!zr.call(Y,z))cG(Y,z,{get:Vr.bind($,z),enumerable:!0});if(X)J.set($,Y);return Y};var AK=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var Hr=($)=>$;function Br($,Z){this[$]=Hr.bind(null,Z)}var R0=($,Z)=>{for(var Q in Z)cG($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:Br.bind(Z,Q)})};var v=($,Z)=>()=>($&&(Z=$($=0)),Z);var x4=import.meta.require;var aT={};R0(aT,{lokiDir:()=>T0,homeLokiDir:()=>m7,findRepoRootForVersion:()=>iG,REPO_ROOT:()=>i0});import{resolve as S4,dirname as lG}from"path";import{fileURLToPath as Ur}from"url";import{existsSync as CK}from"fs";import{homedir as Or}from"os";function Nr(){let $=iT;for(let Z=0;Z<6;Z++){if(CK(S4($,"VERSION"))&&CK(S4($,"autonomy/run.sh")))return $;let Q=lG($);if(Q===$)break;$=Q}return S4(iT,"..","..","..")}function iG($){let Z=$;for(let Q=0;Q<6;Q++){if(CK(S4(Z,"VERSION"))&&CK(S4(Z,"autonomy/run.sh")))return Z;let X=lG(Z);if(X===Z)break;Z=X}return S4($,"..","..","..")}function T0(){return process.env.LOKI_DIR??S4(process.cwd(),".loki")}function m7(){return S4(Or(),".loki")}var iT,i0;var J8=v(()=>{iT=lG(Ur(import.meta.url));i0=Nr()});import{readFileSync as Mr}from"fs";import{resolve as jr,dirname as Lr}from"path";import{fileURLToPath as Ar}from"url";function b4(){if(u7!==null)return u7;let $="10.5.24";if(typeof $==="string"&&$.length>0)return u7=$,u7;try{let Z=Lr(Ar(import.meta.url)),Q=iG(Z);u7=Mr(jr(Q,"VERSION"),"utf-8").trim()}catch{u7="unknown"}return u7}var u7=null;var h$=v(()=>{J8()});var $D={};R0($D,{runOrThrow:()=>fr,run:()=>D0,readStreamCapped:()=>TK,commandVersion:()=>hr,commandExists:()=>O9,ShellError:()=>oG,MAX_STDOUT_BYTES:()=>eT});async function TK($,Z=eT){let Q=$.getReader(),X=new TextDecoder,J="",K=0;try{while(K<Z){let{done:Y,value:z}=await Q.read();if(Y)break;if(!z)continue;if(K+=z.byteLength,K>Z){let V=z.byteLength-(K-Z);J+=X.decode(z.subarray(0,V),{stream:!0});break}J+=X.decode(z,{stream:!0})}J+=X.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function D0($,Z={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Z.env?{...process.env,...Z.env}:process.env,cwd:Z.cwd}),X,J;if(Z.timeoutMs&&Z.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},Z.timeoutMs);try{let[K,Y,z]=await Promise.all([TK(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:Y,exitCode:z}}finally{if(X)clearTimeout(X);if(J)clearTimeout(J)}}async function fr($,Z={}){let Q=await D0($,Z);if(Q.exitCode!==0)throw new oG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function O9($){let Z=vr($),Q=await D0(["sh","-c",`command -v ${Z}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function vr($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function hr($,Z="--version"){if(!await O9($))return null;let X=await D0([$,Z],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var eT=16777216,oG;var J9=v(()=>{oG=class oG extends Error{message;exitCode;stdout;stderr;constructor($,Z,Q,X){super($);this.message=$;this.exitCode=Z;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function y4($){return gr?"":$}var gr,k0,P8,p0,XZ8,K8,L8,K9,c;var o5=v(()=>{gr=(process.env.NO_COLOR??"").length>0;k0=y4("\x1B[0;31m"),P8=y4("\x1B[0;32m"),p0=y4("\x1B[1;33m"),XZ8=y4("\x1B[0;34m"),K8=y4("\x1B[0;36m"),L8=y4("\x1B[1m"),K9=y4("\x1B[2m"),c=y4("\x1B[0m")});import{accessSync as nr,constants as sr,existsSync as rr,statSync as tr}from"fs";async function n5(){if(g$!==void 0)return g$;let $="/opt/homebrew/bin/python3.12";if(rr($))return g$=$,$;let Z=await O9("python3.12");if(Z)return g$=Z,Z;let Q=await O9("python3");return g$=Q,Q}async function T6($,Z={}){let Q=await n5();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return D0([Q,"-c",$],Z)}async function XD(){let $=(process.env.PATH??"").split(":").filter((Z)=>Z.startsWith("/"));for(let Z of[...$t,...$.map((Q)=>`${Q}/python3`)])try{if(!tr(Z).isFile())continue;if(nr(Z,sr.X_OK),(await D0([Z,"-I","-S","-c",""],{timeoutMs:1e4})).exitCode===0)return Z}catch{}return null}var g$,er,$t;var D6=v(()=>{J9();er=["/usr/bin/python3","/bin/python3"],$t=er});var CD={};R0(CD,{runStatus:()=>Ft});import{existsSync as Y9,readFileSync as W2,readdirSync as BD,statSync as UD}from"fs";import{resolve as u8,basename as Nt}from"path";import{homedir as Mt}from"os";function OD($){let Z=Math.trunc($);if(Z>=1e6)return`${(Math.trunc(Z/1e6*10)/10).toFixed(1)}M`;if(Z>=1000)return`${(Math.trunc(Z/1000*10)/10).toFixed(1)}K`;return String(Z)}function ND($,Z,Q){if(Z===0)return null;let X=Math.trunc($*100/Z),J=Math.trunc($*IK/Z);if(J>IK)J=IK;let K=IK-J,Y=P8;if(X>=80)Y=k0;else if(X>=50)Y=p0;let z="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,K)),V=OD($),W=OD(Z);return` ${L8}${Q}${c} ${Y}[${z}]${c} ${X}% (${V} / ${W})`}async function Lt(){if(await O9("jq"))return!0;return process.stdout.write(`${k0}Error: jq is required but not installed.${c}
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)
@@ -1568,4 +1568,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1568
1568
  `),2}case"start":{let{runStart:X}=await Promise.resolve().then(() => (Va(),za));return X(Q)}case"engine10":{let{runEngine10:X}=await Promise.resolve().then(() => (Ga(),qa)),{registryLoader:J}=await Promise.resolve().then(() => (zG(),ns));return X(Q,J)}default:return process.stderr.write(`Unknown command: ${Z}
1569
1569
  `),process.stderr.write(ss),2}}GD();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var g$8=await h$8(Bun.argv.slice(2));process.exit(g$8);
1570
1570
 
1571
- //# debugId=6415D8B155B3C69871FB228501A02B06
1571
+ //# debugId=DE3AF6140481AEE15FA9878226413D5E
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '10.5.22'
78
+ __version__ = '10.5.24'
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": "10.5.22",
4
+ "version": "10.5.24",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -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": "10.5.22",
5
+ "version": "10.5.24",
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",
@@ -74,13 +74,18 @@ function buildDetails(data, payload) {
74
74
  */
75
75
  function initIntegrations() {
76
76
  // Jira
77
- if (process.env.LOKI_JIRA_URL && process.env.LOKI_JIRA_TOKEN) {
77
+ var jiraVars = ['LOKI_JIRA_URL', 'LOKI_JIRA_EMAIL', 'LOKI_JIRA_TOKEN'];
78
+ var jiraMissing = jiraVars.filter(function (k) { return !process.env[k]; });
79
+ if (jiraMissing.length > 0 && jiraMissing.length < jiraVars.length) {
80
+ console.error('[sync-subscriber] Jira not started, missing: ' + jiraMissing.join(', '));
81
+ } else if (jiraMissing.length === 0) {
78
82
  try {
79
83
  var JiraApiClient = require('./jira/api-client').JiraApiClient;
80
84
  var JiraSyncManager = require('./jira/sync-manager').JiraSyncManager;
81
85
  var client = new JiraApiClient({
82
86
  baseUrl: process.env.LOKI_JIRA_URL,
83
- token: process.env.LOKI_JIRA_TOKEN,
87
+ email: process.env.LOKI_JIRA_EMAIL,
88
+ apiToken: process.env.LOKI_JIRA_TOKEN,
84
89
  });
85
90
  var syncManager = new JiraSyncManager({ apiClient: client });
86
91
  integrations.push({
@@ -1,4 +1,4 @@
1
- import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-DqLaggNg.js";import{B as C}from"./Button-OEb0K5fU.js";import{T as $e}from"./trending-up-DwB8jgl2.js";import{C as z}from"./clock-BDKw1_R8.js";import{A as Be,U as ue,M as De}from"./Avatar-DdlzHGiT.js";import{A as J}from"./activity-B43aIno-.js";import{R as pe}from"./refresh-cw-DpmPbMhN.js";import{G as ze}from"./globe-NgUZ94HR.js";import{C as Le}from"./chevron-left-DqQV0gcd.js";import{C as je}from"./check-DfMG8EL7.js";import{D as Y}from"./dollar-sign-C2JeiZKd.js";import{U as Te}from"./user-BgUGFZBV.js";import{D as Me}from"./database-B9oHux-i.js";import{L as Ue}from"./lock-Dzt5MqiP.js";import{S as Re}from"./scroll-text-C7dHDNJR.js";import{S as Ie}from"./shield-alert-B86sjYoT.js";/**
1
+ import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-r93xpUon.js";import{B as C}from"./Button-B1u8l20V.js";import{T as $e}from"./trending-up-Cm4s3m48.js";import{C as z}from"./clock-Cq-zj0ZJ.js";import{A as Be,U as ue,M as De}from"./Avatar-CPKsZYTu.js";import{A as J}from"./activity-CKvd8U1b.js";import{R as pe}from"./refresh-cw-CWDIiQWB.js";import{G as ze}from"./globe-CVl8_kt5.js";import{C as Le}from"./chevron-left-d1OZMSD2.js";import{C as je}from"./check-B-xfD1pQ.js";import{D as Y}from"./dollar-sign-NAaKHtUp.js";import{U as Te}from"./user-Be2fDa0U.js";import{D as Me}from"./database-hJAIBBOu.js";import{L as Ue}from"./lock-BxBPSPk_.js";import{S as Re}from"./scroll-text-ghD5rTL5.js";import{S as Ie}from"./shield-alert-qDqPANTP.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as l,j as s}from"./index-DqLaggNg.js";/**
1
+ import{c as l,j as s}from"./index-r93xpUon.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-DqLaggNg.js";import{C as r}from"./clock-BDKw1_R8.js";import{C as a}from"./circle-alert-7GFVd60S.js";import{C as l}from"./check-DfMG8EL7.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-r93xpUon.js";import{C as r}from"./clock-Cq-zj0ZJ.js";import{C as a}from"./circle-alert-BDPtB3PN.js";import{C as l}from"./check-B-xfD1pQ.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-DqLaggNg.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-r93xpUon.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
@@ -1,4 +1,4 @@
1
- import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-DqLaggNg.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-BG1SdbI9.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-C5Y3O7Ik.js";import{C as oe}from"./check-DfMG8EL7.js";import{C as Ye}from"./clock-BDKw1_R8.js";import{D as Xe}from"./dollar-sign-C2JeiZKd.js";import{U as Ze}from"./upload-DyaOVrs9.js";import{L as V}from"./loader-circle-D3Re-zBz.js";/**
1
+ import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-r93xpUon.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DMvaiN2_.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-MLrmE9p8.js";import{C as oe}from"./check-B-xfD1pQ.js";import{C as Ye}from"./clock-Cq-zj0ZJ.js";import{D as Xe}from"./dollar-sign-NAaKHtUp.js";import{U as Ze}from"./upload-DjdbK3Je.js";import{L as V}from"./loader-circle-BkL9W5Mv.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as o,j as e}from"./index-DqLaggNg.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
1
+ import{r as o,j as e}from"./index-r93xpUon.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
@@ -1,4 +1,4 @@
1
- import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-DqLaggNg.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-r93xpUon.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as l,a as x,j as e}from"./index-DqLaggNg.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
1
+ import{r as l,a as x,j as e}from"./index-r93xpUon.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
@@ -1,4 +1,4 @@
1
- import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-DqLaggNg.js";import{B as N}from"./Button-OEb0K5fU.js";import{C as y}from"./thumbs-up-C5Y3O7Ik.js";import{R as S}from"./refresh-cw-DpmPbMhN.js";import{C as z}from"./circle-alert-7GFVd60S.js";import{U as D}from"./user-BgUGFZBV.js";import{L as G}from"./loader-circle-D3Re-zBz.js";import{R as T}from"./rotate-ccw-DdkhV-ED.js";/**
1
+ import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-r93xpUon.js";import{B as N}from"./Button-B1u8l20V.js";import{C as y}from"./thumbs-up-MLrmE9p8.js";import{R as S}from"./refresh-cw-CWDIiQWB.js";import{C as z}from"./circle-alert-BDPtB3PN.js";import{U as D}from"./user-Be2fDa0U.js";import{L as G}from"./loader-circle-BkL9W5Mv.js";import{R as T}from"./rotate-ccw-BgVXIVTU.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-DqLaggNg.js";import{B as y}from"./Button-OEb0K5fU.js";import{C as ge}from"./chevron-left-DqQV0gcd.js";import{G as P}from"./thumbs-up-C5Y3O7Ik.js";import{R as $}from"./refresh-cw-DpmPbMhN.js";import{C as Ne}from"./circle-alert-7GFVd60S.js";import{L as Q,S as je}from"./ProjectPage-BDryei4O.js";import{S as se}from"./shield-alert-B86sjYoT.js";import{F as ye}from"./file-code-corner-CkqFpKah.js";import{C as V}from"./clock-BDKw1_R8.js";import{C as re}from"./check-DfMG8EL7.js";import"./ErrorBoundary-BG1SdbI9.js";import"./TerminalOutput-BZxTHYwT.js";import"./lock-Dzt5MqiP.js";import"./package-dKDrYcHV.js";import"./file-plus-DbNKpj5U.js";import"./activity-B43aIno-.js";import"./scroll-text-C7dHDNJR.js";import"./bot-B8WyaOPt.js";import"./loader-circle-D3Re-zBz.js";import"./hammer-BMDwR3rq.js";import"./dollar-sign-C2JeiZKd.js";import"./globe-NgUZ94HR.js";import"./trash-2-ByEJRbuH.js";import"./upload-DyaOVrs9.js";import"./plus-P6H35lZz.js";import"./rotate-ccw-DdkhV-ED.js";import"./code-xml-V_GOUJ82.js";import"./trending-up-DwB8jgl2.js";import"./layers-JrA9gfn-.js";import"./trending-down-Dc44T-Va.js";import"./server-D7SziIKB.js";/**
1
+ import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-r93xpUon.js";import{B as y}from"./Button-B1u8l20V.js";import{C as ge}from"./chevron-left-d1OZMSD2.js";import{G as P}from"./thumbs-up-MLrmE9p8.js";import{R as $}from"./refresh-cw-CWDIiQWB.js";import{C as Ne}from"./circle-alert-BDPtB3PN.js";import{L as Q,S as je}from"./ProjectPage-D7_H_qgT.js";import{S as se}from"./shield-alert-qDqPANTP.js";import{F as ye}from"./file-code-corner-D7XBEpP-.js";import{C as V}from"./clock-Cq-zj0ZJ.js";import{C as re}from"./check-B-xfD1pQ.js";import"./ErrorBoundary-DMvaiN2_.js";import"./TerminalOutput-jOfxyPFJ.js";import"./lock-BxBPSPk_.js";import"./package-BO4fpgTO.js";import"./file-plus-KZyMeKo5.js";import"./activity-CKvd8U1b.js";import"./scroll-text-ghD5rTL5.js";import"./bot-C_jRLKqH.js";import"./loader-circle-BkL9W5Mv.js";import"./hammer-NhQB95s9.js";import"./dollar-sign-NAaKHtUp.js";import"./globe-CVl8_kt5.js";import"./trash-2-7s8w8-_n.js";import"./upload-DjdbK3Je.js";import"./plus-CQZ1XzjX.js";import"./rotate-ccw-BgVXIVTU.js";import"./code-xml-BadEEBt6.js";import"./trending-up-Cm4s3m48.js";import"./layers-N-hCKTPD.js";import"./trending-down-fhZdmlgX.js";import"./server-kP2j3KGS.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.