@polderlabs/bizar 6.2.5 → 6.3.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.
- package/.claude/CLAUDE.md +15 -0
- package/.claude/agents/_shared/AGENT_BASELINE.md +168 -0
- package/.claude/agents/_shared/CLAUDE_TOOLS.md +412 -0
- package/.claude/agents/_shared/SKILLS.md +109 -0
- package/.claude/agents/agent-browser.md +80 -0
- package/.claude/agents/baldr.md +49 -0
- package/.claude/agents/forseti.md +51 -0
- package/.claude/agents/frigg.md +42 -0
- package/.claude/agents/heimdall.md +33 -0
- package/.claude/agents/hermod.md +53 -0
- package/.claude/agents/mimir.md +49 -0
- package/.claude/agents/odin.md +287 -0
- package/.claude/agents/quick.md +34 -0
- package/.claude/agents/semble-search.md +50 -0
- package/.claude/agents/thor.md +53 -0
- package/.claude/agents/tyr.md +56 -0
- package/.claude/agents/vidarr.md +54 -0
- package/.claude/agents/vor.md +53 -0
- package/.claude/commands/audit.md +25 -0
- package/.claude/commands/bizar.md +22 -0
- package/.claude/commands/explain.md +17 -0
- package/.claude/commands/init.md +29 -0
- package/.claude/commands/learn.md +44 -0
- package/.claude/commands/plan.md +35 -0
- package/.claude/commands/plow-through.md +50 -0
- package/.claude/commands/pr-review.md +49 -0
- package/.claude/commands/setup-provider.md +96 -0
- package/.claude/commands/tailscale-serve.md +100 -0
- package/.claude/commands/team.md +132 -0
- package/.claude/commands/test.md +62 -0
- package/.claude/commands/validate.md +68 -0
- package/.claude/commands/visual-plan.md +24 -0
- package/.claude/hooks/README.md +92 -0
- package/.claude/hooks/posttooluse-editwrite.mjs +91 -0
- package/.claude/hooks/pretooluse-bash.mjs +81 -0
- package/.claude/hooks/pretooluse-editwrite.mjs +139 -0
- package/.claude/hooks/sessionend-recall.mjs +74 -0
- package/.claude/hooks/sessionstart-prime.mjs +80 -0
- package/.claude/hooks/userpromptsubmit-tag.mjs +80 -0
- package/.claude/settings.json +116 -0
- package/.claude/skills/9router/SKILL.md +80 -0
- package/.claude/skills/9router-chat/SKILL.md +73 -0
- package/.claude/skills/9router-embeddings/SKILL.md +69 -0
- package/.claude/skills/9router-image/SKILL.md +86 -0
- package/.claude/skills/9router-stt/SKILL.md +79 -0
- package/.claude/skills/9router-tts/SKILL.md +80 -0
- package/.claude/skills/9router-web-fetch/SKILL.md +99 -0
- package/.claude/skills/9router-web-search/SKILL.md +91 -0
- package/.claude/skills/bizar/README.md +9 -0
- package/.claude/skills/bizar/SKILL.md +450 -0
- package/.claude/skills/cpp-coding-standards/README.md +28 -0
- package/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
- package/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
- package/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
- package/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
- package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
- package/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
- package/.claude/skills/cpp-testing/README.md +28 -0
- package/.claude/skills/cpp-testing/SKILL.md +304 -0
- package/.claude/skills/cpp-testing/references/coverage.md +370 -0
- package/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
- package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
- package/.claude/skills/cpp-testing/references/mocking.md +364 -0
- package/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
- package/.claude/skills/cubesandbox/SKILL.md +148 -0
- package/.claude/skills/embedded-esp-idf/README.md +41 -0
- package/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
- package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
- package/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
- package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
- package/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
- package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
- package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
- package/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
- package/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
- package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
- package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
- package/.claude/skills/glyph/SKILL.md +163 -0
- package/.claude/skills/harness-engineering/SKILL.md +143 -0
- package/.claude/skills/lightrag/SKILL.md +81 -0
- package/.claude/skills/memory-protocol/SKILL.md +105 -0
- package/.claude/skills/obsidian/SKILL.md +306 -0
- package/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
- package/.claude/skills/self-improvement/SKILL.md +64 -0
- package/README.md +87 -59
- package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js → EnvVarsSection-B58aiJiE.js} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js.map → EnvVarsSection-B58aiJiE.js.map} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js → MobileChat-BJrqwVDd.js} +1 -1
- package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js.map → MobileChat-BJrqwVDd.js.map} +1 -1
- package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js → MobileSettings-CEQNJNLJ.js} +1 -1
- package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js.map → MobileSettings-CEQNJNLJ.js.map} +1 -1
- package/bizar-dash/dist/assets/{main-DYiZqMrn.js → main-IvfQAOfy.js} +1 -1
- package/bizar-dash/dist/assets/{main-DYiZqMrn.js.map → main-IvfQAOfy.js.map} +1 -1
- package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js → markdown-tOLaD6nm.js} +1 -1
- package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js.map → markdown-tOLaD6nm.js.map} +1 -1
- package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js → mobile-DYCHcUpq.js} +1 -1
- package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js.map → mobile-DYCHcUpq.js.map} +1 -1
- package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js → mobile-layout-CBHjpwsb.js} +2 -2
- package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js.map → mobile-layout-CBHjpwsb.js.map} +1 -1
- package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js → useSlashCommands-Bd7_FA6U.js} +2 -2
- package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js.map → useSlashCommands-Bd7_FA6U.js.map} +1 -1
- package/bizar-dash/dist/assets/{vendor-CeHGtduv.js → vendor-C843201K.js} +12 -12
- package/bizar-dash/dist/assets/vendor-C843201K.js.map +1 -0
- package/bizar-dash/dist/index.html +6 -6
- package/bizar-dash/dist/mobile.html +2 -2
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/api.mjs +4 -4
- package/bizar-dash/src/server/background-store.mjs +15 -16
- package/bizar-dash/src/server/bg-poller.mjs +25 -35
- package/bizar-dash/src/server/bg-retry.mjs +66 -194
- package/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
- package/bizar-dash/src/server/claude-info.mjs +412 -0
- package/bizar-dash/src/server/{cline-runner.mjs → claude-runner.mjs} +53 -48
- package/bizar-dash/src/server/claude-sdk.mjs +191 -0
- package/bizar-dash/src/server/providers-store.mjs +22 -49
- package/bizar-dash/src/server/routes/background.mjs +24 -20
- package/bizar-dash/src/server/routes/chat.mjs +223 -326
- package/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
- package/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
- package/bizar-dash/src/server/routes/tasks.mjs +20 -28
- package/bizar-dash/src/server/task-delegator.mjs +76 -77
- package/bizar-dash/src/web/components/chat/useChat.ts +23 -27
- package/bizar-dash/src/web/views/Chat.tsx +8 -8
- package/cli/bin.mjs +17 -18
- package/cli/commands/claude-cmd.mjs +348 -0
- package/cli/commands/install.mjs +12 -11
- package/cli/commands/validate.mjs +252 -325
- package/cli/dev-link.test.mjs +11 -11
- package/cli/doctor.mjs +131 -213
- package/cli/install.mjs +33 -37
- package/cli/install.test.mjs +9 -9
- package/cli/provision-claude.mjs +893 -0
- package/cli/provision.mjs +224 -227
- package/cli/utils.mjs +72 -58
- package/config/AGENTS.md +28 -28
- package/install.sh +66 -44
- package/package.json +19 -11
- package/packages/sdk/ARCHITECTURE.md +40 -36
- package/packages/sdk/package-lock.json +32 -0
- package/packages/sdk/package.json +15 -5
- package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
- package/packages/sdk/src/fingerprint.ts +0 -0
- package/packages/sdk/src/index.ts +38 -73
- package/packages/sdk/src/mcp/bin.ts +51 -0
- package/packages/sdk/src/mcp/server.ts +498 -0
- package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
- package/packages/sdk/tests/sdk.test.mjs +148 -0
- package/packages/sdk/vitest.config.ts +1 -1
- package/scripts/bh-full-e2e.mjs +166 -363
- package/scripts/check-deps.mjs +28 -46
- package/scripts/mirror-claude-md.sh +78 -0
- package/scripts/test-in-container.sh +31 -9
- package/templates/clean-state-checklist.md +3 -3
- package/templates/sprint-contract.md +2 -2
- package/bizar-dash/.bizar/activity.log +0 -3
- package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
- package/bizar-dash/.omx/state/session.json +0 -10
- package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
- package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
- package/bizar-dash/bizar-design/canvas.html +0 -281
- package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/components.css +0 -1665
- package/bizar-dash/bizar-design/components.html +0 -557
- package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/agents.html +0 -74
- package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/memory.html +0 -75
- package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
- package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/overview.html +0 -95
- package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/desktop/settings.html +0 -70
- package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/icons.svg +0 -44
- package/bizar-dash/bizar-design/index.html +0 -192
- package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/agents.html +0 -29
- package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/memory.html +0 -28
- package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
- package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/overview.html +0 -33
- package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/mobile/settings.html +0 -28
- package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
- package/bizar-dash/bizar-design/prototype.js +0 -114
- package/bizar-dash/bizar-design/tokens.css +0 -106
- package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
- package/bizar-dash/node_modules/.package-lock.json +0 -6
- package/bizar-dash/package-lock.json +0 -6
- package/bizar-dash/src/server/cline-sdk.mjs +0 -132
- package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
- package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
- package/cli/commands/cline-cmd.mjs +0 -289
- package/cli/commands/validate.test.mjs +0 -379
- package/cli/doctor.test.mjs +0 -350
- package/config/cline.json.template +0 -342
- package/packages/sdk/src/client.ts +0 -188
- package/packages/sdk/src/cline-events.ts +0 -134
- package/packages/sdk/src/cline-types.ts +0 -66
- package/packages/sdk/src/cline.ts +0 -339
- package/packages/sdk/src/errors.ts +0 -129
- package/packages/sdk/src/events.ts +0 -153
- package/packages/sdk/src/types.ts +0 -176
- package/packages/sdk/tests/client.test.ts +0 -217
- package/packages/sdk/tests/errors.test.ts +0 -108
- package/packages/sdk/tests/events.test.ts +0 -139
- package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
- package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
- package/plugins/bizar/ARCHITECTURE.md +0 -142
- package/plugins/bizar/CONSTRAINTS.md +0 -67
- package/plugins/bizar/LICENSE +0 -21
- package/plugins/bizar/README.md +0 -448
- package/plugins/bizar/index.ts +0 -925
- package/plugins/bizar/package.json +0 -39
- package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
- package/plugins/bizar/src/background-state.ts +0 -641
- package/plugins/bizar/src/background.ts +0 -1806
- package/plugins/bizar/src/cline-runner.ts +0 -203
- package/plugins/bizar/src/clineruntime.ts +0 -227
- package/plugins/bizar/src/commands-impl.ts +0 -151
- package/plugins/bizar/src/commands.ts +0 -1799
- package/plugins/bizar/src/compaction.d.mts +0 -48
- package/plugins/bizar/src/compaction.mjs +0 -192
- package/plugins/bizar/src/dashboard-client.ts +0 -233
- package/plugins/bizar/src/event-stream.ts +0 -606
- package/plugins/bizar/src/fingerprint.ts +0 -120
- package/plugins/bizar/src/handoff.ts +0 -79
- package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
- package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
- package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
- package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
- package/plugins/bizar/src/http-client.ts +0 -467
- package/plugins/bizar/src/key-rotation.ts +0 -218
- package/plugins/bizar/src/logger.ts +0 -144
- package/plugins/bizar/src/loop-engineering.ts +0 -241
- package/plugins/bizar/src/loop.ts +0 -176
- package/plugins/bizar/src/mistake-recovery.ts +0 -98
- package/plugins/bizar/src/odin.ts +0 -227
- package/plugins/bizar/src/options.ts +0 -470
- package/plugins/bizar/src/plan-fs.ts +0 -323
- package/plugins/bizar/src/reasoning-clean.ts +0 -454
- package/plugins/bizar/src/report.ts +0 -178
- package/plugins/bizar/src/research-prompt.ts +0 -35
- package/plugins/bizar/src/serve-info.ts +0 -228
- package/plugins/bizar/src/serve.ts +0 -496
- package/plugins/bizar/src/settings.ts +0 -349
- package/plugins/bizar/src/state.ts +0 -298
- package/plugins/bizar/src/tool-discipline.ts +0 -105
- package/plugins/bizar/src/tools/agent-browser.ts +0 -315
- package/plugins/bizar/src/tools/bg-collect.ts +0 -131
- package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
- package/plugins/bizar/src/tools/bg-kill.ts +0 -116
- package/plugins/bizar/src/tools/bg-pause.ts +0 -99
- package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
- package/plugins/bizar/src/tools/bg-resume.ts +0 -94
- package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
- package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
- package/plugins/bizar/src/tools/bg-status.ts +0 -130
- package/plugins/bizar/src/tools/graph-query.ts +0 -278
- package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
- package/plugins/bizar/src/tools/memory-list.ts +0 -43
- package/plugins/bizar/src/tools/memory-read.ts +0 -69
- package/plugins/bizar/src/tools/memory-search.ts +0 -47
- package/plugins/bizar/src/tools/memory-write.ts +0 -54
- package/plugins/bizar/src/tools/open-kb.ts +0 -198
- package/plugins/bizar/src/tools/plan-action.ts +0 -785
- package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
- package/plugins/bizar/src/tools/sandbox.ts +0 -232
- package/plugins/bizar/src/tools/team-spawn.ts +0 -73
- package/plugins/bizar/src/tools/team-status.ts +0 -76
- package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
- package/plugins/bizar/src/trajectory.ts +0 -104
- package/plugins/bizar/tests/README.md +0 -99
- package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
- package/plugins/bizar/tests/background-state.test.ts +0 -277
- package/plugins/bizar/tests/background.test.ts +0 -402
- package/plugins/bizar/tests/block.test.ts +0 -195
- package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
- package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
- package/plugins/bizar/tests/commands-impl.test.ts +0 -316
- package/plugins/bizar/tests/commands.test.ts +0 -584
- package/plugins/bizar/tests/compaction.test.ts +0 -264
- package/plugins/bizar/tests/config.test.ts +0 -128
- package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
- package/plugins/bizar/tests/dispose.test.ts +0 -336
- package/plugins/bizar/tests/event-stream.test.ts +0 -409
- package/plugins/bizar/tests/event.test.ts +0 -262
- package/plugins/bizar/tests/fingerprint.test.ts +0 -190
- package/plugins/bizar/tests/http-client.test.ts +0 -404
- package/plugins/bizar/tests/init-helpers.test.ts +0 -203
- package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
- package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
- package/plugins/bizar/tests/key-rotation.test.ts +0 -396
- package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
- package/plugins/bizar/tests/loop.test.ts +0 -397
- package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
- package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
- package/plugins/bizar/tests/odin.test.ts +0 -125
- package/plugins/bizar/tests/options.test.ts +0 -329
- package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
- package/plugins/bizar/tests/safety.test.ts +0 -281
- package/plugins/bizar/tests/serve.test.ts +0 -339
- package/plugins/bizar/tests/settings.test.ts +0 -351
- package/plugins/bizar/tests/stall-think.test.ts +0 -750
- package/plugins/bizar/tests/state.test.ts +0 -276
- package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
- package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
- package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
- package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
- package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
- package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
- package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
- package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
- package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
- package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
- package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
- package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
- package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
- package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
- package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
- package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
- package/plugins/bizar/tests/tools/sandbox.test.ts +0 -117
- package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
- package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
- package/plugins/bizar/tsconfig.json +0 -29
- package/scripts/mirror-agents-md.sh +0 -69
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# BizarHarness ᛟ
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Claude Code-native multi-agent coding harness with a closed learning loop.**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
14 agents across 5 cost tiers. Odin routes, subagents execute, Forseti audits.
|
|
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
|
+
[](https://docs.claude.com/claude-code)
|
|
13
13
|
[](https://github.com/DrB0rk/BizarHarness)
|
|
14
14
|
[](docs/INDEX.md)
|
|
15
15
|
[](docs/safety.md)
|
|
@@ -26,7 +26,7 @@ ClineCore in-process — no subprocess, no port, no serve-info file.
|
|
|
26
26
|
|
|
27
27
|
## Table of Contents
|
|
28
28
|
|
|
29
|
-
- [What's new in v6.
|
|
29
|
+
- [What's new in v6.3.0](#-whats-new-in-v630)
|
|
30
30
|
- [Quick start](#-quick-start)
|
|
31
31
|
- [The Pantheon](#-the-pantheon)
|
|
32
32
|
- [Architecture](#-architecture)
|
|
@@ -37,43 +37,53 @@ ClineCore in-process — no subprocess, no port, no serve-info file.
|
|
|
37
37
|
- [Knowledge Graph Tools](#-knowledge-graph-tools)
|
|
38
38
|
- [Harness engineering audit (73/73)](#-harness-engineering-audit-7373)
|
|
39
39
|
- [Documentation](#-documentation)
|
|
40
|
-
- [Migration from
|
|
40
|
+
- [Migration from v6.2.x (Cline era)](#-migration-from-v62x-cline-era)
|
|
41
|
+
- [Historical: OpenCode → Cline (v5.6/v6.0)](#-historical-opencode--cline-v56v60)
|
|
41
42
|
- [Contributing](#-contributing)
|
|
42
43
|
- [License](#-license)
|
|
43
44
|
|
|
44
45
|
---
|
|
45
46
|
|
|
46
|
-
## ✨ What's new in v6.
|
|
47
|
+
## ✨ What's new in v6.3.0
|
|
47
48
|
|
|
48
|
-
v6.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
v6.3.0 is a **complete migration** from Cline to Claude Code. The plugin
|
|
50
|
+
framework that previously lived as a Cline `AgentPlugin` is now expressed
|
|
51
|
+
as Claude Code skills + MCP servers + `.claude/agents/` definitions.
|
|
52
|
+
Claude Code's Agent SDK (`@anthropic-ai/claude-agent-sdk`) is embedded
|
|
53
|
+
in-process — no subprocess spawn, no port, no password, no serve-info
|
|
54
|
+
file. Hooks execute in Claude Code's event loop; mistake recovery uses
|
|
55
|
+
the Agent SDK's `onConsecutiveMistakeLimitReached`; subagent dispatch
|
|
56
|
+
uses the Claude Code `Agent` tool.
|
|
52
57
|
|
|
53
58
|
| Feature | Description |
|
|
54
59
|
| --- | --- |
|
|
55
|
-
| **
|
|
56
|
-
| **22 tools, 4 hooks** | All use `
|
|
57
|
-
| **
|
|
58
|
-
| **
|
|
59
|
-
| **
|
|
60
|
+
| **Claude Code-native hooks** | `PreToolUse` / `PostToolUse` / `UserPromptSubmit` / `SessionStart` / `SessionEnd` — typed payloads, idiomatic Claude Code shape. |
|
|
61
|
+
| **22 tools, 4 hooks** | All use Claude Code `MCP tool registration`. 0 compat shims. |
|
|
62
|
+
| **Skills + MCP** | `.claude/skills/<name>/SKILL.md` (auto-loaded) + `.claude/mcp.json` (Semble, Bizar memory, CubeSandbox). Replaces the previous "plugin" surface. |
|
|
63
|
+
| **Agent dispatch** | Subagents dispatched via the Claude Code `Agent` tool with `run_in_background: true`. The previous `bizar_spawn_team` tool is now `Agent` with `agent_team: "<name>"`. |
|
|
64
|
+
| **Knowledge graph tools** | `bizar_graph_query/path/explain` over `.bizar/graph/graph.json` (still file-based; unchanged). |
|
|
65
|
+
| **DANGEROUS_PATTERNS gate** | 36 patterns (25 deny + 11 require-approval) checked in `PreToolUse`. |
|
|
60
66
|
| **Skill curator** | Per-skill use/failure tracking. The differentiator (1/106 projects). |
|
|
61
67
|
| **Pre-compaction memory flush** | Durable snapshot before summarizer. Closes the durability gap. |
|
|
62
68
|
| **In-process memory vault** | Tools read/write `~/.bizar_memory/` directly. No dashboard needed. |
|
|
63
69
|
| **Harness audit 73/73** | Full L01–L12 compliance. `make check-arch` enforces 7 rules. |
|
|
64
|
-
| **Removed:
|
|
70
|
+
| **Removed: plugin layer** | The `plugins/bizar/` plugin entry is now a Claude Code MCP server — skills do the rest. v6.0.0–v6.2.5. |
|
|
65
71
|
|
|
66
|
-
See the full [CHANGELOG.md](CHANGELOG.md) for
|
|
72
|
+
See the full [CHANGELOG.md](CHANGELOG.md) for v6.0.0 → v6.3.0 history.
|
|
67
73
|
|
|
68
74
|
---
|
|
69
75
|
|
|
70
76
|
## 🚀 Quick start
|
|
71
77
|
|
|
78
|
+
Prerequisites: **Claude Code CLI** (`claude` on `PATH`; install via
|
|
79
|
+
`npm install -g @anthropic-ai/claude-code` or follow
|
|
80
|
+
[the Claude Code install docs](https://docs.claude.com/claude-code/getting-started)).
|
|
81
|
+
|
|
72
82
|
```bash
|
|
73
|
-
# Install (stable
|
|
83
|
+
# Install (stable v6.3.0)
|
|
74
84
|
npm install @polderlabs/bizar
|
|
75
85
|
|
|
76
|
-
# Or try the
|
|
86
|
+
# Or try the latest beta
|
|
77
87
|
npm install @polderlabs/bizar@beta
|
|
78
88
|
|
|
79
89
|
# Run
|
|
@@ -83,8 +93,9 @@ npx bizar
|
|
|
83
93
|
The installer handles:
|
|
84
94
|
|
|
85
95
|
- Cloning the dashboard repo
|
|
86
|
-
-
|
|
87
|
-
|
|
96
|
+
- Installing Bizar skills + agents + commands to `.claude/`
|
|
97
|
+
(`skills/`, `agents/`, `commands/`, `hooks/`)
|
|
98
|
+
- Configuring Semble (code search MCP) and Skills CLI
|
|
88
99
|
- Headroom (token-saving proxy)
|
|
89
100
|
|
|
90
101
|
If you'd rather install manually, see
|
|
@@ -113,8 +124,8 @@ If you'd rather install manually, see
|
|
|
113
124
|
|
|
114
125
|
Odin is the only primary agent. Every request hits him first. He
|
|
115
126
|
**never executes work** — he decomposes into parallel streams and
|
|
116
|
-
dispatches to subagents
|
|
117
|
-
(Tyr, Vidarr) before execution.
|
|
127
|
+
dispatches to subagents via the Claude Code `Agent` tool. The Forseti
|
|
128
|
+
gate audits all Tier 4/5 work (Tyr, Vidarr) before execution.
|
|
118
129
|
|
|
119
130
|
See [plugins/bizar/ARCHITECTURE.md](plugins/bizar/ARCHITECTURE.md) for
|
|
120
131
|
the full agent roster and routing rules.
|
|
@@ -128,27 +139,30 @@ the full agent roster and routing rules.
|
|
|
128
139
|
│ Layer 1: UI (bizar-dash/) │
|
|
129
140
|
│ - React + TypeScript dashboard (17 tabs) │
|
|
130
141
|
│ - Express server (HTTP + WS) │
|
|
131
|
-
│ - In-process
|
|
142
|
+
│ - In-process Claude Code Agent SDK (no daemon / no subprocess) │
|
|
132
143
|
│ - Harness engineering dashboard view │
|
|
133
144
|
│ - Kanban board (5 columns + backlog) │
|
|
134
145
|
└────────────────────────────────────────────────────────────────────┘
|
|
135
146
|
↕ HTTP REST + WebSocket
|
|
136
147
|
┌────────────────────────────────────────────────────────────────────┐
|
|
137
|
-
│ Layer 0: Core (plugins/bizar/)
|
|
138
|
-
│ -
|
|
139
|
-
│ -
|
|
140
|
-
│ -
|
|
141
|
-
│ -
|
|
142
|
-
│ -
|
|
143
|
-
│ -
|
|
144
|
-
│ -
|
|
148
|
+
│ Layer 0: Core (.claude/skills + .claude/agents + plugins/bizar/) │
|
|
149
|
+
│ - Skills (SKILL.md + bundled scripts) │
|
|
150
|
+
│ - Agents (Odin, Frigg, Vör, Mimir, Heimdall, ...) │
|
|
151
|
+
│ - Bizar MCP server (plugins/bizar/, 19 tools) │
|
|
152
|
+
│ - 4 hooks (PreToolUse, PostToolUse, ...) │
|
|
153
|
+
│ - In-process memory vault │
|
|
154
|
+
│ - DANGEROUS_PATTERNS approval gate │
|
|
155
|
+
│ - Skill curator (closed learning loop) │
|
|
156
|
+
│ - Pre-compaction memory flush │
|
|
145
157
|
└────────────────────────────────────────────────────────────────────┘
|
|
146
|
-
↕
|
|
158
|
+
↕ Claude Code Agent SDK
|
|
147
159
|
┌────────────────────────────────────────────────────────────────────┐
|
|
148
|
-
│ Substrate:
|
|
149
|
-
│ - In-process runtime, no subprocess
|
|
150
|
-
│ -
|
|
151
|
-
│ -
|
|
160
|
+
│ Substrate: Claude Code (@anthropic-ai/claude-code + Agent SDK) │
|
|
161
|
+
│ - In-process runtime via Agent SDK, no subprocess │
|
|
162
|
+
│ - Skills auto-loaded from .claude/skills/ │
|
|
163
|
+
│ - MCP servers spawned from .claude/mcp.json │
|
|
164
|
+
│ - Agent dispatch via Agent tool │
|
|
165
|
+
│ - Hooks executed in session event loop │
|
|
152
166
|
└────────────────────────────────────────────────────────────────────┘
|
|
153
167
|
```
|
|
154
168
|
|
|
@@ -159,25 +173,31 @@ model, module map, and inter-component contracts.
|
|
|
159
173
|
|
|
160
174
|
## 🛠 Tools (22 total)
|
|
161
175
|
|
|
176
|
+
Bizar's 22 tools are exposed as a Claude Code MCP server (replacing
|
|
177
|
+
Cline's `createTool` shape with the Claude Code MCP `tool`
|
|
178
|
+
registration shape):
|
|
179
|
+
|
|
162
180
|
| Category | Count | Tools |
|
|
163
181
|
| --- | --- | --- |
|
|
164
182
|
| **Background agents** | 9 | `bizar_spawn_background`, `bizar_status`, `bizar_collect`, `bizar_kill`, `bizar_pause`, `bizar_resume`, `bizar_send_message`, `bizar_get_comments`, `bizar_report_progress` |
|
|
165
183
|
| **Memory** | 4 | `bizar_memory_list`, `bizar_memory_read`, `bizar_memory_write`, `bizar_memory_search` |
|
|
166
184
|
| **Plan / Glyphs** | 4 | `bizar_plan_action`, `bizar_open_kb`, `bizar_wait_for_feedback`, `bizar_read_glyph_feedback` |
|
|
167
|
-
| **
|
|
185
|
+
| **Agent teams** | 2 | `bizar_spawn_team`, `bizar_team_status` |
|
|
168
186
|
| **Knowledge graph** | 3 | `bizar_graph_query`, `bizar_graph_path`, `bizar_graph_explain` |
|
|
169
|
-
| **Total** | **22** | All
|
|
187
|
+
| **Total** | **22** | All registered as MCP tools via the Claude Code MCP SDK |
|
|
170
188
|
|
|
171
189
|
---
|
|
172
190
|
|
|
173
191
|
## 🪝 Hooks (4 + 2 safety)
|
|
174
192
|
|
|
193
|
+
Claude Code-native hooks (typed event payloads, idiomatic shape):
|
|
194
|
+
|
|
175
195
|
| Hook | Purpose |
|
|
176
196
|
| --- | --- |
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
197
|
+
| `PreToolUse` | Loop guard + **DANGEROUS_PATTERNS gate** |
|
|
198
|
+
| `PostToolUse` | Per-tool-call log to `LogWriter` |
|
|
199
|
+
| `UserPromptSubmit` | **Pre-compaction memory flush** (writes snapshot to vault) |
|
|
200
|
+
| `SessionStart` / `SessionEnd` | `message-added` (slash commands) + `run-finished`/`run-failed` (memory write) |
|
|
181
201
|
|
|
182
202
|
| Safety component | Purpose |
|
|
183
203
|
| --- | --- |
|
|
@@ -262,7 +282,7 @@ See [docs/graph-tools.md](docs/graph-tools.md) for the full reference.
|
|
|
262
282
|
|
|
263
283
|
## 🛡 Harness engineering audit (73/73)
|
|
264
284
|
|
|
265
|
-
v6.
|
|
285
|
+
v6.3.0 passes the full L01–L12 audit at **73/73 = 100%**:
|
|
266
286
|
|
|
267
287
|
| Subsystem | Score |
|
|
268
288
|
| --- | --- |
|
|
@@ -273,7 +293,7 @@ v6.0.0 passes the full L01–L12 audit at **73/73 = 100%**:
|
|
|
273
293
|
| 5. Feedback | 7/7 (`make check/test/e2e/clean-check/arch/vcr/session-*`) |
|
|
274
294
|
| 6. L05 Cross-session | 6/6 (Current State + clock-in/out + context anxiety) |
|
|
275
295
|
| 7. L03 System of record | 4/4 (ACID: Durability, Consistency, Atomicity, Proximity) |
|
|
276
|
-
| 8. L07 WIP=1 + VCR | 3/3 (WIP=1 + `make vcr` + VCR
|
|
296
|
+
| 8. L07 WIP=1 + VCR | 3/3 (WIP=1 + `make vcr` + VCR 31/31 = 1.0) |
|
|
277
297
|
| 9. L08 Feature list | 6/6 (evidence + verify-feature + granularity + state machine) |
|
|
278
298
|
| 10. L09 DoD | 5/5 (3-layer verification + runtime signals + repair instructions) |
|
|
279
299
|
| 11. L10 E2E + Arch | 8/8 (`make e2e` + `make check-arch` + 7 arch rules + E2E requirement) |
|
|
@@ -314,19 +334,27 @@ See [PROGRESS.md](PROGRESS.md) § Current State and the
|
|
|
314
334
|
|
|
315
335
|
---
|
|
316
336
|
|
|
317
|
-
## 🔄 Migration from
|
|
337
|
+
## 🔄 Migration from v6.2.x (Cline era)
|
|
318
338
|
|
|
319
|
-
Upgrading from
|
|
339
|
+
Upgrading from a Cline-era BizarHarness (v6.0.0 → v6.2.x)? See
|
|
320
340
|
[docs/migration-guide.md](docs/migration-guide.md) for:
|
|
321
341
|
|
|
322
|
-
- Breaking changes (
|
|
323
|
-
- New tools (
|
|
324
|
-
- Removed tools (
|
|
342
|
+
- Breaking changes (hook shape: `beforeTool` → `PreToolUse`)
|
|
343
|
+
- New tools (Claude Code MCP server shape; Agent SDK dispatch)
|
|
344
|
+
- Removed tools (the `bizar_spawn_background` tool family is now
|
|
345
|
+
Claude Code `run_in_background`)
|
|
325
346
|
- Verification commands
|
|
326
347
|
|
|
327
|
-
TL;DR: `npm install @polderlabs/bizar@
|
|
328
|
-
|
|
329
|
-
|
|
348
|
+
TL;DR: `npm install @polderlabs/bizar@latest` and update any custom
|
|
349
|
+
hooks that consumed the old `beforeTool` hook payload shape.
|
|
350
|
+
|
|
351
|
+
## 📜 Historical: OpenCode → Cline (v5.6/v6.0)
|
|
352
|
+
|
|
353
|
+
The OpenCode-era Bizar (≤ v5.5.x) was rebuilt on Cline across
|
|
354
|
+
**v5.6.0-beta.x → v6.0.0** (the "Cline rewrite"). That migration is
|
|
355
|
+
preserved as historical context only — see [docs/migration-guide.md](docs/migration-guide.md)
|
|
356
|
+
§ Historical for the archived OpenCode → Cline guide. No current
|
|
357
|
+
release of Bizar supports OpenCode.
|
|
330
358
|
|
|
331
359
|
---
|
|
332
360
|
|
|
@@ -349,8 +377,8 @@ The harness engineering protocol:
|
|
|
349
377
|
Development of BizarHarness uses a separate sandbox repo for Docker/dev
|
|
350
378
|
tooling. See [DrB0rk/BizarHarness-dev](https://github.com/DrB0rk/BizarHarness-dev)
|
|
351
379
|
(private) for the local dev environment, including the Docker-based
|
|
352
|
-
|
|
353
|
-
the system
|
|
380
|
+
Claude Code sandbox used to test config and plugin changes without
|
|
381
|
+
touching the system Claude Code install.
|
|
354
382
|
|
|
355
383
|
---
|
|
356
384
|
|
|
@@ -364,8 +392,8 @@ MIT — see [LICENSE](LICENSE).
|
|
|
364
392
|
|
|
365
393
|
Inspired by the [walkinglabs/learn-harness-engineering](https://github.com/walkinglabs/learn-harness-engineering)
|
|
366
394
|
course and the [awesome-harness-engineering](https://github.com/walkinglabs/awesome-harness-engineering)
|
|
367
|
-
curated list. Built on [
|
|
368
|
-
[@
|
|
395
|
+
curated list. Built on [Claude Code](https://docs.claude.com/claude-code)
|
|
396
|
+
and [@anthropic-ai/claude-agent-sdk](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk).
|
|
369
397
|
|
|
370
398
|
---
|
|
371
399
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as c,j as e,R as ye}from"./react-vendor-Dn4wqh4Z.js";import{u as Y}from"./Toast-Cpl6-E63.js";import{c as T,W as be,a as k,_ as ke}from"./mobile-layout-
|
|
1
|
+
import{r as c,j as e,R as ye}from"./react-vendor-Dn4wqh4Z.js";import{u as Y}from"./Toast-Cpl6-E63.js";import{c as T,W as be,a as k,_ as ke}from"./mobile-layout-CBHjpwsb.js";import{a7 as G,bg as V,C as me,D as ie,R as O,bh as we,z as Ne,bi as Ce,aB as ce,bj as Se,i as ze,g as pe,ag as se,a0 as Ae,b2 as Re,ac as Le,J as Ie,r as te,V as ne,I as Ee,t as Be,aZ as Pe,X as oe,aC as xe,e as Te,d as $e,Y as Me,a6 as De,_ as _e}from"./icons-Do5N2jmX.js";const b=c.forwardRef(function({variant:s="secondary",size:l="md",iconOnly:d=!1,loading:i=!1,disabled:p,className:x,children:r,...n},u){return e.jsxs("button",{ref:u,type:n.type??"button",disabled:p||i,className:T("btn",`btn-${s}`,`btn-size-${l}`,d&&"btn-icon",i&&"btn-loading",x),...n,children:[i?e.jsx("span",{className:"btn-spinner","aria-hidden":!0}):null,r]})});function E({variant:a="elevated",interactive:s=!1,className:l,children:d,...i}){return e.jsx("div",{className:T("card",`card-${a}`,s&&"card-interactive",l),...i,children:d})}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 ae=[{id:"bizar",name:"Bizar CLI"},{id:"bizar-dash",name:"Dashboard"},{id:"bizar-plugin",name:"Opencode Plugin"}];function Qe(){const a=Y(),[s,l]=c.useState({current:{},latest:null,checking:!1,updating:!1,hasUpdates:!1,requiresRestart:!1,perPackage:{}});c.useEffect(()=>{const r=new be;return r.on(n=>{(n.type==="update:progress"||n.type==="update:log"||n.type==="update:complete")&&l(u=>{if(n.type==="update:complete")return{...u,updating:!1,requiresRestart:!!n.requiresRestart};if(n.type==="update:log"){const j=n,y=u.perPackage[j.pkg]||{logs:[]};return{...u,perPackage:{...u.perPackage,[j.pkg]:{...y,logs:[...(y.logs||[]).slice(-50),j.line]}}}}const g=n;return{...u,perPackage:{...u.perPackage,[g.pkg]:{...u.perPackage[g.pkg],status:g.status,error:g.error,newVersion:g.newVersion}}}})}),()=>r.close()},[]),c.useEffect(()=>{k.get("/updates/status").then(r=>l(n=>({...n,current:r.current}))).catch(r=>l(n=>({...n,error:r.message})))},[]);const d=async()=>{l(r=>({...r,checking:!0,error:void 0}));try{const r=await k.get("/updates/check");l(n=>({...n,checking:!1,current:r.current,latest:r.latest,hasUpdates:r.hasUpdates}))}catch(r){l(n=>({...n,checking:!1,error:r.message}))}},i=async()=>{if(confirm("Update Bizar packages? The dashboard will restart automatically.")){l(r=>({...r,updating:!0,requiresRestart:!1,perPackage:{},error:void 0}));try{await k.post("/updates/apply",{packages:["bizar","bizar-dash","bizar-plugin"]})}catch(r){l(n=>({...n,updating:!1,error:r.message}))}}},p=async()=>{if(confirm("Restart the dashboard? You will be disconnected briefly."))try{await k.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(G,{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:ae.map(r=>e.jsxs("li",{children:[e.jsx("span",{children:r.name}),e.jsx("code",{className:"mono",children:s.current[r.id]||"—"})]},r.id))})]}),s.latest&&e.jsxs("div",{className:"updates-latest",children:[e.jsx("h4",{children:"Latest available"}),e.jsx("ul",{children:ae.map(r=>{var j;const n=s.current[r.id],u=(j=s.latest)==null?void 0:j[r.id],g=n&&u&&n!==u;return e.jsxs("li",{className:g?"updates-outdated":"updates-current-version",children:[e.jsx("span",{children:r.name}),e.jsxs("code",{className:"mono",children:[u||"—",g&&e.jsx("span",{className:"updates-badge",children:"update available"})]})]},r.id)})})]}),s.updating&&e.jsx("div",{className:"updates-progress-rows",children:ae.map(r=>{const n=s.perPackage[r.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:r.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(V,{size:14,className:"icon-success"}),n.status==="error"&&e.jsx(me,{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(`
|
|
2
2
|
`)})]}),n.status==="error"&&n.error&&e.jsxs("div",{className:"updates-pkg-error",children:[e.jsx(ie,{size:12})," ",n.error]})]},r.id)})}),e.jsxs("div",{className:"updates-actions",children:[e.jsxs(b,{onClick:d,disabled:x,children:[s.checking?e.jsx("span",{className:"btn-spinner"}):e.jsx(O,{size:14}),"Check for updates"]}),e.jsxs(b,{variant:"primary",onClick:i,disabled:!s.hasUpdates||s.updating,children:[s.updating?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:14}),s.updating?"Updating…":s.hasUpdates?"Update now":"Up to date"]}),s.requiresRestart&&e.jsxs(b,{variant:"danger",onClick:p,children:[e.jsx(O,{size:14})," Restart Dashboard"]})]}),s.error&&e.jsxs("div",{className:"updates-error",children:[e.jsx(ie,{size:14}),e.jsx("span",{children:s.error})]})]})}function Ue(a,s,{delay:l=800,onSaved:d,onError:i}={}){const[p,x]=c.useState(a),[r,n]=c.useState("idle"),u=c.useRef(null),g=c.useRef(null),j=c.useRef(a),y=c.useRef(!1),S=c.useCallback(async m=>{n("saving");try{await s(m),j.current=m,g.current=null,n("saved"),d==null||d(),setTimeout(()=>n("idle"),2e3)}catch(v){n("error"),i==null||i(v)}},[s,d,i]),L=c.useCallback(m=>{x(m),g.current=m,y.current=!0,u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{u.current=null,y.current=!1;const v=g.current;g.current=null,v!==null&&S(v)},l)},[l,S]),C=c.useCallback(()=>{u.current&&(clearTimeout(u.current),u.current=null,y.current=!1)},[]),h=c.useCallback(async()=>{if(u.current){clearTimeout(u.current),u.current=null,y.current=!1;const m=g.current;g.current=null,m!==null&&await S(m)}},[S]);return c.useEffect(()=>()=>{if(u.current){clearTimeout(u.current),u.current=null;const m=g.current;g.current=null,m!==null&&(n("saving"),s(m).then(()=>{j.current=m,n("saved"),d==null||d()}).catch(v=>{n("error"),i==null||i(v)}).finally(()=>{setTimeout(()=>n("idle"),2e3)}))}},[s,d,i]),{value:p,setValue:L,status:r,save:S,flush:h,clearDebounce:C,hasPendingDebounceRef:y,pendingValueRef:g}}function de({initialValue:a,saveFn:s,delay:l=800,render:d,className:i}){const{value:p,setValue:x,status:r,save:n,clearDebounce:u,hasPendingDebounceRef:g,pendingValueRef:j}=Ue(a,s,{delay:l}),y=ye.useCallback(()=>{g.current&&(u(),j.current!==null&&n(j.current))},[u,g,n,j]);return e.jsxs("div",{className:`autosave-field ${i||""} ${r}`,children:[d({value:p,onChange:x,onBlur:y}),e.jsxs("span",{className:"autosave-status",role:"status","aria-live":"polite",children:[r==="saving"&&e.jsx(we,{className:"spinning",size:12}),r==="saved"&&e.jsx(Ne,{size:12}),r==="error"&&e.jsx(me,{size:12})]})]})}const He=[{id:"topnav",label:"Top nav"},{id:"sidebar",label:"Sidebar"},{id:"both",label:"Both"}];function Je({settings:a,patchUi:s,patchTop:l,autoSave:d}){return e.jsxs(e.Fragment,{children:[e.jsxs(E,{id:"settings-layout","data-section":"layout",children:[e.jsxs(B,{children:[e.jsx(Ce,{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:He.map(i=>e.jsx("button",{type:"button",className:T("layout-card",a.ui.layout===i.id&&"layout-card-active"),onClick:()=>s({layout:i.id}),children:e.jsx("span",{className:"layout-card-label",children:i.label})},i.id))}),e.jsxs("label",{className:"checkbox-row","data-setting-id":"ui.showHeader",children:[e.jsx("input",{type:"checkbox",checked:a.ui.showHeader,onChange:i=>s({showHeader:i.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:i=>s({showStatusBar:i.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:i=>s({defaultTab:i.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(de,{initialValue:a.defaultAgent||"",saveFn:async i=>{l("defaultAgent",i),d==null||d("defaultAgent",i)},render:({value:i,onChange:p,onBlur:x})=>e.jsx("input",{id:"set-default-agent",className:"input",type:"text",placeholder:"e.g. odin",value:i,onChange:r=>p(r.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(de,{initialValue:a.defaultModel||"",saveFn:async i=>{l("defaultModel",i),d==null||d("defaultModel",i)},render:({value:i,onChange:p,onBlur:x})=>e.jsx("input",{id:"set-default-model",className:"input",type:"text",placeholder:"(leave empty for provider default)",value:i,onChange:r=>p(r.target.value),onBlur:x})})]})]})]})}function es({initialStatus:a}){var m;const[s,l]=c.useState(a??null),[d,i]=c.useState(""),[p,x]=c.useState(!1),[r,n]=c.useState(null);c.useEffect(()=>{s===null&&k.get("/tailscale/status").then(v=>l(v)).catch(()=>l(null))},[]);const u=async()=>{try{const v=await k.get("/tailscale/status");l(v)}catch{n("Failed to load Tailscale status")}},g=async()=>{if(d.trim()){x(!0),n(null);try{await k.post("/tailscale/setup",{authKey:d.trim()}),await u(),i("")}catch(v){n(v.message||"Authentication failed")}finally{x(!1)}}},j=async()=>{var v,w,z;if(s){x(!0),n(null);try{await k.post("/tailscale/setup",{port:((v=s.settings)==null?void 0:v.port)||4321,https:((w=s.settings)==null?void 0:w.https)!==!1,hostname:((z=s.settings)==null?void 0:z.hostname)||""}),await u()}catch($){n($.message||"Setup failed")}finally{x(!1)}}},y=async()=>{x(!0),n(null);try{await k.post("/tailscale/unserve"),await u()}catch(v){n(v.message||"Remove failed")}finally{x(!1)}},S=(s==null?void 0:s.installed)??!1,L=(s==null?void 0:s.authenticated)??!1,C=((m=s==null?void 0:s.settings)==null?void 0:m.enabled)??!1,h=C?`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(ce,{size:14})," Tailscale Integration"]}),e.jsx(P,{children:"Expose the dashboard over your Tailscale network using an auth key."}),r&&e.jsx("p",{style:{color:"var(--color-error, #f85149)",fontSize:"0.85rem"},children:r}),L?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(V,{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"})]})]}),C&&h?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(Se,{size:16}),e.jsx("a",{href:h,target:"_blank",rel:"noreferrer",children:h})]}),e.jsx(b,{variant:"secondary",size:"sm",onClick:y,disabled:p,children:"Remove serve"})]}):e.jsx(b,{variant:"primary",size:"sm",onClick:j,disabled:p,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:d,onChange:v=>i(v.target.value),style:{flex:1,minWidth:"200px"},disabled:p}),e.jsx(b,{variant:"primary",size:"sm",onClick:g,disabled:p||!d.trim(),children:"Authenticate"})]})]})]}):e.jsxs(E,{id:"settings-tailscale-auth","data-section":"tailscale",children:[e.jsxs(B,{children:[e.jsx(ce,{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 ss({settings:a,patchTop:s}){var l,d,i;return e.jsxs(E,{id:"settings-system-llm","data-section":"system-llm",children:[e.jsxs(B,{children:[e.jsx(ze,{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:p=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,enabled:p.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:((d=a.systemLlm)==null?void 0:d.provider)||"cline",onChange:p=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,provider:p.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:((i=a.systemLlm)==null?void 0:i.model)||"cline/deepseek-v4-flash-free",onChange:p=>{const x=a.systemLlm||{enabled:!0,provider:"cline",model:"cline/deepseek-v4-flash-free"};s("systemLlm",{...x,model:p.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 Ve=[{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=Y(),[d,i]=c.useState(null),[p,x]=c.useState(null),[r,n]=c.useState(!1),[u,g]=c.useState(!1),[j,y]=c.useState(!1),[S,L]=c.useState(!1),[C,h]=c.useState(!1),[m,v]=c.useState(!1),w=c.useCallback(async()=>{n(!0);try{const[o,_]=await Promise.all([k.get("/headroom/status"),k.get("/headroom/stats?hours=24").catch(()=>({error:"no stats"}))]);i(o),_.error||x(_)}catch(o){l.error(`Failed to load Headroom status: ${o.message}`)}finally{n(!1)}},[l]);c.useEffect(()=>{w()},[w]);const z=async()=>{g(!0);try{const o=await k.post("/headroom/install",{force:!0});o.installed?(l.success(`Headroom installed via ${o.method}.`),await w()):l.error('Headroom install failed. Try: pip install "headroom-ai[all]"')}catch(o){l.error(`Install failed: ${o.message}`)}finally{g(!1)}},$=async()=>{y(!0);try{(await k.post("/headroom/wrap",{port:a.port})).ok?(l.success("cline wrapped with Headroom."),await w()):l.error("Wrap failed.")}catch(o){l.error(`Wrap failed: ${o.message}`)}finally{y(!1)}},U=async()=>{L(!0);try{(await k.post("/headroom/unwrap")).ok?(l.success("cline unwrapped from Headroom."),await w()):l.error("Unwrap failed.")}catch(o){l.error(`Unwrap failed: ${o.message}`)}finally{L(!1)}},W=async()=>{h(!0);try{(await k.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(o){l.error(`Proxy start failed: ${o.message}`)}finally{h(!1)}},K=async()=>{v(!0);try{(await k.post("/headroom/proxy/stop")).ok?(l.success("Headroom proxy stopped."),await w()):l.error("Proxy stop failed.")}catch(o){l.error(`Proxy stop failed: ${o.message}`)}finally{v(!1)}},Z=async()=>{try{const{spawn:o}=await ke(async()=>{const{spawn:_}=await import("./__vite-browser-external-BIHI7g3E.js");return{spawn:_}},[]);o("headroom",["dashboard"],{detached:!0,stdio:"ignore"})}catch{l.error("Could not open Headroom dashboard. Run `headroom dashboard` manually.")}},{installed:R,version:q,proxyRunning:M,proxyPort:X,wrapped:A}=d||{},H=(p==null?void 0:p.compressionRatio)??0,D=(p==null?void 0:p.tokensSaved)??0;return e.jsx("div",{id:"settings-headroom","data-section":"headroom",children:e.jsxs(E,{children:[e.jsxs(B,{children:[e.jsx(pe,{size:14,style:{color:M?"var(--success)":"var(--text-dim)"}}),"Headroom",R&&q&&e.jsxs("span",{style:{fontSize:11,color:"var(--text-dim)",marginLeft:6},children:["v",q," ",M?"✓":"✗"]}),!R&&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:[R?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--error)"}}),e.jsx("span",{children:R?"Installed":"Not installed"})]}),e.jsxs("div",{className:"headroom-status-item",children:[M?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["Proxy ",M?`${X} ✓`:"stopped"]})]}),e.jsxs("div",{className:"headroom-status-item",children:[A?e.jsx(V,{size:12,style:{color:"var(--success)"}}):e.jsx(se,{size:12,style:{color:"var(--text-dim)"}}),e.jsxs("span",{children:["cline ",A?"wrapped":"not wrapped"]})]})]}),(D>0||H>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:H>0?`${Math.round(H*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:D>0?D.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:[R?e.jsxs(e.Fragment,{children:[e.jsxs(b,{variant:"secondary",size:"sm",onClick:$,disabled:j||A,title:A?"cline is already wrapped":"Wrap cline to route through Headroom proxy",children:[j?e.jsx("span",{className:"btn-spinner"}):e.jsx(Ae,{size:13}),j?"Wrapping…":A?"Wrapped ✓":"Wrap cline"]}),A&&e.jsxs(b,{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(b,{variant:"primary",size:"sm",onClick:z,disabled:u,children:[u?e.jsx("span",{className:"btn-spinner"}):e.jsx(G,{size:13}),u?"Installing…":"Install Headroom"]}),R&&e.jsxs(e.Fragment,{children:[M?e.jsxs(b,{variant:"secondary",size:"sm",onClick:K,disabled:m,children:[m?e.jsx("span",{className:"btn-spinner"}):e.jsx(Re,{size:13}),m?"Stopping…":"Stop proxy"]}):e.jsxs(b,{variant:"secondary",size:"sm",onClick:W,disabled:C,children:[C?e.jsx("span",{className:"btn-spinner"}):e.jsx(Le,{size:13}),C?"Starting…":"Start proxy"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:Z,children:[e.jsx(Ie,{size:13}),"Dashboard"]})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:w,disabled:r,children:e.jsx(O,{size:13,className:r?"spin":""})})]}),e.jsxs("div",{style:{marginTop:16},children:[e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.enabled,onChange:o=>s({enabled:o.target.checked})}),e.jsx("span",{children:"Enable Headroom"})]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:a.autoInstall,onChange:o=>s({autoInstall:o.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:o=>s({autoStart:o.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:o=>s({autoWrap:o.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:o=>s({routeAllProviders:o.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:o=>s({port:Math.max(1,Math.min(65535,parseInt(o.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:o=>s({host:o.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:o=>s({backend:o.target.value}),children:Ve.map(o=>e.jsx("option",{value:o.value,children:o.label},o.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:o=>s({budget:Math.max(0,parseFloat(o.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:o=>s({outputShaper:o.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:o=>s({telemetry:o.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 as({settings:a,setSettings:s,setDirty:l}){return e.jsx(Oe,{settings:a.headroom||ue,onPatch:d=>{s(i=>({...i,headroom:{...i.headroom||ue,...d}})),l(!0)}})}function Fe(){const a=Y(),[s,l]=c.useState([]),[d,i]=c.useState(new Set),[p,x]=c.useState(!0),[r,n]=c.useState(""),[u,g]=c.useState(!0),j=c.useCallback(async()=>{x(!0);try{const[h,m]=await Promise.all([k.get("/activity"),k.get("/activity/hidden")]);l(Array.isArray(h.items)?h.items:[]),i(new Set(m.hidden||[]))}catch(h){a.error(`Load failed: ${h.message}`)}finally{x(!1)}},[a]);c.useEffect(()=>{j()},[j]);const y=(h,m)=>{const v=`${h.kind||""}|${h.ts||""}|${h.slug||""}|${m}`;let w=0;for(let z=0;z<v.length;z++)w=(w<<5)-w+v.charCodeAt(z)|0;return Math.abs(w).toString(16).padStart(8,"0").slice(0,16)},S=async()=>{try{await k.del("/activity/hide"),i(new Set),a.success("All hidden activity restored.")}catch(h){a.error(`Restore failed: ${h.message}`)}},L=async h=>{try{await k.del(`/activity/hide/${encodeURIComponent(h)}`);const m=new Set(d);m.delete(h),i(m)}catch(m){a.error(`Restore failed: ${m.message}`)}},C=s.filter((h,m)=>{const v=y(h,m);if(!u&&d.has(v))return!1;if(!r)return!0;const w=r.toLowerCase();return[h.kind,h.slug,h.message].some(z=>typeof z=="string"&&z.toLowerCase().includes(w))});return e.jsxs(E,{id:"settings-activity-log","data-section":"activity-log",children:[e.jsxs(B,{children:[e.jsx(pe,{size:14})," Activity log",e.jsxs("span",{className:"muted",style:{fontWeight:400,marginLeft:8,fontSize:12},children:[s.length," total · ",d.size," hidden"]}),e.jsx(b,{variant:"ghost",size:"sm",style:{marginLeft:"auto"},onClick:j,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(te,{size:12}),e.jsx("input",{type:"text",className:"input",placeholder:"Filter by kind, slug, or message…",value:r,onChange:h=>n(h.target.value)})]}),e.jsxs("label",{className:"activity-log-toggle",children:[e.jsx("input",{type:"checkbox",checked:u,onChange:h=>g(h.target.checked)}),"Show hidden"]}),e.jsxs(b,{variant:"ghost",size:"sm",disabled:d.size===0,onClick:S,title:"Restore all hidden items to the Overview",children:[e.jsx(ne,{size:12})," Restore all"]})]}),p?e.jsx("div",{className:"muted",style:{padding:"12px 0",fontSize:12},children:"Loading…"}):C.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:C.slice(0,200).map((h,m)=>{const v=y(h,m),w=d.has(v);return e.jsxs("tr",{className:T(w&&"activity-log-row-hidden"),children:[e.jsx("td",{className:"activity-log-kind",children:h.kind||"activity"}),e.jsx("td",{className:"activity-log-detail",children:h.message||h.slug||"—"}),e.jsx("td",{className:"activity-log-time mono",children:h.ts?new Date(h.ts).toLocaleString():"—"}),e.jsx("td",{children:w?e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>L(v),title:"Restore to Overview",children:e.jsx(ne,{size:12})}):e.jsx("span",{className:"activity-log-state-tag",children:"shown"})})]},`${h.ts}-${m}`)})})]}),C.length>200&&e.jsxs("div",{className:"muted",style:{fontSize:11,padding:"8px 0"},children:["Showing first 200 of ",C.length,"."]})]})]})}function We({about:a}){return e.jsxs(E,{id:"settings-about","data-section":"about",children:[e.jsxs(B,{children:[e.jsx(Ee,{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 ts({about:a}){return e.jsxs(e.Fragment,{children:[e.jsx(Fe,{}),e.jsx(We,{about:a})]})}function Ke({onError:a}){const s=Y(),[l,d]=c.useState([]),[i,p]=c.useState(!1),[x,r]=c.useState(!1),[n,u]=c.useState(new Set),[g,j]=c.useState(null),[y,S]=c.useState(""),[L,C]=c.useState(!1),[h,m]=c.useState(""),[v,w]=c.useState(""),[z,$]=c.useState(!1),[U,W]=c.useState(""),[K,Z]=c.useState(!1),[R,q]=c.useState(""),[M,X]=c.useState(new Set),A=c.useCallback(async()=>{p(!0);try{const t=await k.get("/env-vars");d(t)}catch(t){s.error(`Load failed: ${t.message}`),a==null||a(t.message)}finally{p(!1)}},[s,a]);c.useEffect(()=>{A()},[A]);const H=t=>{u(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},D=async()=>{const t=h.trim().toUpperCase(),N=v.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}r(!0);try{await k.post("/env-vars",{name:t,value:N}),s.success(`${t} created.`),C(!1),m(""),w(""),await A()}catch(f){s.error(`Create failed: ${f.message}`)}finally{r(!1)}},o=t=>{j(t.name),S(t.value===t.value.replace(/\*/g,"")?t.value:""),u(N=>{const f=new Set(N);return f.add(t.name),f})},_=async t=>{if(!y.trim()){s.warning("Value cannot be empty.");return}r(!0);try{await k.put(`/env-vars/${encodeURIComponent(t)}`,{value:y.trim()}),s.success(`${t} updated.`),j(null),await A()}catch(N){s.error(`Update failed: ${N.message}`)}finally{r(!1)}},re=async t=>{if(confirm(`Delete ${t}? This cannot be undone.`))try{await k.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 k.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 k.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=c.useMemo(()=>{if(!R.trim())return l;const t=R.toLowerCase();return l.filter(N=>N.name.toLowerCase().includes(t))},[l,R]),Q=c.useMemo(()=>{const t={};for(const N of F){const f=N.name.split("_")[0]+"_";(t[f]??(t[f]=[])).push(N)}return t},[F]),ve=t=>{X(N=>{const f=new Set(N);return f.has(t)?f.delete(t):f.add(t),f})},le=c.useMemo(()=>{const t=["BIZAR_","PROVIDER_","MODEL_","API_"];return Object.keys(Q).sort((f,I)=>{const J=t.indexOf(f),ee=t.indexOf(I);return J===-1&&ee===-1?f.localeCompare(I):J===-1?1:ee===-1?-1:J-ee})},[Q]);if(i)return e.jsx("div",{className:"muted",style:{padding:"16px 0",fontSize:13},children:"Loading env vars…"});const fe=le.length>1;return e.jsxs("div",{className:"env-var-manager",children:[e.jsxs("div",{className:"env-var-toolbar",children:[e.jsxs(b,{variant:"primary",size:"sm",onClick:()=>C(!0),children:[e.jsx(Be,{size:12})," New variable"]}),e.jsxs(b,{variant:"secondary",size:"sm",onClick:()=>$(t=>!t),className:z?"active":"",children:[e.jsx(Pe,{size:12})," Bulk import"]}),e.jsxs(b,{variant:"ghost",size:"sm",onClick:je,title:"Export as .env",children:[e.jsx(G,{size:12})," Export"]}),e.jsxs("div",{className:"env-var-search-wrap",children:[e.jsx(te,{size:12,className:"env-var-search-icon"}),e.jsx("input",{className:"env-var-search input",placeholder:"Filter…",value:R,onChange:t=>q(t.target.value)})]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:A,title:"Reload",children:e.jsx(O,{size:12})})]}),z&&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(b,{variant:"ghost",size:"sm",onClick:()=>$(!1),children:e.jsx(oe,{size:12})})]}),e.jsx("textarea",{className:"input mono env-var-bulk-textarea",placeholder:`BIZAR_API_KEY=your-key-here
|
|
3
3
|
PROVIDER_OPENAI_KEY=sk-...
|
|
4
4
|
MODEL_KEY=gem-...`,value:U,onChange:t=>W(t.target.value),rows:6}),e.jsxs("div",{className:"env-var-bulk-footer",children:[e.jsx(b,{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&&!L&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(xe,{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."})]}),L&&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:h,onChange:t=>m(t.target.value.toUpperCase()),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&C(!1)},autoFocus:!0}),e.jsx("input",{className:"input mono",type:"password",placeholder:"value (API key, token, etc.)",value:v,onChange:t=>w(t.target.value),onKeyDown:t=>{t.key==="Enter"&&D(),t.key==="Escape"&&C(!1)}}),e.jsxs(b,{variant:"primary",size:"sm",onClick:D,disabled:x,children:[e.jsx(V,{size:12})," Create"]}),e.jsx(b,{variant:"ghost",size:"sm",onClick:()=>{C(!1),m(""),w("")},children:e.jsx(oe,{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&&(fe?e.jsx("div",{className:"env-var-groups",children:le.map(t=>{const N=Q[t],f=M.has(t);return e.jsxs("div",{className:"env-var-group",children:[e.jsxs("button",{type:"button",className:"env-var-group-header",onClick:()=>ve(t),children:[f?e.jsx(Te,{size:12}):e.jsx($e,{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(he,{v:I,editing:g,editValue:y,isRevealed:n.has(I.name),onToggleReveal:H,onStartEdit:o,onEditValueChange:S,onHandleUpdate:_,onCancelEdit:()=>j(null),onDelete:re,saving:x},I.name))})]},t)})}):e.jsx("div",{className:"env-var-list",children:F.map(t=>e.jsx(he,{v:t,editing:g,editValue:y,isRevealed:n.has(t.name),onToggleReveal:H,onStartEdit:o,onEditValueChange:S,onHandleUpdate:_,onCancelEdit:()=>j(null),onDelete:re,saving:x},t.name))})),F.length===0&&l.length>0&&e.jsxs("div",{className:"env-var-empty",children:[e.jsx(te,{size:16}),e.jsxs("span",{children:['No env vars match "',R,'"']})]})]})}function he({v:a,editing:s,editValue:l,isRevealed:d,onToggleReveal:i,onStartEdit:p,onEditValueChange:x,onHandleUpdate:r,onCancelEdit:n,onDelete:u,saving:g}){const j=s===a.name;return e.jsxs("div",{className:T("env-var-row",j&&"env-var-row-editing"),children:[e.jsx("span",{className:"env-var-name mono",children:a.name}),j?e.jsx("input",{className:"input mono",type:"password",style:{flex:1,minWidth:200},value:l,onChange:y=>x(y.target.value),onKeyDown:y=>{y.key==="Enter"&&r(a.name),y.key==="Escape"&&n()},autoFocus:!0}):e.jsx("span",{className:T("env-var-value mono",!d&&"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:[!j&&e.jsx("button",{type:"button",className:"icon-btn",title:d?"Hide":"Reveal",onClick:()=>i(a.name),children:d?e.jsx(Me,{size:12}):e.jsx(ne,{size:12})}),j?e.jsxs(e.Fragment,{children:[e.jsx(b,{variant:"primary",size:"sm",onClick:()=>r(a.name),disabled:g,children:"Save"}),e.jsx(b,{variant:"ghost",size:"sm",onClick:n,children:"Cancel"})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"icon-btn",title:"Edit",onClick:()=>p(a),children:e.jsx(De,{size:12})}),e.jsx("button",{type:"button",className:"icon-btn icon-btn-danger",title:"Delete",onClick:()=>u(a.name),children:e.jsx(_e,{size:12})})]})]})]})}function ns(){return e.jsxs(E,{id:"settings-env-vars","data-section":"env-vars",children:[e.jsxs(B,{children:[e.jsx(xe,{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{de as A,b as B,E as C,ns as E,Je as G,as as H,ss as S,es as T,Qe as U,B as a,P as b,ts as c};
|