@polderlabs/bizar 6.2.5 → 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 (540) hide show
  1. package/.claude/CLAUDE.md +15 -0
  2. package/.claude/agents/_shared/AGENT_BASELINE.md +168 -0
  3. package/.claude/agents/_shared/CLAUDE_TOOLS.md +412 -0
  4. package/.claude/agents/_shared/SKILLS.md +109 -0
  5. package/.claude/agents/agent-browser.md +80 -0
  6. package/.claude/agents/baldr.md +49 -0
  7. package/.claude/agents/forseti.md +51 -0
  8. package/.claude/agents/frigg.md +42 -0
  9. package/.claude/agents/heimdall.md +33 -0
  10. package/.claude/agents/hermod.md +53 -0
  11. package/.claude/agents/mimir.md +49 -0
  12. package/.claude/agents/odin.md +287 -0
  13. package/.claude/agents/quick.md +34 -0
  14. package/.claude/agents/semble-search.md +50 -0
  15. package/.claude/agents/thor.md +53 -0
  16. package/.claude/agents/tyr.md +56 -0
  17. package/.claude/agents/vidarr.md +54 -0
  18. package/.claude/agents/vor.md +53 -0
  19. package/.claude/commands/audit.md +25 -0
  20. package/.claude/commands/bizar.md +22 -0
  21. package/.claude/commands/explain.md +17 -0
  22. package/.claude/commands/init.md +29 -0
  23. package/.claude/commands/learn.md +44 -0
  24. package/.claude/commands/plan.md +35 -0
  25. package/.claude/commands/plow-through.md +50 -0
  26. package/.claude/commands/pr-review.md +49 -0
  27. package/.claude/commands/setup-provider.md +96 -0
  28. package/.claude/commands/tailscale-serve.md +100 -0
  29. package/.claude/commands/team.md +132 -0
  30. package/.claude/commands/test.md +62 -0
  31. package/.claude/commands/validate.md +68 -0
  32. package/.claude/commands/visual-plan.md +24 -0
  33. package/.claude/hooks/README.md +92 -0
  34. package/.claude/hooks/posttooluse-editwrite.mjs +91 -0
  35. package/.claude/hooks/pretooluse-bash.mjs +81 -0
  36. package/.claude/hooks/pretooluse-editwrite.mjs +139 -0
  37. package/.claude/hooks/sessionend-recall.mjs +74 -0
  38. package/.claude/hooks/sessionstart-prime.mjs +80 -0
  39. package/.claude/hooks/userpromptsubmit-tag.mjs +80 -0
  40. package/.claude/hooks/worker-suggest.mjs +110 -0
  41. package/.claude/settings.json +125 -0
  42. package/.claude/skills/9router/SKILL.md +80 -0
  43. package/.claude/skills/9router-chat/SKILL.md +73 -0
  44. package/.claude/skills/9router-embeddings/SKILL.md +69 -0
  45. package/.claude/skills/9router-image/SKILL.md +86 -0
  46. package/.claude/skills/9router-stt/SKILL.md +79 -0
  47. package/.claude/skills/9router-tts/SKILL.md +80 -0
  48. package/.claude/skills/9router-web-fetch/SKILL.md +99 -0
  49. package/.claude/skills/9router-web-search/SKILL.md +91 -0
  50. package/.claude/skills/bizar/README.md +9 -0
  51. package/.claude/skills/bizar/SKILL.md +450 -0
  52. package/.claude/skills/cpp-coding-standards/README.md +28 -0
  53. package/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
  54. package/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
  55. package/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
  56. package/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
  57. package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
  58. package/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
  59. package/.claude/skills/cpp-testing/README.md +28 -0
  60. package/.claude/skills/cpp-testing/SKILL.md +304 -0
  61. package/.claude/skills/cpp-testing/references/coverage.md +370 -0
  62. package/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
  63. package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
  64. package/.claude/skills/cpp-testing/references/mocking.md +364 -0
  65. package/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
  66. package/.claude/skills/cubesandbox/SKILL.md +148 -0
  67. package/.claude/skills/embedded-esp-idf/README.md +41 -0
  68. package/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
  69. package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
  70. package/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
  71. package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
  72. package/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
  73. package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
  74. package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
  75. package/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
  76. package/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
  77. package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
  78. package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
  79. package/.claude/skills/glyph/SKILL.md +163 -0
  80. package/.claude/skills/harness-engineering/SKILL.md +143 -0
  81. package/.claude/skills/lightrag/SKILL.md +81 -0
  82. package/.claude/skills/memory-protocol/SKILL.md +105 -0
  83. package/.claude/skills/obsidian/SKILL.md +306 -0
  84. package/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
  85. package/.claude/skills/self-improvement/SKILL.md +64 -0
  86. package/README.md +87 -59
  87. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js → EnvVarsSection-CW6fWKds.js} +3 -3
  88. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js.map → EnvVarsSection-CW6fWKds.js.map} +1 -1
  89. package/bizar-dash/dist/assets/MobileChat-D7zRhU9K.js +1 -0
  90. package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js.map → MobileChat-D7zRhU9K.js.map} +1 -1
  91. package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js +1 -0
  92. package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js.map → MobileSettings-K-sNsn_r.js.map} +1 -1
  93. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js → Toast-WTxc3m2g.js} +1 -1
  94. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js.map → Toast-WTxc3m2g.js.map} +1 -1
  95. package/bizar-dash/dist/assets/flow-BpU0-gK2.js +1 -0
  96. package/bizar-dash/dist/assets/flow-BpU0-gK2.js.map +1 -0
  97. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js +1 -0
  98. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js.map +1 -0
  99. package/bizar-dash/dist/assets/{icons-Do5N2jmX.js → icons-B0AKnYI3.js} +98 -103
  100. package/bizar-dash/dist/assets/icons-B0AKnYI3.js.map +1 -0
  101. package/bizar-dash/dist/assets/main-C-Md3DaY.css +1 -0
  102. package/bizar-dash/dist/assets/main-CO8fIxQK.js +18 -0
  103. package/bizar-dash/dist/assets/main-CO8fIxQK.js.map +1 -0
  104. package/bizar-dash/dist/assets/markdown-w2bDDkAH.js +1 -0
  105. package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js.map → markdown-w2bDDkAH.js.map} +1 -1
  106. package/bizar-dash/dist/assets/mobile-DXYCA0hC.js +1 -0
  107. package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js.map → mobile-DXYCA0hC.js.map} +1 -1
  108. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js +2 -0
  109. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js.map +1 -0
  110. package/bizar-dash/dist/assets/react-vendor-BnuhLJ6X.css +1 -0
  111. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js +46 -0
  112. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js.map +1 -0
  113. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js +2 -0
  114. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js.map +1 -0
  115. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js +45 -0
  116. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js.map +1 -0
  117. package/bizar-dash/dist/index.html +12 -10
  118. package/bizar-dash/dist/mobile.html +7 -4
  119. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  120. package/bizar-dash/src/server/api.mjs +15 -4
  121. package/bizar-dash/src/server/background-store.mjs +15 -16
  122. package/bizar-dash/src/server/bg-poller.mjs +25 -35
  123. package/bizar-dash/src/server/bg-retry.mjs +66 -194
  124. package/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
  125. package/bizar-dash/src/server/claude-info.mjs +412 -0
  126. package/bizar-dash/src/server/{cline-runner.mjs → claude-runner.mjs} +53 -48
  127. package/bizar-dash/src/server/claude-sdk.mjs +191 -0
  128. package/bizar-dash/src/server/memory-consolidator.mjs +218 -0
  129. package/bizar-dash/src/server/memory-distillation.mjs +296 -0
  130. package/bizar-dash/src/server/providers-store.mjs +22 -49
  131. package/bizar-dash/src/server/routes/background.mjs +24 -20
  132. package/bizar-dash/src/server/routes/chat.mjs +223 -326
  133. package/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
  134. package/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
  135. package/bizar-dash/src/server/routes/distill.mjs +129 -0
  136. package/bizar-dash/src/server/routes/goal-planner.mjs +236 -0
  137. package/bizar-dash/src/server/routes/tasks.mjs +20 -28
  138. package/bizar-dash/src/server/task-delegator.mjs +76 -77
  139. package/bizar-dash/src/web/App.tsx +4 -0
  140. package/bizar-dash/src/web/components/Tag.tsx +18 -5
  141. package/bizar-dash/src/web/components/Topbar.tsx +3 -0
  142. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +126 -0
  143. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +163 -0
  144. package/bizar-dash/src/web/components/agents/QualityGates.tsx +123 -0
  145. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +127 -0
  146. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +148 -0
  147. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +160 -0
  148. package/bizar-dash/src/web/components/chat/useChat.ts +23 -27
  149. package/bizar-dash/src/web/components/goals/GoalInput.tsx +86 -0
  150. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +111 -0
  151. package/bizar-dash/src/web/lib/goapPlanner.ts +614 -0
  152. package/bizar-dash/src/web/lib/types.ts +25 -0
  153. package/bizar-dash/src/web/styles/agents-redesign.css +311 -0
  154. package/bizar-dash/src/web/styles/main.css +251 -0
  155. package/bizar-dash/src/web/styles/tasks-redesign.css +231 -0
  156. package/bizar-dash/src/web/ui/controls/Button.tsx +77 -0
  157. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +95 -0
  158. package/bizar-dash/src/web/ui/controls/IconButton.tsx +66 -0
  159. package/bizar-dash/src/web/ui/controls/Kbd.tsx +24 -0
  160. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +77 -0
  161. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +109 -0
  162. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +91 -0
  163. package/bizar-dash/src/web/ui/controls/Select.tsx +92 -0
  164. package/bizar-dash/src/web/ui/controls/Slider.tsx +70 -0
  165. package/bizar-dash/src/web/ui/controls/TextInput.tsx +67 -0
  166. package/bizar-dash/src/web/ui/controls/Toggle.tsx +79 -0
  167. package/bizar-dash/src/web/ui/controls/controls.css +454 -0
  168. package/bizar-dash/src/web/ui/controls/index.ts +33 -0
  169. package/bizar-dash/src/web/ui/data/BarChart.tsx +60 -0
  170. package/bizar-dash/src/web/ui/data/DataTable.tsx +216 -0
  171. package/bizar-dash/src/web/ui/data/EmptyState.tsx +60 -0
  172. package/bizar-dash/src/web/ui/data/ErrorState.tsx +56 -0
  173. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +106 -0
  174. package/bizar-dash/src/web/ui/data/LoadingState.tsx +65 -0
  175. package/bizar-dash/src/web/ui/data/Sparkline.tsx +87 -0
  176. package/bizar-dash/src/web/ui/data/StatTile.tsx +87 -0
  177. package/bizar-dash/src/web/ui/data/data.css +535 -0
  178. package/bizar-dash/src/web/ui/data/index.ts +31 -0
  179. package/bizar-dash/src/web/ui/feedback/Badge.tsx +49 -0
  180. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +209 -0
  181. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +69 -0
  182. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +50 -0
  183. package/bizar-dash/src/web/ui/feedback/Toast.tsx +200 -0
  184. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +126 -0
  185. package/bizar-dash/src/web/ui/feedback/feedback.css +314 -0
  186. package/bizar-dash/src/web/ui/feedback/index.ts +43 -0
  187. package/bizar-dash/src/web/ui/index.ts +56 -0
  188. package/bizar-dash/src/web/ui/layout/AppShell.tsx +51 -0
  189. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +97 -0
  190. package/bizar-dash/src/web/ui/layout/Panel.tsx +73 -0
  191. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +39 -0
  192. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +131 -0
  193. package/bizar-dash/src/web/ui/layout/Tabs.tsx +133 -0
  194. package/bizar-dash/src/web/ui/layout/Topbar.tsx +42 -0
  195. package/bizar-dash/src/web/ui/layout/index.ts +33 -0
  196. package/bizar-dash/src/web/ui/layout/layout.css +413 -0
  197. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +199 -0
  198. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +95 -0
  199. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +93 -0
  200. package/bizar-dash/src/web/ui/navigation/index.ts +17 -0
  201. package/bizar-dash/src/web/ui/navigation/navigation.css +343 -0
  202. package/bizar-dash/src/web/ui/primitives/Box.tsx +91 -0
  203. package/bizar-dash/src/web/ui/primitives/Grid.tsx +49 -0
  204. package/bizar-dash/src/web/ui/primitives/Inline.tsx +55 -0
  205. package/bizar-dash/src/web/ui/primitives/Separator.tsx +46 -0
  206. package/bizar-dash/src/web/ui/primitives/Stack.tsx +54 -0
  207. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +26 -0
  208. package/bizar-dash/src/web/ui/primitives/index.ts +23 -0
  209. package/bizar-dash/src/web/ui/primitives/primitives.css +183 -0
  210. package/bizar-dash/src/web/ui/styles/globals.css +86 -0
  211. package/bizar-dash/src/web/ui/styles/reset.css +125 -0
  212. package/bizar-dash/src/web/ui/styles/tokens.css +195 -0
  213. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +142 -0
  214. package/bizar-dash/src/web/ui/theme/tokens.ts +131 -0
  215. package/bizar-dash/src/web/ui/theme/useTheme.ts +22 -0
  216. package/bizar-dash/src/web/ui/utils/cx.ts +42 -0
  217. package/bizar-dash/src/web/views/Agents.tsx +506 -266
  218. package/bizar-dash/src/web/views/Chat.tsx +8 -8
  219. package/bizar-dash/src/web/views/GoalPlanner.tsx +158 -0
  220. package/bizar-dash/src/web/views/Overview.tsx +996 -448
  221. package/bizar-dash/src/web/views/Tasks.tsx +277 -273
  222. package/bizar-dash/tests/communication-log.test.tsx +67 -0
  223. package/bizar-dash/tests/dep-graph.test.tsx +40 -0
  224. package/bizar-dash/tests/event-log.test.tsx +61 -0
  225. package/bizar-dash/tests/goal-input.test.tsx +72 -0
  226. package/bizar-dash/tests/goap-planner.test.ts +68 -0
  227. package/bizar-dash/tests/quality-gates.test.tsx +59 -0
  228. package/bizar-dash/tests/setup.ts +31 -1
  229. package/bizar-dash/tests/ui/controls/Button.test.tsx +50 -0
  230. package/bizar-dash/tests/ui/controls/Checkbox.test.tsx +44 -0
  231. package/bizar-dash/tests/ui/controls/IconButton.test.tsx +37 -0
  232. package/bizar-dash/tests/ui/controls/Kbd.test.tsx +39 -0
  233. package/bizar-dash/tests/ui/controls/NumberInput.test.tsx +56 -0
  234. package/bizar-dash/tests/ui/controls/RadioGroup.test.tsx +58 -0
  235. package/bizar-dash/tests/ui/controls/SearchInput.test.tsx +52 -0
  236. package/bizar-dash/tests/ui/controls/Select.test.tsx +66 -0
  237. package/bizar-dash/tests/ui/controls/Slider.test.tsx +41 -0
  238. package/bizar-dash/tests/ui/controls/TextInput.test.tsx +44 -0
  239. package/bizar-dash/tests/ui/controls/Toggle.test.tsx +39 -0
  240. package/bizar-dash/tests/ui/data/BarChart.test.tsx +55 -0
  241. package/bizar-dash/tests/ui/data/DataTable.test.tsx +112 -0
  242. package/bizar-dash/tests/ui/data/EmptyState.test.tsx +57 -0
  243. package/bizar-dash/tests/ui/data/ErrorState.test.tsx +47 -0
  244. package/bizar-dash/tests/ui/data/KeyValueList.test.tsx +59 -0
  245. package/bizar-dash/tests/ui/data/LoadingState.test.tsx +37 -0
  246. package/bizar-dash/tests/ui/data/Sparkline.test.tsx +56 -0
  247. package/bizar-dash/tests/ui/data/StatTile.test.tsx +69 -0
  248. package/bizar-dash/tests/ui/feedback/Badge.test.tsx +41 -0
  249. package/bizar-dash/tests/ui/feedback/Dialog.test.tsx +99 -0
  250. package/bizar-dash/tests/ui/feedback/ProgressBar.test.tsx +66 -0
  251. package/bizar-dash/tests/ui/feedback/StatusDot.test.tsx +41 -0
  252. package/bizar-dash/tests/ui/feedback/Toast.test.tsx +124 -0
  253. package/bizar-dash/tests/ui/feedback/Tooltip.test.tsx +102 -0
  254. package/bizar-dash/tests/ui/layout/AppShell.test.tsx +50 -0
  255. package/bizar-dash/tests/ui/layout/Breadcrumbs.test.tsx +85 -0
  256. package/bizar-dash/tests/ui/layout/Panel.test.tsx +52 -0
  257. package/bizar-dash/tests/ui/layout/PanelHeader.test.tsx +32 -0
  258. package/bizar-dash/tests/ui/layout/Sidebar.test.tsx +95 -0
  259. package/bizar-dash/tests/ui/layout/Tabs.test.tsx +87 -0
  260. package/bizar-dash/tests/ui/layout/Topbar.test.tsx +41 -0
  261. package/bizar-dash/tests/ui/navigation/CommandPalette.test.tsx +105 -0
  262. package/bizar-dash/tests/ui/navigation/NavGroup.test.tsx +55 -0
  263. package/bizar-dash/tests/ui/navigation/NavLink.test.tsx +61 -0
  264. package/bizar-dash/tests/ui/primitives/Box.test.tsx +49 -0
  265. package/bizar-dash/tests/ui/primitives/Grid.test.tsx +37 -0
  266. package/bizar-dash/tests/ui/primitives/Inline.test.tsx +33 -0
  267. package/bizar-dash/tests/ui/primitives/Separator.test.tsx +34 -0
  268. package/bizar-dash/tests/ui/primitives/Stack.test.tsx +45 -0
  269. package/bizar-dash/tests/ui/primitives/VisuallyHidden.test.tsx +27 -0
  270. package/bizar-dash/tests/views/Agents.test.tsx +359 -0
  271. package/bizar-dash/tests/views/Overview.test.tsx +413 -0
  272. package/bizar-dash/tests/views/Tasks.test.tsx +250 -0
  273. package/bizar-dash/vitest.config.ts +3 -1
  274. package/cli/__tests__/cost-gate.test.mjs +301 -0
  275. package/cli/__tests__/feature-list-bridge.test.mjs +371 -0
  276. package/cli/bin.mjs +55 -18
  277. package/cli/commands/claim.mjs +282 -0
  278. package/cli/commands/claude-cmd.mjs +348 -0
  279. package/cli/commands/cost.mjs +279 -0
  280. package/cli/commands/install.mjs +12 -11
  281. package/cli/commands/validate.mjs +252 -325
  282. package/cli/cost-gate.mjs +501 -0
  283. package/cli/dev-link.test.mjs +11 -11
  284. package/cli/doctor.mjs +131 -213
  285. package/cli/feature-list-bridge.mjs +400 -0
  286. package/cli/install.mjs +33 -37
  287. package/cli/install.test.mjs +9 -9
  288. package/cli/memory-constants.mjs +17 -0
  289. package/cli/provision-claude.mjs +893 -0
  290. package/cli/provision.mjs +224 -227
  291. package/cli/utils.mjs +72 -58
  292. package/cli/worker-dispatcher.mjs +259 -0
  293. package/cli/worker-dispatcher.test.mjs +204 -0
  294. package/config/AGENTS.md +28 -28
  295. package/config/trigger-patterns.json +186 -0
  296. package/install.sh +66 -44
  297. package/package.json +19 -11
  298. package/packages/sdk/ARCHITECTURE.md +40 -36
  299. package/packages/sdk/package.json +15 -5
  300. package/packages/sdk/src/agent-registry.ts +304 -0
  301. package/packages/sdk/src/consensus/byzantine.ts +587 -0
  302. package/packages/sdk/src/consensus/index.ts +147 -0
  303. package/packages/sdk/src/consensus/queen.ts +173 -0
  304. package/packages/sdk/src/consensus/types.ts +199 -0
  305. package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
  306. package/packages/sdk/src/federation/audit.ts +156 -0
  307. package/packages/sdk/src/federation/budget.ts +269 -0
  308. package/packages/sdk/src/federation/envelope.ts +144 -0
  309. package/packages/sdk/src/federation/hmac.ts +160 -0
  310. package/packages/sdk/src/federation/index.ts +443 -0
  311. package/packages/sdk/src/federation/pii.ts +241 -0
  312. package/packages/sdk/src/federation/policy.ts +112 -0
  313. package/packages/sdk/src/federation/trust.ts +146 -0
  314. package/packages/sdk/src/fingerprint.ts +0 -0
  315. package/packages/sdk/src/index.ts +101 -69
  316. package/packages/sdk/src/mcp/bin.ts +51 -0
  317. package/packages/sdk/src/mcp/server.ts +848 -0
  318. package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
  319. package/packages/sdk/src/router/codemod-intent.ts +125 -0
  320. package/packages/sdk/src/router/index.ts +247 -0
  321. package/packages/sdk/src/router/memory-distillation-shim.mjs +18 -0
  322. package/packages/sdk/src/router/memory-distillation.ts +249 -0
  323. package/packages/sdk/src/router/model-router.ts +235 -0
  324. package/packages/sdk/src/router/q-learning-router.ts +304 -0
  325. package/packages/sdk/src/swarm-topology.ts +279 -0
  326. package/packages/sdk/tests/agent-registry.test.ts +285 -0
  327. package/packages/sdk/tests/consensus.test.ts +376 -0
  328. package/packages/sdk/tests/federation/audit.test.ts +164 -0
  329. package/packages/sdk/tests/federation/budget.test.ts +189 -0
  330. package/packages/sdk/tests/federation/envelope.test.ts +120 -0
  331. package/packages/sdk/tests/federation/hmac.test.ts +194 -0
  332. package/packages/sdk/tests/federation/orchestrator.test.ts +176 -0
  333. package/packages/sdk/tests/federation/pii.test.ts +106 -0
  334. package/packages/sdk/tests/federation/policy.test.ts +140 -0
  335. package/packages/sdk/tests/federation/trust.test.ts +124 -0
  336. package/packages/sdk/tests/mcp-tools.test.ts +204 -0
  337. package/packages/sdk/tests/memory-distillation.test.mjs +186 -0
  338. package/packages/sdk/tests/model-router.test.mjs +108 -0
  339. package/packages/sdk/tests/q-learning-router.test.mjs +100 -0
  340. package/packages/sdk/tests/router-orchestrator.test.mjs +172 -0
  341. package/packages/sdk/tests/router.test.mjs +91 -0
  342. package/packages/sdk/tests/sdk.test.mjs +172 -0
  343. package/packages/sdk/tests/swarm-topology.test.ts +258 -0
  344. package/packages/sdk/vitest.config.ts +1 -1
  345. package/scripts/bh-full-e2e.mjs +167 -368
  346. package/scripts/check-deps.mjs +28 -46
  347. package/scripts/mirror-claude-md.sh +78 -0
  348. package/scripts/test-in-container.sh +31 -9
  349. package/templates/clean-state-checklist.md +3 -3
  350. package/templates/sprint-contract.md +2 -2
  351. package/bizar-dash/.bizar/activity.log +0 -3
  352. package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
  353. package/bizar-dash/.omx/state/session.json +0 -10
  354. package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
  355. package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
  356. package/bizar-dash/bizar-design/canvas.html +0 -281
  357. package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
  358. package/bizar-dash/bizar-design/components.css +0 -1665
  359. package/bizar-dash/bizar-design/components.html +0 -557
  360. package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
  361. package/bizar-dash/bizar-design/desktop/agents.html +0 -74
  362. package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
  363. package/bizar-dash/bizar-design/desktop/memory.html +0 -75
  364. package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
  365. package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
  366. package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
  367. package/bizar-dash/bizar-design/desktop/overview.html +0 -95
  368. package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
  369. package/bizar-dash/bizar-design/desktop/settings.html +0 -70
  370. package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
  371. package/bizar-dash/bizar-design/icons.svg +0 -44
  372. package/bizar-dash/bizar-design/index.html +0 -192
  373. package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
  374. package/bizar-dash/bizar-design/mobile/agents.html +0 -29
  375. package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
  376. package/bizar-dash/bizar-design/mobile/memory.html +0 -28
  377. package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
  378. package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
  379. package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
  380. package/bizar-dash/bizar-design/mobile/overview.html +0 -33
  381. package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
  382. package/bizar-dash/bizar-design/mobile/settings.html +0 -28
  383. package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
  384. package/bizar-dash/bizar-design/prototype.js +0 -114
  385. package/bizar-dash/bizar-design/tokens.css +0 -106
  386. package/bizar-dash/dist/assets/MobileChat-BnKN_Ks_.js +0 -1
  387. package/bizar-dash/dist/assets/MobileSettings-DjCPxC-Q.js +0 -1
  388. package/bizar-dash/dist/assets/icons-Do5N2jmX.js.map +0 -1
  389. package/bizar-dash/dist/assets/main-DYiZqMrn.js +0 -18
  390. package/bizar-dash/dist/assets/main-DYiZqMrn.js.map +0 -1
  391. package/bizar-dash/dist/assets/main-ietCEg_R.css +0 -1
  392. package/bizar-dash/dist/assets/markdown-C6mXtQxD.js +0 -1
  393. package/bizar-dash/dist/assets/mobile-CMHqtLV2.js +0 -1
  394. package/bizar-dash/dist/assets/mobile-layout-3jIhHX_p.js +0 -2
  395. package/bizar-dash/dist/assets/mobile-layout-3jIhHX_p.js.map +0 -1
  396. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js +0 -40
  397. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js.map +0 -1
  398. package/bizar-dash/dist/assets/useSlashCommands-DtITw8Xv.js +0 -2
  399. package/bizar-dash/dist/assets/useSlashCommands-DtITw8Xv.js.map +0 -1
  400. package/bizar-dash/dist/assets/vendor-CeHGtduv.js +0 -29
  401. package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
  402. package/bizar-dash/node_modules/.package-lock.json +0 -6
  403. package/bizar-dash/package-lock.json +0 -6
  404. package/bizar-dash/src/server/cline-sdk.mjs +0 -132
  405. package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
  406. package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
  407. package/cli/commands/cline-cmd.mjs +0 -289
  408. package/cli/commands/validate.test.mjs +0 -379
  409. package/cli/doctor.test.mjs +0 -350
  410. package/config/cline.json.template +0 -342
  411. package/packages/sdk/src/client.ts +0 -188
  412. package/packages/sdk/src/cline-events.ts +0 -134
  413. package/packages/sdk/src/cline-types.ts +0 -66
  414. package/packages/sdk/src/cline.ts +0 -339
  415. package/packages/sdk/src/errors.ts +0 -129
  416. package/packages/sdk/src/events.ts +0 -153
  417. package/packages/sdk/src/types.ts +0 -176
  418. package/packages/sdk/tests/client.test.ts +0 -217
  419. package/packages/sdk/tests/errors.test.ts +0 -108
  420. package/packages/sdk/tests/events.test.ts +0 -139
  421. package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
  422. package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
  423. package/plugins/bizar/ARCHITECTURE.md +0 -142
  424. package/plugins/bizar/CONSTRAINTS.md +0 -67
  425. package/plugins/bizar/LICENSE +0 -21
  426. package/plugins/bizar/README.md +0 -448
  427. package/plugins/bizar/index.ts +0 -925
  428. package/plugins/bizar/package.json +0 -39
  429. package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
  430. package/plugins/bizar/src/background-state.ts +0 -641
  431. package/plugins/bizar/src/background.ts +0 -1806
  432. package/plugins/bizar/src/cline-runner.ts +0 -203
  433. package/plugins/bizar/src/clineruntime.ts +0 -227
  434. package/plugins/bizar/src/commands-impl.ts +0 -151
  435. package/plugins/bizar/src/commands.ts +0 -1799
  436. package/plugins/bizar/src/compaction.d.mts +0 -48
  437. package/plugins/bizar/src/compaction.mjs +0 -192
  438. package/plugins/bizar/src/dashboard-client.ts +0 -233
  439. package/plugins/bizar/src/event-stream.ts +0 -606
  440. package/plugins/bizar/src/fingerprint.ts +0 -120
  441. package/plugins/bizar/src/handoff.ts +0 -79
  442. package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
  443. package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
  444. package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
  445. package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
  446. package/plugins/bizar/src/http-client.ts +0 -467
  447. package/plugins/bizar/src/key-rotation.ts +0 -218
  448. package/plugins/bizar/src/logger.ts +0 -144
  449. package/plugins/bizar/src/loop-engineering.ts +0 -241
  450. package/plugins/bizar/src/loop.ts +0 -176
  451. package/plugins/bizar/src/mistake-recovery.ts +0 -98
  452. package/plugins/bizar/src/odin.ts +0 -227
  453. package/plugins/bizar/src/options.ts +0 -470
  454. package/plugins/bizar/src/plan-fs.ts +0 -323
  455. package/plugins/bizar/src/reasoning-clean.ts +0 -454
  456. package/plugins/bizar/src/report.ts +0 -178
  457. package/plugins/bizar/src/research-prompt.ts +0 -35
  458. package/plugins/bizar/src/serve-info.ts +0 -228
  459. package/plugins/bizar/src/serve.ts +0 -496
  460. package/plugins/bizar/src/settings.ts +0 -349
  461. package/plugins/bizar/src/state.ts +0 -298
  462. package/plugins/bizar/src/tool-discipline.ts +0 -105
  463. package/plugins/bizar/src/tools/agent-browser.ts +0 -315
  464. package/plugins/bizar/src/tools/bg-collect.ts +0 -131
  465. package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
  466. package/plugins/bizar/src/tools/bg-kill.ts +0 -116
  467. package/plugins/bizar/src/tools/bg-pause.ts +0 -99
  468. package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
  469. package/plugins/bizar/src/tools/bg-resume.ts +0 -94
  470. package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
  471. package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
  472. package/plugins/bizar/src/tools/bg-status.ts +0 -130
  473. package/plugins/bizar/src/tools/graph-query.ts +0 -278
  474. package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
  475. package/plugins/bizar/src/tools/memory-list.ts +0 -43
  476. package/plugins/bizar/src/tools/memory-read.ts +0 -69
  477. package/plugins/bizar/src/tools/memory-search.ts +0 -47
  478. package/plugins/bizar/src/tools/memory-write.ts +0 -54
  479. package/plugins/bizar/src/tools/open-kb.ts +0 -198
  480. package/plugins/bizar/src/tools/plan-action.ts +0 -785
  481. package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
  482. package/plugins/bizar/src/tools/sandbox.ts +0 -232
  483. package/plugins/bizar/src/tools/team-spawn.ts +0 -73
  484. package/plugins/bizar/src/tools/team-status.ts +0 -76
  485. package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
  486. package/plugins/bizar/src/trajectory.ts +0 -104
  487. package/plugins/bizar/tests/README.md +0 -99
  488. package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
  489. package/plugins/bizar/tests/background-state.test.ts +0 -277
  490. package/plugins/bizar/tests/background.test.ts +0 -402
  491. package/plugins/bizar/tests/block.test.ts +0 -195
  492. package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
  493. package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
  494. package/plugins/bizar/tests/commands-impl.test.ts +0 -316
  495. package/plugins/bizar/tests/commands.test.ts +0 -584
  496. package/plugins/bizar/tests/compaction.test.ts +0 -264
  497. package/plugins/bizar/tests/config.test.ts +0 -128
  498. package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
  499. package/plugins/bizar/tests/dispose.test.ts +0 -336
  500. package/plugins/bizar/tests/event-stream.test.ts +0 -409
  501. package/plugins/bizar/tests/event.test.ts +0 -262
  502. package/plugins/bizar/tests/fingerprint.test.ts +0 -190
  503. package/plugins/bizar/tests/http-client.test.ts +0 -404
  504. package/plugins/bizar/tests/init-helpers.test.ts +0 -203
  505. package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
  506. package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
  507. package/plugins/bizar/tests/key-rotation.test.ts +0 -396
  508. package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
  509. package/plugins/bizar/tests/loop.test.ts +0 -397
  510. package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
  511. package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
  512. package/plugins/bizar/tests/odin.test.ts +0 -125
  513. package/plugins/bizar/tests/options.test.ts +0 -329
  514. package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
  515. package/plugins/bizar/tests/safety.test.ts +0 -281
  516. package/plugins/bizar/tests/serve.test.ts +0 -339
  517. package/plugins/bizar/tests/settings.test.ts +0 -351
  518. package/plugins/bizar/tests/stall-think.test.ts +0 -750
  519. package/plugins/bizar/tests/state.test.ts +0 -276
  520. package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
  521. package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
  522. package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
  523. package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
  524. package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
  525. package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
  526. package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
  527. package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
  528. package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
  529. package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
  530. package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
  531. package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
  532. package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
  533. package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
  534. package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
  535. package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
  536. package/plugins/bizar/tests/tools/sandbox.test.ts +0 -117
  537. package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
  538. package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
  539. package/plugins/bizar/tsconfig.json +0 -29
  540. package/scripts/mirror-agents-md.sh +0 -69
@@ -1,606 +0,0 @@
1
- /**
2
- * event-stream.ts
3
- *
4
- * Global SSE subscription for cline serve events (v0.4.2 spec §2.1, §4).
5
- *
6
- * Design contract:
7
- * - ONE `GET /event?directory=<worktree>` connection per plugin process.
8
- * - Events are filtered in-memory by `sessionID` and dispatched to
9
- * per-session handlers registered via `onSessionEvent`.
10
- * - The connection auto-reconnects with exponential backoff
11
- * (1s, 2s, 4s, 8s, 16s, capped at 30s) on unexpected drops.
12
- * - During the gap between drop and reconnect, in-flight instances are
13
- * NOT marked failed (they may still complete once we reconnect).
14
- * - `disconnect()` closes the stream and prevents further reconnects.
15
- *
16
- * v0.4.3 — CloudEvents-style schema support (see
17
- * `.bizar/cline-sse-investigation.md`):
18
- * - The actual event schema on cline serve 1.17.7 has two flavors:
19
- *
20
- * 1) **Direct events** (flat JSON, native `type` field):
21
- * ```
22
- * { id, type: "session.idle", properties: { sessionID } }
23
- * { id, type: "message.part.delta", properties: { sessionID, ... } }
24
- * ```
25
- *
26
- * 2) **Sync events** (CloudEvents-style, wrapped):
27
- * ```
28
- * { type: "sync", syncEvent: {
29
- * type: "session.created.1", // `.1` version suffix
30
- * id, seq, aggregateID,
31
- * data: { sessionID, info }
32
- * }}
33
- * ```
34
- * Sync events are the primary delivery mechanism for session and
35
- * message lifecycle events. Event names like `session.created.1`,
36
- * `message.part.updated.1` carry a numeric version suffix.
37
- *
38
- * - This module unwraps sync events and strips the version suffix so
39
- * downstream consumers (InstanceManager) see the same logical
40
- * `StreamEvent` shape regardless of which wire format arrived.
41
- *
42
- * This module is a pure transport. The `InstanceManager` registers a
43
- * handler per instance that does the actual state work (tool counting,
44
- * loop-guard detection, status transitions, awaiting collect).
45
- */
46
-
47
- import type { HttpClient, HttpResult } from "./http-client.js";
48
-
49
- // --- Logger interface -----------------------------------------------------
50
-
51
- /**
52
- * Minimal Logger interface — matches the shape in `state.ts` / `logger.ts`.
53
- */
54
- export interface Logger {
55
- log(opts: { level: "debug" | "info" | "warn" | "error"; message: string }): void;
56
- debug(message: string): void;
57
- info(message: string): void;
58
- warn(message: string): void;
59
- error(message: string): void;
60
- }
61
-
62
- // --- Public event types ---------------------------------------------------
63
-
64
- /**
65
- * The subset of session lifecycle events the plugin cares about. Each
66
- * variant carries a `sessionID` plus the event-specific payload.
67
- *
68
- * The `type` field follows cline's event namespacing
69
- * (`session.created`, `session.idle`, `message.part.updated`, …).
70
- *
71
- * Note: there is no catch-all variant on purpose. The catch-all would
72
- * have `type: string` which would defeat type narrowing on
73
- * `ev.type === "session.idle"` checks. Untyped events are dropped
74
- * silently in `dispatchEvent`.
75
- */
76
- export type StreamEvent =
77
- | { type: "session.created"; sessionID: string; raw: unknown }
78
- | { type: "session.updated"; sessionID: string; raw: unknown }
79
- | { type: "session.deleted"; sessionID: string; raw: unknown }
80
- | { type: "session.idle"; sessionID: string; raw: unknown }
81
- | { type: "session.error"; sessionID: string; error?: string; raw: unknown }
82
- | { type: "message.updated"; sessionID: string; messageID: string; raw: unknown }
83
- | {
84
- type: "message.part.updated";
85
- sessionID: string;
86
- messageID: string;
87
- partID: string;
88
- part: { type: string; text?: string; error?: string; state?: { status?: string; error?: string } };
89
- raw: unknown;
90
- };
91
-
92
- /**
93
- * A per-session event handler. Called for every event whose `sessionID`
94
- * matches the registration. Handlers are called synchronously; long
95
- * work should be scheduled (await / setImmediate) inside the handler.
96
- */
97
- export type SessionEventHandler = (event: StreamEvent) => void;
98
-
99
- // --- Stream class ---------------------------------------------------------
100
-
101
- /**
102
- * Owns the single global SSE connection. The plugin constructs one
103
- * instance at init time and disposes it on plugin shutdown.
104
- *
105
- * Public surface (interface contract for Thor's tests):
106
- * - `connect()` — open the SSE stream. Idempotent (no-op if already connected).
107
- * - `disconnect()` — close the stream; stop reconnecting.
108
- * - `onSessionEvent(sessionId, handler)` — register a per-session handler.
109
- * Returns an unsubscribe function.
110
- *
111
- * Internal lifecycle (not part of the contract):
112
- * - `readLoop()` runs until disconnect; on error, schedules a reconnect.
113
- * - `parseSseChunk()` splits a raw chunk into individual events.
114
- * - `dispatch()` routes each event to handlers whose `sessionID` matches.
115
- */
116
- export class EventStream {
117
- private _baseUrl: string;
118
- private _directory: string;
119
- private _authHeader: string;
120
- private _logger: Logger;
121
- private _http: HttpClient;
122
- private _handlers = new Map<string, Set<SessionEventHandler>>();
123
- /** Global handler invoked for every event regardless of session (v0.7.0). */
124
- private _globalHandler: SessionEventHandler | null = null;
125
- private _connected = false;
126
- private _aborted = false;
127
- private _abortController: AbortController | null = null;
128
- private _reader: ReadableStreamDefaultReader<Uint8Array> | null = null;
129
- private _reconnectAttempt = 0;
130
- private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;
131
- private _connectPromise: Promise<void> | null = null;
132
-
133
- /**
134
- * Register a global handler invoked for every event (regardless of
135
- * session). Used to forward events to the dashboard publisher. Returns
136
- * an unsubscribe function. (v0.7.0-alpha.1 — wired into the v2
137
- * SDK dashboard-client.ts bridge.)
138
- */
139
- onEvent(handler: SessionEventHandler): () => void {
140
- this._globalHandler = handler;
141
- return () => {
142
- if (this._globalHandler === handler) {
143
- this._globalHandler = null;
144
- }
145
- };
146
- }
147
-
148
- constructor(opts: {
149
- baseUrl: string;
150
- directory: string;
151
- authHeader: string;
152
- logger: Logger;
153
- http: HttpClient;
154
- }) {
155
- this._baseUrl = opts.baseUrl.replace(/\/+$/, "");
156
- this._directory = opts.directory;
157
- this._authHeader = opts.authHeader;
158
- this._logger = opts.logger;
159
- this._http = opts.http;
160
- }
161
-
162
- // --- Getters ------------------------------------------------------------
163
-
164
- get connected(): boolean {
165
- return this._connected;
166
- }
167
-
168
- get directory(): string {
169
- return this._directory;
170
- }
171
-
172
- // --- Lifecycle ----------------------------------------------------------
173
-
174
- /**
175
- * Open the SSE connection. Idempotent: a second call while a connection
176
- * is in progress is a no-op that returns the in-flight promise.
177
- *
178
- * The first read block-waits up to 5s for the initial event so the
179
- * caller can confirm the connection is alive (spec §2.1).
180
- */
181
- async connect(): Promise<void> {
182
- if (this._aborted) {
183
- throw new Error("EventStream: cannot connect after disconnect()");
184
- }
185
- if (this._connectPromise !== null) {
186
- return this._connectPromise;
187
- }
188
- this._connectPromise = this.openConnection();
189
- try {
190
- await this._connectPromise;
191
- } finally {
192
- this._connectPromise = null;
193
- }
194
- }
195
-
196
- /**
197
- * Close the stream and stop further reconnects. Idempotent.
198
- */
199
- async disconnect(): Promise<void> {
200
- this._aborted = true;
201
- if (this._reconnectTimer !== null) {
202
- clearTimeout(this._reconnectTimer);
203
- this._reconnectTimer = null;
204
- }
205
- if (this._abortController !== null) {
206
- try {
207
- this._abortController.abort();
208
- } catch {
209
- // ignore
210
- }
211
- this._abortController = null;
212
- }
213
- if (this._reader !== null) {
214
- try {
215
- await this._reader.cancel();
216
- } catch {
217
- // ignore
218
- }
219
- try {
220
- this._reader.releaseLock();
221
- } catch {
222
- // ignore
223
- }
224
- this._reader = null;
225
- }
226
- this._connected = false;
227
- }
228
-
229
- /**
230
- * Register a handler for events of one session. Returns an unsubscribe
231
- * function. Multiple handlers per session are allowed.
232
- */
233
- onSessionEvent(sessionId: string, handler: SessionEventHandler): () => void {
234
- if (typeof sessionId !== "string" || sessionId.length === 0) {
235
- throw new Error("EventStream.onSessionEvent: sessionId must be non-empty");
236
- }
237
- let set = this._handlers.get(sessionId);
238
- if (!set) {
239
- set = new Set();
240
- this._handlers.set(sessionId, set);
241
- }
242
- set.add(handler);
243
- return () => {
244
- const s = this._handlers.get(sessionId);
245
- if (!s) return;
246
- s.delete(handler);
247
- if (s.size === 0) this._handlers.delete(sessionId);
248
- };
249
- }
250
-
251
- // --- Internal: connection lifecycle ------------------------------------
252
-
253
- private async openConnection(): Promise<void> {
254
- this._abortController = new AbortController();
255
- const result: HttpResult<ReadableStream> = await this._http.fetchEventStream(
256
- this._directory,
257
- this._abortController.signal,
258
- );
259
- if (!result.ok) {
260
- this._connected = false;
261
- throw new Error(`EventStream: failed to open SSE: ${result.error}`);
262
- }
263
- this._connected = true;
264
- this._reconnectAttempt = 0;
265
- this._logger.info(
266
- `bizar: SSE event stream open (directory=${this._directory})`,
267
- );
268
- // Start the read loop in the background.
269
- void this.readLoop(result.value);
270
- }
271
-
272
- /**
273
- * Read the SSE stream chunk by chunk, parse events, and dispatch them.
274
- * On error, schedule a reconnect (unless we're aborted).
275
- */
276
- private async readLoop(stream: ReadableStream<Uint8Array>): Promise<void> {
277
- const reader = stream.getReader() as ReadableStreamDefaultReader<Uint8Array>;
278
- this._reader = reader;
279
- const decoder = new TextDecoder("utf-8");
280
- let buffer = "";
281
- try {
282
- while (!this._aborted) {
283
- const { done, value } = await reader.read();
284
- if (done) {
285
- // Stream closed cleanly. This is unexpected unless we initiated it.
286
- if (!this._aborted) {
287
- this._logger.warn("bizar: SSE stream closed unexpectedly; will reconnect");
288
- this.scheduleReconnect();
289
- }
290
- return;
291
- }
292
- const chunk = decoder.decode(value, { stream: true });
293
- buffer += chunk;
294
- // Process as many complete events as we have.
295
- let sep: number;
296
- // SSE events are separated by a blank line (\n\n or \r\n\r\n).
297
- while ((sep = buffer.indexOf("\n\n")) >= 0 || (sep = buffer.indexOf("\r\n\r\n")) >= 0) {
298
- const rawEvent = buffer.slice(0, sep);
299
- buffer = buffer.slice(sep + (buffer[sep] === "\r" ? 4 : 2));
300
- this.processSseBlock(rawEvent);
301
- }
302
- }
303
- } catch (err: unknown) {
304
- if (this._aborted) return;
305
- const msg = err instanceof Error ? err.message : String(err);
306
- this._logger.warn(`bizar: SSE read error: ${msg}; will reconnect`);
307
- this.scheduleReconnect();
308
- } finally {
309
- this._connected = false;
310
- try {
311
- this._reader?.releaseLock();
312
- } catch {
313
- // ignore
314
- }
315
- this._reader = null;
316
- }
317
- }
318
-
319
- private processSseBlock(block: string): void {
320
- if (block.trim() === "") return;
321
- // An SSE block has lines like `event: <name>` and `data: <payload>`.
322
- // Some servers only send `data:`. We treat unknown prefix lines as
323
- // comments and skip them.
324
- let eventName: string | null = null;
325
- const dataLines: string[] = [];
326
- for (const line of block.split(/\r?\n/)) {
327
- if (line === "" || line.startsWith(":")) continue;
328
- const colon = line.indexOf(":");
329
- if (colon < 0) continue;
330
- const field = line.slice(0, colon);
331
- let value = line.slice(colon + 1);
332
- if (value.startsWith(" ")) value = value.slice(1);
333
- if (field === "event") {
334
- eventName = value;
335
- } else if (field === "data") {
336
- dataLines.push(value);
337
- }
338
- }
339
- if (dataLines.length === 0) return;
340
- const data = dataLines.join("\n");
341
- let parsed: unknown;
342
- try {
343
- parsed = JSON.parse(data);
344
- } catch {
345
- this._logger.debug(`bizar: SSE: dropping non-JSON data (${data.slice(0, 80)}…)`);
346
- return;
347
- }
348
- this.dispatchEvent(eventName, parsed);
349
- }
350
-
351
- /**
352
- * Map a raw cline event to a `StreamEvent` and dispatch to handlers.
353
- *
354
- * v0.4.3: handles two wire formats.
355
- * 1) Direct events — `{type, properties: {sessionID, ...}}`.
356
- * 2) Sync events — `{type: "sync", syncEvent: {type: "x.y.1", data: {...}}}`.
357
- * We unwrap the sync wrapper and set `obj` to `syncEvent.data` so
358
- * downstream code can read `obj.sessionID`, `obj.part`, etc.
359
- *
360
- * After unwrapping, the event type from sync events has a version
361
- * suffix (e.g. `session.created.1`). We strip the suffix so
362
- * downstream code can match on `session.created` (the version is
363
- * for the wire format, not the plugin's logical event name).
364
- */
365
- private dispatchEvent(eventName: string | null, raw: unknown): void {
366
- let obj = raw as Record<string, unknown> | null;
367
- if (obj === null || typeof obj !== "object") return;
368
-
369
- // Step 1: Detect sync event wrapper, unwrap to the inner data.
370
- // Sync events have shape: {type: "sync", syncEvent: {type: "x.y.1", data: {...}}}
371
- // After unwrap, obj points to the inner data so the rest of this
372
- // method can read fields directly (obj.sessionID, obj.part, etc.).
373
- let innerType: string | null = null;
374
- if (obj.type === "sync" && obj.syncEvent) {
375
- const syncEvent = obj.syncEvent as Record<string, unknown> | null;
376
- if (syncEvent && typeof syncEvent === "object") {
377
- if (typeof syncEvent.type === "string") innerType = syncEvent.type;
378
- const syncData = syncEvent.data;
379
- if (syncData && typeof syncData === "object") {
380
- obj = syncData as Record<string, unknown>;
381
- }
382
- }
383
- }
384
-
385
- // Step 2: Resolve the event type and strip the version suffix.
386
- // Sync event types look like "session.created.1"; we strip to "session.created".
387
- const typeFromObj = innerType ?? (typeof obj.type === "string" ? obj.type : null);
388
- const rawType = typeFromObj ?? eventName ?? "unknown";
389
- const type = stripVersionSuffix(rawType);
390
-
391
- const sessionID = extractSessionId(obj);
392
- const messageID = extractMessageId(obj);
393
- // After unwrap, `obj.part` exists for `message.part.updated.*` events
394
- // (sync) and may exist on the top-level payload. We also fall back to
395
- // `obj.partID` on the part object itself for sync events whose
396
- // `data` block does not carry `partID` separately.
397
- const part = obj.part as { type?: string; text?: string; error?: string; state?: { status?: string; error?: string }; id?: string } | undefined;
398
- const partID = extractPartId(obj, part);
399
-
400
- // Build the typed event. We use a temporary permissive shape and only
401
- // assign to a strongly-typed StreamEvent at the end of each branch.
402
- let event: StreamEvent | null = null;
403
- if (type === "message.part.updated" && sessionID && part) {
404
- const partShape: { type: string; text?: string; error?: string; state?: { status?: string; error?: string } } = {
405
- type: part.type ?? "unknown",
406
- };
407
- if (part.text !== undefined) partShape.text = part.text;
408
- if (part.error !== undefined) partShape.error = part.error;
409
- if (part.state !== undefined) partShape.state = part.state;
410
- event = {
411
- type: "message.part.updated",
412
- sessionID,
413
- messageID: messageID ?? "",
414
- partID,
415
- part: partShape,
416
- raw,
417
- };
418
- } else if (type === "message.updated" && sessionID) {
419
- event = { type: "message.updated", sessionID, messageID: messageID ?? "", raw };
420
- } else if (type === "session.error" && sessionID) {
421
- // session.error may carry the error string on `properties.error`
422
- // (direct event) or on `data.error` (sync, but we already
423
- // unwrapped, so both paths land at `obj.error`).
424
- const props = obj.properties;
425
- let errorField: string | undefined =
426
- typeof obj.error === "string" ? obj.error : undefined;
427
- if (errorField === undefined && props && typeof props === "object") {
428
- const p = props as Record<string, unknown>;
429
- if (typeof p.error === "string") errorField = p.error;
430
- }
431
- event = errorField !== undefined
432
- ? { type: "session.error", sessionID, error: errorField, raw }
433
- : { type: "session.error", sessionID, raw };
434
- } else if (type === "session.idle" && sessionID) {
435
- event = { type: "session.idle", sessionID, raw };
436
- } else if (type === "session.created" && sessionID) {
437
- event = { type: "session.created", sessionID, raw };
438
- } else if (type === "session.updated" && sessionID) {
439
- event = { type: "session.updated", sessionID, raw };
440
- } else if (type === "session.deleted" && sessionID) {
441
- event = { type: "session.deleted", sessionID, raw };
442
- } else {
443
- // Unknown / untyped event — drop silently. Logged at debug level.
444
- // We log the *raw* type (with version suffix) for diagnostics.
445
- this._logger.debug(
446
- `bizar: SSE: dropping untyped event (rawType=${rawType}${sessionID ? ` sessionID=${sessionID}` : ""})`,
447
- );
448
- return;
449
- }
450
-
451
- if (event === null) {
452
- this._logger.debug(`bizar: SSE: event without sessionID (rawType=${rawType})`);
453
- return;
454
- }
455
- this.dispatchToHandlers(sessionID, event);
456
- }
457
-
458
- private dispatchToHandlers(sessionID: string, event: StreamEvent): void {
459
- // v0.7.0-alpha.1 — Forward every event to the global handler
460
- // (typically the dashboard publisher) BEFORE the per-session dispatch.
461
- // Failures here are isolated so one bad handler doesn't break the
462
- // dispatch chain for other subscribers.
463
- if (this._globalHandler) {
464
- try {
465
- this._globalHandler(event);
466
- } catch (err: unknown) {
467
- const msg = err instanceof Error ? err.message : String(err);
468
- this._logger.warn(
469
- `bizar: SSE global handler threw for session ${sessionID} (type=${event.type}): ${msg}`,
470
- );
471
- }
472
- }
473
-
474
- const set = this._handlers.get(sessionID);
475
- if (!set || set.size === 0) {
476
- this._logger.debug(
477
- `bizar: SSE event for untracked session ${sessionID} (type=${event.type})`,
478
- );
479
- return;
480
- }
481
- // Snapshot to avoid mutation during iteration.
482
- for (const handler of [...set]) {
483
- try {
484
- handler(event);
485
- } catch (err: unknown) {
486
- const msg = err instanceof Error ? err.message : String(err);
487
- this._logger.warn(
488
- `bizar: SSE handler threw for session ${sessionID} (type=${event.type}): ${msg}`,
489
- );
490
- }
491
- }
492
- }
493
-
494
- // --- Reconnect ----------------------------------------------------------
495
-
496
- private scheduleReconnect(): void {
497
- if (this._aborted) return;
498
- if (this._reconnectTimer !== null) return;
499
- // Exponential backoff: 1s, 2s, 4s, 8s, 16s, capped at 30s.
500
- const base = 1000 * Math.pow(2, this._reconnectAttempt);
501
- const delay = Math.min(30_000, base);
502
- this._reconnectAttempt += 1;
503
- this._logger.warn(`bizar: SSE reconnecting in ${delay}ms (attempt ${this._reconnectAttempt})`);
504
- this._reconnectTimer = setTimeout(() => {
505
- this._reconnectTimer = null;
506
- if (this._aborted) return;
507
- void this.attemptReconnect();
508
- }, delay);
509
- }
510
-
511
- private async attemptReconnect(): Promise<void> {
512
- try {
513
- this._abortController = new AbortController();
514
- const result = await this._http.fetchEventStream(
515
- this._directory,
516
- this._abortController.signal,
517
- );
518
- if (!result.ok) {
519
- this._logger.warn(`bizar: SSE reconnect failed: ${result.error}`);
520
- this.scheduleReconnect();
521
- return;
522
- }
523
- this._connected = true;
524
- this._reconnectAttempt = 0;
525
- this._logger.info("bizar: SSE reconnected");
526
- void this.readLoop(result.value);
527
- } catch (err: unknown) {
528
- if (this._aborted) return;
529
- const msg = err instanceof Error ? err.message : String(err);
530
- this._logger.warn(`bizar: SSE reconnect threw: ${msg}`);
531
- this.scheduleReconnect();
532
- }
533
- }
534
- }
535
-
536
- // --- Helpers --------------------------------------------------------------
537
-
538
- /**
539
- * Extract the `sessionID` from an cline event payload.
540
- *
541
- * v0.4.3: this is called AFTER sync unwrapping, so the `obj` we receive
542
- * is either:
543
- * - A direct event: `{properties: {sessionID}}` or `{sessionID}`.
544
- * - A sync event's `data` block: `{sessionID, ...}` (top-level).
545
- *
546
- * We check (in order):
547
- * 1. `properties.sessionID` / `properties.sessionId` (direct events)
548
- * 2. Top-level `sessionID` / `sessionId` (direct or post-unwrapped sync)
549
- *
550
- * Returns `undefined` if none of those is present.
551
- */
552
- function extractSessionId(obj: Record<string, unknown>): string | undefined {
553
- const props = obj.properties;
554
- if (props && typeof props === "object") {
555
- const p = props as Record<string, unknown>;
556
- if (typeof p.sessionID === "string" && p.sessionID.length > 0) return p.sessionID;
557
- if (typeof p.sessionId === "string" && p.sessionId.length > 0) return p.sessionId;
558
- }
559
- if (typeof obj.sessionID === "string" && obj.sessionID.length > 0) return obj.sessionID;
560
- if (typeof obj.sessionId === "string" && obj.sessionId.length > 0) return obj.sessionId;
561
- return undefined;
562
- }
563
-
564
- function extractMessageId(obj: Record<string, unknown>): string | undefined {
565
- const props = obj.properties;
566
- if (props && typeof props === "object") {
567
- const p = props as Record<string, unknown>;
568
- if (typeof p.messageID === "string") return p.messageID;
569
- if (typeof p.messageId === "string") return p.messageId;
570
- }
571
- if (typeof obj.messageID === "string") return obj.messageID;
572
- if (typeof obj.messageId === "string") return obj.messageId;
573
- return undefined;
574
- }
575
-
576
- /**
577
- * Extract the `partID` from an event payload. We check (in order):
578
- * 1. `properties.partID` (direct events like `message.part.delta`)
579
- * 2. Top-level `partID` (after sync unwrap, if the data block carries it)
580
- * 3. `part.id` (sync `message.part.updated.1` — the part object itself
581
- * carries its own id)
582
- */
583
- function extractPartId(
584
- obj: Record<string, unknown>,
585
- part: { id?: string } | undefined,
586
- ): string {
587
- const props = obj.properties;
588
- if (props && typeof props === "object") {
589
- const p = props as Record<string, unknown>;
590
- if (typeof p.partID === "string" && p.partID.length > 0) return p.partID;
591
- if (typeof p.partId === "string" && p.partId.length > 0) return p.partId;
592
- }
593
- if (typeof obj.partID === "string" && obj.partID.length > 0) return obj.partID;
594
- if (typeof obj.partId === "string" && obj.partId.length > 0) return obj.partId;
595
- if (part && typeof part.id === "string" && part.id.length > 0) return part.id;
596
- return "";
597
- }
598
-
599
- /**
600
- * Strip a trailing version suffix from an event type.
601
- * e.g. `"session.created.1"` → `"session.created"`, `"foo.bar.baz.12"` → `"foo.bar.baz"`.
602
- * If the type has no `.N` suffix at the end, it is returned unchanged.
603
- */
604
- function stripVersionSuffix(type: string): string {
605
- return type.replace(/\.\d+$/, "");
606
- }