@polderlabs/bizar 4.4.12 → 4.5.0

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 (91) hide show
  1. package/bizar-dash/CHANGELOG.md +37 -276
  2. package/bizar-dash/dist/assets/main-CDFKHzBg.css +1 -0
  3. package/bizar-dash/dist/assets/main-NYFpS2wY.js +312 -0
  4. package/bizar-dash/dist/assets/main-NYFpS2wY.js.map +1 -0
  5. package/bizar-dash/dist/assets/{mobile-DSb-t42Y.js → mobile--0FBIKX3.js} +2 -2
  6. package/bizar-dash/dist/assets/{mobile-DSb-t42Y.js.map → mobile--0FBIKX3.js.map} +1 -1
  7. package/bizar-dash/dist/assets/mobile-OgRp8VIb.js +352 -0
  8. package/bizar-dash/dist/assets/mobile-OgRp8VIb.js.map +1 -0
  9. package/bizar-dash/dist/index.html +3 -3
  10. package/bizar-dash/dist/mobile.html +2 -2
  11. package/bizar-dash/skills/agent-baseline/SKILL.md +80 -0
  12. package/bizar-dash/skills/bizar/SKILL.md +96 -0
  13. package/bizar-dash/skills/chat/SKILL.md +74 -0
  14. package/bizar-dash/skills/lightrag/SKILL.md +75 -0
  15. package/bizar-dash/skills/minimax/SKILL.md +80 -0
  16. package/bizar-dash/skills/obsidian/SKILL.md +55 -0
  17. package/bizar-dash/skills/providers/SKILL.md +75 -0
  18. package/bizar-dash/skills/sdk/SKILL.md +138 -0
  19. package/bizar-dash/skills/self-improvement/SKILL.md +53 -0
  20. package/bizar-dash/skills/skills-cli/SKILL.md +94 -0
  21. package/bizar-dash/skills/usage/SKILL.md +62 -0
  22. package/bizar-dash/src/server/api.mjs +12 -0
  23. package/bizar-dash/src/server/memory-lightrag.mjs +5 -2
  24. package/bizar-dash/src/server/memory-store.mjs +38 -0
  25. package/bizar-dash/src/server/minimax-usage-store.mjs +372 -0
  26. package/bizar-dash/src/server/minimax.mjs +427 -110
  27. package/bizar-dash/src/server/providers-store.mjs +966 -6
  28. package/bizar-dash/src/server/routes/config.mjs +52 -1
  29. package/bizar-dash/src/server/routes/env-vars.mjs +165 -0
  30. package/bizar-dash/src/server/routes/lightrag.mjs +154 -0
  31. package/bizar-dash/src/server/routes/memory.mjs +241 -1
  32. package/bizar-dash/src/server/routes/minimax.mjs +50 -57
  33. package/bizar-dash/src/server/routes/opencode-session-detail.mjs +14 -29
  34. package/bizar-dash/src/server/routes/opencode-sessions.mjs +205 -3
  35. package/bizar-dash/src/server/routes/providers.mjs +266 -5
  36. package/bizar-dash/src/server/routes/skills.mjs +32 -43
  37. package/bizar-dash/src/server/routes/update.mjs +340 -0
  38. package/bizar-dash/src/server/routes/usage.mjs +136 -0
  39. package/bizar-dash/src/server/serve-info.mjs +135 -4
  40. package/bizar-dash/src/server/server.mjs +4 -0
  41. package/bizar-dash/src/server/skills-store.mjs +152 -262
  42. package/bizar-dash/src/web/App.tsx +118 -29
  43. package/bizar-dash/src/web/components/EnvVarManager.tsx +247 -0
  44. package/bizar-dash/src/web/components/SettingsSearch.tsx +213 -0
  45. package/bizar-dash/src/web/components/Topbar.tsx +0 -1
  46. package/bizar-dash/src/web/components/UsageChart.tsx +250 -0
  47. package/bizar-dash/src/web/components/UsageTable.tsx +90 -0
  48. package/bizar-dash/src/web/components/chat/ChatComposer.tsx +21 -25
  49. package/bizar-dash/src/web/components/chat/ChatInfoPanel.tsx +199 -37
  50. package/bizar-dash/src/web/components/chat/ChatThread.tsx +29 -17
  51. package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +7 -1
  52. package/bizar-dash/src/web/components/chat/InfoPanel.tsx +71 -6
  53. package/bizar-dash/src/web/components/chat/useChat.ts +751 -257
  54. package/bizar-dash/src/web/lib/api.ts +43 -0
  55. package/bizar-dash/src/web/main.tsx +1 -0
  56. package/bizar-dash/src/web/mobile/views/MobileChat.tsx +110 -35
  57. package/bizar-dash/src/web/styles/chat.css +135 -1
  58. package/bizar-dash/src/web/styles/main.css +46 -0
  59. package/bizar-dash/src/web/styles/minimax-usage.css +471 -0
  60. package/bizar-dash/src/web/styles/settings.css +418 -0
  61. package/bizar-dash/src/web/styles/skills.css +302 -0
  62. package/bizar-dash/src/web/styles/tasks.css +288 -0
  63. package/bizar-dash/src/web/views/Chat.tsx +276 -48
  64. package/bizar-dash/src/web/views/Config.tsx +3 -2065
  65. package/bizar-dash/src/web/views/MiniMaxUsage.tsx +620 -240
  66. package/bizar-dash/src/web/views/Settings.tsx +6 -0
  67. package/bizar-dash/src/web/views/Skills.tsx +208 -260
  68. package/bizar-dash/src/web/views/Tasks.tsx +348 -1119
  69. package/bizar-dash/tests/chat-session-create.test.mjs +391 -0
  70. package/bizar-dash/tests/chat-session-stream.test.mjs +308 -0
  71. package/bizar-dash/tests/env-vars-store.test.mjs +216 -0
  72. package/bizar-dash/tests/lightrag-defaults.node.test.mjs +118 -0
  73. package/bizar-dash/tests/minimax-chat-usage.test.mjs +178 -0
  74. package/bizar-dash/tests/minimax-usage-store.node.test.mjs +293 -0
  75. package/bizar-dash/tests/opencode-sessions-detail.test.mjs +12 -9
  76. package/bizar-dash/tests/providers-store-backup-keys.node.test.mjs +479 -3
  77. package/bizar-dash/tests/providers-store-search.node.test.mjs +166 -0
  78. package/bizar-dash/tests/skills-list.test.mjs +232 -0
  79. package/bizar-dash/tests/skills-search.test.mjs +222 -0
  80. package/bizar-dash/tests/tasks-create.test.mjs +187 -0
  81. package/bizar-dash/tests/update-check.test.mjs +127 -0
  82. package/bizar-dash/tests/update-run.test.mjs +266 -0
  83. package/cli/bin.mjs +345 -4
  84. package/cli/provision.mjs +118 -4
  85. package/config/agents/_shared/SKILLS.md +109 -0
  86. package/package.json +1 -1
  87. package/bizar-dash/dist/assets/main-BKXEqU1w.css +0 -1
  88. package/bizar-dash/dist/assets/main-EK_fzXn_.js +0 -352
  89. package/bizar-dash/dist/assets/main-EK_fzXn_.js.map +0 -1
  90. package/bizar-dash/dist/assets/mobile-Dl1q7Cyq.js +0 -354
  91. package/bizar-dash/dist/assets/mobile-Dl1q7Cyq.js.map +0 -1
@@ -1,288 +1,49 @@
1
1
  # @polderlabs/bizar-dash — Changelog
2
2
 
3
- ## v3.19.0 — Obsidian vault + browser-harness agent + Plans→Artifacts rename
4
-
5
- ### Highlights
6
-
7
- - **Plans renamed to Artifacts.** The old `Plans` tab is now `Artifacts`. The view, server route (`/api/artifacts`), store, CLI subcommand (`bizar artifact`), templates, and on-disk path are all renamed. Artifacts are what agents generate to surface design choices, options, or implementation paths — the user reviews them and approves/rejects/modifies. Same semantics, new naming.
8
- - **Per-project Obsidian vault (`/api/obsidian/*`).** Every project now has an `.obsidian/` directory inside its worktree that gets git-tracked. The vault holds long-term agent memory (markdown notes with YAML frontmatter). Standard subdirs: `daily/`, `decisions/`, `patterns/`, `api/`, `tasks/`. Dashboard exposes CRUD + full-text search + auto-rebuild of `INDEX.md`. The Hindsight memory MCP server has been removed from BizarHarness entirely; Obsidian is the new long-term memory.
9
- - **Ponytail mod** (npm: `@dietrichgebert/ponytail`). Records the active ponytail level (lite/full/ultra/off) in `.obsidian/ponytail/state.json` so any agent that reads the vault at session start picks it up. Dashboard view for switching the level. Install separately: `npx @dietrichgebert/ponytail install --scope=user`.
10
- - **Impeccable mod** (npm: `impeccable`). Wraps `npx impeccable detect` and stores the last scan report in `.obsidian/impeccable/`. Dashboard view shows findings + stat cards. Install separately: `npx impeccable skills install -y --scope=user`.
11
- - **`browser-harness` agent** (`config/agents/browser-harness.md`). Drives a headless Chromium via the Chrome DevTools Protocol for E2E verification, screenshots, smoke tests, and visual regression. Never edits code — reports findings with file:line references.
12
-
13
- ### Files added (1)
14
-
15
- - `src/server/obsidian-store.mjs` — vault CRUD + search + init + INDEX rebuild
16
-
17
- ### Files added (route)
18
-
19
- - `src/server/routes/obsidian.mjs` — `GET/POST /api/obsidian`, `GET/POST/DELETE /api/obsidian/notes`, `GET /api/obsidian/search`, `POST /api/obsidian/index`
20
-
21
- ### Files added (mods)
22
-
23
- - `mods-examples/ponytail/{mod.json,route.mjs,web/index.html}` + mirrored in `bizar-mods/mods/ponytail/`
24
- - `mods-examples/impeccable/{mod.json,route.mjs,web/index.html}` + mirrored in `bizar-mods/mods/impeccable/`
25
-
26
- ### Files added (agent)
27
-
28
- - `config/agents/browser-harness.md`
29
-
30
- ### Test results
31
-
32
- - `vite build`: succeeds; new features present in `dist/`
33
- - `bun test tests/mod-security.test.mjs`: 26/26 pass (no regression)
34
- - TypeScript: clean for the routes and mods; one phantom TS warning about a phantom literal that doesn't exist anywhere in source — Vite/esbuild compilation works regardless
35
-
36
- ## v3.18.0 — Settings tabs work + chat info panel hideable + mod install fix
37
-
38
- ### Highlights
39
-
40
- - **Settings subnav is now a real tab strip** that hides non-matching sections via inline-style `display: none`. The v3.17.0 CSS-attribute-selector approach worked in isolation but a stale scroll-detection useEffect kept resetting the active tab. Now removed. URL hash deep-links (`#settings-theme`) still work.
41
- - **Mod install from registry fixed.** `installFromRegistry` now accepts the `downloadUrl` field directly, plus tries both `mods/<id>/<version>/` and the flat `mods/<id>/` paths as fallbacks. `installFromUrl` also fetches `web/index.html` so mods with self-contained web views round-trip cleanly. The `bizar-mods` registry.json now includes `downloadUrl` pointing at the flat-path on GitHub.
42
- - **Chat info panel (right sidebar) is hideable.** New "Info" button in the chat header toggles the right sidebar (Session info, Agents, Active MCPs, Slash commands). When hidden, a floating "Show info" restore button appears.
43
- - **Version constant fixed.** The header used to show `v3.6.1` regardless of the actual installed version. Now reads `v3.18.0`.
44
-
45
- ## v3.17.0 — Settings section filter + graphify removed
46
-
47
- ### Highlights
48
-
49
- - **Settings section filter.** v3.16.0's subnav scrolled to sections; v3.17.0 actually filters — clicking a subnav button shows ONLY that section, with a "Showing only X" banner and a one-click escape. URL hash deep-links (`#settings-theme`) still work.
50
- - **graphify removed.** Deleted `src/server/routes/graph.mjs`, `src/web/views/Graph.tsx`, and the Graph tab from TABS + VIEW_MAP. Graph is now provided exclusively by the graphify mod (installable from the registry).
51
- - **`dist/` rebuilt.** This version's UI features (settings filter) are present in the published `dist/` (v3.17.0 fixes the v3.16.0 invisibility regression from v3.16.2).
52
-
53
- ## v3.16.2 — Rebuild `dist/` so the v3.16.0 UI changes are actually served
54
-
55
- > **Critical**: v3.15.0 through v3.16.1 all shipped `src/` changes but the `dist/` build was never regenerated. The dashboard's web UI is served from `dist/` (Vite output), not `src/`. Result: every UI change from v3.15.0 onward (activity log overhaul, settings subnav, chat floating input, mods registry browser, provider auto-detect banner) was invisible in the running dashboard — only the new server-side API routes were live. Fixed by running `vite build` and bumping to v3.16.2.
56
-
57
- ### Verification
58
-
59
- `dist/assets/main-*.css` now contains: `settings-subnav`, `chat-input-floating`, `mods-registry`, `autodetect-banner`, `activity-hidden-banner`, `activity-log-table`. `dist/assets/main-*.js` contains `AutoDetect`, `ActivityLog`, etc.
60
-
61
- ## v3.16.1 — Hotfix: dashboard crash on `bizar dash start`
62
-
63
- > **Critical bug**: `bizar dash start` failed with `The requested module '../state.mjs' does not provide an export named 'state'`. v3.15.0 and v3.16.0 both shipped this regression because `routes/activity.mjs` did `import { state } from '../state.mjs'`. The `state` object is created per-server-instance via `createState()` in `server.mjs:178` and threaded through `api.mjs` as a dependency — it's never a module-level export. Fixed by removing the bogus import and reading `state` from the factory function's argument (matching every other router).
64
-
65
- ### Files changed (1)
66
-
67
- - `src/server/routes/activity.mjs` — removed `import { state } from '../state.mjs'`; uses `{ state }` from the factory parameter; added defensive 503 if state is missing.
68
-
69
- ## v3.16.0 — UI overhaul: settings subnav, chat floating input, mods registry browser, provider auto-detect
70
-
71
- ### Highlights
72
-
73
- - **Settings subnav** — sticky horizontal nav with 13 sections (Theme, Layout, General, Service, Tailscale, Notifications, Auth, Agents, Dashboard, Background, Updates, Activity, About). Active section auto-highlights on scroll, click-to-scroll smooth-into-view.
74
- - **Chat floating input** — composer wrapped in a glass-style sticky bottom box with accent border on focus and a backdrop-blur background. No UX changes other than positioning.
75
- - **Providers moved into Config** — top-level Providers tab removed (lived in Config already).
76
- - **Mods registry browser** — collapsible card-grid in the Mods tab. Each card shows name, version with upgrade badge, description, author, homepage, permissions, and an Install button that POSTs `{ id }` to `/api/mods`.
77
- - **Provider auto-detect banner** — `Config → Providers` now has an AutoDetectBanner that scans env vars + opencode.json for 9 known providers (Anthropic, OpenAI, Google, Mistral, Groq, Cohere, OpenRouter, DeepSeek, MiniMax), validates key formats, optionally probes `/models` with 1.5s timeout, and lets you add configured providers to opencode.json with one click.
78
- - **`GET /api/providers/auto-detect`** — JSON endpoint mirroring the banner.
79
-
80
- ### Files changed (8)
81
-
82
- - `src/server/providers-store.mjs` — new `KNOWN_PROVIDERS` + `autoDetect({ probe })`.
83
- - `src/server/routes/providers.mjs` — new `/providers/auto-detect` route.
84
- - `src/web/App.tsx` — removed Providers from VIEW_MAP.
85
- - `src/web/components/Topbar.tsx` — removed Providers tab + Cloud icon.
86
- - `src/web/views/Chat.tsx` — `.chat-input-floating` wrapper.
87
- - `src/web/views/Config.tsx` — new `AutoDetectBanner` component.
88
- - `src/web/views/Mods.tsx` — registry browser state + UI.
89
- - `src/web/views/Settings.tsx` — section IDs + subnav.
90
- - `src/web/styles/main.css` — ~7 KB of new CSS.
91
-
92
- ### Test results
93
-
94
- - `tsc --noEmit` passes.
95
- - `bun test tests/mod-security.test.mjs` — 26/26 pass (no regression from v3.15.0).
96
-
97
- ## v3.15.0 — Activity log overhaul: hide from overview + full log in Settings
3
+ ## v4.5.0 — 2026-07-05
98
4
 
99
5
  ### Highlights
100
6
 
101
- - **Hide from overview** every Recent Activity card now has an X button to hide
102
- it from the Overview feed. Hiding is **non-destructive**: the entry stays in
103
- the full activity log, just out of the feed. A persistent "X items hidden"
104
- banner with a one-click "Show them again" link surfaces the hidden set.
105
- - **Hide all / Show all** two new buttons in the activity header. "Hide all"
106
- hides every currently-visible item; "Show all" restores everything.
107
- - **Settings Activity Log** a new full-history card in Settings with a
108
- filter box, "show hidden" toggle, restore-one / restore-all actions, and a
109
- tabular log (200 rows visible, scroll for more). Backed by
110
- `~/.cache/bizar/activity-hidden.json` for persistence.
111
- - **New REST surface** `/api/activity` (full log), `/api/activity/hidden`
112
- (list), `/api/activity/hide` (POST + DELETE + DELETE/:key).
113
-
114
- ### Files added (1)
115
-
116
- - `src/server/routes/activity.mjs`
117
-
118
- ### Files changed (4)
119
-
120
- - `src/server/api.mjs` — mounts `createActivityRouter({ state })`.
121
- - `src/web/views/Overview.tsx` — per-item hide button + banner + hide-all.
122
- - `src/web/views/Settings.tsx` — new `ActivityLogCard` (filter + restore).
123
- - `src/web/styles/main.css` — `.overview-feed-head-actions`,
124
- `.activity-hidden-banner`, `.activity-feed-row-main`, `.activity-feed-hide-btn`,
125
- `.activity-log-toolbar`, `.activity-log-table`, etc.
126
-
127
- ### Test results
128
-
129
- - TypeScript: `tsc --noEmit` passes.
130
- - Mod-security: 26/26 tests still pass (no regression from v3.14.0).
131
-
132
- ## v3.14.0 — Mod security layer + public mod registry
133
-
134
- > **Security + ecosystem:** Mods now run with permission enforcement, integrity verification, and audit logging. New `/api/mods/registry` endpoint fetches the official mod registry from `DrB0rk/bizarre-mods`. Mods repo template + authoring guide added.
135
-
136
- ### Highlights
137
-
138
- - **Mod security layer (`src/server/mod-security.mjs`).** Mods declare permissions in `mod.json`; the loader enforces them at every privileged action:
139
- - **Filesystem sandboxing** — mods get scoped `readFileSync` / `writeFileSync` helpers. Paths outside `fs:read:<scope>` / `fs:write:<scope>` throw. Scope syntax: exact path, directory with implicit recursion, `/*` suffix, or `~/` home-relative.
140
- - **Subprocess allowlist** — only whitelisted binaries (`bizar`, `opencode`, `python3`, `git`, `node`, `npm`, `pip`, `uv`, `headroom`, `jq`, `graphify`, `pipx`, `opencode-ai`) can be spawned without an explicit `process:spawn:<bin>` permission. Path-style binaries (`/bin/ls`) require explicit permission.
141
- - **Integrity hash** — every mod's files are SHA-256-hashed at install time; the hash is stored under `_integrity` in `mod.json`. On every load the hash is recomputed; a mismatch triggers a critical warning and refuses to load the mod's routes until reinstalled.
142
- - **Audit log** — every privileged action is logged as JSON lines to `~/.cache/bizar/logs/mod-audit.log` with timestamp, mod id, mod version, action, and details. Inspect via `GET /api/mods/audit?mod=<id>&limit=200`.
143
- - **Public mod registry.** New `bizarre-mods` repo at `DrB0rk/bizarre-mods` is the canonical source of mods. `GET /api/mods/registry` fetches `registry.json` and annotates each entry with installed state and upgrade hints. `POST /api/mods { id }` installs from the registry.
144
- - **Mods repo template.** New `templates/mod-template/` shows the canonical mod structure with `mod.json`, `route.mjs`, and `views/registry.json` examples.
145
- - **Authoring guide.** New `docs/MOD-AUTHORING.md` covers permissions, route file shape, view registration, frontend-component caveats, and the PR submission checklist.
146
-
147
- ### Files added (3)
148
-
149
- - `bizar-dash/src/server/mod-security.mjs` — permission parsing, fs sandbox, subprocess allowlist, integrity hash, audit writer.
150
- - `bizar-dash/tests/mod-security.test.mjs` — 26 tests covering parsing, sandbox, allowlist, hashing, integrity verification, context creation.
151
-
152
- ### Files changed (3)
153
-
154
- - `bizar-dash/src/server/mods-loader.mjs` — wires the security context into `loadModRouters`, computes and stores the integrity hash in `installFromPath`, exposes `installFromRegistry` and `fetchRegistry`. Mods whose integrity hash mismatches are refused at load time with a critical warning.
155
- - `bizar-dash/src/server/routes/mods.mjs` — adds `GET /api/mods/registry`, `GET /api/mods/audit`, and a registry-aware install path on `POST /api/mods` (accepts `{ id }` OR `{ path }`).
156
- - `bizar-dash/src/server/cli.mjs` — reordered `start` vs `--bg`/`--detach` dispatch (fixes `bizar dash start --bg` actually backgrounding).
157
-
158
- ### Companion repo (separate git repo)
159
-
160
- - `bizarre-mods/` — `DrB0rk/bizarre-mods`. Contains `registry.json` listing available mods, `mods/graphify/` (the extracted graphify mod), `templates/mod-template/` (starter), and `docs/MOD-AUTHORING.md` (full guide). Configured as the default registry URL in `mods-loader.mjs:DEFAULT_REGISTRY_URL`.
161
-
162
- ### Test results
163
-
164
- - New: 26 mod-security tests pass.
165
- - Total: 282 plugin tests + 19 dashboard smoke tests still pass.
166
- - TypeScript typecheck clean.
167
-
168
- ### v1 limitations (transparent)
169
-
170
- A malicious mod could still bypass the sandbox by importing `node:fs` / `node:child_process` directly. v2 will close this gap with a `vm`-based sandbox or worker-thread isolation. Until then, the security layer makes the mod's *intent* explicit (declared permissions, audit trail, integrity hash) so users can review what they're installing and detect tampering.
171
-
172
- ## v3.13.0 — 2026-06-25
173
-
174
- ### Highlights
175
-
176
- - **Knowledge-graph view (Graph tab).** New top-bar entry "Graph" with Network icon. Embeds the project's `.bizar/graph/graph.html` (graphify's interactive vis-network visualization) via an iframe. Shows live node/edge/community counts in the header; has a "Build / Rebuild" button that runs `bizar graph build` detached via the new `/api/graph/build` endpoint and polls `/api/graph/build/:jobId/status` until done. The button works offline — no LLM key required, falls through to the AST-cache path that ships with `@polderlabs/bizar` v3.15.0+.
177
-
178
- - **`bizar dash start --bg` now actually backgrounds.** Previously the CLI dispatch checked `args.includes('--bg')` AFTER the `args[0] === 'start'` branch, so `bizar dash start --bg` always fell through to the foreground `startDashboard` and blocked. v3.13.0 checks `--bg` inside the `start` branch first and uses `startDashboard({ bg: true })` which returns after writing the PID/PORT files instead of blocking on a signal handler. The launching shell gets immediate control back; the dashboard keeps running in the spawned node process. Same fix for `--detach`.
179
-
180
- ### Files added (6)
181
-
182
- - `bizar-dash/src/server/routes/graph.mjs` — `GET /status`, `GET /html`, `GET /report`, `POST /build`, `GET /build/:jobId/status`. Resolves `.bizar/graph/` from the active project (via `projectsStore.active()`), not from a request-controlled path.
183
- - `bizar-dash/src/web/views/Graph.tsx` — view with stats header, "Build / Rebuild" button, build-poll loop, empty state for projects without a graph yet, and iframe-based rendering of `graph.html` via `/api/graph/html`.
184
-
185
- ### Files changed (4)
186
-
187
- - `bizar-dash/src/server/api.mjs` — wires `createGraphRouter` into the v1 router.
188
- - `bizar-dash/src/web/App.tsx` — adds `graph: Graph` to VIEW_MAP.
189
- - `bizar-dash/src/web/components/Topbar.tsx` — adds `Graph` to TABS (Network icon, between `background` and `skills`).
190
- - `bizar-dash/src/web/styles/main.css` — `.graph-building-banner`, `.graph-iframe-wrap`, `.graph-iframe`, `.graph-meta`, `.graph-empty-actions` (~60 lines).
191
- - `bizar-dash/src/cli.mjs` — reordered `start` vs `--bg`/`--detach` dispatch; `startDashboard` accepts `bg` option and returns without blocking when set; added `detachAfterBoot()`.
192
-
193
- ### Compatibility
194
-
195
- - Same wire format as v3.12.x — all existing endpoints unchanged.
196
- - Requires `@polderlabs/bizar` v3.15.0+ for the `bizar graph build` CLI invoked by the Build button (older versions still work but don't have the offline cache fallback).
197
-
198
- ## v3.11.0 — 2026-06-23
199
-
200
- ### Added
201
- - **Interactive file browser in the Add Project dialog.** New `GET /api/fs?path=<absolute>` endpoint returns a structured listing (`{ path, parent, entries[] }`) for the file picker. Server-side allow-list enforces `os.homedir()` + the configured `dashboard.projectsDirectory`; first-level dotdirs under home (`.ssh`, `.aws`, …) are blocked as roots and silently filtered from listings. All filesystem errors map to structured JSON (`not_found` / `permission_denied` / `not_a_directory` / `forbidden`).
202
- - **New setting: `dashboard.projectsDirectory`** (string, default `''`). When set, the server will scan it for project roots on startup and the `POST /api/projects/scan` endpoint will rescan on demand. Detection: a directory counts as a project if it contains any of `.git/`, `.bizar/`, `package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, `pom.xml`, `build.gradle`, `build.gradle.kts`. One-level scan only — won't recurse into detected projects.
203
- - **`projectsStore.scanDirectory(rootDir)`** — public method that walks one level deep, stats each marker per child (catching per-file errors), and adds detected projects via the existing `add()` path. Idempotent. Returns `{ added, skipped, scanned, error? }`.
204
- - **`POST /api/projects/scan`** — validates that the configured `projectsDirectory` lives under home (rejects with `forbidden` otherwise), runs `scanDirectory()`, and broadcasts a `project:change` event with `kind: 'added'` for each newly registered project so connected clients refresh immediately.
7
+ - **Settings page is now the single home for all configuration.** Config tab merged into Settings; restructured with section nav (General, Env Vars, Providers, Memory, System LLM, Updates, Skills, Dashboard). Add a settings search that finds individual settings by name/value and scrolls to them.
8
+ - **Bizar env-var manager.** First-class UI for managing `BIZAR_*` env vars at `~/.config/bizar/env.json` (mode 0600). When configuring any provider or LLM, the user can pick an existing env var OR create a new one — never paste plaintext keys.
9
+ - **Provider subsystem overhaul.** New `PROVIDER_CATALOG` with 13 well-known providers, fuzzy search, single-key auto-add wizard (`POST /api/providers/auto` probes `/v1/models` and fills in baseURL/models/pattern). Backup keys per provider with automatic rotation on auth/quota/rate-limit/429/5xx errors. Key cooldown tracking, status management (active|standby|disabled|cooldown).
10
+ - **LightRAG defaults to free OpenCode Zen models** (`opencode/gpt-5-nano` for LLM, `opencode/text-embedding-3-small` for embeddings). Configurable via `BIZAR_LIGHTRAG_LLM` / `BIZAR_LIGHTRAG_EMBEDDING` env vars.
11
+ - **Memory settings in Settings Memory.** LightRAG URL, Obsidian vault path, git repo config, sync interval. New `/api/memory/config/global` endpoint persists to `~/.config/bizar/memory-config.json`. `/api/memory/test-git` validates the configured repo.
12
+ - **Usage monitoring and analytics.** New JSONL usage store at `~/.local/share/bizar/usage.jsonl`. Tracks prompt/completion/cached/reasoning tokens, requests, errors, latency per call. New `GET /api/usage?range=24h|7d|30d|custom` returns totals + per-day + per-model + per-key + error breakdowns. MiniMax Usage view rewritten with hand-rolled SVG chart, sortable per-model table, time-range chips, recent-activity feed.
13
+ - **Agents know their limits.** New `getUsageLimitsForAgent(providerId)` returns last-5min + last-24h request/token counts, percent used, time-until-reset. Wired into opencode plugin's prompt context so agents stay aware of quota while working.
14
+ - **Chat overhaul + opencode session fixes.** Fixed "can't open an opencode session" (SSE reconnect + per-session event gating) and "can't create a new session" (Chat.tsx used bare `fetch('/chat/sessions')` which 404'd; now uses `POST /api/opencode-sessions/new`). New `useChat.ts` with SSE reconnect-with-backoff, optimistic-send dedupe, clean unmount lifecycle. `POST/PATCH/DELETE /api/opencode-sessions[/...]` for create/rename/delete. MobileChat.tsx overhaul at mobile size.
15
+ - **Tasks.tsx simplified.** Agent picker removed from task creation; user just types title + description, Odin decides routing and priority. Backlog / Todo / In progress / Done / Failed board with move/retry/edit/delete actions. Submit-to-Odin re-delegates.
16
+ - **Skills tab + toolset refresh.** Skills tab shows Bizar skills (the old code only queried the `skills` CLI which ignored local SKILL.md files). Search output fixed (no more terminal ASCII garbage in titles — old code fell back to text-mode parsing). 11 shipped skills under `bizar-dash/skills/`: bizar, agent-baseline, self-improvement, obsidian, minimax, providers, chat, usage, skills-cli, lightrag, sdk.
17
+ - **Update flow overhaul.** New `/api/updates/{status,check,apply}` endpoints with WS `update:progress` events. `bizar update` gains `--check`, `--channel=stable|beta`, `--no-restart`. Settings → Updates section wired end-to-end.
18
+ - **UI consistency pass.** Standardized spacing tokens (`--spacing-xs/-sm/-md/-lg/-xl`) added to main.css with compact-mode overrides.
19
+ - **CLI.** New `bizar usage [range]` subcommand proxies `/api/usage`.
205
20
 
206
21
  ### Files
207
- - `bizar-dash/src/server/routes/fs.mjs` — **new** — `createFsRouter({ state })` factory; `GET /api/fs` handler.
208
- - `bizar-dash/src/server/lib/path-safe.mjs` — **new** — `resolveSafePath`, `defaultAllowedRoots`, `isDotRoot` helpers shared between `fs.mjs` and the scan route.
209
- - `bizar-dash/src/server/routes/_shared.mjs` — `DEFAULT_SETTINGS.dashboard` gains `projectsDirectory: ''` (default value is empty so existing installs see no change).
210
- - `bizar-dash/src/server/routes/projects.mjs` — adds `POST /api/projects/scan`.
211
- - `bizar-dash/src/server/projects-store.mjs` — adds `PROJECT_ROOT_MARKERS` const + `scanDirectory(rootDir, { maxDepth })` method; adds `node:fs/promises` import.
212
- - `bizar-dash/src/server/api.mjs` — mounts `createFsRouter` immediately after the projects router.
213
- - `bizar-dash/src/server/server.mjs` — fires a one-shot `scanDirectory()` on startup when the setting is set; logs added/skipped/scanned counts; never blocks boot.
214
22
 
215
- ### Verified
216
- - `node --check` passes for every modified/new server file.
217
- - TypeScript (no server-side changes affect frontend types).
218
-
219
- ### Security hardening
220
-
221
- - Added `dashboard.allowedRoots: string[]` setting operators can
222
- declare additional filesystem roots (e.g., `/workspace`,
223
- `/srv/projects`) beyond `os.homedir()` for the file browser and
224
- project scanner. Each entry must itself be inside home; entries
225
- that escape are silently dropped server-side.
226
- - Added `POST /api/fs/mkdir` to allow creating project directories
227
- from the file browser. Parent must be in the allow-list; name is
228
- validated against a denylist of unsafe characters; returns 409 if
229
- the entry already exists.
230
- - `GET /api/fs` now caps responses at 500 entries and reports a
231
- `truncated` flag plus `totalEntries` so huge directories
232
- (`node_modules`, Go module cache) don't OOM the browser.
233
- - `PUT /api/settings` now validates `dashboard.projectsDirectory`
234
- and `dashboard.allowedRoots` server-side, rejecting unsafe values
235
- with a structured 400 instead of writing them to disk.
236
- - **Frontend:** live warnings on the `allowedRoots` textarea mirror the server's validation; pre-flight path check in the Add Project dialog prevents 404s on stale selections.
237
-
238
- ### Background agent dispatch fix
239
-
240
- - Fixed root cause: `pingOpencodeServe` was returning false for a
241
- live opencode serve instance because (a) it pings an HTTP
242
- endpoint that requires Basic auth and any auth-quirk (stale
243
- password file, version mismatch, wrong realm) made the probe
244
- fail with 401 even though the opencode process was perfectly
245
- healthy and answering other requests, AND (b) `readServeInfo`
246
- had a strict 6-field schema that returned `null` when the
247
- on-disk `serve.json` only contained `{password, pid, port}` —
248
- which is what the current plugin build actually writes. The
249
- null then cascaded into `dispatchToBackground` short-circuiting
250
- on the `if (serveInfo && serveReachable)` guard at
251
- `task-delegator.mjs:563`, marking every new bg instance as
252
- `dispatchPending: true` and never creating a tmux session.
253
- Now uses a TCP-connect port-open check via
254
- `net.createConnection` (so the probe does not depend on HTTP
255
- auth or endpoint shape) and the read schema derives `baseUrl`
256
- from `port` when missing, with `worktree`/`startedAt`
257
- defaulting to empty/`0` rather than failing the read.
258
- - Fixed path-concatenation fragility for the bg `worktree`
259
- fallback: `task-delegator.mjs` now uses `projectRoot` as a
260
- fallback for the opencode serve's `?directory=` query param
261
- when serve-info omits `worktree`, so spawns succeed even on
262
- installs where the plugin has not yet written a full serve.json.
263
- - Added `lib/path-safe.mjs` helpers (`deriveAbsoluteBgLogPath`,
264
- `isBrokenBgLogPath`) that always produce an absolute path
265
- (falling back to `~/.cache/bizar/logs/<id>.log`) and detect the
266
- `//.opencode/log/...` shape produced when an older plugin build
267
- concatenated an empty `worktree` to the logPath.
268
- - Added a periodic retry loop (`bg-retry.mjs`, every 30s, started
269
- by `server.mjs` on boot) that re-runs dispatch for any bg
270
- instance stuck in `dispatchPending: true` with
271
- `toolCallCount === 0` for more than 30 seconds. Caps each
272
- instance at 10 retries before marking it as `failed` with
273
- `error: "exceeded max dispatch retries"`. Repairs broken
274
- logPath values atomically before re-dispatching.
275
- - Added `POST /api/background/:id/retry` for manual unstick —
276
- resets `retryCount: 0`, `dispatchPending: true`, and calls
277
- `retryDispatchOnce` immediately without waiting for the next
278
- periodic tick.
23
+ - `bizar-dash/src/web/views/Settings.tsx` — full rewrite
24
+ - `bizar-dash/src/web/views/Config.tsx` collapsed (Settings is canonical)
25
+ - `bizar-dash/src/web/views/MiniMaxUsage.tsx` — full rewrite (interactive SVG chart, sortable table)
26
+ - `bizar-dash/src/web/views/Chat.tsx` + `MobileChat.tsx` + `hooks/useChat.ts` — overhaul
27
+ - `bizar-dash/src/web/views/Tasks.tsx` — agent picker removed, kanban board
28
+ - `bizar-dash/src/web/views/Skills.tsx` — full rewrite (source tabs, fuzzy search)
29
+ - `bizar-dash/src/server/providers-store.mjs` — backup keys, catalog, rotation
30
+ - `bizar-dash/src/server/routes/{providers,env-vars,usage,update,memory,lightrag,opencode-sessions,opencode-session-detail,config,skills}.mjs` new + extended endpoints
31
+ - `bizar-dash/src/server/minimax.mjs` `chatCompletion` records usage
32
+ - `bizar-dash/src/server/minimax-usage-store.mjs` (NEW) JSONL store
33
+ - `bizar-dash/src/server/skills-store.mjs` scans local SKILL.md directly
34
+ - `bizar-dash/src/server/serve-info.mjs` session rename/delete helpers
35
+ - `bizar-dash/src/web/components/{EnvVarManager,SettingsSearch,UsageChart,UsageTable}.tsx` (NEW)
36
+ - `bizar-dash/src/web/styles/{settings,skills,tasks,chat,minimax-usage}.css` scoped styles
37
+ - `bizar-dash/skills/{bizar,agent-baseline,self-improvement,obsidian,minimax,providers,chat,usage,skills-cli,lightrag,sdk}/SKILL.md` 11 shipped skills
38
+ - `cli/bin.mjs`, `cli/provision.mjs` `bizar update` flags + `bizar usage`
39
+ - `config/agents/_shared/SKILLS.md` skills reference doc
40
+ - `~/.opencode/skills/bizar/` copy of canonical bizar skill
41
+
42
+ ### Tests
43
+
44
+ All 200+ tests pass; `npx tsc --noEmit` reports 0 errors in scope.
279
45
 
280
- ### Files
281
- - `bizar-dash/src/server/routes/_shared.mjs` — `DEFAULT_SETTINGS.dashboard` gains `allowedRoots: []`; new `validateDashboardSettings()` + `writeSettings()` now validates before persisting.
282
- - `bizar-dash/src/server/lib/path-safe.mjs` — new `buildAllowedRootsFromSettings({ settings, home })` helper.
283
- - `bizar-dash/src/server/routes/fs.mjs` — `POST /api/fs/mkdir`; `GET /api/fs` now caps at 500 entries and reports `truncated` / `totalEntries`; switched to the new `buildAllowedRootsFromSettings` helper.
284
- - `bizar-dash/src/server/routes/projects.mjs` — `POST /api/projects/scan` uses the expanded allow-list.
285
- - `bizar-dash/src/server/server.mjs` — startup scan rebuilds and logs the allow-list, re-validates the configured `projectsDirectory`.
46
+ ## v3.19.0 — Obsidian vault + browser-harness agent + Plans→Artifacts rename
286
47
 
287
48
  ## v3.5.4 — 2026-06-19
288
49