@polderlabs/bizar 7.0.0 → 7.0.2
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 +125 -47
- package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js +114 -0
- package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js.map +1 -0
- package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js +1 -0
- package/bizar-dash/dist/assets/{MobileChat-D7zRhU9K.js.map → MobileChat-DLWdv6tQ.js.map} +1 -1
- package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js +1 -0
- package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js.map +1 -0
- package/bizar-dash/dist/assets/Toast-ATSAmbdi.js +26 -0
- package/bizar-dash/dist/assets/Toast-ATSAmbdi.js.map +1 -0
- package/bizar-dash/dist/assets/main-306CZfn6.js +430 -0
- package/bizar-dash/dist/assets/main-306CZfn6.js.map +1 -0
- package/bizar-dash/dist/assets/main-G3bNDpY3.css +1 -0
- package/bizar-dash/dist/assets/mobile-C_naUN91.js +1 -0
- package/bizar-dash/dist/assets/{mobile-DXYCA0hC.js.map → mobile-C_naUN91.js.map} +1 -1
- package/bizar-dash/dist/assets/mobile-layout-BWLtwtfQ.css +1 -0
- package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js +211 -0
- package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js.map +1 -0
- package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js +65 -0
- package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js.map +1 -0
- package/bizar-dash/dist/index.html +7 -13
- package/bizar-dash/dist/mobile.html +3 -8
- package/bizar-dash/src/server/memory-consolidator.mjs +8 -1
- package/bizar-dash/src/web/mobile/MobileApp.tsx +33 -2
- package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +2 -2
- package/bizar-dash/src/web/mobile/MobileEval.tsx +4 -4
- package/bizar-dash/src/web/mobile/MobileMemory.tsx +2 -2
- package/bizar-dash/src/web/mobile/MobileSettings.tsx +3 -3
- package/bizar-dash/src/web/mobile/MobileTasks.tsx +2 -2
- package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +3 -3
- package/bizar-dash/src/web/styles/mobile.css +41 -0
- package/bizar-dash/src/web/styles/tasks-redesign.css +34 -12
- package/bizar-dash/src/web/ui/controls/Textarea.tsx +56 -0
- package/bizar-dash/src/web/ui/controls/controls.css +22 -0
- package/bizar-dash/src/web/ui/controls/index.ts +2 -0
- package/bizar-dash/src/web/ui/layout/ViewHeader.tsx +48 -0
- package/bizar-dash/src/web/ui/layout/index.ts +1 -0
- package/bizar-dash/src/web/ui/layout/layout.css +51 -0
- package/bizar-dash/src/web/ui/styles/tokens.css +13 -0
- package/bizar-dash/src/web/views/Agents.tsx +10 -2
- package/bizar-dash/src/web/views/Overview.tsx +2 -13
- package/bizar-dash/src/web/views/Tasks.tsx +1 -7
- package/bizar-dash/tests/ui/controls/Textarea.test.tsx +56 -0
- package/bizar-dash/tests/ui/layout/ViewHeader.test.tsx +47 -0
- package/cli/provision-claude.mjs +94 -0
- package/package.json +1 -1
- package/bizar-dash/dist/assets/EnvVarsSection-CW6fWKds.js +0 -4
- package/bizar-dash/dist/assets/EnvVarsSection-CW6fWKds.js.map +0 -1
- package/bizar-dash/dist/assets/MobileChat-D7zRhU9K.js +0 -1
- package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js +0 -1
- package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js.map +0 -1
- package/bizar-dash/dist/assets/Toast-WTxc3m2g.js +0 -1
- package/bizar-dash/dist/assets/Toast-WTxc3m2g.js.map +0 -1
- package/bizar-dash/dist/assets/flow-BpU0-gK2.js +0 -1
- package/bizar-dash/dist/assets/flow-BpU0-gK2.js.map +0 -1
- package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js +0 -1
- package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js.map +0 -1
- package/bizar-dash/dist/assets/icons-B0AKnYI3.js +0 -731
- package/bizar-dash/dist/assets/icons-B0AKnYI3.js.map +0 -1
- package/bizar-dash/dist/assets/main-C-Md3DaY.css +0 -1
- package/bizar-dash/dist/assets/main-CO8fIxQK.js +0 -18
- package/bizar-dash/dist/assets/main-CO8fIxQK.js.map +0 -1
- package/bizar-dash/dist/assets/markdown-w2bDDkAH.js +0 -1
- package/bizar-dash/dist/assets/markdown-w2bDDkAH.js.map +0 -1
- package/bizar-dash/dist/assets/mobile-DXYCA0hC.js +0 -1
- package/bizar-dash/dist/assets/mobile-layout-CJnZNLy3.css +0 -1
- package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js +0 -2
- package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js.map +0 -1
- package/bizar-dash/dist/assets/react-vendor-BnuhLJ6X.css +0 -1
- package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js +0 -46
- package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js.map +0 -1
- package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js +0 -2
- package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js.map +0 -1
- package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js +0 -45
- package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js.map +0 -1
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Claude Code Agent SDK in-process — no subprocess, no port, no serve-info file.
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/@polderlabs/bizar)
|
|
11
|
-
[](https://github.com/DrB0rk/BizarHarness)
|
|
12
12
|
[](https://docs.claude.com/claude-code)
|
|
13
13
|
[](https://github.com/DrB0rk/BizarHarness)
|
|
14
14
|
[](docs/INDEX.md)
|
|
@@ -26,50 +26,58 @@ Claude Code Agent SDK in-process — no subprocess, no port, no serve-info file.
|
|
|
26
26
|
|
|
27
27
|
## Table of Contents
|
|
28
28
|
|
|
29
|
-
- [What's new in
|
|
29
|
+
- [What's new in v7.0.0](#-whats-new-in-v700)
|
|
30
30
|
- [Quick start](#-quick-start)
|
|
31
31
|
- [The Pantheon](#-the-pantheon)
|
|
32
32
|
- [Architecture](#-architecture)
|
|
33
|
-
- [Tools (
|
|
34
|
-
- [Hooks (
|
|
33
|
+
- [Tools (23 total)](#-tools-23-total)
|
|
34
|
+
- [Hooks (7 total)](#-hooks-7-total)
|
|
35
35
|
- [Safety — DANGEROUS_PATTERNS](#-safety--dangerous-patterns)
|
|
36
36
|
- [Skill Curator — closed learning loop](#-skill-curator--closed-learning-loop)
|
|
37
37
|
- [Knowledge Graph Tools](#-knowledge-graph-tools)
|
|
38
|
+
- [Agents and history dashboard](#-agents-and-history-dashboard)
|
|
38
39
|
- [Harness engineering audit (73/73)](#-harness-engineering-audit-7373)
|
|
39
40
|
- [Documentation](#-documentation)
|
|
40
|
-
- [Migration from v6.
|
|
41
|
+
- [Migration from v6.3.x](#-migration-from-v63x)
|
|
41
42
|
- [Historical: OpenCode → Cline (v5.6/v6.0)](#-historical-opencode--cline-v56v60)
|
|
42
43
|
- [Contributing](#-contributing)
|
|
43
44
|
- [License](#-license)
|
|
44
45
|
|
|
45
46
|
---
|
|
46
47
|
|
|
47
|
-
## ✨ What's new in
|
|
48
|
+
## ✨ What's new in v7.0.0
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
v7.0.0 lands **F-040 — the dashboard redesign** — on top of the
|
|
51
|
+
v6.3.0 Claude Code migration. The dashboard ships a custom `ui/`
|
|
52
|
+
design system (42 components across controls, data, feedback,
|
|
53
|
+
layout, navigation, primitives, theme + tokens) and rewrites
|
|
54
|
+
the Overview, Agents, and Tasks views on top of it. v7.0.0 also
|
|
55
|
+
carries the v6.5.0 work (F-037 migration cleanup, F-038
|
|
56
|
+
federation skeleton, F-039 Byzantine consensus) that had been
|
|
57
|
+
prepared but not published.
|
|
57
58
|
|
|
58
59
|
| Feature | Description |
|
|
59
60
|
| --- | --- |
|
|
60
|
-
|
|
|
61
|
-
| **
|
|
62
|
-
| **
|
|
63
|
-
| **
|
|
64
|
-
| **
|
|
65
|
-
| **
|
|
66
|
-
| **
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
| **`bizar-dash/src/web/ui/` design system** | 42 components (Button, Checkbox, Select, Slider, Toggle, DataTable, BarChart, Sparkline, StatTile, Tooltip, Toast, Dialog, AppShell, Sidebar, Topbar, CommandPalette, Box, Stack, Grid, + 23 more), tokenized via `ui/styles/tokens.css`, themeable via `ui/theme/ThemeProvider.tsx`. |
|
|
62
|
+
| **Three view rewrites** | `Overview`, `Agents`, `Tasks` rebuilt on the design system. 123 dashboard test files (41 component tests + 82 view/integration tests). |
|
|
63
|
+
| **18 dashboard tabs** | Overview, Chat, Agents, Glyphs, Tasks, Activity, Active, Skills, Memory, Mods, Schedules, History, Usage, Eval, Doctor, Harness, Goals, Settings. |
|
|
64
|
+
| **Federation skeleton (F-038)** | 8 modules under `packages/sdk/src/federation/` — HMAC+nonce envelopes, PII pipeline, TrustEvaluator, PolicyEngine, AuditService, FederationBudget. Exposed as the `federation_status` MCP tool. |
|
|
65
|
+
| **Byzantine consensus (F-039)** | 4 modules under `packages/sdk/src/consensus/` — 3-of-5 majority for review/decision steps; PBFT pre-prepare/prepare/commit/reply. Exposed as the `consensus_propose` MCP tool. |
|
|
66
|
+
| **23 MCP tools, 7 hooks** | All Claude Code `MCP tool registration`; hooks cover bash + edit/write pre+post, session lifecycle, prompt tagging, and worker suggestion. |
|
|
67
|
+
| **Agents + History dashboard** | 11 `/api/agents/*` endpoints with on-disk status persistence; `/api/history` aggregator over activity log + tasks + plans + projects. See the [honest scope note](#-agents--history-dashboard) below. |
|
|
68
|
+
|
|
69
|
+
> **Honest scope note.** The Agents and History *infrastructure*
|
|
70
|
+
> is fully wired (REST, store, WebSocket broadcast, 11 endpoints).
|
|
71
|
+
> The *hook-driven auto-feed* — hooks that POST to
|
|
72
|
+
> `/api/agents/:name/status` as Claude Code tools fire — is **not**
|
|
73
|
+
> wired in v7.0.0. That was in PR #2, deferred to a follow-up.
|
|
74
|
+
> Today the Agents view surfaces data from manual `status` POSTs
|
|
75
|
+
> and CLI operations; running-agent detection lights up once the
|
|
76
|
+
> hook layer lands (target v7.1).
|
|
77
|
+
|
|
78
|
+
See the full [CHANGELOG.md](CHANGELOG.md) and
|
|
79
|
+
[docs/releases/v7.0.0.md](docs/releases/v7.0.0.md) for what
|
|
80
|
+
landed, what's wired, and what's still to come.
|
|
73
81
|
|
|
74
82
|
---
|
|
75
83
|
|
|
@@ -80,7 +88,7 @@ Prerequisites: **Claude Code CLI** (`claude` on `PATH`; install via
|
|
|
80
88
|
[the Claude Code install docs](https://docs.claude.com/claude-code/getting-started)).
|
|
81
89
|
|
|
82
90
|
```bash
|
|
83
|
-
# Install (stable
|
|
91
|
+
# Install (stable v7.0.0)
|
|
84
92
|
npm install @polderlabs/bizar
|
|
85
93
|
|
|
86
94
|
# Or try the latest beta
|
|
@@ -137,19 +145,20 @@ the full agent roster and routing rules.
|
|
|
137
145
|
```
|
|
138
146
|
┌────────────────────────────────────────────────────────────────────┐
|
|
139
147
|
│ Layer 1: UI (bizar-dash/) │
|
|
140
|
-
│ - React + TypeScript dashboard (
|
|
148
|
+
│ - React + TypeScript dashboard (18 tabs) │
|
|
141
149
|
│ - Express server (HTTP + WS) │
|
|
142
150
|
│ - In-process Claude Code Agent SDK (no daemon / no subprocess) │
|
|
143
151
|
│ - Harness engineering dashboard view │
|
|
144
152
|
│ - Kanban board (5 columns + backlog) │
|
|
153
|
+
│ - Custom `ui/` design system (42 components, F-040) │
|
|
145
154
|
└────────────────────────────────────────────────────────────────────┘
|
|
146
155
|
↕ HTTP REST + WebSocket
|
|
147
156
|
┌────────────────────────────────────────────────────────────────────┐
|
|
148
157
|
│ Layer 0: Core (.claude/skills + .claude/agents + plugins/bizar/) │
|
|
149
158
|
│ - Skills (SKILL.md + bundled scripts) │
|
|
150
159
|
│ - Agents (Odin, Frigg, Vör, Mimir, Heimdall, ...) │
|
|
151
|
-
│ - Bizar MCP server (plugins/bizar/,
|
|
152
|
-
│ -
|
|
160
|
+
│ - Bizar MCP server (plugins/bizar/, 23 tools) │
|
|
161
|
+
│ - 7 hooks (PreToolUse × 2, PostToolUse, SessionStart/End, ...) │
|
|
153
162
|
│ - In-process memory vault │
|
|
154
163
|
│ - DANGEROUS_PATTERNS approval gate │
|
|
155
164
|
│ - Skill curator (closed learning loop) │
|
|
@@ -171,33 +180,39 @@ model, module map, and inter-component contracts.
|
|
|
171
180
|
|
|
172
181
|
---
|
|
173
182
|
|
|
174
|
-
## 🛠 Tools (
|
|
183
|
+
## 🛠 Tools (23 total)
|
|
175
184
|
|
|
176
|
-
Bizar's
|
|
185
|
+
Bizar's 23 tools are exposed as a Claude Code MCP server (replacing
|
|
177
186
|
Cline's `createTool` shape with the Claude Code MCP `tool`
|
|
178
187
|
registration shape):
|
|
179
188
|
|
|
180
189
|
| Category | Count | Tools |
|
|
181
190
|
| --- | --- | --- |
|
|
182
|
-
| **
|
|
183
|
-
| **
|
|
184
|
-
| **
|
|
185
|
-
| **
|
|
186
|
-
| **
|
|
187
|
-
| **
|
|
191
|
+
| **Memory** | 4 | `memory_read`, `memory_write`, `memory_list`, `memory_search` |
|
|
192
|
+
| **Plan / Glyphs** | 2 | `plan_action`, `open_kb` |
|
|
193
|
+
| **Loop control** | 4 | `loop_list`, `loop_status`, `loop_start`, `loop_stop` |
|
|
194
|
+
| **Graph / Knowledge** | 3 | `graph_query`, `graph_path`, `graph_explain` |
|
|
195
|
+
| **Agents** | 3 | `agent_spawn`, `agent_list`, `agent_terminate` |
|
|
196
|
+
| **Swarm + routing** | 3 | `swarm_init`, `model_route`, `agent_route` |
|
|
197
|
+
| **Hooks + safety** | 2 | `hooks_route`, `danger_check` |
|
|
198
|
+
| **Distill + consensus + federation** | 2 | `memory_distill`, `consensus_propose`, `federation_status` |
|
|
199
|
+
| **Total** | **23** | All registered as MCP tools via the Claude Code MCP SDK |
|
|
188
200
|
|
|
189
201
|
---
|
|
190
202
|
|
|
191
|
-
## 🪝 Hooks (
|
|
203
|
+
## 🪝 Hooks (7 total)
|
|
192
204
|
|
|
193
205
|
Claude Code-native hooks (typed event payloads, idiomatic shape):
|
|
194
206
|
|
|
195
207
|
| Hook | Purpose |
|
|
196
208
|
| --- | --- |
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
209
|
+
| `pretooluse-bash` | Loop guard + **DANGEROUS_PATTERNS gate** (36 patterns) |
|
|
210
|
+
| `pretooluse-editwrite` | Edit/write pre-flight checks (loop guard, paths) |
|
|
211
|
+
| `posttooluse-editwrite` | Per-edit/write audit log entry |
|
|
212
|
+
| `sessionstart-prime` | Slash command interception + memory prime |
|
|
213
|
+
| `sessionend-recall` | Session-end memory write |
|
|
214
|
+
| `userpromptsubmit-tag` | Prompt tagging + worker suggestion trigger |
|
|
215
|
+
| `worker-suggest` (F-034) | Bizar background-worker dispatch based on prompt text |
|
|
201
216
|
|
|
202
217
|
| Safety component | Purpose |
|
|
203
218
|
| --- | --- |
|
|
@@ -280,9 +295,61 @@ See [docs/graph-tools.md](docs/graph-tools.md) for the full reference.
|
|
|
280
295
|
|
|
281
296
|
---
|
|
282
297
|
|
|
298
|
+
## 🤖 Agents and history dashboard
|
|
299
|
+
|
|
300
|
+
v7.0.0 ships the Agents and History surfaces on the new design
|
|
301
|
+
system. The full data plane:
|
|
302
|
+
|
|
303
|
+
**Server side (fully wired in v7.0.0):**
|
|
304
|
+
|
|
305
|
+
- **11 `/api/agents/*` endpoints** under `bizar-dash/src/server/routes/agents.mjs` —
|
|
306
|
+
list, get, create, update, delete, plus `stuck`, `hierarchy`,
|
|
307
|
+
`invoke`, `status`, `heartbeat`, `restart`.
|
|
308
|
+
- **On-disk status persistence** in `agents-store.mjs` —
|
|
309
|
+
`~/.config/bizar/agent-status.json` survives restarts.
|
|
310
|
+
- **WebSocket broadcast** on every agent mutation
|
|
311
|
+
(`agents:change`).
|
|
312
|
+
- **Stuck detection** + **13-agent hierarchy** (Odin →
|
|
313
|
+
Tyr/Thor/Hermod/Baldr/Mimir → Heimdall/Frigg/Vor; Forseti as
|
|
314
|
+
auditor peer; Vidarr fallback; Quick standalone).
|
|
315
|
+
- **`/api/history`** aggregator — joins `activity-log` + tasks +
|
|
316
|
+
plans + projects with `?since=<iso>` filtering and a 2,000-event
|
|
317
|
+
cap.
|
|
318
|
+
|
|
319
|
+
**UI side (fully wired in v7.0.0):**
|
|
320
|
+
|
|
321
|
+
- **`Agents.tsx`** view (rewritten on F-040 design system) reads
|
|
322
|
+
from `/api/agents`, shows status, tags, category, hierarchy,
|
|
323
|
+
stuck indicators, modals for invoke/restart/delete.
|
|
324
|
+
- **`History.tsx`** view reads `/api/history` with timeline
|
|
325
|
+
rendering.
|
|
326
|
+
|
|
327
|
+
**Live data feed (deferred to v7.1 — was in PR #2):**
|
|
328
|
+
|
|
329
|
+
- Hook-driven status updates as Claude Code tools fire — no hook
|
|
330
|
+
currently POSTs to `/api/agents/:name/status`. Agents show
|
|
331
|
+
"idle" until manually updated.
|
|
332
|
+
- Session-end cleanup of stuck states — no hook flips
|
|
333
|
+
stuck→idle on session end.
|
|
334
|
+
|
|
335
|
+
To push status updates from anywhere today (CLI, scripts, other
|
|
336
|
+
hooks), POST to `/api/agents/:name/status`:
|
|
337
|
+
|
|
338
|
+
```sh
|
|
339
|
+
curl -X POST http://localhost:7842/api/agents/odin/status \
|
|
340
|
+
-H 'content-type: application/json' \
|
|
341
|
+
-d '{"status":"working","currentTaskId":"F-040"}'
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
See [docs/releases/v7.0.0.md](docs/releases/v7.0.0.md) for the
|
|
345
|
+
release notes and [docs/dashboard-ui-migration.md](docs/dashboard-ui-migration.md)
|
|
346
|
+
for the F-040 design-system migration guide.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
283
350
|
## 🛡 Harness engineering audit (73/73)
|
|
284
351
|
|
|
285
|
-
|
|
352
|
+
v7.0.0 passes the full L01–L12 audit at **73/73 = 100%**:
|
|
286
353
|
|
|
287
354
|
| Subsystem | Score |
|
|
288
355
|
| --- | --- |
|
|
@@ -293,7 +360,7 @@ v6.3.0 passes the full L01–L12 audit at **73/73 = 100%**:
|
|
|
293
360
|
| 5. Feedback | 7/7 (`make check/test/e2e/clean-check/arch/vcr/session-*`) |
|
|
294
361
|
| 6. L05 Cross-session | 6/6 (Current State + clock-in/out + context anxiety) |
|
|
295
362
|
| 7. L03 System of record | 4/4 (ACID: Durability, Consistency, Atomicity, Proximity) |
|
|
296
|
-
| 8. L07 WIP=1 + VCR | 3/3 (WIP=1 + `make vcr` + VCR
|
|
363
|
+
| 8. L07 WIP=1 + VCR | 3/3 (WIP=1 + `make vcr` + VCR 39/39 = 1.0) |
|
|
297
364
|
| 9. L08 Feature list | 6/6 (evidence + verify-feature + granularity + state machine) |
|
|
298
365
|
| 10. L09 DoD | 5/5 (3-layer verification + runtime signals + repair instructions) |
|
|
299
366
|
| 11. L10 E2E + Arch | 8/8 (`make e2e` + `make check-arch` + 7 arch rules + E2E requirement) |
|
|
@@ -334,7 +401,18 @@ See [PROGRESS.md](PROGRESS.md) § Current State and the
|
|
|
334
401
|
|
|
335
402
|
---
|
|
336
403
|
|
|
337
|
-
## 🔄 Migration from v6.
|
|
404
|
+
## 🔄 Migration from v6.3.x
|
|
405
|
+
|
|
406
|
+
Upgrading from v6.3.x? The Claude Code migration story is unchanged
|
|
407
|
+
(in-process Agent SDK, MCP tool surface, hook event bag). v7.0.0
|
|
408
|
+
adds the dashboard redesign without changing any plugin surface,
|
|
409
|
+
so existing installations work — the installer just needs
|
|
410
|
+
re-running to pick up the new dashboard assets:
|
|
411
|
+
|
|
412
|
+
```sh
|
|
413
|
+
npm install -g @polderlabs/bizar@latest
|
|
414
|
+
./install.sh
|
|
415
|
+
```
|
|
338
416
|
|
|
339
417
|
Upgrading from a Cline-era BizarHarness (v6.0.0 → v6.2.x)? See
|
|
340
418
|
[docs/migration-guide.md](docs/migration-guide.md) for:
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import{c as C,r as o,j as e,h as T,W as ke,b,R as O,n as be,d as we,A as me,u as Ne,_ as Ce,g as ne,P as ze,X as ce,C as Se,q as Me,T as Ae}from"./mobile-layout-GZ3bE8L6.js";import{u as X,C as xe,T as oe,I as Le,a as Re}from"./Toast-ATSAmbdi.js";/**
|
|
2
|
+
* @license lucide-react v0.460.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Xe=C("Brain",[["path",{d:"M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z",key:"l5xja"}],["path",{d:"M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z",key:"ep3f8r"}],["path",{d:"M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4",key:"1p4c4q"}],["path",{d:"M17.599 6.5a3 3 0 0 0 .399-1.375",key:"tmeiqw"}],["path",{d:"M6.003 5.125A3 3 0 0 0 6.401 6.5",key:"105sqy"}],["path",{d:"M3.477 10.896a4 4 0 0 1 .585-.396",key:"ql3yin"}],["path",{d:"M19.938 10.5a4 4 0 0 1 .585.396",key:"1qfode"}],["path",{d:"M6 18a4 4 0 0 1-1.967-.516",key:"2e4loj"}],["path",{d:"M19.967 17.484A4 4 0 0 1 18 18",key:"159ez6"}]]);/**
|
|
7
|
+
* @license lucide-react v0.460.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const Ie=C("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/**
|
|
12
|
+
* @license lucide-react v0.460.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const q=C("CircleCheckBig",[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);/**
|
|
17
|
+
* @license lucide-react v0.460.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const ae=C("CircleX",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);/**
|
|
22
|
+
* @license lucide-react v0.460.0 - ISC
|
|
23
|
+
*
|
|
24
|
+
* This source code is licensed under the ISC license.
|
|
25
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
+
*/const Qe=C("Cpu",[["rect",{width:"16",height:"16",x:"4",y:"4",rx:"2",key:"14l7u7"}],["rect",{width:"6",height:"6",x:"9",y:"9",rx:"1",key:"5aljv4"}],["path",{d:"M15 2v2",key:"13l42r"}],["path",{d:"M15 20v2",key:"15mkzm"}],["path",{d:"M2 15h2",key:"1gxd5l"}],["path",{d:"M2 9h2",key:"1bbxkp"}],["path",{d:"M20 15h2",key:"19e6y8"}],["path",{d:"M20 9h2",key:"19tzq7"}],["path",{d:"M9 2v2",key:"165o2o"}],["path",{d:"M9 20v2",key:"i2bqo8"}]]);/**
|
|
27
|
+
* @license lucide-react v0.460.0 - ISC
|
|
28
|
+
*
|
|
29
|
+
* This source code is licensed under the ISC license.
|
|
30
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
31
|
+
*/const Y=C("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);/**
|
|
32
|
+
* @license lucide-react v0.460.0 - ISC
|
|
33
|
+
*
|
|
34
|
+
* This source code is licensed under the ISC license.
|
|
35
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
36
|
+
*/const Ee=C("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);/**
|
|
37
|
+
* @license lucide-react v0.460.0 - ISC
|
|
38
|
+
*
|
|
39
|
+
* This source code is licensed under the ISC license.
|
|
40
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
41
|
+
*/const Be=C("EyeOff",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);/**
|
|
42
|
+
* @license lucide-react v0.460.0 - ISC
|
|
43
|
+
*
|
|
44
|
+
* This source code is licensed under the ISC license.
|
|
45
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
46
|
+
*/const re=C("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);/**
|
|
47
|
+
* @license lucide-react v0.460.0 - ISC
|
|
48
|
+
*
|
|
49
|
+
* This source code is licensed under the ISC license.
|
|
50
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
+
*/const Je=C("FolderInput",[["path",{d:"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1",key:"fm4g5t"}],["path",{d:"M2 13h10",key:"pgb2dq"}],["path",{d:"m9 16 3-3-3-3",key:"6m91ic"}]]);/**
|
|
52
|
+
* @license lucide-react v0.460.0 - ISC
|
|
53
|
+
*
|
|
54
|
+
* This source code is licensed under the ISC license.
|
|
55
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
+
*/const es=C("GitBranch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]);/**
|
|
57
|
+
* @license lucide-react v0.460.0 - ISC
|
|
58
|
+
*
|
|
59
|
+
* This source code is licensed under the ISC license.
|
|
60
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
+
*/const ss=C("Globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);/**
|
|
62
|
+
* @license lucide-react v0.460.0 - ISC
|
|
63
|
+
*
|
|
64
|
+
* This source code is licensed under the ISC license.
|
|
65
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
66
|
+
*/const ye=C("KeyRound",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]]);/**
|
|
67
|
+
* @license lucide-react v0.460.0 - ISC
|
|
68
|
+
*
|
|
69
|
+
* This source code is licensed under the ISC license.
|
|
70
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
71
|
+
*/const Pe=C("Link",[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]]);/**
|
|
72
|
+
* @license lucide-react v0.460.0 - ISC
|
|
73
|
+
*
|
|
74
|
+
* This source code is licensed under the ISC license.
|
|
75
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
76
|
+
*/const as=C("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/**
|
|
77
|
+
* @license lucide-react v0.460.0 - ISC
|
|
78
|
+
*
|
|
79
|
+
* This source code is licensed under the ISC license.
|
|
80
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
81
|
+
*/const Te=C("Loader",[["path",{d:"M12 2v4",key:"3427ic"}],["path",{d:"m16.2 7.8 2.9-2.9",key:"r700ao"}],["path",{d:"M18 12h4",key:"wj9ykh"}],["path",{d:"m16.2 16.2 2.9 2.9",key:"1bxg5t"}],["path",{d:"M12 18v4",key:"jadmvz"}],["path",{d:"m4.9 19.1 2.9-2.9",key:"bwix9q"}],["path",{d:"M2 12h4",key:"j09sii"}],["path",{d:"m4.9 4.9 2.9 2.9",key:"giyufr"}]]);/**
|
|
82
|
+
* @license lucide-react v0.460.0 - ISC
|
|
83
|
+
*
|
|
84
|
+
* This source code is licensed under the ISC license.
|
|
85
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
86
|
+
*/const $e=C("PanelsTopLeft",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M9 21V9",key:"1oto5p"}]]);/**
|
|
87
|
+
* @license lucide-react v0.460.0 - ISC
|
|
88
|
+
*
|
|
89
|
+
* This source code is licensed under the ISC license.
|
|
90
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
91
|
+
*/const de=C("Plug",[["path",{d:"M12 22v-5",key:"1ega77"}],["path",{d:"M9 8V2",key:"14iosj"}],["path",{d:"M15 8V2",key:"18g5xt"}],["path",{d:"M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z",key:"osxo6l"}]]);/**
|
|
92
|
+
* @license lucide-react v0.460.0 - ISC
|
|
93
|
+
*
|
|
94
|
+
* This source code is licensed under the ISC license.
|
|
95
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
96
|
+
*/const ts=C("Settings2",[["path",{d:"M20 7h-9",key:"3s1dr2"}],["path",{d:"M14 17H5",key:"gfn3mx"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}],["circle",{cx:"7",cy:"7",r:"3",key:"dfmy0x"}]]);/**
|
|
97
|
+
* @license lucide-react v0.460.0 - ISC
|
|
98
|
+
*
|
|
99
|
+
* This source code is licensed under the ISC license.
|
|
100
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
101
|
+
*/const De=C("Square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);/**
|
|
102
|
+
* @license lucide-react v0.460.0 - ISC
|
|
103
|
+
*
|
|
104
|
+
* This source code is licensed under the ISC license.
|
|
105
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
106
|
+
*/const He=C("Upload",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"17 8 12 3 7 8",key:"t8dd8p"}],["line",{x1:"12",x2:"12",y1:"3",y2:"15",key:"widbto"}]]);/**
|
|
107
|
+
* @license lucide-react v0.460.0 - ISC
|
|
108
|
+
*
|
|
109
|
+
* This source code is licensed under the ISC license.
|
|
110
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
111
|
+
*/const Ve=C("Zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]),k=o.forwardRef(function({variant:s="secondary",size:l="md",iconOnly:c=!1,loading:r=!1,disabled:m,className:x,children:i,...n},h){return e.jsxs("button",{ref:h,type:n.type??"button",disabled:m||r,className:T("btn",`btn-${s}`,`btn-size-${l}`,c&&"btn-icon",r&&"btn-loading",x),...n,children:[r?e.jsx("span",{className:"btn-spinner","aria-hidden":!0}):null,i]})});function ns(...a){const s=[],l=c=>{if(c){if(typeof c=="string"||typeof c=="number"){s.push(String(c));return}if(Array.isArray(c)){for(const r of c)l(r);return}if(typeof c=="object")for(const r in c)c[r]&&s.push(r)}};for(const c of a)l(c);return s.join(" ")}function E({variant:a="elevated",interactive:s=!1,className:l,children:c,...r}){return e.jsx("div",{className:T("card",`card-${a}`,s&&"card-interactive",l),...r,children:c})}function B({children:a,className:s}){return e.jsx("h3",{className:T("card-title",s),children:a})}function P({children:a,className:s}){return e.jsx("div",{className:T("card-meta",s),children:a})}const te=[{id:"bizar",name:"Bizar CLI"},{id:"bizar-dash",name:"Dashboard"},{id:"bizar-plugin",name:"Opencode Plugin"}];function rs(){const a=X(),[s,l]=o.useState({current:{},latest:null,checking:!1,updating:!1,hasUpdates:!1,requiresRestart:!1,perPackage:{}});o.useEffect(()=>{const i=new ke;return i.on(n=>{(n.type==="update:progress"||n.type==="update:log"||n.type==="update:complete")&&l(h=>{if(n.type==="update:complete")return{...h,updating:!1,requiresRestart:!!n.requiresRestart};if(n.type==="update:log"){const g=n,v=h.perPackage[g.pkg]||{logs:[]};return{...h,perPackage:{...h.perPackage,[g.pkg]:{...v,logs:[...(v.logs||[]).slice(-50),g.line]}}}}const y=n;return{...h,perPackage:{...h.perPackage,[y.pkg]:{...h.perPackage[y.pkg],status:y.status,error:y.error,newVersion:y.newVersion}}}})}),()=>i.close()},[]),o.useEffect(()=>{b.get("/updates/status").then(i=>l(n=>({...n,current:i.current}))).catch(i=>l(n=>({...n,error:i.message})))},[]);const c=async()=>{l(i=>({...i,checking:!0,error:void 0}));try{const i=await b.get("/updates/check");l(n=>({...n,checking:!1,current:i.current,latest:i.latest,hasUpdates:i.hasUpdates}))}catch(i){l(n=>({...n,checking:!1,error:i.message}))}},r=async()=>{if(confirm("Update Bizar packages? The dashboard will restart automatically.")){l(i=>({...i,updating:!0,requiresRestart:!1,perPackage:{},error:void 0}));try{await b.post("/updates/apply",{packages:["bizar","bizar-dash","bizar-plugin"]})}catch(i){l(n=>({...n,updating:!1,error:i.message}))}}},m=async()=>{if(confirm("Restart the dashboard? You will be disconnected briefly."))try{await b.post("/restart"),a.info("Restarting…",3e3),setTimeout(()=>window.location.reload(),3e3)}catch{a.error("Restart failed")}},x=s.checking||s.updating;return e.jsxs(E,{id:"settings-updates","data-section":"updates",children:[e.jsxs(B,{children:[e.jsx(Y,{size:14})," Updates"]}),e.jsx(P,{children:"Check installed Bizar packages and apply dashboard updates."}),e.jsxs("div",{className:"updates-current",children:[e.jsx("h4",{children:"Installed versions"}),e.jsx("ul",{children:te.map(i=>e.jsxs("li",{children:[e.jsx("span",{children:i.name}),e.jsx("code",{className:"mono",children:s.current[i.id]||"—"})]},i.id))})]}),s.latest&&e.jsxs("div",{className:"updates-latest",children:[e.jsx("h4",{children:"Latest available"}),e.jsx("ul",{children:te.map(i=>{var g;const n=s.current[i.id],h=(g=s.latest)==null?void 0:g[i.id],y=n&&h&&n!==h;return e.jsxs("li",{className:y?"updates-outdated":"updates-current-version",children:[e.jsx("span",{children:i.name}),e.jsxs("code",{className:"mono",children:[h||"—",y&&e.jsx("span",{className:"updates-badge",children:"update available"})]})]},i.id)})})]}),s.updating&&e.jsx("div",{className:"updates-progress-rows",children:te.map(i=>{const n=s.perPackage[i.id]||{status:"idle",logs:[]};return e.jsxs("div",{className:"updates-pkg-row",children:[e.jsxs("div",{className:"updates-pkg-row-header",children:[e.jsx("span",{className:"updates-pkg-name",children:i.name}),e.jsxs("div",{className:"updates-pkg-status",children:[n.status==="starting"&&e.jsx("span",{className:"btn-spinner"}),n.status==="installing"&&e.jsx("span",{className:"btn-spinner"}),n.status==="done"&&e.jsx(q,{size:14,className:"icon-success"}),n.status==="error"&&e.jsx(xe,{size:14,className:"icon-error"}),e.jsx("span",{children:n.status}),n.newVersion&&e.jsxs("code",{className:"mono",style:{fontSize:11},children:["→ ",n.newVersion]})]})]}),n.logs.length>0&&e.jsxs("details",{className:"updates-pkg-logs",children:[e.jsxs("summary",{children:["npm output (",n.logs.length," lines)"]}),e.jsx("pre",{children:n.logs.join(`
|
|
112
|
+
`)})]}),n.status==="error"&&n.error&&e.jsxs("div",{className:"updates-pkg-error",children:[e.jsx(oe,{size:12})," ",n.error]})]},i.id)})}),e.jsxs("div",{className:"updates-actions",children:[e.jsxs(k,{onClick:c,disabled:x,children:[s.checking?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:14}),"Check for updates"]}),e.jsxs(k,{variant:"primary",onClick:r,disabled:!s.hasUpdates||s.updating,children:[s.updating?e.jsx("span",{className:"btn-spinner"}):e.jsx(Y,{size:14}),s.updating?"Updating…":s.hasUpdates?"Update now":"Up to date"]}),s.requiresRestart&&e.jsxs(k,{variant:"danger",onClick:m,children:[e.jsx(O,{size:14})," Restart Dashboard"]})]}),s.error&&e.jsxs("div",{className:"updates-error",children:[e.jsx(oe,{size:14}),e.jsx("span",{children:s.error})]})]})}function Ue(a,s,{delay:l=800,onSaved:c,onError:r}={}){const[m,x]=o.useState(a),[i,n]=o.useState("idle"),h=o.useRef(null),y=o.useRef(null),g=o.useRef(a),v=o.useRef(!1),S=o.useCallback(async p=>{n("saving");try{await s(p),g.current=p,y.current=null,n("saved"),c==null||c(),setTimeout(()=>n("idle"),2e3)}catch(j){n("error"),r==null||r(j)}},[s,c,r]),R=o.useCallback(p=>{x(p),y.current=p,v.current=!0,h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{h.current=null,v.current=!1;const j=y.current;y.current=null,j!==null&&S(j)},l)},[l,S]),z=o.useCallback(()=>{h.current&&(clearTimeout(h.current),h.current=null,v.current=!1)},[]),u=o.useCallback(async()=>{if(h.current){clearTimeout(h.current),h.current=null,v.current=!1;const p=y.current;y.current=null,p!==null&&await S(p)}},[S]);return o.useEffect(()=>()=>{if(h.current){clearTimeout(h.current),h.current=null;const p=y.current;y.current=null,p!==null&&(n("saving"),s(p).then(()=>{g.current=p,n("saved"),c==null||c()}).catch(j=>{n("error"),r==null||r(j)}).finally(()=>{setTimeout(()=>n("idle"),2e3)}))}},[s,c,r]),{value:m,setValue:R,status:i,save:S,flush:u,clearDebounce:z,hasPendingDebounceRef:v,pendingValueRef:y}}function he({initialValue:a,saveFn:s,delay:l=800,render:c,className:r}){const{value:m,setValue:x,status:i,save:n,clearDebounce:h,hasPendingDebounceRef:y,pendingValueRef:g}=Ue(a,s,{delay:l}),v=be.useCallback(()=>{y.current&&(h(),g.current!==null&&n(g.current))},[h,y,n,g]);return e.jsxs("div",{className:`autosave-field ${r||""} ${i}`,children:[c({value:m,onChange:x,onBlur:v}),e.jsxs("span",{className:"autosave-status",role:"status","aria-live":"polite",children:[i==="saving"&&e.jsx(Te,{className:"spinning",size:12}),i==="saved"&&e.jsx(Ie,{size:12}),i==="error"&&e.jsx(xe,{size:12})]})]})}const _e=[{id:"topnav",label:"Top nav"},{id:"sidebar",label:"Sidebar"},{id:"both",label:"Both"}];function ls({settings:a,patchUi:s,patchTop:l,autoSave:c}){return e.jsxs(e.Fragment,{children:[e.jsxs(E,{id:"settings-layout","data-section":"layout",children:[e.jsxs(B,{children:[e.jsx($e,{size:14})," UI layout"]}),e.jsx(P,{children:"Choose how the dashboard's navigation is presented."}),e.jsx("div",{className:"layout-row","data-setting-id":"ui.layout",children:_e.map(r=>e.jsx("button",{type:"button",className:T("layout-card",a.ui.layout===r.id&&"layout-card-active"),onClick:()=>s({layout:r.id}),children:e.jsx("span",{className:"layout-card-label",children:r.label})},r.id))}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showHeader",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showHeader,onChange:r=>s({showHeader:r.target.checked})}),e.jsx("span",{children:"Show header"})]}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showStatusBar",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showStatusBar,onChange:r=>s({showStatusBar:r.target.checked})}),e.jsx("span",{children:"Show status bar"})]}),e.jsxs("div",{className:"field","data-setting-id":"ui.defaultTab",children:[e.jsx("label",{className:"field-label",children:"Default tab"}),e.jsxs("select",{className:"select",value:a.ui.defaultTab,onChange:r=>s({defaultTab:r.target.value}),children:[e.jsx("option",{value:"overview",children:"Overview"}),e.jsx("option",{value:"chat",children:"Chat"}),e.jsx("option",{value:"agents",children:"Agents"}),e.jsx("option",{value:"artifacts",children:"Plans"}),e.jsx("option",{value:"projects",children:"Projects"}),e.jsx("option",{value:"tasks",children:"Tasks"}),e.jsx("option",{value:"config",children:"Config"}),e.jsx("option",{value:"settings",children:"Settings"}),e.jsx("option",{value:"mods",children:"Mods"}),e.jsx("option",{value:"schedules",children:"Schedules"})]})]})]}),e.jsxs(E,{id:"settings-general","data-section":"general",children:[e.jsx(B,{children:"General"}),e.jsx(P,{children:"Default agent + model override."}),e.jsxs("div",{className:"field","data-setting-id":"defaultAgent",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-agent",children:"Default agent"}),e.jsx(he,{initialValue:a.defaultAgent||"",saveFn:async r=>{l("defaultAgent",r),c==null||c("defaultAgent",r)},render:({value:r,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-agent",className:"input",type:"text",placeholder:"e.g. odin",value:r,onChange:i=>m(i.target.value),onBlur:x})})]}),e.jsxs("div",{className:"field","data-setting-id":"defaultModel",children:[e.jsx("label",{className:"field-label",htmlFor:"set-default-model",children:"Model override"}),e.jsx(he,{initialValue:a.defaultModel||"",saveFn:async r=>{l("defaultModel",r),c==null||c("defaultModel",r)},render:({value:r,onChange:m,onBlur:x})=>e.jsx("input",{id:"set-default-model",className:"input",type:"text",placeholder:"(leave empty for provider default)",value:r,onChange:i=>m(i.target.value),onBlur:x})})]})]})]})}function is({initialStatus:a}){var p;const[s,l]=o.useState(a??null),[c,r]=o.useState(""),[m,x]=o.useState(!1),[i,n]=o.useState(null);o.useEffect(()=>{s===null&&b.get("/tailscale/status").then(j=>l(j)).catch(()=>l(null))},[]);const h=async()=>{try{const j=await b.get("/tailscale/status");l(j)}catch{n("Failed to load Tailscale status")}},y=async()=>{if(c.trim()){x(!0),n(null);try{await b.post("/tailscale/setup",{authKey:c.trim()}),await h(),r("")}catch(j){n(j.message||"Authentication failed")}finally{x(!1)}}},g=async()=>{var j,w,M;if(s){x(!0),n(null);try{await b.post("/tailscale/setup",{port:((j=s.settings)==null?void 0:j.port)||4321,https:((w=s.settings)==null?void 0:w.https)!==!1,hostname:((M=s.settings)==null?void 0:M.hostname)||""}),await h()}catch($){n($.message||"Setup failed")}finally{x(!1)}}},v=async()=>{x(!0),n(null);try{await b.post("/tailscale/unserve"),await h()}catch(j){n(j.message||"Remove failed")}finally{x(!1)}},S=(s==null?void 0:s.installed)??!1,R=(s==null?void 0:s.authenticated)??!1,z=((p=s==null?void 0:s.settings)==null?void 0:p.enabled)??!1,u=z?`https://${(s==null?void 0:s.hostname)||"bizar-dash"}`:null;return S?e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs(B,{children:[e.jsx(de,{size:14})," Tailscale Integration"]}),e.jsx(P,{children:"Expose the dashboard over your Tailscale network using an auth key."}),i&&e.jsx("p",{style:{color:"var(--color-error, #f85149)",fontSize:"0.85rem"},children:i}),R?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(q,{size:16,style:{color:"var(--color-success, #3fb950)"}}),e.jsxs("span",{children:["Authenticated as ",e.jsx("strong",{children:(s==null?void 0:s.hostname)||"unknown"})]})]}),z&&u?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"status-row",style:{display:"flex",alignItems:"center",gap:"0.5rem",marginBottom:"0.75rem"},children:[e.jsx(Pe,{size:16}),e.jsx("a",{href:u,target:"_blank",rel:"noreferrer",children:u})]}),e.jsx(k,{variant:"secondary",size:"sm",onClick:v,disabled:m,children:"Remove serve"})]}):e.jsx(k,{variant:"primary",size:"sm",onClick:g,disabled:m,children:"Set up Tailscale serve"})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"muted",style:{marginBottom:"0.75rem"},children:"Not authenticated with Tailscale."}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",flexWrap:"wrap"},children:[e.jsx("input",{type:"text",className:"input",placeholder:"tskey-...",value:c,onChange:j=>r(j.target.value),style:{flex:1,minWidth:"200px"},disabled:m}),e.jsx(k,{variant:"primary",size:"sm",onClick:y,disabled:m||!c.trim(),children:"Authenticate"})]})]})]}):e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs(B,{children:[e.jsx(de,{size:14})," Tailscale Integration"]}),e.jsx(P,{children:"Tailscale is not installed on this machine."}),e.jsxs("p",{className:"muted",children:["Install from"," ",e.jsx("a",{href:"https://tailscale.com/download",target:"_blank",rel:"noreferrer",children:"tailscale.com/download"})]})]})}function cs({settings:a,patchTop:s}){var l,c,r;return e.jsxs(E,{id:"settings-system-llm","data-section":"system-llm",children:[e.jsxs(B,{children:[e.jsx(we,{size:14})," System LLM API"]}),e.jsx(P,{children:"Configures the LLM used for automatic title generation, prompt enhancement, summarization, and other system-level calls."}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"systemLlm.enabled",children:[e.jsx("input",{type:"checkbox",checked:!!((l=a.systemLlm)!=null&&l.enabled),onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,enabled:m.target.checked})}}),e.jsx("span",{children:"Enable system LLM calls"})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.provider",style:{marginTop:"var(--space-3)"},children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-provider",children:"Provider"}),e.jsxs("select",{id:"set-system-llm-provider",className:"select",value:((c=a.systemLlm)==null?void 0:c.provider)||"cline",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,provider:m.target.value})},children:[e.jsx("option",{value:"cline",children:"Cline"}),e.jsx("option",{value:"openrouter",children:"OpenRouter"}),e.jsx("option",{value:"minimax",children:"MiniMax"})]})]}),e.jsxs("div",{className:"field","data-setting-id":"systemLlm.model",children:[e.jsx("label",{className:"field-label",htmlFor:"set-system-llm-model",children:"Model"}),e.jsx("input",{id:"set-system-llm-model",className:"input mono",type:"text",placeholder:"cline/deepseek-v4-flash-free",value:((r=a.systemLlm)==null?void 0:r.model)||"cline/deepseek-v4-flash-free",onChange:m=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,model:m.target.value})}}),e.jsxs("p",{className:"field-help",children:["The API key is read from ",e.jsx("code",{children:"auth.json"})," for the selected provider. Leave the default model for best results."]})]}),e.jsxs("div",{style:{marginTop:"var(--space-4)"},children:[e.jsx("h4",{style:{margin:"0 0 var(--space-2)"},children:"Features using this API"}),e.jsxs("ul",{className:"settings-feature-list",style:{margin:0,paddingLeft:"var(--space-4)",lineHeight:1.8},children:[e.jsx("li",{children:"Auto-title generation for new chat sessions"}),e.jsx("li",{children:"Auto-title generation for new tasks"}),e.jsx("li",{children:'"Enhance prompt" button in the task input'}),e.jsx("li",{children:'"Enhance prompt" button in the chat composer'}),e.jsx("li",{className:"muted",style:{fontSize:12},children:"Future: summarization, name generation, and more"})]})]})]})}const qe=[{value:"anthropic",label:"Anthropic"},{value:"anyllm",label:"AnyLLM"},{value:"litellm-anthropic",label:"LiteLLM (Anthropic)"},{value:"litellm-openai",label:"LiteLLM (OpenAI)"}];function Oe({settings:a,onPatch:s}){const l=X(),[c,r]=o.useState(null),[m,x]=o.useState(null),[i,n]=o.useState(!1),[h,y]=o.useState(!1),[g,v]=o.useState(!1),[S,R]=o.useState(!1),[z,u]=o.useState(!1),[p,j]=o.useState(!1),w=o.useCallback(async()=>{n(!0);try{const[d,V]=await Promise.all([b.get("/headroom/status"),b.get("/headroom/stats?hours=24").catch(()=>({error:"no stats"}))]);r(d),V.error||x(V)}catch(d){l.error(`Failed to load Headroom status: ${d.message}`)}finally{n(!1)}},[l]);o.useEffect(()=>{w()},[w]);const M=async()=>{y(!0);try{const d=await b.post("/headroom/install",{force:!0});d.installed?(l.success(`Headroom installed via ${d.method}.`),await w()):l.error('Headroom install failed. Try: pip install "headroom-ai[all]"')}catch(d){l.error(`Install failed: ${d.message}`)}finally{y(!1)}},$=async()=>{v(!0);try{(await b.post("/headroom/wrap",{port:a.port})).ok?(l.success("cline wrapped with Headroom."),await w()):l.error("Wrap failed.")}catch(d){l.error(`Wrap failed: ${d.message}`)}finally{v(!1)}},U=async()=>{R(!0);try{(await b.post("/headroom/unwrap")).ok?(l.success("cline unwrapped from Headroom."),await w()):l.error("Unwrap failed.")}catch(d){l.error(`Unwrap failed: ${d.message}`)}finally{R(!1)}},W=async()=>{u(!0);try{(await b.post("/headroom/proxy/start",{port:a.port,host:a.host})).ok?(l.success(`Headroom proxy started on ${a.host}:${a.port}.`),await w()):l.error("Proxy start failed.")}catch(d){l.error(`Proxy start failed: ${d.message}`)}finally{u(!1)}},K=async()=>{j(!0);try{(await b.post("/headroom/proxy/stop")).ok?(l.success("Headroom proxy stopped."),await w()):l.error("Proxy stop failed.")}catch(d){l.error(`Proxy stop failed: ${d.message}`)}finally{j(!1)}},Z=async()=>{try{const{spawn:d}=await Ce(async()=>{const{spawn:V}=await import("./__vite-browser-external-BIHI7g3E.js");return{spawn:V}},[]);d("headroom",["dashboard"],{detached:!0,stdio:"ignore"})}catch{l.error("Could not open Headroom dashboard. Run `headroom dashboard` manually.")}},{installed:L,version:G,proxyRunning:D,proxyPort:Q,wrapped:A}=c||{},_=(m==null?void 0:m.compressionRatio)??0,H=(m==null?void 0:m.tokensSaved)??0;return e.jsx("div",{id:"settings-headroom","data-section":"headroom",children:e.jsxs(E,{children:[e.jsxs(B,{children:[e.jsx(me,{size:14,style:{color:D?"var(--success)":"var(--text-dim)"}}),"Headroom",L&&G&&e.jsxs("span",{style:{fontSize:11,color:"var(--text-dim)",marginLeft:6},children:["v",G," ",D?"✓":"✗"]}),!L&&e.jsx("span",{style:{fontSize:11,color:"var(--error)",marginLeft:6},children:"not installed"})]}),e.jsx(P,{children:"Context compression for token efficiency. Compresses tool outputs, logs, and conversation history by 60–95% before they reach the model."}),e.jsxs("div",{style:{display:"flex",gap:16,flexWrap:"wrap",marginTop:12,marginBottom:12},children:[e.jsxs("div",{className:"headroom-status-item",children:[L?e.jsx(q,{size:12,style:{color:"var(--success)"}}):e.jsx(ae,{size:12,style:{color:"var(--error)"}}),e.jsx("span",{children:L?"Installed":"Not installed"})]}),e.jsxs("div",{className:"headroom-status-item",children:[D?e.jsx(q,{size:12,style:{color:"var(--success)"}}):e.jsx(ae,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["Proxy ",D?`${Q} ✓`:"stopped"]})]}),e.jsxs("div",{className:"headroom-status-item",children:[A?e.jsx(q,{size:12,style:{color:"var(--success)"}}):e.jsx(ae,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["cline ",A?"wrapped":"not wrapped"]})]})]}),(H>0||_>0)&&e.jsxs("div",{style:{display:"flex",gap:24,marginBottom:12},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--success)"},children:_>0?`${Math.round(_*100)}%`:"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Compression ratio"})]}),e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:20,fontWeight:700,color:"var(--accent)"},children:H>0?H.toLocaleString():"—"}),e.jsx("div",{className:"muted",style:{fontSize:11},children:"Tokens saved (24h)"})]})]}),e.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:8},children:[L?e.jsxs(e.Fragment,{children:[e.jsxs(k,{variant:"secondary",size:"sm",onClick:$,disabled:g||A,title:A?"cline is already wrapped":"Wrap cline to route through Headroom proxy",children:[g?e.jsx("span",{className:"btn-spinner"}):e.jsx(Ve,{size:13}),g?"Wrapping…":A?"Wrapped ✓":"Wrap cline"]}),A&&e.jsxs(k,{variant:"ghost",size:"sm",onClick:U,disabled:S,children:[S?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:13}),S?"Unwrapping…":"Unwrap"]})]}):e.jsxs(k,{variant:"primary",size:"sm",onClick:M,disabled:h,children:[h?e.jsx("span",{className:"btn-spinner"}):e.jsx(Y,{size:13}),h?"Installing…":"Install Headroom"]}),L&&e.jsxs(e.Fragment,{children:[D?e.jsxs(k,{variant:"secondary",size:"sm",onClick:K,disabled:p,children:[p?e.jsx("span",{className:"btn-spinner"}):e.jsx(De,{size:13}),p?"Stopping…":"Stop proxy"]}):e.jsxs(k,{variant:"secondary",size:"sm",onClick:W,disabled:z,children:[z?e.jsx("span",{className:"btn-spinner"}):e.jsx(Ne,{size:13}),z?"Starting…":"Start proxy"]}),e.jsxs(k,{variant:"ghost",size:"sm",onClick:Z,children:[e.jsx(Ee,{size:13}),"Dashboard"]})]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:w,disabled:i,children:e.jsx(O,{size:13,className:i?"spin":""})})]}),e.jsxs("div",{style:{marginTop:16},children:[e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.enabled,onChange:d=>s({enabled:d.target.checked})}),e.jsx("span",{children:"Enable Headroom"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoInstall,onChange:d=>s({autoInstall:d.target.checked})}),e.jsx("span",{children:"Auto-install if missing on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoStart,onChange:d=>s({autoStart:d.target.checked})}),e.jsx("span",{children:"Auto-start proxy on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoWrap,onChange:d=>s({autoWrap:d.target.checked})}),e.jsx("span",{children:"Auto-wrap cline on dashboard startup"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.routeAllProviders,onChange:d=>s({routeAllProviders:d.target.checked})}),e.jsx("span",{children:"Route all providers through Headroom proxy"})]}),e.jsxs("div",{className:"task-form-row",style:{marginTop:12},children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy port"}),e.jsx("input",{type:"number",className:"input",value:a.port,min:1,max:65535,onChange:d=>s({port:Math.max(1,Math.min(65535,parseInt(d.target.value,10)||8787))})})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Proxy host"}),e.jsx("input",{type:"text",className:"input",value:a.host,onChange:d=>s({host:d.target.value})})]})]}),e.jsxs("div",{className:"task-form-row",children:[e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Backend"}),e.jsx("select",{className:"select",value:a.backend,onChange:d=>s({backend:d.target.value}),children:qe.map(d=>e.jsx("option",{value:d.value,children:d.label},d.value))})]}),e.jsxs("div",{className:"task-form-field",children:[e.jsx("label",{className:"field-label",children:"Monthly budget (USD)"}),e.jsx("input",{type:"number",className:"input",value:a.budget,min:0,step:1,onChange:d=>s({budget:Math.max(0,parseFloat(d.target.value)||0)})}),e.jsx("span",{className:"field-help",children:"0 = unlimited"})]})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.outputShaper,onChange:d=>s({outputShaper:d.target.checked})}),e.jsx("span",{children:"Enable output shaper"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.telemetry,onChange:d=>s({telemetry:d.target.checked})}),e.jsx("span",{children:"Enable telemetry"})]})]})]})})}const ue={enabled:!0,autoInstall:!0,port:8787,host:"127.0.0.1",outputShaper:!1,telemetry:!1,budget:0,backend:"anthropic",autoStart:!0,autoWrap:!0,routeAllProviders:!0};function os({settings:a,setSettings:s,setDirty:l}){return e.jsx(Oe,{settings:a.headroom||ue,onPatch:c=>{s(r=>({...r,headroom:{...r.headroom||ue,...c}})),l(!0)}})}function Fe(){const a=X(),[s,l]=o.useState([]),[c,r]=o.useState(new Set),[m,x]=o.useState(!0),[i,n]=o.useState(""),[h,y]=o.useState(!0),g=o.useCallback(async()=>{x(!0);try{const[u,p]=await Promise.all([b.get("/activity"),b.get("/activity/hidden")]);l(Array.isArray(u.items)?u.items:[]),r(new Set(p.hidden||[]))}catch(u){a.error(`Load failed: ${u.message}`)}finally{x(!1)}},[a]);o.useEffect(()=>{g()},[g]);const v=(u,p)=>{const j=`${u.kind||""}|${u.ts||""}|${u.slug||""}|${p}`;let w=0;for(let M=0;M<j.length;M++)w=(w<<5)-w+j.charCodeAt(M)|0;return Math.abs(w).toString(16).padStart(8,"0").slice(0,16)},S=async()=>{try{await b.del("/activity/hide"),r(new Set),a.success("All hidden activity restored.")}catch(u){a.error(`Restore failed: ${u.message}`)}},R=async u=>{try{await b.del(`/activity/hide/${encodeURIComponent(u)}`);const p=new Set(c);p.delete(u),r(p)}catch(p){a.error(`Restore failed: ${p.message}`)}},z=s.filter((u,p)=>{const j=v(u,p);if(!h&&c.has(j))return!1;if(!i)return!0;const w=i.toLowerCase();return[u.kind,u.slug,u.message].some(M=>typeof M=="string"&&M.toLowerCase().includes(w))});return e.jsxs(E,{id:"settings-activity-log","data-section":"activity-log",children:[e.jsxs(B,{children:[e.jsx(me,{size:14})," Activity log",e.jsxs("span",{className:"muted",style:{fontWeight:400,marginLeft:8,fontSize:12},children:[s.length," total · ",c.size," hidden"]}),e.jsx(k,{variant:"ghost",size:"sm",style:{marginLeft:"auto"},onClick:g,title:"Reload",children:e.jsx(O,{size:12})})]}),e.jsxs(P,{children:["Full history from ",e.jsx("code",{children:"~/.bizar/activity.log"}),". Hiding an item in the Overview only hides it there — the entry stays here."]}),e.jsxs("div",{className:"activity-log-toolbar",children:[e.jsxs("div",{className:"activity-log-search",children:[e.jsx(ne,{size:12}),e.jsx("input",{type:"text",className:"input",placeholder:"Filter by kind, slug, or message…",value:i,onChange:u=>n(u.target.value)})]}),e.jsxs("label",{className:"activity-log-toggle",children:[e.jsx("input",{type:"checkbox",checked:h,onChange:u=>y(u.target.checked)}),"Show hidden"]}),e.jsxs(k,{variant:"ghost",size:"sm",disabled:c.size===0,onClick:S,title:"Restore all hidden items to the Overview",children:[e.jsx(re,{size:12})," Restore all"]})]}),m?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:"Loading…"}):z.length===0?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:s.length===0?"No activity yet.":"No items match the current filter."}):e.jsxs("div",{className:"activity-log-table-wrap",children:[e.jsxs("table",{className:"activity-log-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Kind"}),e.jsx("th",{children:"Detail"}),e.jsx("th",{children:"Time"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:z.slice(0,200).map((u,p)=>{const j=v(u,p),w=c.has(j);return e.jsxs("tr",{className:T(w&&"activity-log-row-hidden"),children:[e.jsx("td",{className:"activity-log-kind",children:u.kind||"activity"}),e.jsx("td",{className:"activity-log-detail",children:u.message||u.slug||"—"}),e.jsx("td",{className:"activity-log-time mono",children:u.ts?new Date(u.ts).toLocaleString():"—"}),e.jsx("td",{children:w?e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>R(j),title:"Restore to Overview",children:e.jsx(re,{size:12})}):e.jsx("span",{className:"activity-log-state-tag",children:"shown"})})]},`${u.ts}-${p}`)})})]}),z.length>200&&e.jsxs("div",{className:"muted",style:{fontSize:11,padding:"8px 0"},children:["Showing first 200 of ",z.length,"."]})]})]})}function We({about:a}){return e.jsxs(E,{id:"settings-about","data-section":"about",children:[e.jsxs(B,{children:[e.jsx(Le,{size:14})," About"]}),e.jsx(P,{children:"Build metadata."}),e.jsxs("dl",{className:"about-table",children:[e.jsx("dt",{children:"Version"}),e.jsx("dd",{className:"mono",children:(a==null?void 0:a.version)||"—"}),e.jsx("dt",{children:"Homepage"}),e.jsx("dd",{children:e.jsx("a",{href:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness",target:"_blank",rel:"noopener noreferrer",children:(a==null?void 0:a.homepage)||"https://github.com/DrB0rk/BizarHarness"})}),e.jsx("dt",{children:"License"}),e.jsx("dd",{children:(a==null?void 0:a.license)||"MIT"})]})]})}function ds({about:a}){return e.jsxs(e.Fragment,{children:[e.jsx(Fe,{}),e.jsx(We,{about:a})]})}function Ke({onError:a}){const s=X(),[l,c]=o.useState([]),[r,m]=o.useState(!1),[x,i]=o.useState(!1),[n,h]=o.useState(new Set),[y,g]=o.useState(null),[v,S]=o.useState(""),[R,z]=o.useState(!1),[u,p]=o.useState(""),[j,w]=o.useState(""),[M,$]=o.useState(!1),[U,W]=o.useState(""),[K,Z]=o.useState(!1),[L,G]=o.useState(""),[D,Q]=o.useState(new Set),A=o.useCallback(async()=>{m(!0);try{const t=await b.get("/env-vars");c(t)}catch(t){s.error(`Load failed: ${t.message}`),a==null||a(t.message)}finally{m(!1)}},[s,a]);o.useEffect(()=>{A()},[A]);const _=t=>{h(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},H=async()=>{const t=u.trim().toUpperCase(),N=j.trim();if(!t||!/^BIZAR_[A-Z0-9_]+$/.test(t)){s.warning("Name must match BIZAR_<NAME> (e.g. BIZAR_MINIMAX_KEY)");return}if(!N){s.warning("Value is required.");return}if(l.some(f=>f.name===t)){s.warning(`${t} already exists.`);return}i(!0);try{await b.post("/env-vars",{name:t,value:N}),s.success(`${t} created.`),z(!1),p(""),w(""),await A()}catch(f){s.error(`Create failed: ${f.message}`)}finally{i(!1)}},d=t=>{g(t.name),S(t.value===t.value.replace(/\*/g,"")?t.value:""),h(N=>{const f=new Set(N);return f.add(t.name),f})},V=async t=>{if(!v.trim()){s.warning("Value cannot be empty.");return}i(!0);try{await b.put(`/env-vars/${encodeURIComponent(t)}`,{value:v.trim()}),s.success(`${t} updated.`),g(null),await A()}catch(N){s.error(`Update failed: ${N.message}`)}finally{i(!1)}},le=async t=>{if(confirm(`Delete ${t}? This cannot be undone.`))try{await b.del(`/env-vars/${encodeURIComponent(t)}`),s.success(`${t} deleted.`),await A()}catch(N){s.error(`Delete failed: ${N.message}`)}},ge=async()=>{if(!U.trim()){s.warning("Nothing to import.");return}Z(!0);try{const t=await b.post("/env-vars/bulk-import",{envContent:U});s.success(`Imported ${t.imported}, skipped ${t.skipped}.`),t.errors.length>0&&s.warning(`${t.errors.length} lines had errors: ${t.errors.slice(0,3).join("; ")}${t.errors.length>3?"…":""}`),W(""),$(!1),await A()}catch(t){s.error(`Bulk import failed: ${t.message}`)}finally{Z(!1)}},je=async()=>{try{const t=await b.get("/env-vars/export"),N=new Blob([t],{type:"text/plain"}),f=URL.createObjectURL(N),I=document.createElement("a");I.href=f,I.download=".env",I.click(),URL.revokeObjectURL(f),s.success("Exported .env file.")}catch(t){s.error(`Export failed: ${t.message}`)}},F=o.useMemo(()=>{if(!L.trim())return l;const t=L.toLowerCase();return l.filter(N=>N.name.toLowerCase().includes(t))},[l,L]),J=o.useMemo(()=>{const t={};for(const N of F){const f=N.name.split("_")[0]+"_";(t[f]??(t[f]=[])).push(N)}return t},[F]),fe=t=>{Q(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},ie=o.useMemo(()=>{const t=["BIZAR_","PROVIDER_","MODEL_","API_"];return Object.keys(J).sort((f,I)=>{const ee=t.indexOf(f),se=t.indexOf(I);return ee===-1&&se===-1?f.localeCompare(I):ee===-1?1:se===-1?-1:ee-se})},[J]);if(r)return e.jsx("div",{className:"muted",style:{padding:"16px 0",fontSize:13},children:"Loading env vars…"});const ve=ie.length>1;return e.jsxs("div",{className:"env-var-manager",children:[e.jsxs("div",{className:"env-var-toolbar",children:[e.jsxs(k,{variant:"primary",size:"sm",onClick:()=>z(!0),children:[e.jsx(ze,{size:12})," New variable"]}),e.jsxs(k,{variant:"secondary",size:"sm",onClick:()=>$(t=>!t),className:M?"active":"",children:[e.jsx(He,{size:12})," Bulk import"]}),e.jsxs(k,{variant:"ghost",size:"sm",onClick:je,title:"Export as .env",children:[e.jsx(Y,{size:12})," Export"]}),e.jsxs("div",{className:"env-var-search-wrap",children:[e.jsx(ne,{size:12,className:"env-var-search-icon"}),e.jsx("input",{className:"env-var-search input",placeholder:"Filter…",value:L,onChange:t=>G(t.target.value)})]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:A,title:"Reload",children:e.jsx(O,{size:12})})]}),M&&e.jsxs("div",{className:"env-var-bulk-panel",children:[e.jsxs("div",{className:"env-var-bulk-header",children:[e.jsxs("span",{children:["Paste ",e.jsx("code",{children:"KEY=value"})," lines (one per line):"]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>$(!1),children:e.jsx(ce,{size:12})})]}),e.jsx("textarea",{className:"input mono env-var-bulk-textarea",placeholder:`BIZAR_API_KEY=your-key-here
|
|
113
|
+
PROVIDER_OPENAI_KEY=sk-...
|
|
114
|
+
MODEL_KEY=gem-...`,value:U,onChange:t=>W(t.target.value),rows:6}),e.jsxs("div",{className:"env-var-bulk-footer",children:[e.jsx(k,{variant:"primary",size:"sm",onClick:ge,disabled:K||!U.trim(),children:K?"Importing…":"Import"}),e.jsx("span",{className:"muted",style:{fontSize:11},children:"Existing keys are skipped unless re-created individually. Invalid lines are reported."})]})]}),l.length===0&&!R&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(ye,{size:20}),e.jsx("span",{children:"No BIZAR_* env vars yet."}),e.jsx("span",{style:{fontSize:11},children:"Create one to store API keys securely."})]}),R&&e.jsxs("div",{className:"env-var-add-form",children:[e.jsxs("div",{className:"env-var-add-row",children:[e.jsx("input",{className:"input mono",style:{width:240},placeholder:"BIZAR_NAME",value:u,onChange:t=>p(t.target.value.toUpperCase()),onKeyDown:t=>{t.key==="Enter"&&H(),t.key==="Escape"&&z(!1)},autoFocus:!0}),e.jsx("input",{className:"input mono",type:"password",placeholder:"value (API key, token, etc.)",value:j,onChange:t=>w(t.target.value),onKeyDown:t=>{t.key==="Enter"&&H(),t.key==="Escape"&&z(!1)}}),e.jsxs(k,{variant:"primary",size:"sm",onClick:H,disabled:x,children:[e.jsx(q,{size:12})," Create"]}),e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>{z(!1),p(""),w("")},children:e.jsx(ce,{size:12})})]}),e.jsxs("p",{style:{fontSize:11,color:"var(--text-dim)",margin:0},children:["Names must match ",e.jsxs("code",{children:["BIZAR_",e.jsx("var",{children:"NAME"})]})," (uppercase letters, digits, underscores)."]})]}),F.length>0&&(ve?e.jsx("div",{className:"env-var-groups",children:ie.map(t=>{const N=J[t],f=D.has(t);return e.jsxs("div",{className:"env-var-group",children:[e.jsxs("button",{type:"button",className:"env-var-group-header",onClick:()=>fe(t),children:[f?e.jsx(Se,{size:12}):e.jsx(Re,{size:12}),e.jsx("span",{className:"env-var-group-prefix mono",children:t}),e.jsxs("span",{className:"env-var-group-count muted",children:["(",N.length,")"]})]}),!f&&e.jsx("div",{className:"env-var-list",children:N.map(I=>e.jsx(pe,{v:I,editing:y,editValue:v,isRevealed:n.has(I.name),onToggleReveal:_,onStartEdit:d,onEditValueChange:S,onHandleUpdate:V,onCancelEdit:()=>g(null),onDelete:le,saving:x},I.name))})]},t)})}):e.jsx("div",{className:"env-var-list",children:F.map(t=>e.jsx(pe,{v:t,editing:y,editValue:v,isRevealed:n.has(t.name),onToggleReveal:_,onStartEdit:d,onEditValueChange:S,onHandleUpdate:V,onCancelEdit:()=>g(null),onDelete:le,saving:x},t.name))})),F.length===0&&l.length>0&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(ne,{size:16}),e.jsxs("span",{children:['No env vars match "',L,'"']})]})]})}function pe({v:a,editing:s,editValue:l,isRevealed:c,onToggleReveal:r,onStartEdit:m,onEditValueChange:x,onHandleUpdate:i,onCancelEdit:n,onDelete:h,saving:y}){const g=s===a.name;return e.jsxs("div",{className:T("env-var-row",g&&"env-var-row-editing"),children:[e.jsx("span",{className:"env-var-name mono",children:a.name}),g?e.jsx("input",{className:"input mono",type:"password",style:{flex:1,minWidth:200},value:l,onChange:v=>x(v.target.value),onKeyDown:v=>{v.key==="Enter"&&i(a.name),v.key==="Escape"&&n()},autoFocus:!0}):e.jsx("span",{className:T("env-var-value mono",!c&&"env-var-value-masked"),children:a.value}),e.jsx("span",{className:"env-var-source muted",children:a.source}),e.jsxs("div",{className:"env-var-actions",children:[!g&&e.jsx("button",{type:"button",className:"icon-btn",title:c?"Hide":"Reveal",onClick:()=>r(a.name),children:c?e.jsx(Be,{size:12}):e.jsx(re,{size:12})}),g?e.jsxs(e.Fragment,{children:[e.jsx(k,{variant:"primary",size:"sm",onClick:()=>i(a.name),disabled:y,children:"Save"}),e.jsx(k,{variant:"ghost",size:"sm",onClick:n,children:"Cancel"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"icon-btn",title:"Edit",onClick:()=>m(a),children:e.jsx(Me,{size:12})}),e.jsx("button",{type:"button",className:"icon-btn icon-btn-danger",title:"Delete",onClick:()=>h(a.name),children:e.jsx(Ae,{size:12})})]})]})]})}function hs(){return e.jsxs(E,{id:"settings-env-vars","data-section":"env-vars",children:[e.jsxs(B,{children:[e.jsx(ye,{size:14})," Environment Variables"]}),e.jsxs(P,{children:["Manage BIZAR_* env vars (API keys, secrets). Values are stored in ",e.jsx("code",{children:"~/.config/bizar/env.json"})," (mode 0600)."]}),e.jsx(Ke,{})]})}export{he as A,Xe as B,Qe as C,Y as D,Ee as E,Je as F,es as G,os as H,ye as K,as as L,de as P,ts as S,is as T,rs as U,Ve as Z,k as a,Ie as b,ns as c,E as d,B as e,P as f,Be as g,re as h,ae as i,ss as j,ls as k,hs as l,cs as m,ds as n,He as o,De as p};
|