loki-mode 10.7.1 → 10.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +20 -32
- package/autonomy/run.sh +9 -5
- package/autonomy/tui.sh +5 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/api_phases.py +1 -1
- package/dashboard/api_start.py +0 -1
- package/dashboard/server.py +28 -146
- package/docs/COCKPIT-SPEC.md +3 -1
- package/docs/DASHBOARD-9.12-EVIDENCE.md +1 -1
- package/docs/DASHBOARD-ARCHITECTURE.md +13 -11
- package/docs/DASHBOARD_V2_CHECKLIST.md +2 -0
- package/docs/INSTALLATION.md +12 -11
- package/docs/MERGE-DEDUP-MAP.md +1 -1
- package/docs/MERGE-ROUTE-MAP.md +1 -1
- package/docs/MERGE3-PLAN.md +2 -2
- package/docs/R3-COST-OBSERVABILITY-DESIGN.md +2 -2
- package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +1 -1
- package/docs/R5-AUTO-WIKI-DESIGN.md +1 -1
- package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +1 -1
- package/docs/RARV-C-100X-PLAN.md +3 -3
- package/docs/SONNET5-DEFAULT-PLAN.md +2 -2
- package/docs/SYNERGY-TASKS.md +1 -1
- package/docs/TOOL-INTEGRATION.md +1 -1
- package/docs/TOP-100-BACKLOG.md +1 -1
- package/docs/alternative-installations.md +1 -1
- package/docs/architecture/ADR-001-runtime-migration.md +1 -1
- package/docs/architecture/DASHBOARD_V2_ARCHITECTURE.md +2 -0
- package/docs/audit-logging.md +2 -0
- package/docs/authentication.md +2 -0
- package/docs/authorization.md +2 -0
- package/docs/certification/02-enterprise-features/lab.md +2 -0
- package/docs/certification/02-enterprise-features/lesson.md +2 -0
- package/docs/certification/04-production-deployment/lab.md +2 -0
- package/docs/certification/04-production-deployment/lesson.md +2 -0
- package/docs/control-plane-migration.md +97 -0
- package/docs/dashboard-guide.md +6 -7
- package/docs/dev/release-checklist.md +9 -11
- package/docs/enterprise/integration-cookbook.md +2 -0
- package/docs/enterprise/migration.md +1 -1
- package/docs/enterprise/performance.md +3 -1
- package/docs/enterprise/sdk-guide.md +2 -0
- package/docs/enterprise/security.md +2 -0
- package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +2 -2
- package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
- package/docs/retrospectives/v7.5.15-honesty-audit.md +2 -2
- package/docs/test-scenarios/enterprise-scenarios.md +2 -2
- package/docs/v10/ARCHITECT-CUTS.md +9 -9
- package/docs/v10/BACKLOG.md +7 -7
- package/docs/v10/BOARD.md +25 -25
- package/docs/v10/CONTROL-PLANE.md +4 -4
- package/docs/v10/CP-ENTERPRISE-UI.md +270 -9
- package/docs/v10/D51-PHASE-B.md +1 -1
- package/docs/v10/DECISIONS.md +3 -3
- package/docs/v10/DEPS.md +10 -10
- package/docs/v10/FAILURE-CLASSES.md +66 -1
- package/docs/v10/LEGACY-REMOVAL.md +2 -2
- package/docs/v10/METRICS.md +6 -0
- package/docs/v10/SWARM.md +2 -2
- package/loki-ts/data/model-pricing.json +6 -6
- package/loki-ts/dist/cockpit.js +11 -11
- package/loki-ts/dist/loki.js +819 -809
- package/loki-ts/package.json +1 -1
- package/magic/core/design_tokens.py +1 -2
- package/magic/core/generator.py +2 -2
- package/magic/tokens/README.md +1 -3
- package/mcp/__init__.py +1 -1
- package/package.json +3 -8
- package/packages/control-plane/dist/server.js +17954 -5696
- package/packages/control-plane/drizzle/0004_cpe03_local_repos_actions.sql +17 -0
- package/packages/control-plane/drizzle/meta/0004_snapshot.json +542 -0
- package/packages/control-plane/drizzle/meta/_journal.json +9 -2
- package/packages/control-plane/package.json +4 -1
- package/packages/control-plane/src/db/schema.ts +19 -0
- package/packages/control-plane/src/server/app.ts +11 -22
- package/packages/control-plane/src/server/audit.ts +15 -0
- package/packages/control-plane/src/server/auth.ts +7 -1
- package/packages/control-plane/src/server/legacy/routes-audit.ts +50 -0
- package/packages/control-plane/src/server/legacy/routes-control.ts +26 -0
- package/packages/control-plane/src/server/legacy/routes-memory.ts +30 -0
- package/packages/control-plane/src/server/legacy/routes-metrics.ts +18 -0
- package/packages/control-plane/src/server/legacy/routes.ts +237 -0
- package/packages/control-plane/src/server/legacy/shim.ts +201 -0
- package/packages/control-plane/src/server/repos.ts +27 -0
- package/packages/control-plane/src/server/routes/artifacts.ts +104 -0
- package/packages/control-plane/src/server/routes/audit.ts +17 -0
- package/packages/control-plane/src/server/routes/checkpoints.ts +171 -0
- package/packages/control-plane/src/server/routes/config.ts +319 -0
- package/packages/control-plane/src/server/routes/control.ts +75 -0
- package/packages/control-plane/src/server/routes/cost.ts +70 -0
- package/packages/control-plane/src/server/routes/cost_ledger.ts +210 -0
- package/packages/control-plane/src/server/routes/fleet.ts +101 -0
- package/packages/control-plane/src/server/routes/index.ts +71 -0
- package/packages/control-plane/src/server/routes/integrations.ts +123 -0
- package/packages/control-plane/src/server/routes/memory.ts +219 -0
- package/packages/control-plane/src/server/routes/merge_risk.ts +209 -0
- package/packages/control-plane/src/server/routes/metrics.ts +93 -0
- package/packages/control-plane/src/server/routes/notify.ts +48 -0
- package/packages/control-plane/src/server/routes/providers.ts +111 -0
- package/packages/control-plane/src/server/routes/session_control.ts +155 -0
- package/packages/control-plane/src/server/routes/start.ts +39 -0
- package/packages/control-plane/src/server/routes/stats.ts +76 -0
- package/packages/control-plane/src/server/routes/stream.ts +85 -0
- package/packages/control-plane/src/server/routes/verify.ts +66 -0
- package/packages/control-plane/src/server/spawn.ts +79 -0
- package/packages/control-plane/src/shipper/discover.ts +19 -1
- package/packages/control-plane/ui/dist/assets/index-BQbFv65M.css +1 -0
- package/packages/control-plane/ui/dist/assets/index-Dbhu244h.js +155 -0
- package/packages/control-plane/ui/dist/index.html +2 -2
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/references/magic-modules-patterns.md +2 -2
- package/skills/factory-operations.md +3 -3
- package/skills/magic-modules.md +1 -1
- package/skills/release-cadence.md +1 -1
- package/tools/audit-docs.py +1 -1
- package/tools/index-codebase.py +1 -1
- package/web-app/dist/assets/{AdminPage-BJSU5hY1.js → AdminPage-DqMnfZrH.js} +1 -1
- package/web-app/dist/assets/{Avatar-CSOSpw9c.js → Avatar-BEof29du.js} +1 -1
- package/web-app/dist/assets/{Badge-COr7vj0D.js → Badge-WD53OL5m.js} +1 -1
- package/web-app/dist/assets/{Button-DGoWFERp.js → Button-Rzk5flhU.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-CBpWkNXY.js → CockpitPage-Bqz3PCMh.js} +1 -1
- package/web-app/dist/assets/{ComparePage-BwT8vqrL.js → ComparePage-Byo2NzAZ.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-D7SicDDA.js → ErrorBoundary-BuE0kH3W.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-bx-5liG2.js → EvidenceReceiptPanel-CKFHOPBx.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-BAeeWLqY.js → GitHubIssuesPanel-Df_kTMqI.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-CssD8lGI.js → GitHubPRsPanel-CouvcKrZ.js} +1 -1
- package/web-app/dist/assets/{HomePage-SL5PT3m5.js → HomePage-dEpLzj0x.js} +2 -2
- package/web-app/dist/assets/{LoginPage-C8hFOZOM.js → LoginPage-6DVjUND5.js} +1 -1
- package/web-app/dist/assets/{MagicPage-xHbHkrPf.js → MagicPage-BDQ9MOfY.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-B_2CKFcC.js → MetricsPage-CXiJ04G_.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-CXwXMq35.js → NotFoundPage-BaXhZvyj.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-AaisMQI-.js → ProjectPage-BzE4V7Ti.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Cej5ResX.js → ProjectsPage-ipf6TLMX.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-DKv4mn9H.js → SettingsPage-BDxkUKN6.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Dkiyzne4.js → ShowcasePage-YQXD72SM.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-DaBLQ5dU.js → SystemSettingsPage-Dou7zHS0.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-B2yUr31k.js → TeamsPage-CQarfcYr.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-CfYiANhU.js → TemplatesPage-CPi1R8Xj.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-CMXoexLM.js → TerminalOutput-WiGhWdYD.js} +1 -1
- package/web-app/dist/assets/{activity-B0dzoZtY.js → activity-DOa7ejQA.js} +1 -1
- package/web-app/dist/assets/{bell-DFOTaSoo.js → bell-CX-VAlYN.js} +1 -1
- package/web-app/dist/assets/{bot-Dz-WSQyP.js → bot-EDXaZmHc.js} +1 -1
- package/web-app/dist/assets/{check-L1QIRueJ.js → check-CnBdKk3L.js} +1 -1
- package/web-app/dist/assets/{chevron-left-1TrnIEZS.js → chevron-left-BJ_ydRQW.js} +1 -1
- package/web-app/dist/assets/{circle-alert-8Bf6xEDx.js → circle-alert-tz8ufhc_.js} +1 -1
- package/web-app/dist/assets/{clock-DB8NE6P5.js → clock-DFBZPSsH.js} +1 -1
- package/web-app/dist/assets/{cloud-DUSL3wZS.js → cloud-uy3p_5Q7.js} +1 -1
- package/web-app/dist/assets/{code-xml-DbjryWNl.js → code-xml-3CbYD9YL.js} +1 -1
- package/web-app/dist/assets/{database-DrezrMSs.js → database-YiNBXc9c.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-CGbaLMzR.js → dollar-sign-D0wBa4Cv.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-Dfypa-r4.js → file-code-corner-DDdZVZ5v.js} +1 -1
- package/web-app/dist/assets/{file-plus-CzV5L2Gd.js → file-plus-D09LTBqt.js} +1 -1
- package/web-app/dist/assets/{globe-BoYjTwPQ.js → globe-BirTPwff.js} +1 -1
- package/web-app/dist/assets/{hammer-WO-HuiyJ.js → hammer-DaE5qgnd.js} +1 -1
- package/web-app/dist/assets/{index-CjIOUjnd.js → index-D8t7KnQf.js} +3 -3
- package/web-app/dist/assets/{layers-Bn6jtKNk.js → layers-DVVrckRY.js} +1 -1
- package/web-app/dist/assets/{loader-circle-gERWRnmW.js → loader-circle-2-nMGmcb.js} +1 -1
- package/web-app/dist/assets/{lock-BIiMLJq8.js → lock-D0Xj43pC.js} +1 -1
- package/web-app/dist/assets/{package-dLvDSVys.js → package-BB7S3egm.js} +1 -1
- package/web-app/dist/assets/{plus-BHM3ZLhZ.js → plus-BLhoMrn3.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-BAp_alv6.js → refresh-cw-DMc2uPLw.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-CBhwq_MG.js → rotate-ccw-DM3IP9x7.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DoS-6dfU.js → scroll-text-lH2uW7rB.js} +1 -1
- package/web-app/dist/assets/{server-5JgdDWQO.js → server-BkerZcdR.js} +1 -1
- package/web-app/dist/assets/{shield-alert-DjmlLT34.js → shield-alert-B8ohcUfu.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BtiEXl3p.js → thumbs-up-CTIxLzPD.js} +1 -1
- package/web-app/dist/assets/{trash-2-ClsWU_Vg.js → trash-2-C3zIpsH5.js} +1 -1
- package/web-app/dist/assets/{trending-down-DPS4M7_X.js → trending-down-BTT7wV4Y.js} +1 -1
- package/web-app/dist/assets/{trending-up-D6OJ38-V.js → trending-up-BzHdCDvF.js} +1 -1
- package/web-app/dist/assets/{upload-DOCzLUpF.js → upload-HxR34-A8.js} +1 -1
- package/web-app/dist/assets/{usePolling-CljQTWj_.js → usePolling-DDj6Fupy.js} +1 -1
- package/web-app/dist/assets/{user-C0G82Weu.js → user-qH5y9yNy.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/dashboard/static/assets/mermaid.min.js +0 -2030
- package/dashboard/static/cost.html +0 -344
- package/dashboard/static/favicon.svg +0 -5
- package/dashboard/static/index.html +0 -15577
- package/dashboard/static/proofs.html +0 -194
- package/dashboard/static/start.html +0 -131
- package/dashboard/static/trust.html +0 -325
- package/packages/control-plane/src/server/actions.ts +0 -60
- package/packages/control-plane/ui/dist/assets/index-DHDI_dHM.css +0 -1
- package/packages/control-plane/ui/dist/assets/index-DaQr0MPS.js +0 -129
|
@@ -62,7 +62,8 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
|
|
|
62
62
|
- fix.ts:63 escalation gate;
|
|
63
63
|
- implement.ts:56 limit;
|
|
64
64
|
- the plan stage on the "fast" tier;
|
|
65
|
-
- no effort field in SessionRunOptions
|
|
65
|
+
- no effort field in SessionRunOptions;
|
|
66
|
+
- `loki start prd.md` still goes to the legacy run.sh route, whose default is sonnet (providers/claude.sh CLAUDE_DEFAULT_DEVELOPMENT).
|
|
66
67
|
- Mechanism: a catalog best_default plus a top tier for each provider (EL-W0-06, EL-W0-07), and a size gate on the artifact (EL-W0-05).
|
|
67
68
|
- Fixture: a unit test that the default run.started.model equals the catalog best_default, plus a parity replay row.
|
|
68
69
|
|
|
@@ -125,6 +126,18 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
|
|
|
125
126
|
- Mechanism: one runner-config registry for each runner. Any added or changed file that it names (configs, preloads, setup files, conftest) caps the verdict below VERIFIED, with NOT PROVEN naming the file.
|
|
126
127
|
- Fixture: a stub-provider repro for each runner (bun preload, vitest setupFiles, jest moduleNameMapper, pytest conftest).
|
|
127
128
|
|
|
129
|
+
## FC-10 Live line truncated to ~20 columns on a pty with no size
|
|
130
|
+
- User saw: on a pty with no column size (script -q, CI, tmux before a resize, IDE terminals) the quiet-mode live status line was cut to about 20 characters, for example "[implement] implemen". Raw: the stage events were complete; only the rendering was wrong.
|
|
131
|
+
- Law: L7 (outputs are contracts).
|
|
132
|
+
- Siblings (every terminal width read, with its old fallback):
|
|
133
|
+
- loki-ts/src/engine10/supervisor.ts:334 passed process.stdout.columns straight to LiveLine (undefined or 0);
|
|
134
|
+
- loki-ts/src/e10ext/liveline.ts:35 used Math.max(20, (columns ?? 80) - 1), so 0 became 20 (the bug);
|
|
135
|
+
- loki-ts/src/cockpit/cli.ts:73 used columns || $COLUMNS || 0 with no 80 default and accepted widths of 5 or more;
|
|
136
|
+
- autonomy/tui.sh:27 used `tput cols || echo 80`, which accepts tput printing 0 or nothing;
|
|
137
|
+
- packages/*/src: no terminal width reads.
|
|
138
|
+
- Mechanism: one shared terminalWidth() helper (loki-ts/src/util/term_width.ts): a finite columns >= 40, else a valid $COLUMNS >= 40, else 80. Every TS read goes through it and the bash read applies the same rule.
|
|
139
|
+
- Fixture: loki-ts/tests/engine10/term_width.test.ts (columns undefined, 0 and 20 give >= 80; the live line shows the full "[implement] implementing" text; a guard fails on any raw .columns read in src outside the helper).
|
|
140
|
+
|
|
128
141
|
## FC-11 Repo-wide structural guards went red after slices passed narrowed reviews
|
|
129
142
|
- User saw: nothing yet; the 10.7.1 train was blocked on main 51e02b229 (2 failures in the full loki-ts bun test).
|
|
130
143
|
- Law: L7 (the release is a contract), and the D44 gate.
|
|
@@ -143,3 +156,55 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
|
|
|
143
156
|
- the shipper imports in e10ext/ship_hook.ts and commands/control.ts, which have no external deps today but share the same path.
|
|
144
157
|
- Mechanism: one `postinstall` in loki-ts/package.json installs packages/control-plane from its frozen lockfile, so every loki-ts install (CI, Docker, local) gets the sibling's deps. No per-workflow steps.
|
|
145
158
|
- Fixture: a clean `git worktree add` at HEAD, then `bun install --frozen-lockfile && bun run build` in loki-ts, and again with `--production`. Both exit 0 and the dist is byte-identical to the committed one; without the postinstall the build exits 1 with the error above.
|
|
159
|
+
|
|
160
|
+
## FC-13 Tests pin a data value that a correct change is allowed to move
|
|
161
|
+
- User saw: nothing; the full loki-ts bun test on merged main ca9b85b7f had 5 red in "budget: cache token pricing" after MW-1 correctly moved sonnet from 3/15/0.3/3.75 to 2/10/0.2/2.5. The expected totals (0.6617, 3.0) and tiers were literals, so the price change read as a cost bug. The MW-1 review was approved on the slice's own suites, without the full bun test (an FC-11 sibling).
|
|
162
|
+
- Law: L7 (the release is a contract); a guard must fail on wrong behavior, not on a legitimate data change.
|
|
163
|
+
- Siblings:
|
|
164
|
+
- tests/dashboard/test_api_cost_cache.py stubs its own table, so it stays consistent, but its docstring says the other routes return 0.6617, which is stale (cosmetic);
|
|
165
|
+
- tests/test-pricing-parity.sh (MW-1) compares routes against model-pricing.json, the correct shape;
|
|
166
|
+
- the codex and gpt rows drift between run.sh and budget.ts (rv-mw1 follow-up), which is the same file-is-the-source rule.
|
|
167
|
+
- Mechanism: arithmetic tests derive expectations from the single pricing source (loki-ts/data/model-pricing.json) and assert the loaded table equals the file; only the fixture token counts are literal. Pricing-table changes run the full bun test in main before the train (FC-11 mechanism).
|
|
168
|
+
- Fixture: loki-ts/test/budget_cache_pricing.test.ts at 0de0838e1, 8 pass 0 fail; "cache tiers survive loading" compares the loaded PRICING with the file (loader mutation not yet run; follow-up).
|
|
169
|
+
|
|
170
|
+
## FC-14 A nested sandbox trusts an inherited pointer to the real environment
|
|
171
|
+
- User saw: running the test runner truncated the founder real ~/.loki/keys/receipt-ed25519.pem. A fixture wrote through an inherited LOKI_REAL_HOME that still named the real home while HOME was a stand-in.
|
|
172
|
+
- Law: L2 (trust fails closed).
|
|
173
|
+
- Siblings:
|
|
174
|
+
- loki_hermetic_home_enter (tests/lib/hermetic-home.sh) took LOKI_REAL_HOME from the environment;
|
|
175
|
+
- loki-ts/tests/preload.ts used LOKI_REAL_HOME ?? HOME;
|
|
176
|
+
- run_runner in tests/test-e154-e155-guards.sh kept the exported LOKI_REAL_HOME;
|
|
177
|
+
- the outer E-154 key check compared names only, so truncating an existing key was invisible.
|
|
178
|
+
- Mechanism: derive the real path from the current HOME, never from an inherited variable (enter unsets LOKI_REAL_HOME, preload reads HOME); the key check fingerprints name, size and mtime.
|
|
179
|
+
- Fixture: tests/test-e154-e155-guards.sh (run_runner strips the pointers; t-keys writes only the runner-derived stand-in). A decoy-pointer probe and a bun HOME probe are owed after Oct 7 (B3, phase D vacuity).
|
|
180
|
+
|
|
181
|
+
## FC-15 A run judges "already done" against Loki's own unmerged work
|
|
182
|
+
- User saw: FireLater#17 rerun on 10.7.1 (e10-20261003T185853Z-2d44) reported ALREADY_SATISFIED in 2m07s for $0.52. That was false. The run branched from the checked-out loki/e10-20261003T150744Z-59b1 (eda184e). That branch was the earlier FAILED run's unmerged draft PR #25, which also lacks the route edits the old scope control reverted.
|
|
183
|
+
- Law: L4 (the base is a contract), L2 (trust fails closed).
|
|
184
|
+
- Founder rule (2026-10-03):
|
|
185
|
+
- Base precedence: an explicit CLI flag (add `--base` if none exists), then the loki.yaml base_branch setting (a branch name, `current` or `default`), then the user's checked-out branch.
|
|
186
|
+
- The repo default branch is used only when it is configured as `default`. Never hardcode "main" (L0).
|
|
187
|
+
- The start line prints `base: <branch> (<flag, config or checkout>)`.
|
|
188
|
+
- The PR target is the configured target, else the repo default branch, and the PR body names it.
|
|
189
|
+
- Siblings: every outcome that compares against the base (ALREADY_SATISFIED, the Wall base run, the scope diff, the receipt delta).
|
|
190
|
+
- Mechanism:
|
|
191
|
+
- Detect Loki's own unmerged work on the base from its run records (the loki/e10-* branch plus the run receipt), not from a branch-name regex.
|
|
192
|
+
- Report "this branch already has run <id>'s unmerged work (PR #N, <state>); resume or review it", never ALREADY_SATISFIED.
|
|
193
|
+
- A dirty or foreign checkout is noted in the output.
|
|
194
|
+
- Fixture: owed. A repo whose checkout is a prior run's branch with a receipt must yield the unmerged-work outcome.
|
|
195
|
+
|
|
196
|
+
## FC-16 ALREADY_SATISFIED with zero Loki-executed checks
|
|
197
|
+
- User saw: the same run had verify "checks": [] and changed_files []. The verdict rested only on the implement agent's self-report ("10/10 named impacted tests pass ... via npx vitest run").
|
|
198
|
+
- Law: L0 and L3 (the model never grades its own work), L5; Seal accuracy.
|
|
199
|
+
- Siblings: every outcome that is reachable with an empty checks list.
|
|
200
|
+
- Mechanism:
|
|
201
|
+
- A success-class outcome requires harness-executed evidence against the target base: the impacted tests run through the Project Model commands, plus each acceptance point of the issue checked.
|
|
202
|
+
- With zero executed checks the outcome is NOT VERIFIED.
|
|
203
|
+
- Fixture: owed. A verify with checks [] and a self-reported pass must yield NOT VERIFIED.
|
|
204
|
+
|
|
205
|
+
## FC-17 The Wall spends time and money and writes nothing
|
|
206
|
+
- User saw: the same run's Wall produced "files": [] in 1m42s, with base_run 0/0/0. This is the D82-WALL0 class again.
|
|
207
|
+
- Law: L5 (no work without evidence), cost.
|
|
208
|
+
- Siblings: D82-WALL0 and any stage that can finish with zero artifacts and still bill.
|
|
209
|
+
- Mechanism: if the Wall cannot write a check, it skips in under 10s with a NOT PROVEN note and never runs a model session to an empty result.
|
|
210
|
+
- Fixture: owed. A repo with no runnable test command yields a Wall skip under 10s with NOT PROVEN.
|
|
@@ -66,7 +66,7 @@ Evidence: `grep -rn autonomy/|providers/` over loki-ts/src/engine10, packages/co
|
|
|
66
66
|
| loki-ts/src/runner, commands, providers (v8 loop) | PORT subset | engine10 imports runner/github_token, types, retry_class, providers, budget; providers/claude_flags, mcp_config; delete the rest |
|
|
67
67
|
| council/, quality gates scripts, swarm/, agents/ | DELETE (6e) | no engine10 refs |
|
|
68
68
|
| dashboard/ (Python) | KEEP until D56 flip, then DELETE | D57 item 3 |
|
|
69
|
-
|
|
|
69
|
+
| legacy-ui/ | KEEP until D56 flip, then DELETE | same |
|
|
70
70
|
| engine10/dashboard | KEEP until D56 flip | engine10/cli.ts TABLE |
|
|
71
71
|
| web-app/ (Purple Lab) | DELETE | no engine10 or CP ref; 55k lines |
|
|
72
72
|
| mcp/ | DELETE (6d) | mcp/server.py has 0 engine10 calls; loki-ts refs are v8 runner only |
|
|
@@ -94,7 +94,7 @@ Wall check for every slice: v10 suite, Bun Parity (redefined in W2-01), first-ru
|
|
|
94
94
|
10. W2-10 providers/*.sh (~3k).
|
|
95
95
|
11. W2-11 autonomy/run.sh, autonomy/loki, autonomy/lib except KEEP rows (~125k). Last code slice; depends on 01, 02, 08, 09.
|
|
96
96
|
12. W2-12 legacy docs/ plans and wiki pages (~1000 mentions).
|
|
97
|
-
13. W2-13 dashboard/ +
|
|
97
|
+
13. W2-13 dashboard/ + legacy-ui/ (~113k), only after D56 default flip.
|
|
98
98
|
|
|
99
99
|
## 5. Guard spec (D57 item 4)
|
|
100
100
|
|
package/docs/v10/METRICS.md
CHANGED
|
@@ -579,3 +579,9 @@ Raw rows: ~/loki-ci-logs/d50-{raw-haiku,raw-sonnet,v10-haiku,v10-sonnet}/results
|
|
|
579
579
|
| pub-humanize-174 | 0/3 | 2/3 |
|
|
580
580
|
| aiq-52-searchbar (no_change_needed) | 0/3 | 2/3 |
|
|
581
581
|
Two of the four baseline losses were noise; two are real. Internal measurement, not for publication until the fixes are re-measured.
|
|
582
|
+
|
|
583
|
+
## Cost rate re-baseline (MW-1)
|
|
584
|
+
| Date | Model | Input $/MTok | Output $/MTok | Cache read | Cache write 5m | Context | Source |
|
|
585
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
586
|
+
| 2026-10-03 | claude-sonnet-5-5 (and claude-sonnet-5, now the standard price) | 2 (was 3 in loki-ts/data/model-pricing.json) | 10 (was 15) | 0.20 | 2.50 | 1M, standard pricing | platform.claude.com/docs/en/about-claude/pricing, read 2026-10-03 |
|
|
587
|
+
Cost per completed task for sonnet arms measured before this date used the old 3/15 table; they overstate by 1.5x and are not comparable without rescaling.
|
package/docs/v10/SWARM.md
CHANGED
|
@@ -159,8 +159,8 @@ shrink for pending), `CHANGELOG.md`, `docs/v10/BACKLOG.md`,
|
|
|
159
159
|
|
|
160
160
|
**Generated bundles** (never edited by hand by a builder; the Captain
|
|
161
161
|
rebuilds all three after every merge that could touch their sources):
|
|
162
|
-
`loki-ts/dist/loki.js` (from `loki-ts/src`), `
|
|
163
|
-
and `
|
|
162
|
+
`loki-ts/dist/loki.js` (from `loki-ts/src`), `legacy-ui-static/index.html`
|
|
163
|
+
and `legacy-ui/dist` (from `legacy-ui/scripts/build-standalone.js` and
|
|
164
164
|
components), `web-app/dist` (from `web-app/src`).
|
|
165
165
|
|
|
166
166
|
**Cross-wave exclusion:** a promise chain only serializes within one
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema_version": 1,
|
|
3
3
|
"_comment": "Rolling pricing table consumed by loki-ts/src/runner/budget.ts. Update this file when Anthropic / OpenAI / others publish new prices; no code change required. Pricing is USD per 1 million tokens. Aliases (opus/sonnet/haiku) point to the latest model of that family per providers/model_catalog.json.",
|
|
4
|
-
"_updated": "2026-
|
|
5
|
-
"_source": "https://www.anthropic.com/pricing + provider docs. sonnet=claude-sonnet-5 (
|
|
4
|
+
"_updated": "2026-10-03",
|
|
5
|
+
"_source": "https://www.anthropic.com/pricing + provider docs. sonnet=claude-sonnet-5 and claude-sonnet-5-5, both $2/$10 per MTok (the Sonnet 5 intro price became the standard price; the 2026-09-01 increase to $3/$15 will not occur), cache write 5m $2.50, cache read $0.20, 1M context at standard pricing (platform.claude.com/docs/en/about-claude/pricing, read 2026-10-03). opus=claude-opus-5. codex=gpt-5.3-codex standard tier. Cache tiers: read 0.1x input, write 1.25x input (Anthropic + OpenAI published multipliers).",
|
|
6
6
|
"pricing": {
|
|
7
7
|
"fable": {
|
|
8
8
|
"input": 10.0,
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"cache_write": 6.25
|
|
18
18
|
},
|
|
19
19
|
"sonnet": {
|
|
20
|
-
"input":
|
|
21
|
-
"output":
|
|
22
|
-
"cache_read": 0.
|
|
23
|
-
"cache_write":
|
|
20
|
+
"input": 2.0,
|
|
21
|
+
"output": 10.0,
|
|
22
|
+
"cache_read": 0.2,
|
|
23
|
+
"cache_write": 2.5
|
|
24
24
|
},
|
|
25
25
|
"haiku": {
|
|
26
26
|
"input": 1.0,
|
package/loki-ts/dist/cockpit.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
2
|
+
var zD=Object.defineProperty;var FD=(D)=>D;function HD(D,J){this[D]=FD.bind(null,J)}var BD=(D,J)=>{for(var Q in J)zD(D,Q,{get:J[Q],enumerable:!0,configurable:!0,set:HD.bind(J,Q)})};var ID=(D,J)=>()=>(D&&(J=D(D=0)),J);var F=import.meta.require;var qD={};BD(qD,{initWasm:()=>pD,Resvg:()=>nD});function A(D){if(_===W.length)W.push(W.length+1);let J=_;return _=W[J],W[J]=D,J}function U(D){return W[D]}function xD(D){if(D<132)return;W[D]=_,_=D}function z(D){let J=U(D);return xD(D),J}function b(){if(j===null||j.byteLength===0)j=new Uint8Array(G.memory.buffer);return j}function n(D,J,Q){if(Q===void 0){let K=y.encode(D),N=J(K.length,1)>>>0;return b().subarray(N,N+K.length).set(K),h=K.length,N}let X=D.length,Z=J(X,1)>>>0,$=b(),q=0;for(;q<X;q++){let K=D.charCodeAt(q);if(K>127)break;$[Z+q]=K}if(q!==X){if(q!==0)D=D.slice(q);Z=Q(Z,X,X=q+D.length*3,1)>>>0;let K=b().subarray(Z+q,Z+X),N=_D(D,K);q+=N.written,Z=Q(Z,X,q,1)>>>0}return h=q,Z}function i(D){return D===void 0||D===null}function P(){if(x===null||x.byteLength===0)x=new Int32Array(G.memory.buffer);return x}function w(D,J){return D=D>>>0,GD.decode(b().subarray(D,D+J))}function hD(D,J){if(!(D instanceof J))throw Error(`expected instance of ${J.name}`);return D.ptr}function uD(D,J){try{return D.apply(this,J)}catch(Q){G.__wbindgen_exn_store(A(Q))}}async function yD(D,J){if(typeof Response==="function"&&D instanceof Response){if(typeof WebAssembly.instantiateStreaming==="function")try{return await WebAssembly.instantiateStreaming(D,J)}catch(X){if(D.headers.get("Content-Type")!="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",X);else throw X}let Q=await D.arrayBuffer();return await WebAssembly.instantiate(Q,J)}else{let Q=await WebAssembly.instantiate(D,J);if(Q instanceof WebAssembly.Instance)return{instance:Q,module:D};else return Q}}function wD(){let D={};return D.wbg={},D.wbg.__wbg_new_28c511d9baebfa89=function(J,Q){let X=Error(w(J,Q));return A(X)},D.wbg.__wbindgen_memory=function(){let J=G.memory;return A(J)},D.wbg.__wbg_buffer_12d079cc21e14bdb=function(J){let Q=U(J).buffer;return A(Q)},D.wbg.__wbg_newwithbyteoffsetandlength_aa4a17c33a06e5cb=function(J,Q,X){let Z=new Uint8Array(U(J),Q>>>0,X>>>0);return A(Z)},D.wbg.__wbindgen_object_drop_ref=function(J){z(J)},D.wbg.__wbg_new_63b92bc8671ed464=function(J){let Q=new Uint8Array(U(J));return A(Q)},D.wbg.__wbg_values_839f3396d5aac002=function(J){let Q=U(J).values();return A(Q)},D.wbg.__wbg_next_196c84450b364254=function(){return uD(function(J){let Q=U(J).next();return A(Q)},arguments)},D.wbg.__wbg_done_298b57d23c0fc80c=function(J){return U(J).done},D.wbg.__wbg_value_d93c65011f51a456=function(J){let Q=U(J).value;return A(Q)},D.wbg.__wbg_instanceof_Uint8Array_2b3bbecd033d19f6=function(J){let Q;try{Q=U(J)instanceof Uint8Array}catch(Z){Q=!1}return Q},D.wbg.__wbindgen_string_get=function(J,Q){let X=U(Q),Z=typeof X==="string"?X:void 0;var $=i(Z)?0:n(Z,G.__wbindgen_malloc,G.__wbindgen_realloc),q=h;P()[J/4+1]=q,P()[J/4+0]=$},D.wbg.__wbg_new_16b304a2cfa7ff4a=function(){return A([])},D.wbg.__wbindgen_string_new=function(J,Q){let X=w(J,Q);return A(X)},D.wbg.__wbg_push_a5b05aedc7234f9f=function(J,Q){return U(J).push(U(Q))},D.wbg.__wbg_length_c20a40f15020d68a=function(J){return U(J).length},D.wbg.__wbg_set_a47bac70306a19a7=function(J,Q,X){U(J).set(U(Q),X>>>0)},D.wbg.__wbindgen_throw=function(J,Q){throw Error(w(J,Q))},D}function lD(D,J){}function mD(D,J){return G=D.exports,KD.__wbindgen_wasm_module=J,x=null,j=null,G}async function KD(D){if(G!==void 0)return G;if(typeof D>"u")D=new URL("index_bg.wasm",void 0);let J=wD();if(typeof D==="string"||typeof Request==="function"&&D instanceof Request||typeof URL==="function"&&D instanceof URL)D=fetch(D);lD(J);let{instance:Q,module:X}=await yD(await D,J);return mD(Q,X)}function iD(D){return Object.prototype.hasOwnProperty.call(D,"fontBuffers")}var G,W,_,h=0,j=null,y,_D,x=null,GD,ZD,p=class D{static __wrap(J){J=J>>>0;let Q=Object.create(D.prototype);return Q.__wbg_ptr=J,ZD.register(Q,Q.__wbg_ptr,Q),Q}__destroy_into_raw(){let J=this.__wbg_ptr;return this.__wbg_ptr=0,ZD.unregister(this),J}free(){let J=this.__destroy_into_raw();G.__wbg_bbox_free(J)}get x(){return G.__wbg_get_bbox_x(this.__wbg_ptr)}set x(J){G.__wbg_set_bbox_x(this.__wbg_ptr,J)}get y(){return G.__wbg_get_bbox_y(this.__wbg_ptr)}set y(J){G.__wbg_set_bbox_y(this.__wbg_ptr,J)}get width(){return G.__wbg_get_bbox_width(this.__wbg_ptr)}set width(J){G.__wbg_set_bbox_width(this.__wbg_ptr,J)}get height(){return G.__wbg_get_bbox_height(this.__wbg_ptr)}set height(J){G.__wbg_set_bbox_height(this.__wbg_ptr,J)}},$D,fD=class D{static __wrap(J){J=J>>>0;let Q=Object.create(D.prototype);return Q.__wbg_ptr=J,$D.register(Q,Q.__wbg_ptr,Q),Q}__destroy_into_raw(){let J=this.__wbg_ptr;return this.__wbg_ptr=0,$D.unregister(this),J}free(){let J=this.__destroy_into_raw();G.__wbg_renderedimage_free(J)}get width(){return G.renderedimage_width(this.__wbg_ptr)>>>0}get height(){return G.renderedimage_height(this.__wbg_ptr)>>>0}asPng(){try{let Z=G.__wbindgen_add_to_stack_pointer(-16);G.renderedimage_asPng(Z,this.__wbg_ptr);var J=P()[Z/4+0],Q=P()[Z/4+1],X=P()[Z/4+2];if(X)throw z(Q);return z(J)}finally{G.__wbindgen_add_to_stack_pointer(16)}}get pixels(){let J=G.renderedimage_pixels(this.__wbg_ptr);return z(J)}},vD,bD=class{__destroy_into_raw(){let D=this.__wbg_ptr;return this.__wbg_ptr=0,vD.unregister(this),D}free(){let D=this.__destroy_into_raw();G.__wbg_resvg_free(D)}constructor(D,J,Q){try{let N=G.__wbindgen_add_to_stack_pointer(-16);var X=i(J)?0:n(J,G.__wbindgen_malloc,G.__wbindgen_realloc),Z=h;G.resvg_new(N,A(D),X,Z,i(Q)?0:A(Q));var $=P()[N/4+0],q=P()[N/4+1],K=P()[N/4+2];if(K)throw z(q);return this.__wbg_ptr=$>>>0,this}finally{G.__wbindgen_add_to_stack_pointer(16)}}get width(){return G.resvg_width(this.__wbg_ptr)}get height(){return G.resvg_height(this.__wbg_ptr)}render(){try{let X=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_render(X,this.__wbg_ptr);var D=P()[X/4+0],J=P()[X/4+1],Q=P()[X/4+2];if(Q)throw z(J);return fD.__wrap(D)}finally{G.__wbindgen_add_to_stack_pointer(16)}}toString(){let D,J;try{let Z=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_toString(Z,this.__wbg_ptr);var Q=P()[Z/4+0],X=P()[Z/4+1];return D=Q,J=X,w(Q,X)}finally{G.__wbindgen_add_to_stack_pointer(16),G.__wbindgen_free(D,J,1)}}innerBBox(){let D=G.resvg_innerBBox(this.__wbg_ptr);return D===0?void 0:p.__wrap(D)}getBBox(){let D=G.resvg_getBBox(this.__wbg_ptr);return D===0?void 0:p.__wrap(D)}cropByBBox(D){hD(D,p),G.resvg_cropByBBox(this.__wbg_ptr,D.__wbg_ptr)}imagesToResolve(){try{let X=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_imagesToResolve(X,this.__wbg_ptr);var D=P()[X/4+0],J=P()[X/4+1],Q=P()[X/4+2];if(Q)throw z(J);return z(D)}finally{G.__wbindgen_add_to_stack_pointer(16)}}resolveImage(D,J){try{let Z=G.__wbindgen_add_to_stack_pointer(-16),$=n(D,G.__wbindgen_malloc,G.__wbindgen_realloc),q=h;G.resvg_resolveImage(Z,this.__wbg_ptr,$,q,A(J));var Q=P()[Z/4+0],X=P()[Z/4+1];if(X)throw z(Q)}finally{G.__wbindgen_add_to_stack_pointer(16)}}},dD,g=!1,pD=async(D)=>{if(g)throw Error("Already initialized. The `initWasm()` function can be used only once.");await dD(await D),g=!0},nD;var LD=ID(()=>{W=Array(128).fill(void 0);W.push(void 0,null,!0,!1);_=W.length;y=typeof TextEncoder<"u"?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},_D=typeof y.encodeInto==="function"?function(D,J){return y.encodeInto(D,J)}:function(D,J){let Q=y.encode(D);return J.set(Q),{read:D.length,written:Q.length}};GD=typeof TextDecoder<"u"?new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw Error("TextDecoder not available")}};if(typeof TextDecoder<"u")GD.decode();ZD=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_bbox_free(D>>>0)),$D=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_renderedimage_free(D>>>0)),vD=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_resvg_free(D>>>0));dD=KD,nD=class extends bD{constructor(D,J){if(!g)throw Error("Wasm has not been initialized. Call `initWasm()` function.");let Q=J?.font;if(!!Q&&iD(Q)){let X={...J,font:{...Q,fontBuffers:void 0}};super(D,JSON.stringify(X),Q.fontBuffers)}else super(D,JSON.stringify(J))}}});function T(D){return String(D??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function RD(D,J,Q){let X=Q/512;return`<g transform="translate(${D},${J}) scale(${X})">
|
|
3
3
|
<rect x="0" y="0" width="512" height="512" rx="118" fill="#553de9"/>
|
|
4
4
|
<path d="M152 405 L242 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
|
|
5
5
|
<path d="M360 405 L270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
|
|
6
6
|
<path d="M242 120 Q256 86 270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
|
|
7
7
|
<circle cx="256" cy="295" r="20" fill="#1FC5A8"/>
|
|
8
|
-
</g>`}function
|
|
9
|
-
<text x="${
|
|
8
|
+
</g>`}function SD(D){switch(D){case"verified":return"#1f8a52";case"failed":return"#b23a3a";case"working":case"pending":return"#9a6a12";default:return"#6b6675"}}function MD(D){switch(D){case"pass":return"#1f8a52";case"fail":return"#b23a3a";case"pending":return"#9a6a12";default:return"#6b6675"}}function kD(D){switch(D){case"approve":return"#1f8a52";case"reject":return"#b23a3a";case"concern":return"#9a6a12";default:return"#6b6675"}}function v(D,J,Q,X,Z="#201515"){return`<text x="${D}" y="${J}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675" letter-spacing="0.5">${T(Q.toUpperCase())}</text>
|
|
9
|
+
<text x="${D}" y="${J+24}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="20" font-weight="600" fill="${Z}">${T(X)}</text>`}var OD=["Reason","Act","Reflect","Verify"];function jD(D){let J=(D||"").toLowerCase();if(/verif|complet|done|ship|deploy/.test(J))return 3;if(/reflect|review|council|critique|assess/.test(J))return 2;if(/reason|plan|design|architect|spec|analy/.test(J))return 0;return 1}function XD(D){let X={run:D?.run||"cockpit",iteration:typeof D?.iteration==="number"?D.iteration:0,phase:D?.phase||"idle",tier:D?.tier||"",provider:D?.provider||"",verdict:D?.verdict||"unknown",budgetUsd:typeof D?.budgetUsd==="number"?D.budgetUsd:0,budgetLimitUsd:D?.budgetLimitUsd,freshness:D?.freshness,gates:Array.isArray(D?.gates)?D.gates:[],council:Array.isArray(D?.council)?D.council:[],fleet:Array.isArray(D?.fleet)?D.fleet:[]},Z=X.budgetLimitUsd&&X.budgetLimitUsd>0?`$${X.budgetUsd.toFixed(2)} / $${X.budgetLimitUsd.toFixed(2)}`:`$${X.budgetUsd.toFixed(2)}`,$="";$+=RD(32,32,44),$+=`<text x="92" y="54" font-family="'Fraunces','Georgia',serif" font-size="24" font-weight="600" fill="#201515">Autonomi</text>`,$+=`<text x="92" y="74" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">Loki Cockpit</text>`;let q=X.freshness?`updated ${X.freshness}`:"live";$+=`<text x="868" y="54" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${T(q)}</text>`,$+=`<text x="868" y="74" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="${SD(X.verdict)}" font-weight="600">${T(X.verdict.toUpperCase())}</text>`;let K=96,N=168;$+=`<rect x="32" y="${K}" width="836" height="${N}" rx="16" fill="#ffffff" stroke="#e2e0e8"/>`,$+=`<text x="56" y="${K+34}" font-family="'Fraunces','Georgia',serif" font-size="20" font-weight="600" fill="#201515">${T(X.run)}</text>`,$+=`<text x="56" y="${K+54}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">phase ${T(X.phase)}</text>`;let E=K+96,Y=(L)=>56+L*168;$+=v(Y(0),E,"iteration",String(X.iteration)),$+=v(Y(1),E,"tier",X.tier),$+=v(Y(2),E,"provider",X.provider),$+=v(Y(3),E,"budget",Z);let c=K+N+40;$+=`<text x="32" y="${c}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">RARV LOOP</text>`;let s=jD(X.phase),R=c+14,o=200;OD.forEach((L,C)=>{let V=32+C*(o+12),O=C<s,B=C===s;$+=`<rect x="${V}" y="${R}" width="${o}" height="40" rx="10" fill="${B?"#553de9":"#ffffff"}" fill-opacity="${B?"0.10":"1"}" stroke="${B?"#553de9":O?"#1f8a52":"#6b6675"}" stroke-width="${B?2:1}"/>`;let QD=O?"check":B?"dot":"wait";if(QD==="check")$+=`<path d="M${V+16} ${R+20} l6 6 l10 -12" stroke="#1f8a52" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`;else if(QD==="dot")$+=`<circle cx="${V+22}" cy="${R+20}" r="5" fill="#553de9"/>`;else $+=`<circle cx="${V+22}" cy="${R+20}" r="5" fill="none" stroke="#6b6675" stroke-width="1.5"/>`;$+=`<text x="${V+40}" y="${R+25}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="14" font-weight="${B?600:500}" fill="${B?"#553de9":O?"#201515":"#6b6675"}">${L}</text>`});let a=R+40+40;$+=`<text x="32" y="${a}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">QUALITY GATES</text>`;let r=X.gates.length?X.gates:[{name:"no gates yet",status:"pending"}],S=30,M=a+12;$+=`<rect x="32" y="${M}" width="836" height="${r.slice(0,8).length*S+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,M+=8;for(let L of r.slice(0,8)){let C=MD(L.status),V=M+S/2;if($+=`<circle cx="50" cy="${V}" r="4" fill="${C}"/>`,$+=`<text x="66" y="${V+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#201515">${T(L.name)}</text>`,L.runner)$+=`<text x="242" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${T(L.runner)}</text>`;if(L.evidence){let O=L.evidence.length>52?`${L.evidence.slice(0,49)}...`:L.evidence;$+=`<text x="332" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${T(O)}</text>`}$+=`<text x="852" y="${V+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${T(L.status.toUpperCase())}</text>`,M+=S}let e=M+40;$+=`<text x="32" y="${e}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">COMPLETION COUNCIL</text>`;let t=X.council.length?X.council:[{reviewer:"pending",vote:"pending"}],k=e+12;$+=`<rect x="32" y="${k}" width="836" height="${t.slice(0,6).length*S+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,k+=8;for(let L of t.slice(0,6)){let C=kD(L.vote),V=k+S/2;if($+=`<circle cx="50" cy="${V}" r="4" fill="${C}"/>`,$+=`<text x="66" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12.5" font-weight="500" fill="#201515">${T(L.reviewer)}</text>`,L.tier)$+=`<text x="292" y="${V+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" fill="#6b6675">${T(L.tier)}</text>`;$+=`<text x="852" y="${V+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${T(L.vote.toUpperCase())}</text>`,k+=S}let DD=k+46,JD=X.fleet.filter((L)=>L.running).length,WD=JD>0?`FLEET (${JD} active / ${X.fleet.length})`:`FLEET (${X.fleet.length}, none active)`;$+=`<text x="32" y="${DD}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">${WD}</text>`;let H=DD+20,m=X.fleet.slice(0,4);for(let L of m){let C=L.running?"#1f8a52":"#6b6675";$+=`<circle cx="38" cy="${H-4}" r="5" fill="${C}"/>`,$+=`<text x="52" y="${H}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="#201515">${T(L.name)}</text>`;let V=`iter ${L.iteration??0} ${T(L.phase||L.status||"")}`;$+=`<text x="868" y="${H}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${V}</text>`,H+=26}if(X.fleet.length>m.length)$+=`<text x="52" y="${H}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675">+ ${X.fleet.length-m.length} more</text>`,H+=26;let d=Math.round(H+32);return`<svg xmlns="http://www.w3.org/2000/svg" width="900" height="${d}" viewBox="0 0 900 ${d}">
|
|
10
10
|
<rect x="0" y="0" width="900" height="${d}" fill="#f1f2f6"/>
|
|
11
|
-
${
|
|
12
|
-
</svg>`}var f
|
|
13
|
-
`),process.stdout.write(`resvg=${
|
|
14
|
-
`),process.stdout.write(`path=${
|
|
15
|
-
`),0}async function
|
|
16
|
-
`),3}let
|
|
17
|
-
`),3}if(import.meta.main)
|
|
11
|
+
${$}
|
|
12
|
+
</svg>`}var u,f;function ND(){if(u!==void 0)return u;try{let D=globalThis.require??F;D.resolve("@resvg/resvg-js"),u=D("@resvg/resvg-js")}catch{u=null}return u}async function VD(){if(f!==void 0)return f;try{let D=await Promise.resolve().then(() => (LD(),qD)),J=globalThis.require??F,{readFileSync:Q,existsSync:X}=await import("fs"),{resolve:Z,dirname:$}=await import("path"),{fileURLToPath:q}=await import("url"),K=null;try{let N=$(q(import.meta.url));for(let E of["../data/resvg.wasm","../../data/resvg.wasm"]){let Y=Z(N,E);if(X(Y)){K=Q(Y);break}}}catch{}if(!K){let N=J.resolve("@resvg/resvg-wasm/index_bg.wasm");K=Q(N)}await D.initWasm(K),f={Resvg:D.Resvg}}catch{f=null}return f}async function PD(){if(ND()?.Resvg)return!0;return(await VD())?.Resvg!=null}var I;async function gD(){if(I!==void 0)return I;try{let{readFileSync:D,existsSync:J}=await import("fs"),Q=["/System/Library/Fonts/Supplemental/Arial.ttf","/System/Library/Fonts/Helvetica.ttc","/Library/Fonts/Arial.ttf","/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf","/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf","/usr/share/fonts/dejavu/DejaVuSans.ttf","/usr/share/fonts/TTF/DejaVuSans.ttf","C:\\Windows\\Fonts\\arial.ttf","C:\\Windows\\Fonts\\segoeui.ttf"];for(let X of Q)if(J(X))return I=new Uint8Array(D(X)),I;I=null}catch{I=null}return I}async function TD(D,J=900){let Q=ND();if(Q?.Resvg)try{let Z=new Q.Resvg(D,{fitTo:{mode:"width",value:J}});return{png:Uint8Array.from(Z.render().asPng()),available:!0}}catch{}let X=await VD();if(X?.Resvg)try{let Z=await gD(),$={fitTo:{mode:"width",value:J}};if(Z)$.font={fontBuffers:[Z],defaultFontFamily:"Arial",loadSystemFonts:!1};else $.font={loadSystemFonts:!0};let q=new X.Resvg(D,$);return{png:Uint8Array.from(q.render().asPng()),available:!0}}catch(Z){return{png:null,available:!1,reason:`raster failed: ${Z.message}`}}return{png:null,available:!1,reason:"rasterizer unavailable (no resvg native or wasm)"}}function UD(D){return Buffer.from(D).toString("base64")}function cD(D,J){let Q=UD(D),X=J&&J>0?`${J}`:"auto";return`\x1B]1337;File=${`inline=1;size=${D.length};width=${X};height=auto;preserveAspectRatio=1`}:${Q}\x07`}function sD(D,J=4096,Q){let X=UD(D);if(X.length===0)return"\x1B_Ga=T,f=100,m=0;\x1B\\";let Z=[];for(let K=0;K<X.length;K+=J)Z.push(X.slice(K,K+J));let $=Q&&Q>0?`,c=${Q}`:"",q="";for(let K=0;K<Z.length;K++){let E=K===Z.length-1?0:1,Y=K===0?`a=T,f=100${$},m=${E}`:`m=${E}`;q+=`\x1B_G${Y};${Z[K]}\x1B\\`}return q}function AD(D,J,Q){return D==="kitty"?sD(J,4096,Q):cD(J,Q)}var oD=new Set(["iterm.app","wezterm","ghostty"]);function l(D=process.env){let J=(D.LOKI_COCKPIT_PROTOCOL||"").trim().toLowerCase();if(J==="iterm2"||J==="kitty"||J==="none")return J;let Q=(D.KITTY_WINDOW_ID||"").trim(),X=(D.TERM||"").trim().toLowerCase();if(Q.length>0||X==="xterm-kitty")return"kitty";let Z=(D.TERM_PROGRAM||"").trim().toLowerCase();if(oD.has(Z))return"iterm2";return"none"}async function CD(D,J={}){let Q=XD(D);if(J.forceText)return{kind:"fallback",protocol:"none",reason:"--no-image (text/browser fallback)",svg:Q};let X;if(J.protocol&&J.protocol!=="auto")X=J.protocol;else X=l(J.env);if(X==="none")return{kind:"fallback",protocol:X,reason:"no inline-image terminal detected",svg:Q};let Z=await TD(Q);if(!Z.available||!Z.png)return{kind:"fallback",protocol:X,reason:Z.reason||"rasterization unavailable",svg:Q};let $=AD(X,Z.png,J.cols);return{kind:"image",protocol:X,data:$,svg:Q}}var ED=(D)=>typeof D==="number"&&Number.isFinite(D)&&D>=40;function YD(D=process.stdout,J=process.env){let Q=D?.columns;if(ED(Q))return Math.floor(Q);let X=Number(J.COLUMNS);if(ED(X))return Math.floor(X);return 80}async function aD(){let D=[];for await(let J of process.stdin)D.push(J);return Buffer.concat(D).toString("utf-8")}function rD(D){let J="auto",Q=!1,X;for(let Z=0;Z<D.length;Z++){let $=D[Z];if($==="--protocol"){let q=(D[++Z]||"auto").toLowerCase();J=q==="iterm2"||q==="kitty"||q==="none"?q:"auto"}else if($==="--no-image")Q=!0;else if($==="--svg-out")X=D[++Z]}return{protocol:J,noImage:Q,svgOut:X}}async function eD(){let D=l(),J=await PD(),Q=D!=="none"&&J?"image":"text+dashboard";return process.stdout.write(`protocol=${D}
|
|
13
|
+
`),process.stdout.write(`resvg=${J?"yes":"no"}
|
|
14
|
+
`),process.stdout.write(`path=${Q}
|
|
15
|
+
`),0}async function tD(D=process.argv.slice(2)){if(D.includes("--probe"))return await eD();let{protocol:J,noImage:Q,svgOut:X}=rD(D),Z;try{let K=await aD();Z=JSON.parse(K)}catch(K){return process.stderr.write(`FALLBACK could not parse cockpit state: ${K.message}
|
|
16
|
+
`),3}let $=YD()-2,q=await CD(Z,{protocol:J,forceText:Q,cols:$});if(X)try{let{writeFileSync:K}=await import("fs");K(X,q.svg)}catch{}if(q.kind==="image"&&q.data)return process.stdout.write(q.data),0;return process.stderr.write(`FALLBACK ${q.reason||"image unavailable"}
|
|
17
|
+
`),3}if(import.meta.main)tD().then((D)=>process.exit(D));export{tD as main};
|
|
18
18
|
|
|
19
|
-
//# debugId=
|
|
19
|
+
//# debugId=2F4CD3BF5DE92F4F02A2CF0BED7BBB85
|