loki-mode 11.17.73 → 11.17.74

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 (69) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/dashboard/__init__.py +1 -1
  4. package/docs/CLI-REFERENCE.md +1 -1
  5. package/docs/INSTALLATION.md +1 -1
  6. package/docs/environment-variables.md +1 -1
  7. package/docs/v10/DECISIONS.md +1 -1
  8. package/docs/v10/PROGRESS.md +3 -0
  9. package/loki-ts/dist/loki.js +3 -3
  10. package/mcp/__init__.py +1 -1
  11. package/package.json +2 -2
  12. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  13. package/web-app/dist/assets/{AdminPage-CAw3IFCu.js → AdminPage-BMEz6PjD.js} +1 -1
  14. package/web-app/dist/assets/{Avatar-D4-XntzA.js → Avatar-CWqr7n5f.js} +1 -1
  15. package/web-app/dist/assets/{Badge-C1fHRqJG.js → Badge-0HwtDygF.js} +1 -1
  16. package/web-app/dist/assets/{Button-CzD_JfV1.js → Button-9dckZRDN.js} +1 -1
  17. package/web-app/dist/assets/{CockpitPage-biH-pfqC.js → CockpitPage-nYMuXSfl.js} +1 -1
  18. package/web-app/dist/assets/{ComparePage-xMMPe6lI.js → ComparePage-Bc5srye5.js} +1 -1
  19. package/web-app/dist/assets/{ErrorBoundary-LISxmNUO.js → ErrorBoundary-BkDMHZsx.js} +1 -1
  20. package/web-app/dist/assets/{EvidenceReceiptPanel-BJ70o_uy.js → EvidenceReceiptPanel-M8zrEQxG.js} +1 -1
  21. package/web-app/dist/assets/{GitHubIssuesPanel-D5ApCUhD.js → GitHubIssuesPanel-MvOtqrJO.js} +1 -1
  22. package/web-app/dist/assets/{GitHubPRsPanel-BtTNo3-s.js → GitHubPRsPanel-Cx6sFkSQ.js} +1 -1
  23. package/web-app/dist/assets/{HomePage-C9NPfbCn.js → HomePage-KoGFVyhn.js} +2 -2
  24. package/web-app/dist/assets/{LoginPage-Dfei1DgX.js → LoginPage-BJKuRfBJ.js} +1 -1
  25. package/web-app/dist/assets/{MagicPage-KUCdTZ47.js → MagicPage-CH19MKyX.js} +1 -1
  26. package/web-app/dist/assets/{MetricsPage-CMwW5kgY.js → MetricsPage-CTiPy6uL.js} +1 -1
  27. package/web-app/dist/assets/{NotFoundPage-DyK_dXex.js → NotFoundPage-B3x9Admx.js} +1 -1
  28. package/web-app/dist/assets/{ProjectPage--I3rB_p4.js → ProjectPage-B7NMYrmn.js} +3 -3
  29. package/web-app/dist/assets/{ProjectsPage-CW57oFYD.js → ProjectsPage-BNbo3wR3.js} +1 -1
  30. package/web-app/dist/assets/{SettingsPage-cW-BXZGS.js → SettingsPage-Dk9w3rKx.js} +1 -1
  31. package/web-app/dist/assets/{ShowcasePage-__24vOZq.js → ShowcasePage-Dk7LBonS.js} +1 -1
  32. package/web-app/dist/assets/{SystemSettingsPage-CM-54CV0.js → SystemSettingsPage-FTbJ_2Hn.js} +1 -1
  33. package/web-app/dist/assets/{TeamsPage-NphA-ubY.js → TeamsPage-CdKmEVIO.js} +1 -1
  34. package/web-app/dist/assets/{TemplatesPage-9ERZiFUR.js → TemplatesPage-Du6EHrwu.js} +1 -1
  35. package/web-app/dist/assets/{TerminalOutput-BT2DzBO1.js → TerminalOutput-BTlTI6D7.js} +1 -1
  36. package/web-app/dist/assets/{activity-CQJpef5Z.js → activity-BXuoHaM2.js} +1 -1
  37. package/web-app/dist/assets/{bell-Bxopl5iP.js → bell-DCDgirjw.js} +1 -1
  38. package/web-app/dist/assets/{bot-BEjHVO92.js → bot-vJgiSrdQ.js} +1 -1
  39. package/web-app/dist/assets/{check-Do1juwL_.js → check-D-RGuqkl.js} +1 -1
  40. package/web-app/dist/assets/{chevron-left-Hn3UM-NM.js → chevron-left-NKl5Cd-R.js} +1 -1
  41. package/web-app/dist/assets/{circle-alert-Btc-PWto.js → circle-alert-ByXEu_ry.js} +1 -1
  42. package/web-app/dist/assets/{clock-9J88OP3M.js → clock-sHF7TkaL.js} +1 -1
  43. package/web-app/dist/assets/{cloud-JPIPzxJd.js → cloud-D6mqiMKo.js} +1 -1
  44. package/web-app/dist/assets/{code-xml-iv1keZ9N.js → code-xml-huk-YFT0.js} +1 -1
  45. package/web-app/dist/assets/{database-DwFbyMQf.js → database-BOlnZ1VP.js} +1 -1
  46. package/web-app/dist/assets/{dollar-sign-Bt1rF0Up.js → dollar-sign-BkQRFa0q.js} +1 -1
  47. package/web-app/dist/assets/{file-code-corner-BvhHgreH.js → file-code-corner-ugbZnTSY.js} +1 -1
  48. package/web-app/dist/assets/{file-plus-CeOevK8W.js → file-plus-C36sokvh.js} +1 -1
  49. package/web-app/dist/assets/{globe-BIMbYVfR.js → globe-CJQelTw1.js} +1 -1
  50. package/web-app/dist/assets/{hammer-CMG6alC6.js → hammer-DPzU4Wtq.js} +1 -1
  51. package/web-app/dist/assets/{index-D1-1DZ1A.js → index-CmNcswQv.js} +3 -3
  52. package/web-app/dist/assets/{layers-Dwoys6vF.js → layers-DzMH-GEN.js} +1 -1
  53. package/web-app/dist/assets/{loader-circle-CelYAWD2.js → loader-circle-BNbNqvck.js} +1 -1
  54. package/web-app/dist/assets/{lock-BgFsHF5L.js → lock-9PCIcJ6T.js} +1 -1
  55. package/web-app/dist/assets/{package-5sdo-e9y.js → package-j3aJqney.js} +1 -1
  56. package/web-app/dist/assets/{plus-CSzQUjW8.js → plus-DGAY2LNf.js} +1 -1
  57. package/web-app/dist/assets/{refresh-cw-Bdo9tSnG.js → refresh-cw-BBJiyS_M.js} +1 -1
  58. package/web-app/dist/assets/{rotate-ccw-BaY8Qfhk.js → rotate-ccw-BNLXFero.js} +1 -1
  59. package/web-app/dist/assets/{scroll-text-BN8nd88z.js → scroll-text-CGG6Enap.js} +1 -1
  60. package/web-app/dist/assets/{server-Bi6RuZbH.js → server-Bv6QDqpn.js} +1 -1
  61. package/web-app/dist/assets/{shield-alert-aZX8uTyl.js → shield-alert-BFJHSdqK.js} +1 -1
  62. package/web-app/dist/assets/{thumbs-up-CJBtXUbH.js → thumbs-up-BGbIHMwH.js} +1 -1
  63. package/web-app/dist/assets/{trash-2-bgGf4gkl.js → trash-2-C7mlnJL3.js} +1 -1
  64. package/web-app/dist/assets/{trending-down-BJ0IybHJ.js → trending-down-BbxICDz5.js} +1 -1
  65. package/web-app/dist/assets/{trending-up-CGmXxQM4.js → trending-up-DQqCw2fH.js} +1 -1
  66. package/web-app/dist/assets/{upload-rDccLEQm.js → upload-SWiggmcJ.js} +1 -1
  67. package/web-app/dist/assets/{usePolling-BN36YyBK.js → usePolling-CTxzJty2.js} +1 -1
  68. package/web-app/dist/assets/{user-DeS27GvT.js → user-DPVl5QyH.js} +1 -1
  69. 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 v11.17.73
6
+ # Loki Mode v11.17.74
7
7
 
8
8
  **Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
9
9
 
@@ -483,4 +483,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
483
483
 
484
484
  ---
485
485
 
486
- **v11.17.73 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
486
+ **v11.17.74 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.17.73
1
+ 11.17.74
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.17.73"
10
+ __version__ = "11.17.74"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.73. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.74. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
4
4
 
5
- **Version:** v11.17.73
5
+ **Version:** v11.17.74
6
6
 
7
7
  **Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
8
8
 
@@ -50,7 +50,7 @@ interact and why hitting one is a failure rather than a success.
50
50
  | `LOKI_SUMMARY_JSON` | unset | `1` prints the end-of-run summary as one JSON line on the previous loop. |
51
51
  | `LOKI_TIER` | `oss` | **Not a model setting.** The open-core licensing seam. Leave it unset. |
52
52
  | `LOKI_E10_STABLE_PREFIX` | on | Engine10 sessions send the `claude_code` preset with `excludeDynamicSections: true`, so the system prompt is byte-identical across stages and runs and hits the prompt cache. `0` restores the previous preset. `LOKI_E10_PREFIX=lean` still wins when set. |
53
- | `LOKI_E10_INSTALL` | on | Up-front dependency install at intake. `0` disables it (same as `verify.install_deps: false` in loki.yaml); the run then reports the missing dependencies as NOT PROVEN. When on, each package whose dependencies are absent is installed once per run before the baseline, using the lockfile-frozen form when the package has a lockfile: `npm ci`, `pnpm install --frozen-lockfile`, `yarn install --immutable` (Yarn Berry) or `--frozen-lockfile`, `bun install --frozen-lockfile`, `uv sync --locked`, `poetry install` (already lock-honoring, kept as written), `pipenv install --deploy`, `cargo fetch --locked`, `BUNDLE_FROZEN=true bundle install`, `composer install`. These never rewrite the lockfile. A lockfile governs a package only when it sits in the package directory, or in an ancestor that declares a workspace containing it (package.json `workspaces`, pnpm-workspace.yaml, Cargo `[workspace]`, uv `tool.uv.workspace`); a standalone sub-project beside a root lockfile keeps its own install command. The install command is rewritten only if it is simple enough to reason about without a shell parser; otherwise it is left as written and recorded `locked: false`: a `||` anywhere (lock_note "fallback masks install failure"); any character outside letters, digits, space, tab and `_./=:@+,%~-` besides the separators `&&`, `;` and newline, or anything before the first install other than `cd <path>`, `export VAR=value` or plain VAR=value assignments, or any PATH assignment (lock_note "unparsed shell construct"); and an install followed by a `;` or newline command, which would mask its failure (lock_note "later command masks install failure"), so after the install only `&&` is allowed. If the locked install fails (for example the lockfile is out of sync with the manifest), the run reports NOT PROVEN with the real error and does not retry with a mutating install. With no lockfile, or no matching rule, the project's own install command runs and the receipt records `locked: false`. The project's own install scripts (for example npm postinstall) run just as they do for a developer, so disable the install for a repo you do not trust. |
53
+ | `LOKI_E10_INSTALL` | on | Up-front dependency install at intake. `0` disables it (same as `verify.install_deps: false` in loki.yaml); the run then reports the missing dependencies as NOT PROVEN. When on, each package whose dependencies are absent is installed once per run before the baseline, using the lockfile-frozen form when the package has a lockfile: `npm ci`, `pnpm install --frozen-lockfile`, `yarn install --immutable` (Yarn Berry) or `--frozen-lockfile`, `bun install --frozen-lockfile`, `uv sync --locked`, `poetry install` (already lock-honoring, kept as written), `pipenv install --deploy`, `cargo fetch --locked`, `BUNDLE_FROZEN=true bundle install`, `composer install`. These never rewrite the lockfile. A lockfile governs a package only when it sits in the package directory, or in an ancestor that declares a workspace containing it (package.json `workspaces`, pnpm-workspace.yaml, Cargo `[workspace]`, uv `tool.uv.workspace`); a standalone sub-project beside a root lockfile keeps its own install command. The install command is rewritten only if it is simple enough to reason about without a shell parser; otherwise it is left as written and recorded `locked: false`: a `||` anywhere (lock_note "fallback masks install failure"); any character outside letters, digits, space, tab and `_./=:@+,%~-` besides the separators `&&`, `;` and newline, or anything before the first install other than `cd <path>`, `export VAR=value` or plain VAR=value assignments, or any assignment to PATH, NODE_OPTIONS, BASH_ENV or ENV (lock_note "unparsed shell construct"); and an install followed by a `;` or newline command, which would mask its failure (lock_note "later command masks install failure"), so after the install only `&&` is allowed. If the locked install fails (for example the lockfile is out of sync with the manifest), the run reports NOT PROVEN with the real error and does not retry with a mutating install. With no lockfile, or no matching rule, the project's own install command runs and the receipt records `locked: false`. The project's own install scripts (for example npm postinstall) run just as they do for a developer, so disable the install for a repo you do not trust. |
54
54
  | `LOKI_REPO_BASELINE` | unset | `0` skips the intake repo profile and baseline test run (see docs/HARNESS-INTELLIGENCE-PLAN.md). |
55
55
  | `LOKI_ALLOW_CLAUDE_SIDECALLS` | unset | `1` (exactly) lets PRD enrichment, done recognition, the council voters, the USAGE.md refresh and the quickstart intent check prompt the `claude` CLI under a non-claude provider; `loki doctor --airgap` then reports that as required egress to Anthropic. |
56
56
 
@@ -870,7 +870,7 @@ FC-AGENT-PROOF: a run whose only executed passing check is a test file the same
870
870
  1. The founder kept the intake dependency install shipped in 11.17.68 (intakeDeps installs each package whose dependencies are absent, before the baseline and the Wall base run) and asked that it meet industry-standard, enterprise practice. This supersedes the "only when a selected check fails" wording of FOUNDER-QUEUE row 19 part (b); the evidence-triggered path stays as well.
871
871
  2. Locked: install.ts `lockedInstall` maps (package root contents, model command) to the ecosystem's frozen form through one table. Lockfile to form: package-lock.json or npm-shrinkwrap.json `npm ci`; pnpm-lock.yaml `pnpm install --frozen-lockfile`; yarn.lock `yarn install --immutable` (Berry: .yarnrc.yml or packageManager yarn@>=2) else `--frozen-lockfile`; bun.lock or bun.lockb `bun install --frozen-lockfile`; uv.lock `uv sync --locked`; poetry.lock `poetry install` (already lock-honoring, kept as written); Pipfile.lock `pipenv install --deploy`; Cargo.lock `cargo fetch --locked`; Gemfile.lock `BUNDLE_FROZEN=true bundle install`; composer.lock `composer install`. A lockfile governs a package only if it is in the package directory or in an ancestor that declares a workspace containing the package (package.json workspaces for npm, yarn and bun; pnpm-workspace.yaml; Cargo [workspace] members; uv tool.uv.workspace members); otherwise the command is kept and recorded unlocked. A `cd X` segment moves the lookup to X. An already-locked model command is kept byte for byte; flags are kept; a command that names packages, a missing lockfile or no matching rule keeps the model command and the check records `locked: false` with `lock_note`.
872
872
  3. poetry: `poetry install` already honors poetry.lock and is kept unchanged. `--no-root` is deliberately not added (it skips installing the project itself and breaks src-layout imports) and neither is `--sync` (it removes environment packages the lock lacks).
873
- 4. Fail closed: a locked install that fails (for example a lockfile out of sync with its manifest) is a harness-owned NOT PROVEN with the real output excerpt; the harness never falls back to a mutating install. A command containing a `||` anywhere is left entirely as written (every install in it, `locked: false`, lock_note "fallback masks install failure"), because the shell reads `a && b || c` as `(a && b) || c` and the fallback masks a failure in any earlier segment; so is any command outside an allowlist (lock_note "unparsed shell construct"), since there is no shell parser: after trimming trailing whitespace and `;`/newline separators and joining `\<newline>` continuations, the command may contain only [A-Za-z0-9 _./=:@+,%~-], tabs and the separators `&&`, `;` and newline (so no quotes, backticks, parens, braces, `$`, redirects, `|` or lone `&`), every segment before the first install must be `cd <path>`, `export VAR=value` or pure VAR=value assignments (so set, pushd, trap, function, alias, shopt, eval, source, exec and the like are refused), and any assignment to PATH, bare, exported or as an install prefix, is refused. A command that passes is rewritten only where each install and every segment after it are joined by `&&`: runDetached runs `bash -c` without -e, so a later `;` or newline command (for example `npm install; echo done`) would mask a failed locked install, and the whole command is then left as written with `locked: false` and lock_note "later command masks install failure". Separators before the install (`cd x; npm install`) are fine. pnpm `--no-frozen-lockfile` is dropped when `--frozen-lockfile` is added.
873
+ 4. Fail closed: a locked install that fails (for example a lockfile out of sync with its manifest) is a harness-owned NOT PROVEN with the real output excerpt; the harness never falls back to a mutating install. A command containing a `||` anywhere is left entirely as written (every install in it, `locked: false`, lock_note "fallback masks install failure"), because the shell reads `a && b || c` as `(a && b) || c` and the fallback masks a failure in any earlier segment; so is any command outside an allowlist (lock_note "unparsed shell construct"), since there is no shell parser: after trimming trailing whitespace and `;`/newline separators and joining `\<newline>` continuations, the command may contain only [A-Za-z0-9 _./=:@+,%~-], tabs and the separators `&&`, `;` and newline (so no quotes, backticks, parens, braces, `$`, redirects, `|` or lone `&`), every segment before the first install must be `cd <path>`, `export VAR=value` or pure VAR=value assignments (so set, pushd, trap, function, alias, shopt, eval, source, exec and the like are refused), and any assignment to PATH, NODE_OPTIONS, BASH_ENV or ENV, bare, exported or as an install prefix, is refused. A command that passes is rewritten only where each install and every segment after it are joined by `&&`: runDetached runs `bash -c` without -e, so a later `;` or newline command (for example `npm install; echo done`) would mask a failed locked install, and the whole command is then left as written with `locked: false` and lock_note "later command masks install failure". Separators before the install (`cd x; npm install`) are fine. pnpm `--no-frozen-lockfile` is dropped when `--frozen-lockfile` is added.
874
874
  5. Visible: the install check and the deps.install event carry `cmd` (what ran), `locked`, `lock_note` and, when rewritten, `model_cmd`.
875
875
  6. The project's own install scripts (for example npm postinstall) run exactly as they do for a developer; opt-out is LOKI_E10_INSTALL=0 or loki.yaml `verify.install_deps: false`, documented in docs/environment-variables.md.
876
876
  - Amendment (D99): uv uses `uv sync --locked` (fails on an out-of-sync uv.lock; `--frozen` is replaced) and pipenv uses `pipenv install --deploy` (fails on an out-of-date Pipfile.lock; `pipenv sync` is replaced); pnpm-workspace.yaml is read in inline-list, block and unindented-block forms with `!` exclusions.
@@ -2593,3 +2593,6 @@ v11.17.21 published (Release success on 462fbc40a; npm latest 11.17.21, next 11.
2593
2593
 
2594
2594
  ## 2026-10-19T03:12Z (CoS) v11.17.73
2595
2595
  - 11.17.73: P0 fix-forward for D106 install masking (live in 71/72). af838b55 commits 2bb2f0194..279f1ac5d cherry-picked as 2599744de..20cf84915 plus D106 wording fix. HIGH a1168a6d: BLOCK x5 (||, quoted separators, later ; list, trap/function/alias, set -n), APPROVE round 6 at 279f1ac5d: fc22_install+intake+budget 145 pass 0 fail, real npm stale-lock probes all rc=1 on rewritten shapes.
2596
+
2597
+ ## 2026-10-19T03:16Z (CoS) v11.17.74
2598
+ - 11.17.74: D106 follow-up, NODE_OPTIONS/BASH_ENV/ENV refused like PATH. af838b55 4284ae1fb cherry-picked. HIGH a1168a6d round 7 APPROVE: 4 files 5+/5-, probes 8 refused, no over-match, fc22_install+intake+budget 145 pass 0 fail; red 56/1 with source reverted.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var ZS0=Object.create;var{getPrototypeOf:$S0,defineProperty:cW,getOwnPropertyNames:va,getOwnPropertyDescriptor:JS0}=Object,ha=Object.prototype.hasOwnProperty;function fa(Z){return this[Z]}var XS0,YS0,zS0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?XS0??=new WeakMap:YS0??=new WeakMap,z=Y.get(Z);if(z)return z}J=Z!=null?ZS0($S0(Z)):{};let Q=$||!Z||!Z.__esModule?cW(J,"default",{value:Z,enumerable:!0}):J;for(let W of va(Z))if(!ha.call(Q,W))cW(Q,W,{get:fa.bind(Z,W),enumerable:!0});if(X)Y.set(Z,Q);return Q},QS0=(Z)=>{var $=(ya??=new WeakMap).get(Z),J;if($)return $;if($=cW({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of va(Z))if(!ha.call($,X))cW($,X,{get:fa.bind(Z,X),enumerable:!(J=JS0(Z,X))||J.enumerable})}return ya.set(Z,$),$},ya,UN=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var WS0=(Z)=>Z;function KS0(Z,$){this[Z]=WS0.bind(null,$)}var A0=(Z,$)=>{for(var J in $)cW(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:KS0.bind($,J)})};var b=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var i9=import.meta.require;var ma={};A0(ma,{lokiDir:()=>P0,homeLokiDir:()=>U2,findRepoRootForVersion:()=>dW,REPO_ROOT:()=>j0});import{resolve as BZ,dirname as nP}from"path";import{fileURLToPath as VS0}from"url";import{existsSync as BN}from"fs";import{homedir as GS0}from"os";function HS0(){let Z=ga;for(let $=0;$<6;$++){if(BN(BZ(Z,"VERSION"))&&BN(BZ(Z,"autonomy/run.sh")))return Z;let J=nP(Z);if(J===Z)break;Z=J}return BZ(ga,"..","..","..")}function dW(Z){let $=Z;for(let J=0;J<6;J++){if(BN(BZ($,"VERSION"))&&BN(BZ($,"autonomy/run.sh")))return $;let X=nP($);if(X===$)break;$=X}return BZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??BZ(process.cwd(),".loki")}function U2(){return BZ(GS0(),".loki")}var ga,j0;var o0=b(()=>{ga=nP(VS0(import.meta.url));j0=HS0()});import{readFileSync as qS0}from"fs";import{resolve as US0,dirname as BS0}from"path";import{fileURLToPath as NS0}from"url";function H6(){if(N1!==null)return N1;let Z="11.17.73";if(typeof Z==="string"&&Z.length>0)return N1=Z,N1;try{let $=BS0(NS0(import.meta.url)),J=dW($);N1=qS0(US0(J,"VERSION"),"utf-8").trim()}catch{N1="unknown"}return N1}var N1=null;var NZ=b(()=>{o0()});import{mkdirSync as rP,readFileSync as NN,realpathSync as MS0,statSync as OS0,writeFileSync as tP}from"fs";import{dirname as uX,join as sP,resolve as ua}from"path";function CS0(){return ua(U2(),"cache","update-check.json")}function MZ(Z){let $=/^(\d+)\.(\d+)\.(\d+)$/.exec(Z.trim());if(!$)return null;return[Number($[1]),Number($[2]),Number($[3])]}function lW(Z,$){let J=MZ(Z),X=MZ($);if(!J||!X)return!1;let[Y,z,Q]=J,[W,K,V]=X;if(Y!==W)return Y>W;if(z!==K)return z>K;return Q>V}function pa(){let Z=(process.env.LOKI_NO_UPDATE_CHECK??"").trim().toLowerCase();if(Z==="1"||Z==="true"||Z==="yes")return!0;if(process.env.CI)return!0;if(!process.stdout.isTTY)return!0;return!1}function ca(Z){try{let $=NN(Z,"utf-8"),J=JSON.parse($);if(typeof J.checkedAt==="number"&&typeof J.latest==="string"&&MZ(J.latest)!==null)return{checkedAt:J.checkedAt,latest:J.latest}}catch{}return null}function IS0(Z){try{let $=JSON.parse(NN(Z,"utf-8")).failedAt;if(typeof $==="number")return $}catch{}return null}function TS0(Z,$){let J=ca(Z);try{rP(uX(Z),{recursive:!0}),tP(Z,JSON.stringify({...J??{},failedAt:$}),"utf-8")}catch{}}function PS0(Z,$){try{rP(uX(Z),{recursive:!0}),tP(Z,JSON.stringify($),"utf-8")}catch{}}async function RS0(){try{let Z=await fetch(AS0,{signal:AbortSignal.timeout(jS0),headers:{accept:"application/json"}});if(!Z.ok)return null;let $=await Z.json();if(typeof $.version==="string"&&MZ($.version)!==null)return $.version}catch{}return null}async function ES0(Z=Date.now(),$=RS0,J=CS0()){let X=ca(J);if(X&&Z-X.checkedAt<LS0)return X.latest;let Y=IS0(J);if(Y!==null&&Z-Y>=0&&Z-Y<FS0)return null;let z=await $();if(z===null)return TS0(J,Z),null;return PS0(J,{checkedAt:Z,latest:z}),z}function DS0(Z,$=process.env){if(MZ(Z)===null)return null;let X=$.PATH;if(!X)return null;let Y=new Set;for(let z of X.split(":")){if(!z)continue;let Q=sP(z,"loki"),W;try{OS0(Q),W=MS0(Q)}catch{continue}if(Y.has(W))continue;Y.add(W);try{let K=sP(uX(uX(W)),"package.json"),V=JSON.parse(NN(K,"utf8")).version;if(typeof V!=="string")continue;if(lW(V,Z))return{path:Q,version:V}}catch{continue}}return null}function wS0(){return ua(U2(),"cache","last-seen-version.json")}function _S0(Z,$={}){try{if(pa())return!1;if(MZ(Z)===null)return!1;let J=$.seenFile??wS0(),X=null;try{let z=JSON.parse(NN(J,"utf-8")).version;if(typeof z==="string"&&MZ(z)!==null)X=z}catch{}if(X!==null&&!lW(Z,X))return!1;try{rP(uX(J),{recursive:!0}),tP(J,JSON.stringify({version:Z}),"utf-8")}catch{return!1}if(X===null)return!1;return($.write??((z)=>process.stderr.write(z)))(`Loki Mode upgraded ${X} -> ${Z}. What is new: https://github.com/asklokesh/loki-mode/releases/tag/v${Z}
2
+ var ZS0=Object.create;var{getPrototypeOf:$S0,defineProperty:cW,getOwnPropertyNames:va,getOwnPropertyDescriptor:JS0}=Object,ha=Object.prototype.hasOwnProperty;function fa(Z){return this[Z]}var XS0,YS0,zS0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?XS0??=new WeakMap:YS0??=new WeakMap,z=Y.get(Z);if(z)return z}J=Z!=null?ZS0($S0(Z)):{};let Q=$||!Z||!Z.__esModule?cW(J,"default",{value:Z,enumerable:!0}):J;for(let W of va(Z))if(!ha.call(Q,W))cW(Q,W,{get:fa.bind(Z,W),enumerable:!0});if(X)Y.set(Z,Q);return Q},QS0=(Z)=>{var $=(ya??=new WeakMap).get(Z),J;if($)return $;if($=cW({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of va(Z))if(!ha.call($,X))cW($,X,{get:fa.bind(Z,X),enumerable:!(J=JS0(Z,X))||J.enumerable})}return ya.set(Z,$),$},ya,UN=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var WS0=(Z)=>Z;function KS0(Z,$){this[Z]=WS0.bind(null,$)}var A0=(Z,$)=>{for(var J in $)cW(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:KS0.bind($,J)})};var b=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var i9=import.meta.require;var ma={};A0(ma,{lokiDir:()=>P0,homeLokiDir:()=>U2,findRepoRootForVersion:()=>dW,REPO_ROOT:()=>j0});import{resolve as BZ,dirname as nP}from"path";import{fileURLToPath as VS0}from"url";import{existsSync as BN}from"fs";import{homedir as GS0}from"os";function HS0(){let Z=ga;for(let $=0;$<6;$++){if(BN(BZ(Z,"VERSION"))&&BN(BZ(Z,"autonomy/run.sh")))return Z;let J=nP(Z);if(J===Z)break;Z=J}return BZ(ga,"..","..","..")}function dW(Z){let $=Z;for(let J=0;J<6;J++){if(BN(BZ($,"VERSION"))&&BN(BZ($,"autonomy/run.sh")))return $;let X=nP($);if(X===$)break;$=X}return BZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??BZ(process.cwd(),".loki")}function U2(){return BZ(GS0(),".loki")}var ga,j0;var o0=b(()=>{ga=nP(VS0(import.meta.url));j0=HS0()});import{readFileSync as qS0}from"fs";import{resolve as US0,dirname as BS0}from"path";import{fileURLToPath as NS0}from"url";function H6(){if(N1!==null)return N1;let Z="11.17.74";if(typeof Z==="string"&&Z.length>0)return N1=Z,N1;try{let $=BS0(NS0(import.meta.url)),J=dW($);N1=qS0(US0(J,"VERSION"),"utf-8").trim()}catch{N1="unknown"}return N1}var N1=null;var NZ=b(()=>{o0()});import{mkdirSync as rP,readFileSync as NN,realpathSync as MS0,statSync as OS0,writeFileSync as tP}from"fs";import{dirname as uX,join as sP,resolve as ua}from"path";function CS0(){return ua(U2(),"cache","update-check.json")}function MZ(Z){let $=/^(\d+)\.(\d+)\.(\d+)$/.exec(Z.trim());if(!$)return null;return[Number($[1]),Number($[2]),Number($[3])]}function lW(Z,$){let J=MZ(Z),X=MZ($);if(!J||!X)return!1;let[Y,z,Q]=J,[W,K,V]=X;if(Y!==W)return Y>W;if(z!==K)return z>K;return Q>V}function pa(){let Z=(process.env.LOKI_NO_UPDATE_CHECK??"").trim().toLowerCase();if(Z==="1"||Z==="true"||Z==="yes")return!0;if(process.env.CI)return!0;if(!process.stdout.isTTY)return!0;return!1}function ca(Z){try{let $=NN(Z,"utf-8"),J=JSON.parse($);if(typeof J.checkedAt==="number"&&typeof J.latest==="string"&&MZ(J.latest)!==null)return{checkedAt:J.checkedAt,latest:J.latest}}catch{}return null}function IS0(Z){try{let $=JSON.parse(NN(Z,"utf-8")).failedAt;if(typeof $==="number")return $}catch{}return null}function TS0(Z,$){let J=ca(Z);try{rP(uX(Z),{recursive:!0}),tP(Z,JSON.stringify({...J??{},failedAt:$}),"utf-8")}catch{}}function PS0(Z,$){try{rP(uX(Z),{recursive:!0}),tP(Z,JSON.stringify($),"utf-8")}catch{}}async function RS0(){try{let Z=await fetch(AS0,{signal:AbortSignal.timeout(jS0),headers:{accept:"application/json"}});if(!Z.ok)return null;let $=await Z.json();if(typeof $.version==="string"&&MZ($.version)!==null)return $.version}catch{}return null}async function ES0(Z=Date.now(),$=RS0,J=CS0()){let X=ca(J);if(X&&Z-X.checkedAt<LS0)return X.latest;let Y=IS0(J);if(Y!==null&&Z-Y>=0&&Z-Y<FS0)return null;let z=await $();if(z===null)return TS0(J,Z),null;return PS0(J,{checkedAt:Z,latest:z}),z}function DS0(Z,$=process.env){if(MZ(Z)===null)return null;let X=$.PATH;if(!X)return null;let Y=new Set;for(let z of X.split(":")){if(!z)continue;let Q=sP(z,"loki"),W;try{OS0(Q),W=MS0(Q)}catch{continue}if(Y.has(W))continue;Y.add(W);try{let K=sP(uX(uX(W)),"package.json"),V=JSON.parse(NN(K,"utf8")).version;if(typeof V!=="string")continue;if(lW(V,Z))return{path:Q,version:V}}catch{continue}}return null}function wS0(){return ua(U2(),"cache","last-seen-version.json")}function _S0(Z,$={}){try{if(pa())return!1;if(MZ(Z)===null)return!1;let J=$.seenFile??wS0(),X=null;try{let z=JSON.parse(NN(J,"utf-8")).version;if(typeof z==="string"&&MZ(z)!==null)X=z}catch{}if(X!==null&&!lW(Z,X))return!1;try{rP(uX(J),{recursive:!0}),tP(J,JSON.stringify({version:Z}),"utf-8")}catch{return!1}if(X===null)return!1;return($.write??((z)=>process.stderr.write(z)))(`Loki Mode upgraded ${X} -> ${Z}. What is new: https://github.com/asklokesh/loki-mode/releases/tag/v${Z}
3
3
  `),!0}catch{return!1}}function xS0(Z){let $=Z.replace(/\\/g,"/");if($.includes("/Cellar/"))return"brew upgrade loki-mode";if(/\/pnpm\//.test($)||$.includes("/.pnpm/"))return"pnpm add -g loki-mode (or npm i -g loki-mode)";if($.includes("/yarn/global/")||$.includes("/.yarn/"))return"yarn global add loki-mode (or npm i -g loki-mode)";if($.includes("/.bun/"))return"bun install -g loki-mode (or npm i -g loki-mode)";if($.includes("/lib/node_modules/"))return"npm i -g loki-mode (or bun install -g loki-mode)";if($.includes("/homebrew/"))return"brew upgrade loki-mode";return"bun install -g loki-mode (or npm i -g loki-mode)"}async function da(Z,$={}){try{if(pa())return;if(MZ(Z)===null)return;let J=$.write??((z)=>process.stderr.write(z));_S0(Z,{write:J,...$.cacheFile?{seenFile:sP(uX($.cacheFile),"last-seen-version.json")}:{}});let X=DS0(Z,$.env??process.env);if(X!==null){J(`Loki Mode ${X.version} is installed but not the one running (you are running ${Z}).
4
4
  Another loki earlier on PATH is winning. Newer copy: ${X.path}
5
5
  Run \`which -a loki\` to see the order, then remove or re-point the earlier entry.
@@ -532,7 +532,7 @@ ${$}
532
532
  ${dQ0(lQ0(Z)).replace(/^# /,"## ")}`}catch{return""}};var jj=b(()=>{_0();f2();G$();C7();d7()});import{lstatSync as Mp8}from"fs";import{join as Op8}from"path";function oQ0(Z,$){let J=[],X={};for(let Y of $){let z=/^([ MADRCU?!]{1,2}) (.+)$/.exec(Y);if(z&&/^(M|MM)$/.test(z[1].trim())&&Ap8.test(z[2]))X[z[2]]=Ly(Z,z[2]);else J.push(Y)}return{blocking:J,preexisting:X}}function jy(Z){return $0(Z,["ls-files","-o","--exclude-standard","-z"]).split("\x00").filter(Boolean)}function nQ0(Z){let $={},J=Number(process.env.LOKI_E10_SNAPSHOT_MAX),X=J>0&&Number.isFinite(J)?J:50000000;for(let Y of jy(Z)){let z;try{z=Mp8(Op8(Z,Y))}catch{$[Y]="!gone";continue}try{if(!z.isFile()||z.size>X)throw Error("skip");$[Y]=`${Ly(Z,Y)} ${(z.mode&511).toString(8)}`}catch{$[Y]=`!${z.size}:${z.mtimeMs}:${z.ctimeMs}`}}return $}function sQ0(Z,$,J=process.env){if(!$||typeof $!=="object")return[];return Object.entries($).filter(([X,Y])=>{try{return Ly(Z,X,J)===Y}catch{return!1}}).map(([X])=>X)}var Ap8,Ly=(Z,$,J=process.env)=>$0(Z,["hash-object","-w","--no-filters","--",$],{env:J}).trim();var Fy=b(()=>{_0();Ap8=/(^|\/)([^/]+\.lockb?|[^/]*\.lockfile|lockfile|[^/]+-lock\.(json|ya?ml)|go\.sum|npm-shrinkwrap\.json|Package\.resolved)$/});function Lp8(Z){return/^\s*Tests:?\s+.*\b[1-9]\d* failed\b/m.test(Z)||/^(?:=+ )?.*\b[1-9]\d* failed\b.* in [\d.]+s/m.test(Z)||/^FAILED \S+::/m.test(Z)||/^(?:#|\u2139) fail [1-9]/m.test(Z)||/^\s*[1-9]\d*\s+fail\s*$/m.test(Z)||/^\s*(?:FAIL|\u00D7)\s+\S.*\s>\s/m.test(Z)||/\bAssertionError\b/.test(Z)}function Fp8(Z){let $=Z.split(`
533
533
  `).map((X)=>X.trim()).filter(Boolean);return($.find((X)=>/^(?:E\s+)?(?:Error|\w*Error|ERROR|Failed|FAIL)\b|Cannot find|Interrupted:|No test files found|\d+: [\w.-]+: not found$|: command not found$|canceled due to missing packages/.test(X))??$[0]??"").replace(/\s+/g," ").slice(0,160)}function Fj(Z){if(!Lp8(Z)){for(let[$,J]of jp8)if($.test(Z))return{kind:"load_error",owner:"harness",reason:`runner could not load: ${J}: ${Fp8(Z)}`}}return{kind:"test_failure",owner:"code"}}var jp8;var rQ0=b(()=>{jp8=[[/Failed Suites\s+[1-9]/,"test suite failed to load"],[/Test suite failed to run/,"test suite failed to run"],[/Failed to load (?:url|config)|failed to load config|Failed to resolve (?:import|entry)/i,"runner config or import could not be loaded"],[/^\s*(?:\w*Error: )?Cannot find (?:module|package) '[^']+'/m,"module not found while loading tests"],[/ERR_MODULE_NOT_FOUND/,"module not found while loading tests"],[/Interrupted: \d+ errors? during collection/,"collection error"],[/^_+ ERROR collecting /m,"collection error"],[/ImportError while importing test module/,"test module import error"],[/ImportError: Failed to import test module/,"unittest test module import error"],[/^ERROR: (?:file or directory not found|not found:)/m,"test path not found by the runner"],[/No test files found, exiting with code [1-9]/,"runner found no test files (wrong cwd or path)"],[/\[setup failed\]|cannot find package|no required module provides package/,"go package could not be set up"],[/could not determine executable to run/i,"test runner executable not found"],[/^(?:\S+: )?(?:line \d+: )?[\w.-]+: command not found$/m,"test runner executable not found"],[/^(?:\S+: )?\d+: [\w.-]+: not found$/m,"test runner executable not found (not installed)"],[/^npm (?:error|ERR!) (?:npx )?canceled due to missing packages/m,"test runner package not installed"]]});import{spawnSync as Cp8}from"child_process";import{mkdtempSync as Ip8,realpathSync as Tp8,rmSync as Pp8}from"fs";import{tmpdir as Rp8}from"os";import{basename as Ep8,extname as tQ0,join as $W0}from"path";function wp8(Z,$,J){return J.filter((X)=>{if(Z.includes(X)||Z.includes($W0($,X)))return!0;let Y=X.split("/");if(eQ0(Y,2).some((Q)=>Q!==X&&Dp8(Z,Q,"(?![\\w-])")))return!0;if(tQ0(X)===".go"&&Y.length>1&&eQ0(Y.slice(0,-1),1).some((Q)=>new RegExp(`(?<=[\\w-])/${Cy(Q)}(?![\\w./-])`).test(Z)))return!0;let z=Ep8(X,tQ0(X));if(z.length<2||z==="index"||z==="__init__")return!1;return new RegExp(`(?<![\\w-])${Cy(z)}(?![\\w-])`).test(Z)})}function ZW0(Z,$){let J=Z;for(let Y of $.flatMap((z)=>{try{return[z,Tp8(z)]}catch{return[z]}}).sort((z,Q)=>Q.length-z.length))J=J.split(Y).join("<repo>");let X=new Set;for(let Y of J.matchAll(/Cannot find (?:module|package) '([^']+)'/g))X.add(`mod:${Y[1]}`);for(let Y of J.matchAll(/([\w.-]+): command not found/g))X.add(`cmd:${Y[1]}`);for(let Y of J.matchAll(/^(?:\S+: )?\d+: ([\w.-]+): not found$/gm))X.add(`cmd:${Y[1]}`);for(let Y of J.matchAll(/canceled due to missing packages[^\[\n]*\[([^\]\n]*)\]/g))for(let z of(Y[1]??"").split(",")){let Q=z.trim().replace(/^["']|["']$/g,"").replace(/(?<=.)@[^@/]*$/,"");if(Q)X.add(`pkg:${Q}`)}return{keys:X,reason:(Fj(J).reason??"").replace(/:\d+(?::\d+)?/g,"")}}function _p8(Z,$,J,X){let Y=ZW0(Z,J),z=ZW0($,X);if(z.keys.size)return Y.keys.size>0&&[...z.keys].every((Q)=>Y.keys.has(Q));return Y.keys.size===0&&Y.reason===z.reason}function xp8(Z){let $=[Z];for(let J=0;J<$.length;J++){let X=Cp8("pgrep",["-P",String($[J])],{encoding:"utf8",env:process.env}).stdout.split(/\s+/).filter(Boolean).map(Number);$.push(...X.filter((Y)=>Number.isInteger(Y)&&!$.includes(Y)))}try{if(Number.isInteger(Z)&&Z>1)process.kill(-Z,"SIGKILL")}catch{}for(let J of $.reverse())try{process.kill(J,"SIGKILL")}catch{}}async function kp8(Z,$){let J=(Y)=>Y.split(Z.repoDir).join($),X=AbortSignal.any([Z.signal,AbortSignal.timeout(Z.timeoutMs??60000)]);try{let Y=Bun.spawn([J(Z.cmd),...Z.args.map(J)],{cwd:J(Z.cwd??Z.repoDir),stdin:"ignore",stdout:"pipe",stderr:"pipe",detached:!0,env:{...h5(),...Z.env??{}}}),z="",Q=[Y.stdout,Y.stderr].map((G)=>G.getReader()),W=Q.map(async(G)=>{let H=new TextDecoder;for(;;){let q=await G.read().catch(()=>({done:!0,value:void 0}));if(q.done)return;z=(z+H.decode(q.value,{stream:!0})).slice(-65536)}}),K=new Promise((G)=>{if(X.aborted)G(null);else X.addEventListener("abort",()=>G(null),{once:!0})}),V=await Promise.race([Y.exited,K]);if(V===null)return xp8(Y.pid),null;return await Promise.race([Promise.all(W),new Promise((G)=>setTimeout(G,300))]),Q.forEach((G)=>G.cancel().catch(()=>{})),X.aborted||V===0?null:f5(z)}catch{return null}}function Sp8(Z,$,J){let X=(Y)=>$0(Z,Y).split(`
534
534
  `).map((z)=>z.trim()).filter(Boolean);return[...new Set([...X(["diff","--name-only",$]),...X(["ls-files","--others","--exclude-standard"])])].filter((Y)=>!Y.startsWith(".loki/")&&!J?.(Y))}async function bp8(Z){if(Z.protect||!Z.baseSha||Z.signal.aborted)return!1;let $;try{$=Sp8(Z.repoDir,Z.baseSha,Z.skip)}catch{return!1}if(wp8(Z.out,Z.repoDir,$).length>0)return!1;if(Z.args.some((Y)=>$.includes(Y.replace(/^\.\//,""))))return!1;let J=Ip8($W0(Rp8(),"e10-loadown-")),X=(Y)=>{$0(Z.repoDir,Y,{stdio:"ignore"})};try{X(["worktree","add","--detach",J,Z.baseSha]);let Y=await kp8(Z,J);return Y!==null&&Fj(Y).kind==="load_error"&&_p8(Z.out,Y,[Z.repoDir,...Z.cwd?[Z.cwd]:[]],[J])}catch{return!1}finally{try{X(["worktree","remove","--force",J])}catch{}Pp8(J,{recursive:!0,force:!0});try{X(["worktree","prune"])}catch{}}}async function lz(Z){let $=Fj(Z.out);return $.kind==="load_error"&&await bp8(Z)?$.reason:void 0}var Cy=(Z)=>Z.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),eQ0=(Z,$)=>Z.map((J,X)=>Z.slice(X).join("/")).filter((J)=>J.split("/").length>=$),Dp8=(Z,$,J)=>new RegExp(`(?<![\\w.-])${Cy($)}${J}`).test(Z);var Cj=b(()=>{rQ0();_0();g5()});import{join as JW0}from"path";function XW0(Z){if(!_3(Z))return null;let $=Z.packages().filter((J)=>J.commands.test).map((J)=>{let X=J.commands.test;return{name:`full suite: ${J.name}`,cmd:`(cd ${X.cwd} && ${X.cmd})`,cwd:X.cwd,run:X.cmd}});return $.length?$:null}function YW0(Z,$){return XW0(_9(Z))??$.map((J)=>{let X=[rG[J].cmd,...rG[J].args].join(" ");return{name:`full suite: ${J}`,cmd:X,cwd:".",run:X}})}async function zW0(Z,$,J,X,Y){let z=_9(Z),Q=XW0(z);if(!z||!Q)return!1;for(let{name:W,cmd:K,cwd:V,run:G}of Q){let H=Date.now(),q=await v0(["bash","-c",G],{cwd:JW0(Z,V),timeoutMs:J.timeoutMs,...J.path?{env:{PATH:J.path}}:{}}),U=(Date.now()-H)/1000;if($.aborted){X.push({name:W,cmd:K,result:"not_run",duration_s:U}),Y.add(`not run: ${W} (aborted)`);continue}let B=`${q.stdout}
535
- ${q.stderr}`,N=q.exitCode===0||!J.baseSha?void 0:await lz({repoDir:Z,baseSha:J.baseSha,...J.skip?{skip:J.skip}:{},out:B,cmd:"bash",args:["-c",G],signal:$,cwd:JW0(Z,V),...J.path?{env:{PATH:J.path}}:{}});if(N){X.push({name:W,cmd:K,result:"not_run",duration_s:U}),Y.add(`${N} (${W}; harness-owned)`);continue}let M=OJ({kind:"test",ok:q.exitCode===0,out:B,...uz(G)});if(X.push({name:W,cmd:K,result:M.result,duration_s:U,...M.result==="fail"?{ids:y3(B)}:{}}),M.result==="not_run")Y.add(`not run: ${W} (${M.reason??MJ})`)}for(let W of z.packages().filter((K)=>!K.commands.test))Y.add(`full suite: package ${W.name} defines no test command`);return!0}var Iy=b(()=>{Cj();g5();L9();pG();G4()});import{spawn as yp8}from"child_process";import{createHash as vp8}from"crypto";import{existsSync as Ij,lstatSync as hp8,readFileSync as Dy,readlinkSync as fp8,realpathSync as iz}from"fs";import{dirname as Ty,isAbsolute as QW0,join as i4,relative as Ry}from"path";function up8(Z,$){if($.LOKI_E10_INSTALL==="0")return!0;let J=A2(Z,{yamlOnly:!0})[0];return J!==void 0&&o7(J,"verify","install_deps")?.toLowerCase()==="false"}function pp8(Z,$){try{let J=hp8(i4(Z,$));if(J.isFile())return vp8("sha1").update(Dy(i4(Z,$))).digest("hex");if(J.isSymbolicLink())return`link:${fp8(i4(Z,$))}`;return J.isDirectory()?"dir":"other"}catch{return"absent"}}function Ey(Z,$){try{let J=new Map,X=new Map,Y=wy(Z,$,["status","--porcelain","-z"]).split("\x00");for(let z=0;z<Y.length;z++){let Q=Y[z];if(Q.length<4)continue;let W=Q.slice(0,2),K=Q.slice(3);if(/[RC]/.test(W))z++;if(J.set(K,W),!K.endsWith("/"))X.set(K,pp8(Z,K))}return{status:J,hash:X}}catch{return null}}function cp8(Z,$,J,X){let Y=J?Ey(Z,$):null;if(!J||!Y)return!1;let z=[];for(let[W,K]of Y.status)if(!J.status.has(W))if(K==="??")X.untracked.push(W);else try{wy(Z,$,["--literal-pathspecs","checkout","--",W]),z.push(W)}catch{X.unrestored.push(W)}else if(J.hash.get(W)!==Y.hash.get(W))X.unrestored.push(W);if(z.length===0)return!0;let Q=Ey(Z,$);if(!Q)return X.unrestored.push(...z),!1;for(let W of z)(Q.status.has(W)?X.unrestored:X.restored).push(W);return!0}function qW0(Z,$){if(typeof Z!=="number"||!Number.isInteger(Z)||Z<=1)return!1;try{return process.kill(-Z,$),!0}catch{return!1}}async function dp8(Z){for(let $=0;$<40&&qW0(Z,0);$++)await new Promise((J)=>setTimeout(J,50))}function lp8(Z,$,J,X,Y){return new Promise((z)=>{let Q;try{Q=yp8("bash",["-c",Z],{cwd:$,env:J,detached:!0,stdio:["ignore","pipe","pipe"]})}catch(M){z({code:null,cut:null,err:String(M),tail:""});return}let W=Q.pid,K=null,V=!1,G="",H=(M)=>{G=(G+M.toString("utf8")).slice(-gp8)};Q.stdout?.on("data",H),Q.stderr?.on("data",H);let q=()=>{if(!qW0(W,"SIGKILL"))try{Q.kill("SIGKILL")}catch{}},U=async(M)=>{if(V)return;V=!0,clearTimeout(N),X.removeEventListener("abort",B),q(),await dp8(W),Q.stdout?.destroy(),Q.stderr?.destroy(),z({...M,tail:G})},B=()=>{K="abort",q()},N=setTimeout(()=>{K="timeout",q()},Y);if(X.aborted)B();else X.addEventListener("abort",B,{once:!0});Q.on("error",(M)=>{U({code:null,cut:K,err:String(M)})}),Q.on("exit",(M)=>{U({code:M,cut:K})})})}function np8(Z,$,J){let X=iz(Z),Y=iz($);if(J.locks.some((z)=>Ij(i4(Y,z))))return Y;if(!J.ws)return null;for(let z=Ty(Y);!Ry(X,z).startsWith("..");z=Ty(z)){if(J.locks.some((Q)=>Ij(i4(z,Q)))&&op8(J.ws(z),Ry(z,Y).split("\\").join("/")))return z;if(z===X||z===Ty(z))break}return null}function sp8(Z){if(Ij(i4(Z,".yarnrc.yml")))return!0;try{return/^yarn@([2-9]|\d{2,})/.test(String(JSON.parse(Dy(i4(Z,"package.json"),"utf8")).packageManager??""))}catch{return!1}}function rp8(Z,$,J){let X=J.replace(/\\\r?\n/g," ").replace(/[\s;]+$/,""),Y=X.split(/(\s*(?:&&|\|\||;|\n)\s*)/),z=(M)=>{let O=M.trim().split(/\s+/).filter(Boolean),L=O.findIndex((F)=>!/^[A-Za-z_]\w*=/.test(F)),j=L>=0&&O[L+1]!==void 0&&!O[L+1].startsWith("-");return{w:O,e:L,tool:L>=0?O[L]:"",hasSub:j,sub:j?O[L+1]:""}},Q=()=>{for(let M=0;M<Y.length;M+=2){let{w:O,e:L,tool:j,sub:F}=z(Y[M]);if(O.some((I)=>/^PATH=/.test(I)))return!1;if(L<0)continue;if(GW0.some((I)=>I.tool===j&&I.subs.includes(F)))return!0;if(L>0||!(j==="cd"||j==="export"&&O.length>1&&O.slice(1).every((I)=>/^[A-Za-z_]\w*=/.test(I))))return!1}return!0},W=X.includes("||")?"fallback masks install failure":!/^[A-Za-z0-9 _./=:@+,%~\t\n;-]*$/.test(X.replace(/&&/g," "))||!Q()?"unparsed shell construct":null,K=Y.reduce((M,O,L)=>L%2===1&&/[;\n]/.test(O)?L:M,-1),V=!1,G=[],H=0,q=!0,U=!1,B=iz($),N=Y.map((M,O)=>{if(O%2===1)return M;let{w:L,e:j,tool:F,hasSub:I,sub:T}=z(M);if(j<0)return M;let C=L.slice(0,j);if(F==="cd"){try{B=B!==null&&L.length===j+2&&!/[$~`*]/.test(L[j+1])&&!L[j+1].startsWith("-")?iz(i4(B,L[j+1])):null}catch{B=null}return M}let P=GW0.find((w)=>w.tool===F&&w.subs.includes(T));if(!P)return M;if(H++,W)return q=!1,G.push(W),M;if(O<K)return V=!0,q=!1,G.push("later command masks install failure"),M;let D=L.slice(j+(I?2:1));if(D.some((w)=>!w.startsWith("-")))return q=!1,G.push(`${F} ${T} names packages or targets, kept as written`),M;if(B===null)return q=!1,G.push(`${F} runs in a directory that cannot be resolved, kept as written`),M;let R=np8(Z,B,P);if(!R)return q=!1,G.push(`no ${P.locks.join(" or ")} governs this package for ${F}`),M;if(P.locked(T,D,C)){if(F!=="uv"||!m3(D,"--locked","--frozen")||!D.includes("--frozen")||!D.includes("--locked"))return M;return U=!0,[...C,"uv","sync",...D.filter((w)=>w!=="--frozen")].join(" ")}U=!0;let E=P.tool==="bundle"?["BUNDLE_FROZEN=true"]:[];return[...C,...E,...P.build(T,D,{berry:sp8(R)})].join(" ")});if(H===0)return{cmd:J,locked:!1,note:"install not lockfile-locked: no lockfile rule matches this command",rewritten:!1};return{cmd:U&&!V?N.join(""):J,locked:q,rewritten:U&&!V,...!q?{note:`install not lockfile-locked: ${G.join("; ")}`}:U?{note:"install rewritten to its lockfile-frozen form"}:{}}}async function ep8(Z){let $={checks:[],notProven:[],restored:[],unrestored:[],untracked:[],skipped:null},J=HW0(Z.env),X=[...new Set(Z.failed.filter((Q)=>Q.harnessOwned).map((Q)=>Q.root))];if(X.length===0)return $;if(up8(Z.repoDir,J))return $.skipped="opt-out",$.notProven.push(`dependencies not installed for ${X.join(", ")} (install disabled by LOKI_E10_INSTALL=0 or verify.install_deps: false)`),$;let Y=Z.opts.runId,z=Z.timeoutMs;for(let Q of X){let W=`${Y}\x00${Q}`;if(WW0.has(W))continue;WW0.add(W);let K=Z.model?.installFor(Q)??null;if(!K){$.notProven.push(`NOT PROVEN: package ${Q} has no known install command, its dependencies were not installed`);continue}let V=`install:${Q}`,G={cmd:K.cmd,locked:!1,rewritten:!1},H=(T,C,P)=>({name:V,cmd:G.cmd,cwd:K.cwd,result:T,locked:G.locked,...G.note?{lock_note:G.note}:{},...G.rewritten?{model_cmd:K.cmd}:{},duration_s:C,...P?{reason:P}:{},...T==="not_run"?{owner:"harness"}:{}}),q=(T)=>{$.checks.push(H("not_run",0,T)),$.notProven.push(`${V} not run: ${T}`)},U=Math.min(Tj,z);if(U<=0||Z.signal.aborted){q(Z.signal.aborted?"aborted":"no budget left for install");continue}let B;try{B=iz(i4(Z.repoDir,K.cwd));let T=Ry(iz(Z.repoDir),B);if(QW0(K.cwd)||T.startsWith("..")||QW0(T)){q(`install cwd ${K.cwd} resolves outside the repo`);continue}}catch{q(`install cwd ${K.cwd} does not exist`);continue}G=rp8(Z.repoDir,B,K.cmd);let N=Ey(Z.repoDir,J),M=Date.now(),O=await lp8(G.cmd,B,J,Z.signal,U),L=(Date.now()-M)/1000;if(z-=Date.now()-M,!cp8(Z.repoDir,J,N,$))$.notProven.push(`${V} tree guard not run (git status failed)`);if(O.code===0&&!O.cut){$.checks.push(H("pass",L));continue}let j=O.cut==="timeout"?`install timed out after ${(U/1000).toFixed(1)}s`:O.cut==="abort"?"aborted":O.err?`install could not start: ${O.err}`:`install exited ${O.code}`,F=O.cut==="abort"?"":tp8(O.tail),I=F?`${j}: ${F}`:j;$.checks.push(H("not_run",L,I)),$.notProven.push(`${I} (${V}; harness-owned)`)}return $}function Zc8(Z,$,J){if(!$?.known())return[];let X=HW0(J),Y=[];for(let z of $.packages()){let Q=$.installFor(z.root),W=z.root==="."?"":`${z.root}/`;if(!Q||!(Q.cite??[]).some((G)=>G.startsWith(W)&&Ij(i4(Z,G))))continue;let K;try{K=wy(Z,X,["ls-files","--others","--directory","--",z.root])}catch{continue}if(!K.split(`
535
+ ${q.stderr}`,N=q.exitCode===0||!J.baseSha?void 0:await lz({repoDir:Z,baseSha:J.baseSha,...J.skip?{skip:J.skip}:{},out:B,cmd:"bash",args:["-c",G],signal:$,cwd:JW0(Z,V),...J.path?{env:{PATH:J.path}}:{}});if(N){X.push({name:W,cmd:K,result:"not_run",duration_s:U}),Y.add(`${N} (${W}; harness-owned)`);continue}let M=OJ({kind:"test",ok:q.exitCode===0,out:B,...uz(G)});if(X.push({name:W,cmd:K,result:M.result,duration_s:U,...M.result==="fail"?{ids:y3(B)}:{}}),M.result==="not_run")Y.add(`not run: ${W} (${M.reason??MJ})`)}for(let W of z.packages().filter((K)=>!K.commands.test))Y.add(`full suite: package ${W.name} defines no test command`);return!0}var Iy=b(()=>{Cj();g5();L9();pG();G4()});import{spawn as yp8}from"child_process";import{createHash as vp8}from"crypto";import{existsSync as Ij,lstatSync as hp8,readFileSync as Dy,readlinkSync as fp8,realpathSync as iz}from"fs";import{dirname as Ty,isAbsolute as QW0,join as i4,relative as Ry}from"path";function up8(Z,$){if($.LOKI_E10_INSTALL==="0")return!0;let J=A2(Z,{yamlOnly:!0})[0];return J!==void 0&&o7(J,"verify","install_deps")?.toLowerCase()==="false"}function pp8(Z,$){try{let J=hp8(i4(Z,$));if(J.isFile())return vp8("sha1").update(Dy(i4(Z,$))).digest("hex");if(J.isSymbolicLink())return`link:${fp8(i4(Z,$))}`;return J.isDirectory()?"dir":"other"}catch{return"absent"}}function Ey(Z,$){try{let J=new Map,X=new Map,Y=wy(Z,$,["status","--porcelain","-z"]).split("\x00");for(let z=0;z<Y.length;z++){let Q=Y[z];if(Q.length<4)continue;let W=Q.slice(0,2),K=Q.slice(3);if(/[RC]/.test(W))z++;if(J.set(K,W),!K.endsWith("/"))X.set(K,pp8(Z,K))}return{status:J,hash:X}}catch{return null}}function cp8(Z,$,J,X){let Y=J?Ey(Z,$):null;if(!J||!Y)return!1;let z=[];for(let[W,K]of Y.status)if(!J.status.has(W))if(K==="??")X.untracked.push(W);else try{wy(Z,$,["--literal-pathspecs","checkout","--",W]),z.push(W)}catch{X.unrestored.push(W)}else if(J.hash.get(W)!==Y.hash.get(W))X.unrestored.push(W);if(z.length===0)return!0;let Q=Ey(Z,$);if(!Q)return X.unrestored.push(...z),!1;for(let W of z)(Q.status.has(W)?X.unrestored:X.restored).push(W);return!0}function qW0(Z,$){if(typeof Z!=="number"||!Number.isInteger(Z)||Z<=1)return!1;try{return process.kill(-Z,$),!0}catch{return!1}}async function dp8(Z){for(let $=0;$<40&&qW0(Z,0);$++)await new Promise((J)=>setTimeout(J,50))}function lp8(Z,$,J,X,Y){return new Promise((z)=>{let Q;try{Q=yp8("bash",["-c",Z],{cwd:$,env:J,detached:!0,stdio:["ignore","pipe","pipe"]})}catch(M){z({code:null,cut:null,err:String(M),tail:""});return}let W=Q.pid,K=null,V=!1,G="",H=(M)=>{G=(G+M.toString("utf8")).slice(-gp8)};Q.stdout?.on("data",H),Q.stderr?.on("data",H);let q=()=>{if(!qW0(W,"SIGKILL"))try{Q.kill("SIGKILL")}catch{}},U=async(M)=>{if(V)return;V=!0,clearTimeout(N),X.removeEventListener("abort",B),q(),await dp8(W),Q.stdout?.destroy(),Q.stderr?.destroy(),z({...M,tail:G})},B=()=>{K="abort",q()},N=setTimeout(()=>{K="timeout",q()},Y);if(X.aborted)B();else X.addEventListener("abort",B,{once:!0});Q.on("error",(M)=>{U({code:null,cut:K,err:String(M)})}),Q.on("exit",(M)=>{U({code:M,cut:K})})})}function np8(Z,$,J){let X=iz(Z),Y=iz($);if(J.locks.some((z)=>Ij(i4(Y,z))))return Y;if(!J.ws)return null;for(let z=Ty(Y);!Ry(X,z).startsWith("..");z=Ty(z)){if(J.locks.some((Q)=>Ij(i4(z,Q)))&&op8(J.ws(z),Ry(z,Y).split("\\").join("/")))return z;if(z===X||z===Ty(z))break}return null}function sp8(Z){if(Ij(i4(Z,".yarnrc.yml")))return!0;try{return/^yarn@([2-9]|\d{2,})/.test(String(JSON.parse(Dy(i4(Z,"package.json"),"utf8")).packageManager??""))}catch{return!1}}function rp8(Z,$,J){let X=J.replace(/\\\r?\n/g," ").replace(/[\s;]+$/,""),Y=X.split(/(\s*(?:&&|\|\||;|\n)\s*)/),z=(M)=>{let O=M.trim().split(/\s+/).filter(Boolean),L=O.findIndex((F)=>!/^[A-Za-z_]\w*=/.test(F)),j=L>=0&&O[L+1]!==void 0&&!O[L+1].startsWith("-");return{w:O,e:L,tool:L>=0?O[L]:"",hasSub:j,sub:j?O[L+1]:""}},Q=()=>{for(let M=0;M<Y.length;M+=2){let{w:O,e:L,tool:j,sub:F}=z(Y[M]);if(O.some((I)=>/^(PATH|NODE_OPTIONS|BASH_ENV|ENV)=/.test(I)))return!1;if(L<0)continue;if(GW0.some((I)=>I.tool===j&&I.subs.includes(F)))return!0;if(L>0||!(j==="cd"||j==="export"&&O.length>1&&O.slice(1).every((I)=>/^[A-Za-z_]\w*=/.test(I))))return!1}return!0},W=X.includes("||")?"fallback masks install failure":!/^[A-Za-z0-9 _./=:@+,%~\t\n;-]*$/.test(X.replace(/&&/g," "))||!Q()?"unparsed shell construct":null,K=Y.reduce((M,O,L)=>L%2===1&&/[;\n]/.test(O)?L:M,-1),V=!1,G=[],H=0,q=!0,U=!1,B=iz($),N=Y.map((M,O)=>{if(O%2===1)return M;let{w:L,e:j,tool:F,hasSub:I,sub:T}=z(M);if(j<0)return M;let C=L.slice(0,j);if(F==="cd"){try{B=B!==null&&L.length===j+2&&!/[$~`*]/.test(L[j+1])&&!L[j+1].startsWith("-")?iz(i4(B,L[j+1])):null}catch{B=null}return M}let P=GW0.find((w)=>w.tool===F&&w.subs.includes(T));if(!P)return M;if(H++,W)return q=!1,G.push(W),M;if(O<K)return V=!0,q=!1,G.push("later command masks install failure"),M;let D=L.slice(j+(I?2:1));if(D.some((w)=>!w.startsWith("-")))return q=!1,G.push(`${F} ${T} names packages or targets, kept as written`),M;if(B===null)return q=!1,G.push(`${F} runs in a directory that cannot be resolved, kept as written`),M;let R=np8(Z,B,P);if(!R)return q=!1,G.push(`no ${P.locks.join(" or ")} governs this package for ${F}`),M;if(P.locked(T,D,C)){if(F!=="uv"||!m3(D,"--locked","--frozen")||!D.includes("--frozen")||!D.includes("--locked"))return M;return U=!0,[...C,"uv","sync",...D.filter((w)=>w!=="--frozen")].join(" ")}U=!0;let E=P.tool==="bundle"?["BUNDLE_FROZEN=true"]:[];return[...C,...E,...P.build(T,D,{berry:sp8(R)})].join(" ")});if(H===0)return{cmd:J,locked:!1,note:"install not lockfile-locked: no lockfile rule matches this command",rewritten:!1};return{cmd:U&&!V?N.join(""):J,locked:q,rewritten:U&&!V,...!q?{note:`install not lockfile-locked: ${G.join("; ")}`}:U?{note:"install rewritten to its lockfile-frozen form"}:{}}}async function ep8(Z){let $={checks:[],notProven:[],restored:[],unrestored:[],untracked:[],skipped:null},J=HW0(Z.env),X=[...new Set(Z.failed.filter((Q)=>Q.harnessOwned).map((Q)=>Q.root))];if(X.length===0)return $;if(up8(Z.repoDir,J))return $.skipped="opt-out",$.notProven.push(`dependencies not installed for ${X.join(", ")} (install disabled by LOKI_E10_INSTALL=0 or verify.install_deps: false)`),$;let Y=Z.opts.runId,z=Z.timeoutMs;for(let Q of X){let W=`${Y}\x00${Q}`;if(WW0.has(W))continue;WW0.add(W);let K=Z.model?.installFor(Q)??null;if(!K){$.notProven.push(`NOT PROVEN: package ${Q} has no known install command, its dependencies were not installed`);continue}let V=`install:${Q}`,G={cmd:K.cmd,locked:!1,rewritten:!1},H=(T,C,P)=>({name:V,cmd:G.cmd,cwd:K.cwd,result:T,locked:G.locked,...G.note?{lock_note:G.note}:{},...G.rewritten?{model_cmd:K.cmd}:{},duration_s:C,...P?{reason:P}:{},...T==="not_run"?{owner:"harness"}:{}}),q=(T)=>{$.checks.push(H("not_run",0,T)),$.notProven.push(`${V} not run: ${T}`)},U=Math.min(Tj,z);if(U<=0||Z.signal.aborted){q(Z.signal.aborted?"aborted":"no budget left for install");continue}let B;try{B=iz(i4(Z.repoDir,K.cwd));let T=Ry(iz(Z.repoDir),B);if(QW0(K.cwd)||T.startsWith("..")||QW0(T)){q(`install cwd ${K.cwd} resolves outside the repo`);continue}}catch{q(`install cwd ${K.cwd} does not exist`);continue}G=rp8(Z.repoDir,B,K.cmd);let N=Ey(Z.repoDir,J),M=Date.now(),O=await lp8(G.cmd,B,J,Z.signal,U),L=(Date.now()-M)/1000;if(z-=Date.now()-M,!cp8(Z.repoDir,J,N,$))$.notProven.push(`${V} tree guard not run (git status failed)`);if(O.code===0&&!O.cut){$.checks.push(H("pass",L));continue}let j=O.cut==="timeout"?`install timed out after ${(U/1000).toFixed(1)}s`:O.cut==="abort"?"aborted":O.err?`install could not start: ${O.err}`:`install exited ${O.code}`,F=O.cut==="abort"?"":tp8(O.tail),I=F?`${j}: ${F}`:j;$.checks.push(H("not_run",L,I)),$.notProven.push(`${I} (${V}; harness-owned)`)}return $}function Zc8(Z,$,J){if(!$?.known())return[];let X=HW0(J),Y=[];for(let z of $.packages()){let Q=$.installFor(z.root),W=z.root==="."?"":`${z.root}/`;if(!Q||!(Q.cite??[]).some((G)=>G.startsWith(W)&&Ij(i4(Z,G))))continue;let K;try{K=wy(Z,X,["ls-files","--others","--directory","--",z.root])}catch{continue}if(!K.split(`
536
536
  `).some((G)=>G.startsWith(W)&&G.endsWith("/")&&!G.slice(W.length,-1).includes("/")&&G!==".loki/"))Y.push(z.root)}return Y}async function UW0(Z,$,J){let X=_9(Z.repoDir),Y=Zc8(Z.repoDir,X),z=NW0(Z.repoDir),Q=await ep8({repoDir:Z.repoDir,model:X,failed:Y.map((K)=>({root:K,harnessOwned:!0})),signal:$,timeoutMs:Tj,opts:{runId:Z.runId}});for(let K of Q.checks)Z.emit("deps.install","intake",{...K});let W=Q.checks.some((K)=>K.result==="pass")?$c8(Z.repoDir,z):null;return ab(Z.repoDir,YW0(Z.repoDir,J),{rerun:Q.checks.some((K)=>K.result==="pass")}),{...Q.checks.length||Q.notProven.length?{deps_install:Q.checks,deps_not_proven:Q.notProven}:{},...W?{install_created:W}:{}}}function $c8(Z,$){let J={},X=[];for(let Y of NW0(Z))if(!$.has(Y)&&!Y.startsWith(".loki/"))if(Y.endsWith("/"))X.push(Y);else try{J[Y]=BW0(Z,Y)}catch{}return X.length||Object.keys(J).length?{files:J,dirs:X}:null}function l6(Z,$,J=process.env){let X=$,Y=X&&typeof X.files==="object"&&X.files?X.files:{},z=Array.isArray(X?.dirs)?X.dirs:[];return(Q)=>z.some((W)=>typeof W==="string"&&Q.startsWith(W))||Object.hasOwn(Y,Q)&&(()=>{try{return BW0(Z,Q,J)===Y[Q]}catch{return!1}})()}var Tj=300000,WW0,gp8=65536,mp8=67108864,HW0=(Z)=>Object.fromEntries(Object.entries({...process.env,...Z??{}}).filter(($)=>typeof $[1]==="string")),wy=(Z,$,J)=>$0(Z,J,{env:$,maxBuffer:mp8}),m3=(Z,...$)=>Z.some((J)=>$.includes(J)),az=(Z,$)=>Z.includes($)?Z:[...Z,$],_y=(Z,$)=>{try{return Dy(i4(Z,$),"utf8")}catch{return null}},ap8=(Z)=>[...Z.matchAll(/["']([^"']+)["']/g)].map(($)=>$[1]),Py=(Z)=>{try{let $=JSON.parse(_y(Z,"package.json")??"{}").workspaces,J=Array.isArray($)?$:$?.packages;return Array.isArray(J)?J.filter((X)=>typeof X==="string"):[]}catch{return[]}},ip8=(Z)=>{let $=[],J=!1;for(let X of(_y(Z,"pnpm-workspace.yaml")??"").split(`
537
537
  `)){let Y=/^packages\s*:\s*(.*)$/.exec(X);if(Y){let Q=Y[1].replace(/\s+#.*$/,"").trim();if(J=Q===""||Q.startsWith("#"),Q.startsWith("["))$.push(...Q.slice(1,Q.includes("]")?Q.indexOf("]"):void 0).split(",").map((W)=>W.trim().replace(/^["']|["']$/g,"")).filter(Boolean));continue}if(J&&/^[^\s#-]/.test(X))J=!1;let z=J?/^\s*-\s*["']?([^"'#]+?)["']?\s*(#.*)?$/.exec(X):null;if(z)$.push(z[1])}return $},KW0=(Z,$,J)=>{let X=_y(Z,$);if(!X)return[];let Y=X.indexOf(`[${J}]`);if(Y<0)return[];let z=X.slice(Y+J.length+2).split(/^\[/m)[0],Q=(W)=>ap8(new RegExp(`^\\s*${W}\\s*=\\s*\\[([^\\]]*)\\]`,"m").exec(z)?.[1]??"");return[...Q("members"),...Q("exclude").map((W)=>`!${W}`)]},VW0=(Z)=>new RegExp(`^${Z.replace(/^\.\//,"").replace(/\/+$/,"").replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\x00").replace(/\*/g,"[^/]*").replace(/\0/g,".*").replace(/\?/g,"[^/]")}$`),op8=(Z,$)=>Z.some((J)=>!J.startsWith("!")&&VW0(J).test($))&&!Z.some((J)=>J.startsWith("!")&&VW0(J.slice(1)).test($)),GW0,tp8=(Z)=>{return(Z.split(`
538
538
  `).map((J)=>J.trim()).filter(Boolean).pop()??"").replace(/\s+/g," ").slice(0,160)},BW0=(Z,$,J=process.env)=>$0(Z,["hash-object","--no-filters","--",$],{env:J}).trim(),NW0=(Z)=>{try{return new Set($0(Z,["ls-files","-o","--directory","--exclude-standard","-z"]).split("\x00").filter(Boolean))}catch{return new Set}};var IJ=b(()=>{_0();zY();f3();Iy();G4();WW0=new Set;GW0=[{tool:"npm",subs:["install","i","ci"],locks:["package-lock.json","npm-shrinkwrap.json"],locked:(Z)=>Z==="ci",build:(Z,$)=>["npm","ci",...$],ws:Py},{tool:"pnpm",subs:["install","i"],locks:["pnpm-lock.yaml"],locked:(Z,$)=>m3($,"--frozen-lockfile")&&!m3($,"--no-frozen-lockfile"),build:(Z,$)=>["pnpm","install",...az($.filter((J)=>J!=="--no-frozen-lockfile"),"--frozen-lockfile")],ws:ip8},{tool:"yarn",subs:["","install"],locks:["yarn.lock"],locked:(Z,$)=>m3($,"--immutable","--frozen-lockfile"),build:(Z,$,J)=>["yarn","install",...az($,J.berry?"--immutable":"--frozen-lockfile")],ws:Py},{tool:"bun",subs:["install","i","ci"],locks:["bun.lock","bun.lockb"],locked:(Z,$)=>Z==="ci"||m3($,"--frozen-lockfile"),build:(Z,$)=>["bun","install",...az($,"--frozen-lockfile")],ws:Py},{tool:"uv",subs:["sync"],locks:["uv.lock"],locked:(Z,$,J)=>m3($,"--locked")||J.some((X)=>/^UV_(FROZEN|LOCKED)=(?!0$|false$|$)/i.test(X)),build:(Z,$)=>["uv","sync",...az($.filter((J)=>J!=="--frozen"),"--locked")],ws:(Z)=>KW0(Z,"pyproject.toml","tool.uv.workspace")},{tool:"poetry",subs:["install"],locks:["poetry.lock"],locked:()=>!0,build:(Z,$)=>["poetry","install",...$]},{tool:"pipenv",subs:["install","sync"],locks:["Pipfile.lock"],locked:(Z,$)=>m3($,"--deploy"),build:(Z,$)=>["pipenv","install",...az($,"--deploy")]},{tool:"cargo",subs:["fetch","build"],locks:["Cargo.lock"],locked:(Z,$)=>m3($,"--locked","--frozen"),build:(Z,$)=>["cargo",Z,...az($,"--locked")],ws:(Z)=>KW0(Z,"Cargo.toml","workspace")},{tool:"bundle",subs:["","install"],locks:["Gemfile.lock"],locked:(Z,$,J)=>J.includes("BUNDLE_FROZEN=true")||m3($,"--frozen","--deployment"),build:(Z,$)=>["bundle","install",...$]},{tool:"composer",subs:["install","update"],locks:["composer.lock"],locked:(Z)=>Z==="install",build:(Z,$)=>["composer","install",...$]}]});import{dirname as MW0}from"path";function ky(Z,$,J,X=process.env,Y){let z=l6(Z,Y,X),Q=Y?.files??{};return $.concat(sQ0(Z,J,X).map((W)=>({st:"L",f:W})),$.filter(({f:W})=>z(W)).map(({f:W})=>({st:"L",f:W}))).filter(({st:W,f:K})=>K.startsWith(".loki/")||W==="L"||/(^|\/)loki_wall_[^/]*$/.test(K)||W==="A"&&!Object.hasOwn(Q,K)&&!$.some(({f:V})=>/(^|\/)(package\.json|pyproject\.toml|requirements\.txt|Cargo\.toml|go\.mod)$/.test(V)&&MW0(V)===MW0(K))&&/(^|\/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml|bun\.lockb?|poetry\.lock|Cargo\.lock|go\.sum)$/.test(K))}function Jc8(Z,$,J,X,Y,z){let Q=(W)=>$0(Z,W,{env:$,stdio:"ignore"});try{Q(["add","-A","--","."]);let W=xy($0(Z,["diff","--cached","--name-status","--no-renames","-z",X],{env:$})),K=ky(Z,W,Y,$,z);if(K.length>0)Q(["--literal-pathspecs","reset","-q",X,"--",...K.map(({f:V})=>V)]);Q(["diff","--cached","--quiet"])}catch(W){if(W.status!==1)return;try{Q(["commit","-q","-m",`loki: backstop commit (${J})`,"-m",`Loki-Run: ${J}`])}catch{}}}function AW0(Z,$,J,X,Y,z,Q){if(!Z)return"backstop commit skipped: event log failed verification";let W=Sy(Y);if(W===null)return Y===null||Y===void 0?null:"backstop commit skipped: base is not a full object id";return Jc8($,J,X,W,z,Q),null}var xy=(Z)=>Z.split("\x00").reduce(($,J,X,Y)=>X%2===0&&J?[...$,{st:J,f:Y[X+1]}]:$,[]),OW0=(Z,$,J,X=process.env)=>db(Z,$.filter(({st:Y,f:z})=>(Y==="A"||Y==="M")&&!J.has(z)&&!z.startsWith(".loki/")).map(({f:Y})=>Y),I8(X)),Sy=(Z)=>typeof Z==="string"&&/^[0-9a-f]{40,64}$/.test(Z)?Z:null;var by=b(()=>{Fy();IJ();f3();_0()});import{createHash as Xc8}from"crypto";import{existsSync as Yc8,mkdirSync as LW0,readFileSync as FW0,writeFileSync as zc8}from"fs";import{isAbsolute as Qc8,join as QH,relative as CW0}from"path";function Wc8(Z){let $=Z.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if($.length<=40)return $||"task";return`${$.slice(0,31).replace(/-+$/g,"")}-${hy(Z).slice(0,8)}`}function Kc8(Z){if(typeof Z!=="object"||Z===null||Array.isArray(Z))return"not a JSON object";let $=Z,J=(X)=>typeof X==="string"&&X.trim()!==""&&X.length<=yy&&!/[\r\n]/.test(X);if(!J($.intent))return"intent must be a non-empty single-line string";if(!Array.isArray($.criteria)||$.criteria.length<1||$.criteria.length>Pj)return`criteria must be an array of 1 to ${Pj} strings`;if(!$.criteria.every(J))return"every criterion must be a non-empty single-line string";return null}function Vc8(Z,$){let J=Z.split(`
@@ -3220,4 +3220,4 @@ Unknown commands exit 2 with a suggestion; run 'loki help' for the full list.
3220
3220
  `);{let{suggestCommand:X}=await Promise.resolve().then(() => (l7(),ji)),Y=$===void 0?void 0:X($);if(Y)process.stderr.write(`Did you mean 'loki ${Y}'?
3221
3221
  `)}return process.stderr.write(ik0),2}}rL0();var ok0=()=>globalThis[Symbol.for("loki.ownsStopSignals")]===!0;process.on("SIGINT",()=>{if(!ok0())process.exit(130)});process.on("SIGTERM",()=>{if(!ok0())process.exit(143)});var rV9=await sV9(Bun.argv.slice(2));process.exit(rV9);
3222
3222
 
3223
- //# debugId=B4987DD712EE1A22BD96B07E3BB9C079
3223
+ //# debugId=FDAC82476ACA7A97D19C6E244E1CC3DF
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '11.17.73'
78
+ __version__ = '11.17.74'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "11.17.73",
4
+ "version": "11.17.74",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -160,5 +160,5 @@
160
160
  "dependencies": {
161
161
  "@resvg/resvg-wasm": "^2.6.2"
162
162
  },
163
- "gitHead": "f9aad869b0a437e00d1756f6bdacbfcec7ff0495"
163
+ "gitHead": "279247a3326ea3337c4c35266ae45571485cd078"
164
164
  }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "11.17.73",
5
+ "version": "11.17.74",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -1,4 +1,4 @@
1
- import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-D1-1DZ1A.js";import{B as C}from"./Button-CzD_JfV1.js";import{T as $e}from"./trending-up-CGmXxQM4.js";import{C as z}from"./clock-9J88OP3M.js";import{A as Be,U as ue,M as De}from"./Avatar-D4-XntzA.js";import{A as J}from"./activity-CQJpef5Z.js";import{R as pe}from"./refresh-cw-Bdo9tSnG.js";import{G as ze}from"./globe-BIMbYVfR.js";import{C as Le}from"./chevron-left-Hn3UM-NM.js";import{C as je}from"./check-Do1juwL_.js";import{D as Y}from"./dollar-sign-Bt1rF0Up.js";import{U as Te}from"./user-DeS27GvT.js";import{D as Me}from"./database-DwFbyMQf.js";import{L as Ue}from"./lock-BgFsHF5L.js";import{S as Re}from"./scroll-text-BN8nd88z.js";import{S as Ie}from"./shield-alert-aZX8uTyl.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-CmNcswQv.js";import{B as C}from"./Button-9dckZRDN.js";import{T as $e}from"./trending-up-DQqCw2fH.js";import{C as z}from"./clock-sHF7TkaL.js";import{A as Be,U as ue,M as De}from"./Avatar-CWqr7n5f.js";import{A as J}from"./activity-BXuoHaM2.js";import{R as pe}from"./refresh-cw-BBJiyS_M.js";import{G as ze}from"./globe-CJQelTw1.js";import{C as Le}from"./chevron-left-NKl5Cd-R.js";import{C as je}from"./check-D-RGuqkl.js";import{D as Y}from"./dollar-sign-BkQRFa0q.js";import{U as Te}from"./user-DPVl5QyH.js";import{D as Me}from"./database-BOlnZ1VP.js";import{L as Ue}from"./lock-9PCIcJ6T.js";import{S as Re}from"./scroll-text-CGG6Enap.js";import{S as Ie}from"./shield-alert-BFJHSdqK.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-D1-1DZ1A.js";/**
1
+ import{c as l,j as s}from"./index-CmNcswQv.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-D1-1DZ1A.js";import{C as r}from"./clock-9J88OP3M.js";import{C as a}from"./circle-alert-Btc-PWto.js";import{C as l}from"./check-Do1juwL_.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-CmNcswQv.js";import{C as r}from"./clock-sHF7TkaL.js";import{C as a}from"./circle-alert-ByXEu_ry.js";import{C as l}from"./check-D-RGuqkl.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-D1-1DZ1A.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-CmNcswQv.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-D1-1DZ1A.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-LISxmNUO.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-CJBtXUbH.js";import{C as oe}from"./check-Do1juwL_.js";import{C as Ye}from"./clock-9J88OP3M.js";import{D as Xe}from"./dollar-sign-Bt1rF0Up.js";import{U as Ze}from"./upload-rDccLEQm.js";import{L as V}from"./loader-circle-CelYAWD2.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-CmNcswQv.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-BkDMHZsx.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-BGbIHMwH.js";import{C as oe}from"./check-D-RGuqkl.js";import{C as Ye}from"./clock-sHF7TkaL.js";import{D as Xe}from"./dollar-sign-BkQRFa0q.js";import{U as Ze}from"./upload-SWiggmcJ.js";import{L as V}from"./loader-circle-BNbNqvck.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-D1-1DZ1A.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-CmNcswQv.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-D1-1DZ1A.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-CmNcswQv.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-D1-1DZ1A.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
1
+ import{r as l,a as x,j as e}from"./index-CmNcswQv.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
@@ -1,4 +1,4 @@
1
- import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-D1-1DZ1A.js";import{B as N}from"./Button-CzD_JfV1.js";import{C as y}from"./thumbs-up-CJBtXUbH.js";import{R as S}from"./refresh-cw-Bdo9tSnG.js";import{C as z}from"./circle-alert-Btc-PWto.js";import{U as D}from"./user-DeS27GvT.js";import{L as G}from"./loader-circle-CelYAWD2.js";import{R as T}from"./rotate-ccw-BaY8Qfhk.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-CmNcswQv.js";import{B as N}from"./Button-9dckZRDN.js";import{C as y}from"./thumbs-up-BGbIHMwH.js";import{R as S}from"./refresh-cw-BBJiyS_M.js";import{C as z}from"./circle-alert-ByXEu_ry.js";import{U as D}from"./user-DPVl5QyH.js";import{L as G}from"./loader-circle-BNbNqvck.js";import{R as T}from"./rotate-ccw-BNLXFero.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-D1-1DZ1A.js";import{B as y}from"./Button-CzD_JfV1.js";import{C as ge}from"./chevron-left-Hn3UM-NM.js";import{G as P}from"./thumbs-up-CJBtXUbH.js";import{R as $}from"./refresh-cw-Bdo9tSnG.js";import{C as Ne}from"./circle-alert-Btc-PWto.js";import{L as Q,S as je}from"./ProjectPage--I3rB_p4.js";import{S as se}from"./shield-alert-aZX8uTyl.js";import{F as ye}from"./file-code-corner-BvhHgreH.js";import{C as V}from"./clock-9J88OP3M.js";import{C as re}from"./check-Do1juwL_.js";import"./ErrorBoundary-LISxmNUO.js";import"./TerminalOutput-BT2DzBO1.js";import"./lock-BgFsHF5L.js";import"./package-5sdo-e9y.js";import"./file-plus-CeOevK8W.js";import"./activity-CQJpef5Z.js";import"./scroll-text-BN8nd88z.js";import"./bot-BEjHVO92.js";import"./loader-circle-CelYAWD2.js";import"./hammer-CMG6alC6.js";import"./dollar-sign-Bt1rF0Up.js";import"./globe-BIMbYVfR.js";import"./trash-2-bgGf4gkl.js";import"./upload-rDccLEQm.js";import"./plus-CSzQUjW8.js";import"./rotate-ccw-BaY8Qfhk.js";import"./code-xml-iv1keZ9N.js";import"./trending-up-CGmXxQM4.js";import"./layers-Dwoys6vF.js";import"./trending-down-BJ0IybHJ.js";import"./server-Bi6RuZbH.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-CmNcswQv.js";import{B as y}from"./Button-9dckZRDN.js";import{C as ge}from"./chevron-left-NKl5Cd-R.js";import{G as P}from"./thumbs-up-BGbIHMwH.js";import{R as $}from"./refresh-cw-BBJiyS_M.js";import{C as Ne}from"./circle-alert-ByXEu_ry.js";import{L as Q,S as je}from"./ProjectPage-B7NMYrmn.js";import{S as se}from"./shield-alert-BFJHSdqK.js";import{F as ye}from"./file-code-corner-ugbZnTSY.js";import{C as V}from"./clock-sHF7TkaL.js";import{C as re}from"./check-D-RGuqkl.js";import"./ErrorBoundary-BkDMHZsx.js";import"./TerminalOutput-BTlTI6D7.js";import"./lock-9PCIcJ6T.js";import"./package-j3aJqney.js";import"./file-plus-C36sokvh.js";import"./activity-BXuoHaM2.js";import"./scroll-text-CGG6Enap.js";import"./bot-vJgiSrdQ.js";import"./loader-circle-BNbNqvck.js";import"./hammer-DPzU4Wtq.js";import"./dollar-sign-BkQRFa0q.js";import"./globe-CJQelTw1.js";import"./trash-2-C7mlnJL3.js";import"./upload-SWiggmcJ.js";import"./plus-DGAY2LNf.js";import"./rotate-ccw-BNLXFero.js";import"./code-xml-huk-YFT0.js";import"./trending-up-DQqCw2fH.js";import"./layers-DzMH-GEN.js";import"./trending-down-BbxICDz5.js";import"./server-Bv6QDqpn.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.