@polderlabs/bizar 6.3.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/.claude/hooks/sessionend-recall.mjs +3 -3
  2. package/.claude/hooks/worker-suggest.mjs +110 -0
  3. package/.claude/settings.json +9 -0
  4. package/bizar-dash/dist/assets/{EnvVarsSection-B58aiJiE.js → EnvVarsSection-CW6fWKds.js} +3 -3
  5. package/bizar-dash/dist/assets/{EnvVarsSection-B58aiJiE.js.map → EnvVarsSection-CW6fWKds.js.map} +1 -1
  6. package/bizar-dash/dist/assets/MobileChat-D7zRhU9K.js +1 -0
  7. package/bizar-dash/dist/assets/{MobileChat-BJrqwVDd.js.map → MobileChat-D7zRhU9K.js.map} +1 -1
  8. package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js +1 -0
  9. package/bizar-dash/dist/assets/{MobileSettings-CEQNJNLJ.js.map → MobileSettings-K-sNsn_r.js.map} +1 -1
  10. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js → Toast-WTxc3m2g.js} +1 -1
  11. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js.map → Toast-WTxc3m2g.js.map} +1 -1
  12. package/bizar-dash/dist/assets/flow-BpU0-gK2.js +1 -0
  13. package/bizar-dash/dist/assets/flow-BpU0-gK2.js.map +1 -0
  14. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js +1 -0
  15. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js.map +1 -0
  16. package/bizar-dash/dist/assets/{icons-Do5N2jmX.js → icons-B0AKnYI3.js} +98 -103
  17. package/bizar-dash/dist/assets/icons-B0AKnYI3.js.map +1 -0
  18. package/bizar-dash/dist/assets/main-C-Md3DaY.css +1 -0
  19. package/bizar-dash/dist/assets/main-CO8fIxQK.js +18 -0
  20. package/bizar-dash/dist/assets/main-CO8fIxQK.js.map +1 -0
  21. package/bizar-dash/dist/assets/markdown-w2bDDkAH.js +1 -0
  22. package/bizar-dash/dist/assets/{markdown-tOLaD6nm.js.map → markdown-w2bDDkAH.js.map} +1 -1
  23. package/bizar-dash/dist/assets/mobile-DXYCA0hC.js +1 -0
  24. package/bizar-dash/dist/assets/{mobile-DYCHcUpq.js.map → mobile-DXYCA0hC.js.map} +1 -1
  25. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js +2 -0
  26. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js.map +1 -0
  27. package/bizar-dash/dist/assets/react-vendor-BnuhLJ6X.css +1 -0
  28. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js +46 -0
  29. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js.map +1 -0
  30. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js +2 -0
  31. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js.map +1 -0
  32. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js +45 -0
  33. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js.map +1 -0
  34. package/bizar-dash/dist/index.html +12 -10
  35. package/bizar-dash/dist/mobile.html +7 -4
  36. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  37. package/bizar-dash/src/server/api.mjs +11 -0
  38. package/bizar-dash/src/server/memory-consolidator.mjs +218 -0
  39. package/bizar-dash/src/server/memory-distillation.mjs +296 -0
  40. package/bizar-dash/src/server/routes/distill.mjs +129 -0
  41. package/bizar-dash/src/server/routes/goal-planner.mjs +236 -0
  42. package/bizar-dash/src/web/App.tsx +4 -0
  43. package/bizar-dash/src/web/components/Tag.tsx +18 -5
  44. package/bizar-dash/src/web/components/Topbar.tsx +3 -0
  45. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +126 -0
  46. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +163 -0
  47. package/bizar-dash/src/web/components/agents/QualityGates.tsx +123 -0
  48. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +127 -0
  49. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +148 -0
  50. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +160 -0
  51. package/bizar-dash/src/web/components/goals/GoalInput.tsx +86 -0
  52. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +111 -0
  53. package/bizar-dash/src/web/lib/goapPlanner.ts +614 -0
  54. package/bizar-dash/src/web/lib/types.ts +25 -0
  55. package/bizar-dash/src/web/styles/agents-redesign.css +311 -0
  56. package/bizar-dash/src/web/styles/main.css +251 -0
  57. package/bizar-dash/src/web/styles/tasks-redesign.css +231 -0
  58. package/bizar-dash/src/web/ui/controls/Button.tsx +77 -0
  59. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +95 -0
  60. package/bizar-dash/src/web/ui/controls/IconButton.tsx +66 -0
  61. package/bizar-dash/src/web/ui/controls/Kbd.tsx +24 -0
  62. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +77 -0
  63. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +109 -0
  64. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +91 -0
  65. package/bizar-dash/src/web/ui/controls/Select.tsx +92 -0
  66. package/bizar-dash/src/web/ui/controls/Slider.tsx +70 -0
  67. package/bizar-dash/src/web/ui/controls/TextInput.tsx +67 -0
  68. package/bizar-dash/src/web/ui/controls/Toggle.tsx +79 -0
  69. package/bizar-dash/src/web/ui/controls/controls.css +454 -0
  70. package/bizar-dash/src/web/ui/controls/index.ts +33 -0
  71. package/bizar-dash/src/web/ui/data/BarChart.tsx +60 -0
  72. package/bizar-dash/src/web/ui/data/DataTable.tsx +216 -0
  73. package/bizar-dash/src/web/ui/data/EmptyState.tsx +60 -0
  74. package/bizar-dash/src/web/ui/data/ErrorState.tsx +56 -0
  75. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +106 -0
  76. package/bizar-dash/src/web/ui/data/LoadingState.tsx +65 -0
  77. package/bizar-dash/src/web/ui/data/Sparkline.tsx +87 -0
  78. package/bizar-dash/src/web/ui/data/StatTile.tsx +87 -0
  79. package/bizar-dash/src/web/ui/data/data.css +535 -0
  80. package/bizar-dash/src/web/ui/data/index.ts +31 -0
  81. package/bizar-dash/src/web/ui/feedback/Badge.tsx +49 -0
  82. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +209 -0
  83. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +69 -0
  84. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +50 -0
  85. package/bizar-dash/src/web/ui/feedback/Toast.tsx +200 -0
  86. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +126 -0
  87. package/bizar-dash/src/web/ui/feedback/feedback.css +314 -0
  88. package/bizar-dash/src/web/ui/feedback/index.ts +43 -0
  89. package/bizar-dash/src/web/ui/index.ts +56 -0
  90. package/bizar-dash/src/web/ui/layout/AppShell.tsx +51 -0
  91. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +97 -0
  92. package/bizar-dash/src/web/ui/layout/Panel.tsx +73 -0
  93. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +39 -0
  94. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +131 -0
  95. package/bizar-dash/src/web/ui/layout/Tabs.tsx +133 -0
  96. package/bizar-dash/src/web/ui/layout/Topbar.tsx +42 -0
  97. package/bizar-dash/src/web/ui/layout/index.ts +33 -0
  98. package/bizar-dash/src/web/ui/layout/layout.css +413 -0
  99. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +199 -0
  100. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +95 -0
  101. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +93 -0
  102. package/bizar-dash/src/web/ui/navigation/index.ts +17 -0
  103. package/bizar-dash/src/web/ui/navigation/navigation.css +343 -0
  104. package/bizar-dash/src/web/ui/primitives/Box.tsx +91 -0
  105. package/bizar-dash/src/web/ui/primitives/Grid.tsx +49 -0
  106. package/bizar-dash/src/web/ui/primitives/Inline.tsx +55 -0
  107. package/bizar-dash/src/web/ui/primitives/Separator.tsx +46 -0
  108. package/bizar-dash/src/web/ui/primitives/Stack.tsx +54 -0
  109. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +26 -0
  110. package/bizar-dash/src/web/ui/primitives/index.ts +23 -0
  111. package/bizar-dash/src/web/ui/primitives/primitives.css +183 -0
  112. package/bizar-dash/src/web/ui/styles/globals.css +86 -0
  113. package/bizar-dash/src/web/ui/styles/reset.css +125 -0
  114. package/bizar-dash/src/web/ui/styles/tokens.css +195 -0
  115. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +142 -0
  116. package/bizar-dash/src/web/ui/theme/tokens.ts +131 -0
  117. package/bizar-dash/src/web/ui/theme/useTheme.ts +22 -0
  118. package/bizar-dash/src/web/ui/utils/cx.ts +42 -0
  119. package/bizar-dash/src/web/views/Agents.tsx +506 -266
  120. package/bizar-dash/src/web/views/GoalPlanner.tsx +158 -0
  121. package/bizar-dash/src/web/views/Overview.tsx +996 -448
  122. package/bizar-dash/src/web/views/Tasks.tsx +277 -273
  123. package/bizar-dash/tests/communication-log.test.tsx +67 -0
  124. package/bizar-dash/tests/dep-graph.test.tsx +40 -0
  125. package/bizar-dash/tests/event-log.test.tsx +61 -0
  126. package/bizar-dash/tests/goal-input.test.tsx +72 -0
  127. package/bizar-dash/tests/goap-planner.test.ts +68 -0
  128. package/bizar-dash/tests/quality-gates.test.tsx +59 -0
  129. package/bizar-dash/tests/setup.ts +31 -1
  130. package/bizar-dash/tests/ui/controls/Button.test.tsx +50 -0
  131. package/bizar-dash/tests/ui/controls/Checkbox.test.tsx +44 -0
  132. package/bizar-dash/tests/ui/controls/IconButton.test.tsx +37 -0
  133. package/bizar-dash/tests/ui/controls/Kbd.test.tsx +39 -0
  134. package/bizar-dash/tests/ui/controls/NumberInput.test.tsx +56 -0
  135. package/bizar-dash/tests/ui/controls/RadioGroup.test.tsx +58 -0
  136. package/bizar-dash/tests/ui/controls/SearchInput.test.tsx +52 -0
  137. package/bizar-dash/tests/ui/controls/Select.test.tsx +66 -0
  138. package/bizar-dash/tests/ui/controls/Slider.test.tsx +41 -0
  139. package/bizar-dash/tests/ui/controls/TextInput.test.tsx +44 -0
  140. package/bizar-dash/tests/ui/controls/Toggle.test.tsx +39 -0
  141. package/bizar-dash/tests/ui/data/BarChart.test.tsx +55 -0
  142. package/bizar-dash/tests/ui/data/DataTable.test.tsx +112 -0
  143. package/bizar-dash/tests/ui/data/EmptyState.test.tsx +57 -0
  144. package/bizar-dash/tests/ui/data/ErrorState.test.tsx +47 -0
  145. package/bizar-dash/tests/ui/data/KeyValueList.test.tsx +59 -0
  146. package/bizar-dash/tests/ui/data/LoadingState.test.tsx +37 -0
  147. package/bizar-dash/tests/ui/data/Sparkline.test.tsx +56 -0
  148. package/bizar-dash/tests/ui/data/StatTile.test.tsx +69 -0
  149. package/bizar-dash/tests/ui/feedback/Badge.test.tsx +41 -0
  150. package/bizar-dash/tests/ui/feedback/Dialog.test.tsx +99 -0
  151. package/bizar-dash/tests/ui/feedback/ProgressBar.test.tsx +66 -0
  152. package/bizar-dash/tests/ui/feedback/StatusDot.test.tsx +41 -0
  153. package/bizar-dash/tests/ui/feedback/Toast.test.tsx +124 -0
  154. package/bizar-dash/tests/ui/feedback/Tooltip.test.tsx +102 -0
  155. package/bizar-dash/tests/ui/layout/AppShell.test.tsx +50 -0
  156. package/bizar-dash/tests/ui/layout/Breadcrumbs.test.tsx +85 -0
  157. package/bizar-dash/tests/ui/layout/Panel.test.tsx +52 -0
  158. package/bizar-dash/tests/ui/layout/PanelHeader.test.tsx +32 -0
  159. package/bizar-dash/tests/ui/layout/Sidebar.test.tsx +95 -0
  160. package/bizar-dash/tests/ui/layout/Tabs.test.tsx +87 -0
  161. package/bizar-dash/tests/ui/layout/Topbar.test.tsx +41 -0
  162. package/bizar-dash/tests/ui/navigation/CommandPalette.test.tsx +105 -0
  163. package/bizar-dash/tests/ui/navigation/NavGroup.test.tsx +55 -0
  164. package/bizar-dash/tests/ui/navigation/NavLink.test.tsx +61 -0
  165. package/bizar-dash/tests/ui/primitives/Box.test.tsx +49 -0
  166. package/bizar-dash/tests/ui/primitives/Grid.test.tsx +37 -0
  167. package/bizar-dash/tests/ui/primitives/Inline.test.tsx +33 -0
  168. package/bizar-dash/tests/ui/primitives/Separator.test.tsx +34 -0
  169. package/bizar-dash/tests/ui/primitives/Stack.test.tsx +45 -0
  170. package/bizar-dash/tests/ui/primitives/VisuallyHidden.test.tsx +27 -0
  171. package/bizar-dash/tests/views/Agents.test.tsx +359 -0
  172. package/bizar-dash/tests/views/Overview.test.tsx +413 -0
  173. package/bizar-dash/tests/views/Tasks.test.tsx +250 -0
  174. package/bizar-dash/vitest.config.ts +3 -1
  175. package/cli/__tests__/cost-gate.test.mjs +301 -0
  176. package/cli/__tests__/feature-list-bridge.test.mjs +371 -0
  177. package/cli/bin.mjs +38 -0
  178. package/cli/commands/claim.mjs +282 -0
  179. package/cli/commands/cost.mjs +279 -0
  180. package/cli/cost-gate.mjs +501 -0
  181. package/cli/feature-list-bridge.mjs +400 -0
  182. package/cli/memory-constants.mjs +17 -0
  183. package/cli/worker-dispatcher.mjs +259 -0
  184. package/cli/worker-dispatcher.test.mjs +204 -0
  185. package/config/trigger-patterns.json +186 -0
  186. package/package.json +2 -2
  187. package/packages/sdk/package.json +1 -1
  188. package/packages/sdk/src/agent-registry.ts +304 -0
  189. package/packages/sdk/src/consensus/byzantine.ts +587 -0
  190. package/packages/sdk/src/consensus/index.ts +147 -0
  191. package/packages/sdk/src/consensus/queen.ts +173 -0
  192. package/packages/sdk/src/consensus/types.ts +199 -0
  193. package/packages/sdk/src/federation/audit.ts +156 -0
  194. package/packages/sdk/src/federation/budget.ts +269 -0
  195. package/packages/sdk/src/federation/envelope.ts +144 -0
  196. package/packages/sdk/src/federation/hmac.ts +160 -0
  197. package/packages/sdk/src/federation/index.ts +443 -0
  198. package/packages/sdk/src/federation/pii.ts +241 -0
  199. package/packages/sdk/src/federation/policy.ts +112 -0
  200. package/packages/sdk/src/federation/trust.ts +146 -0
  201. package/packages/sdk/src/index.ts +67 -0
  202. package/packages/sdk/src/mcp/server.ts +351 -1
  203. package/packages/sdk/src/router/codemod-intent.ts +125 -0
  204. package/packages/sdk/src/router/index.ts +247 -0
  205. package/packages/sdk/src/router/memory-distillation-shim.mjs +18 -0
  206. package/packages/sdk/src/router/memory-distillation.ts +249 -0
  207. package/packages/sdk/src/router/model-router.ts +235 -0
  208. package/packages/sdk/src/router/q-learning-router.ts +304 -0
  209. package/packages/sdk/src/swarm-topology.ts +279 -0
  210. package/packages/sdk/tests/agent-registry.test.ts +285 -0
  211. package/packages/sdk/tests/consensus.test.ts +376 -0
  212. package/packages/sdk/tests/federation/audit.test.ts +164 -0
  213. package/packages/sdk/tests/federation/budget.test.ts +189 -0
  214. package/packages/sdk/tests/federation/envelope.test.ts +120 -0
  215. package/packages/sdk/tests/federation/hmac.test.ts +194 -0
  216. package/packages/sdk/tests/federation/orchestrator.test.ts +176 -0
  217. package/packages/sdk/tests/federation/pii.test.ts +106 -0
  218. package/packages/sdk/tests/federation/policy.test.ts +140 -0
  219. package/packages/sdk/tests/federation/trust.test.ts +124 -0
  220. package/packages/sdk/tests/mcp-tools.test.ts +204 -0
  221. package/packages/sdk/tests/memory-distillation.test.mjs +186 -0
  222. package/packages/sdk/tests/model-router.test.mjs +108 -0
  223. package/packages/sdk/tests/q-learning-router.test.mjs +100 -0
  224. package/packages/sdk/tests/router-orchestrator.test.mjs +172 -0
  225. package/packages/sdk/tests/router.test.mjs +91 -0
  226. package/packages/sdk/tests/sdk.test.mjs +26 -2
  227. package/packages/sdk/tests/swarm-topology.test.ts +258 -0
  228. package/scripts/bh-full-e2e.mjs +11 -15
  229. package/bizar-dash/dist/assets/MobileChat-BJrqwVDd.js +0 -1
  230. package/bizar-dash/dist/assets/MobileSettings-CEQNJNLJ.js +0 -1
  231. package/bizar-dash/dist/assets/icons-Do5N2jmX.js.map +0 -1
  232. package/bizar-dash/dist/assets/main-IvfQAOfy.js +0 -18
  233. package/bizar-dash/dist/assets/main-IvfQAOfy.js.map +0 -1
  234. package/bizar-dash/dist/assets/main-ietCEg_R.css +0 -1
  235. package/bizar-dash/dist/assets/markdown-tOLaD6nm.js +0 -1
  236. package/bizar-dash/dist/assets/mobile-DYCHcUpq.js +0 -1
  237. package/bizar-dash/dist/assets/mobile-layout-CBHjpwsb.js +0 -2
  238. package/bizar-dash/dist/assets/mobile-layout-CBHjpwsb.js.map +0 -1
  239. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js +0 -40
  240. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js.map +0 -1
  241. package/bizar-dash/dist/assets/useSlashCommands-Bd7_FA6U.js +0 -2
  242. package/bizar-dash/dist/assets/useSlashCommands-Bd7_FA6U.js.map +0 -1
  243. package/bizar-dash/dist/assets/vendor-C843201K.js +0 -29
  244. package/bizar-dash/dist/assets/vendor-C843201K.js.map +0 -1
  245. package/packages/sdk/package-lock.json +0 -32
@@ -14,9 +14,9 @@
14
14
 
15
15
  'use strict';
16
16
 
17
- const fs = require('fs');
18
- const os = require('os');
19
- const path = require('path');
17
+ import fs from 'node:fs';
18
+ import os from 'node:os';
19
+ import path from 'node:path';
20
20
 
21
21
  let raw = '';
22
22
  process.stdin.setEncoding('utf8');
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * .claude/hooks/worker-suggest.mjs
4
+ *
5
+ * Bizar Background Workers — UserPromptSubmit hook.
6
+ *
7
+ * Runs on every user prompt. Calls `dispatch()` from cli/worker-dispatcher.mjs
8
+ * to find Bizar skills/agents that should be suggested for the prompt text.
9
+ * Emits suggestions to stderr (stdout is reserved for Claude Code's hook
10
+ * protocol). Always exits 0 — this is a suggestion, not a gate.
11
+ *
12
+ * Claude Code stdin shape (UserPromptSubmit):
13
+ * {
14
+ * "session_id": "...",
15
+ * "transcript_path": "...",
16
+ * "cwd": "...",
17
+ * "hook_event_name": "UserPromptSubmit",
18
+ * "user_prompt": "raw prompt text"
19
+ * }
20
+ *
21
+ * Claude Code stdout shape (hookSpecificOutput.additionalContext):
22
+ * { "hookSpecificOutput": {
23
+ * "hookEventName": "UserPromptSubmit",
24
+ * "additionalContext": "Bizar workers suggest: …"
25
+ * }}
26
+ *
27
+ * On any unexpected error: log to stderr, write a no-op hook output,
28
+ * exit 0. Never block the user.
29
+ */
30
+ 'use strict';
31
+
32
+ import { dispatch } from '../../cli/worker-dispatcher.mjs';
33
+
34
+ let raw = '';
35
+ process.stdin.setEncoding('utf8');
36
+ process.stdin.on('data', (chunk) => { raw += chunk; });
37
+ process.stdin.on('end', () => {
38
+ let input = {};
39
+ try {
40
+ input = JSON.parse(raw || '{}');
41
+ } catch {
42
+ input = {};
43
+ }
44
+
45
+ const prompt = String(input.user_prompt || '').trim();
46
+
47
+ // Empty prompts get the silent treatment — the user has not yet
48
+ // committed any intent.
49
+ if (prompt.length === 0) {
50
+ process.stdout.write(JSON.stringify({
51
+ hookSpecificOutput: {
52
+ hookEventName: 'UserPromptSubmit',
53
+ additionalContext: '',
54
+ },
55
+ }) + '\n');
56
+ process.exit(0);
57
+ return;
58
+ }
59
+
60
+ let suggestions;
61
+ try {
62
+ suggestions = dispatch(prompt, { maxSuggestions: 3 });
63
+ } catch (err) {
64
+ process.stderr.write(
65
+ `[bizar.workers] WARN: dispatch failed: ${
66
+ err && err.message ? err.message : String(err)
67
+ }\n`,
68
+ );
69
+ process.stdout.write(JSON.stringify({
70
+ hookSpecificOutput: {
71
+ hookEventName: 'UserPromptSubmit',
72
+ additionalContext: '',
73
+ },
74
+ }) + '\n');
75
+ process.exit(0);
76
+ return;
77
+ }
78
+
79
+ // Emit one stderr line per suggestion (for operator visibility in logs).
80
+ for (const s of suggestions) {
81
+ const skill = s.skill ? `skill: ${s.skill}` : 'skill: (none)';
82
+ const agent = s.agent ? `, agent: ${s.agent}` : '';
83
+ process.stderr.write(
84
+ `[bizar.workers] suggested: ${s.workerId} (${skill}${agent}) via pattern "${s.matchedPattern}"\n`,
85
+ );
86
+ }
87
+
88
+ // Build additionalContext for the model so the next turn is primed.
89
+ let note;
90
+ if (suggestions.length === 0) {
91
+ note = '';
92
+ } else {
93
+ const lines = suggestions.map((s) => {
94
+ const skillPart = s.skill ? `, skill=${s.skill}` : '';
95
+ const agentPart = s.agent ? `, agent=${s.agent}` : '';
96
+ return `- ${s.workerId} (weight=${s.weight}${skillPart}${agentPart}) matched "${s.matchedPattern}"`;
97
+ });
98
+ note =
99
+ 'Bizar workers suggest the following skills/agents for this prompt:\n' +
100
+ lines.join('\n');
101
+ }
102
+
103
+ process.stdout.write(JSON.stringify({
104
+ hookSpecificOutput: {
105
+ hookEventName: 'UserPromptSubmit',
106
+ additionalContext: note,
107
+ },
108
+ }) + '\n');
109
+ process.exit(0);
110
+ });
@@ -88,6 +88,15 @@
88
88
  "timeout": 10
89
89
  }
90
90
  ]
91
+ },
92
+ {
93
+ "hooks": [
94
+ {
95
+ "type": "command",
96
+ "command": "node /home/drb0rk/Projects/BizarHarness/.claude/hooks/worker-suggest.mjs",
97
+ "timeout": 10
98
+ }
99
+ ]
91
100
  }
92
101
  ],
93
102
  "SessionStart": [
@@ -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-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
- `)})]}),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
1
+ import{r as c,j as e,R as ye}from"./react-vendor-D3pra6w-.js";import{u as Y}from"./Toast-WTxc3m2g.js";import{c as T,W as be,a as k,_ as ke}from"./mobile-layout-DSmtNPja.js";import{ae as G,bf as V,C as me,E as ie,R as O,bg as we,D as Ne,bh as Ce,aB as ce,bi as Se,i as ze,g as pe,aj as se,a6 as Ae,b1 as Re,ag as Le,Z as Ie,r as te,a4 as ne,J as Ee,t as Be,aY as Pe,X as oe,aC as xe,e as Te,d as $e,a3 as Me,ad as De,a9 as Ue}from"./icons-B0AKnYI3.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
+ `)})]}),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 _e(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}=_e(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,U]=await Promise.all([k.get("/headroom/status"),k.get("/headroom/stats?hours=24").catch(()=>({error:"no stats"}))]);i(o),U.error||x(U)}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)}},_=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:U}=await import("./__vite-browser-external-BIHI7g3E.js");return{spawn:U}},[]);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:_,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),[_,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})},U=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(!_.trim()){s.warning("Nothing to import.");return}Z(!0);try{const t=await k.post("/env-vars/bulk-import",{envContent:_});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
- 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};
4
+ MODEL_KEY=gem-...`,value:_,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||!_.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:U,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:U,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(Ue,{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};