@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,203 +0,0 @@
1
- /**
2
- * Init-helpers regression tests (v0.5.2).
3
- *
4
- * Covers the postmortem-2026-06-18 Layer 1 fix: `client.session.list()`
5
- * is now raced against a 1-second timeout. Without this, a slow or
6
- * broken session store would hang the plugin's `init()` forever and
7
- * stall the UI on a blank screen.
8
- *
9
- * Two layers of test:
10
- * 1) `withTimeout` — pure unit tests on the timeout helper itself.
11
- * 2) `readValidSessionIds` — integration-style test that passes a
12
- * fake `PluginInput` whose `client.session.list()` never resolves
13
- * and verifies that the function returns within ~1.1s.
14
- *
15
- * The second test is what would have caught the original bug: the
16
- * function must NOT block forever on a slow session store.
17
- */
18
-
19
- import { describe, test, expect } from "bun:test";
20
-
21
- import {
22
- withTimeout,
23
- readValidSessionIds,
24
- } from "../index.js";
25
-
26
- // ---------------------------------------------------------------------------
27
- // `withTimeout` — pure unit tests
28
- // ---------------------------------------------------------------------------
29
-
30
- describe("withTimeout", () => {
31
- test("resolves with the promise's value when it completes in time", async () => {
32
- const result = await withTimeout(
33
- Promise.resolve("ok"),
34
- 1000,
35
- "test",
36
- );
37
- expect(result).toBe("ok");
38
- });
39
-
40
- test("rejects with a labeled error when the promise takes too long", async () => {
41
- const hanging = new Promise<string>(() => {
42
- // never resolves
43
- });
44
- const start = Date.now();
45
- let caught: Error | null = null;
46
- try {
47
- await withTimeout(hanging, 100, "hanging-promise");
48
- } catch (err) {
49
- caught = err as Error;
50
- }
51
- const elapsed = Date.now() - start;
52
- expect(caught).not.toBeNull();
53
- expect(caught?.message).toContain("hanging-promise");
54
- expect(caught?.message).toContain("100ms");
55
- // Should fire within ~100ms (allow 50ms of slack for event-loop jitter).
56
- expect(elapsed).toBeGreaterThanOrEqual(95);
57
- expect(elapsed).toBeLessThan(500);
58
- });
59
-
60
- test("propagates rejections from the underlying promise", async () => {
61
- const failing = Promise.reject(new Error("underlying failure"));
62
- let caught: Error | null = null;
63
- try {
64
- await withTimeout(failing, 1000, "test");
65
- } catch (err) {
66
- caught = err as Error;
67
- }
68
- expect(caught).not.toBeNull();
69
- expect(caught?.message).toBe("underlying failure");
70
- });
71
-
72
- test("clears the timer on success (no late rejection)", async () => {
73
- // Resolve after 50ms, well within the 1000ms timeout. The timer
74
- // should be cleared; we can't directly observe the cleanup, but
75
- // the test verifies the function returns the value without ever
76
- // throwing (the cleared timer's callback never fires).
77
- const result = await withTimeout(
78
- new Promise((resolve) => setTimeout(() => resolve("late"), 50)),
79
- 1000,
80
- "test",
81
- );
82
- expect(result).toBe("late");
83
- // Wait long enough that a leaked timer would have fired.
84
- await new Promise((r) => setTimeout(r, 100));
85
- });
86
- });
87
-
88
- // ---------------------------------------------------------------------------
89
- // `readValidSessionIds` — the postmortem Layer 1 fix
90
- // ---------------------------------------------------------------------------
91
-
92
- /**
93
- * Minimal `PluginInput` shape for testing `readValidSessionIds`. We
94
- * only need `client`; the other fields are never read by the
95
- * function under test.
96
- */
97
- function makeInput(client: unknown): { client: unknown } {
98
- return { client } as never;
99
- }
100
-
101
- describe("readValidSessionIds — postmortem Layer 1 fix (v0.5.2)", () => {
102
- test("returns the session IDs when client.session.list() resolves", async () => {
103
- const input = makeInput({
104
- session: {
105
- list: async () => ({
106
- data: [
107
- { id: "ses_a" },
108
- { id: "ses_b" },
109
- ],
110
- }),
111
- },
112
- });
113
- const ids = await readValidSessionIds(input as never);
114
- expect(ids).toBeInstanceOf(Set);
115
- expect([...ids].sort()).toEqual(["ses_a", "ses_b"]);
116
- });
117
-
118
- test("returns the session IDs when client.session.list() returns an array directly", async () => {
119
- const input = makeInput({
120
- session: {
121
- list: async () => [{ id: "ses_x" }, { id: "ses_y" }],
122
- },
123
- });
124
- const ids = await readValidSessionIds(input as never);
125
- expect([...ids].sort()).toEqual(["ses_x", "ses_y"]);
126
- });
127
-
128
- test("returns empty set when client.session is missing", async () => {
129
- const input = makeInput({});
130
- const ids = await readValidSessionIds(input as never);
131
- expect(ids.size).toBe(0);
132
- });
133
-
134
- test("returns empty set when client.session.list is not a function", async () => {
135
- const input = makeInput({ session: { list: "not-a-function" } });
136
- const ids = await readValidSessionIds(input as never);
137
- expect(ids.size).toBe(0);
138
- });
139
-
140
- test("returns empty set when client.session.list() rejects", async () => {
141
- const input = makeInput({
142
- session: {
143
- list: async () => {
144
- throw new Error("session store down");
145
- },
146
- },
147
- });
148
- const ids = await readValidSessionIds(input as never);
149
- expect(ids.size).toBe(0);
150
- });
151
-
152
- test(
153
- "REGRESSION: returns within 1.5s when client.session.list() hangs forever (postmortem Layer 1)",
154
- async () => {
155
- // This is the actual bug from the 2026-06-18 postmortem. Before
156
- // the fix, the call would hang forever and the plugin's `init()`
157
- // would never resolve.
158
- const input = makeInput({
159
- session: {
160
- list: () => new Promise(() => {
161
- // never resolves — simulates a stuck session store
162
- }),
163
- },
164
- });
165
- const start = Date.now();
166
- const ids = await readValidSessionIds(input as never);
167
- const elapsed = Date.now() - start;
168
- // The function should return within ~1s (the timeout). We allow
169
- // 500ms of slack for event-loop jitter.
170
- expect(elapsed).toBeLessThan(1500);
171
- // The fallback is an empty set — the age-based cleanup still
172
- // runs (spec §4.6).
173
- expect(ids.size).toBe(0);
174
- },
175
- );
176
-
177
- test(
178
- "REGRESSION: late rejection from hanging list() does not crash the process",
179
- async () => {
180
- // After the 1s timeout fires, the original `list()` call may
181
- // eventually reject (or it may never). The function attaches a
182
- // no-op `.catch(() => undefined)` to suppress the unhandled-
183
- // rejection. We can't directly observe unhandled rejections in
184
- // bun:test, but we can verify the function returns cleanly.
185
- let rejectFn: ((err: Error) => void) | undefined;
186
- const input = makeInput({
187
- session: {
188
- list: () => new Promise((_, reject: (err: Error) => void) => {
189
- rejectFn = reject;
190
- }),
191
- },
192
- });
193
- const ids = await readValidSessionIds(input as never);
194
- expect(ids.size).toBe(0);
195
- // Now reject the hanging promise AFTER the function returned.
196
- // If the no-op catch is missing, this would be an unhandled
197
- // rejection. With it, the process keeps running.
198
- rejectFn?.(new Error("late rejection"));
199
- // Give the microtask queue a chance to run.
200
- await new Promise((r) => setTimeout(r, 10));
201
- },
202
- );
203
- });
@@ -1,349 +0,0 @@
1
- import { type AgentTool } from "@cline/sdk";
2
- /**
3
- * slash-command.test.ts — Integration tests for the full slash-command
4
- * hook → parser → side-effect → file-I/O path.
5
- *
6
- * Exercises:
7
- * - `/plan new foo` → `plans/foo/meta.json` + `plans/foo/plan.json` on disk
8
- * - `/plan list` → response contains slugs of seeded plans
9
- * - `/plan add foo --title X --type task` → element written to `plan.json`
10
- * - `/plan status foo approved` → `meta.json` status updated
11
- * - `/plan delete foo <elementId>` → element removed from `plan.json`
12
- * - `/plan wait foo` → deferred response (< 100 ms, no blocking)
13
- * - `/plan new foo` on existing slug → refusal, no clobber
14
- * - `/plan comment foo "text"` → comment written to `plan.json`
15
- * - `/plan comments foo` → response lists the comment
16
- */
17
-
18
- import { describe, test, expect, beforeEach, afterEach, afterAll } from "bun:test";
19
- import {
20
- mkdtempSync,
21
- rmSync,
22
- existsSync,
23
- readFileSync,
24
- writeFileSync,
25
- mkdirSync,
26
- } from "node:fs";
27
- import { join } from "node:path";
28
- import { tmpdir } from "node:os";
29
-
30
- import { parseSlashCommand } from "../../src/commands";
31
- import {
32
- executeSideEffect,
33
- type ExecutorContext,
34
- type ExecuteOptions,
35
- } from "../../src/commands-impl";
36
- import { createPlanActionTool } from "../../src/tools/plan-action";
37
- import { createBgGetCommentsTool } from "../../src/tools/bg-get-comments";
38
- import { createWaitForFeedbackTool } from "../../src/tools/wait-for-feedback";
39
- import { DEFAULT_PLAN_SETTINGS, type PlanSettings } from "../../src/settings";
40
-
41
- // ---------------------------------------------------------------------------
42
- // Mock logger
43
- // ---------------------------------------------------------------------------
44
-
45
- class MockLogger {
46
- messages: Array<{ level: string; message: string }> = [];
47
- log(opts: { level: string; message: string }) { this.messages.push(opts); }
48
- debug(m: string) { this.messages.push({ level: "debug", message: m }); }
49
- info(m: string) { this.messages.push({ level: "info", message: m }); }
50
- warn(m: string) { this.messages.push({ level: "warn", message: m }); }
51
- error(m: string) { this.messages.push({ level: "error", message: m }); }
52
- }
53
-
54
- // ---------------------------------------------------------------------------
55
- // Per-test temp worktree
56
- // ---------------------------------------------------------------------------
57
-
58
- let worktree: string;
59
- let logger: MockLogger;
60
-
61
- beforeEach(() => {
62
- worktree = mkdtempSync(join(tmpdir(), "bizar-integration-"));
63
- logger = new MockLogger();
64
- });
65
-
66
- afterEach(() => {
67
- if (worktree) rmSync(worktree, { recursive: true, force: true });
68
- });
69
-
70
- afterAll(() => {
71
- // already cleaned in afterEach, but keep for safety
72
- if (worktree) rmSync(worktree, { recursive: true, force: true });
73
- });
74
-
75
- // ---------------------------------------------------------------------------
76
- // Helper: build minimal ExecutorContext + ExecuteOptions
77
- // ---------------------------------------------------------------------------
78
-
79
- function makeCtx(): ExecutorContext {
80
- return { worktree, directory: worktree, logger };
81
- }
82
-
83
- function makeOpts(): ExecuteOptions {
84
- return {
85
- tools: {
86
- bizar_plan_action: createPlanActionTool({ worktree, logger }) as unknown as AgentTool<unknown, unknown>,
87
- bizar_get_plan_comments: createBgGetCommentsTool({ worktree, logger }) as unknown as AgentTool<unknown, unknown>,
88
- bizar_wait_for_feedback: createWaitForFeedbackTool({ worktree, logger }) as unknown as AgentTool<unknown, unknown>,
89
- },
90
- defaultTemplate: "blank",
91
- defaultPort: 4321,
92
- };
93
- }
94
-
95
- // ---------------------------------------------------------------------------
96
- // Test cases
97
- // ---------------------------------------------------------------------------
98
-
99
- describe("integration: /plan new", () => {
100
- test("/plan new foo → creates plans/foo/meta.json and plan.json with correct content", async () => {
101
- const result = parseSlashCommand("/plan new foo", {
102
- currentSettings: DEFAULT_PLAN_SETTINGS,
103
- availablePlanSlugs: [],
104
- defaultPort: 4321,
105
- });
106
- expect(result).not.toBeNull();
107
- expect(result!.sideEffect!.kind).toBe("create_plan");
108
-
109
- await executeSideEffect(result!.sideEffect!, makeCtx(), makeOpts());
110
-
111
- const metaPath = join(worktree, "plans", "foo", "meta.json");
112
- const planPath = join(worktree, "plans", "foo", "plan.json");
113
- expect(existsSync(metaPath)).toBe(true);
114
- expect(existsSync(planPath)).toBe(true);
115
-
116
- const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
117
- expect(meta.status).toBe("draft");
118
- expect(meta.slug).toBeUndefined(); // slug not stored, title is titleCase
119
- expect(typeof meta.lastEdited).toBe("string");
120
-
121
- const canvas = JSON.parse(readFileSync(planPath, "utf-8"));
122
- expect(canvas.schemaVersion).toBe(2);
123
- expect(canvas.elements).toEqual([]);
124
- expect(canvas.connections).toEqual([]);
125
- expect(canvas.comments).toEqual([]);
126
- });
127
- });
128
-
129
- describe("integration: /plan list", () => {
130
- test("/plan list after creating foo and bar → response contains both slugs", async () => {
131
- // Seed two plans
132
- for (const slug of ["foo", "bar"]) {
133
- const r = parseSlashCommand(`/plan new ${slug}`, {
134
- currentSettings: DEFAULT_PLAN_SETTINGS,
135
- availablePlanSlugs: [],
136
- defaultPort: 4321,
137
- });
138
- await executeSideEffect(r!.sideEffect!, makeCtx(), makeOpts());
139
- }
140
-
141
- const listResult = parseSlashCommand("/plan list", {
142
- currentSettings: DEFAULT_PLAN_SETTINGS,
143
- availablePlanSlugs: ["foo", "bar"],
144
- defaultPort: 4321,
145
- });
146
- expect(listResult).not.toBeNull();
147
- const execResult = await executeSideEffect(listResult!.sideEffect!, makeCtx(), makeOpts());
148
- const response = execResult.responseOverride ?? listResult!.response;
149
- expect(response).toMatch(/foo/);
150
- expect(response).toMatch(/bar/);
151
- });
152
- });
153
-
154
- describe("integration: /plan add", () => {
155
- test("/plan add foo --title X --type task → plan.json contains the element", async () => {
156
- // First create the plan
157
- const newR = parseSlashCommand("/plan new foo", {
158
- currentSettings: DEFAULT_PLAN_SETTINGS,
159
- availablePlanSlugs: [],
160
- defaultPort: 4321,
161
- });
162
- await executeSideEffect(newR!.sideEffect!, makeCtx(), makeOpts());
163
-
164
- // Now add an element
165
- const addR = parseSlashCommand('/plan add foo --title X --type task', {
166
- currentSettings: DEFAULT_PLAN_SETTINGS,
167
- availablePlanSlugs: ["foo"],
168
- defaultPort: 4321,
169
- });
170
- expect(addR).not.toBeNull();
171
- expect(addR!.sideEffect!.kind).toBe("tool_invocation");
172
- const execR = await executeSideEffect(addR!.sideEffect!, makeCtx(), makeOpts());
173
-
174
- const planPath = join(worktree, "plans", "foo", "plan.json");
175
- const canvas = JSON.parse(readFileSync(planPath, "utf-8"));
176
- expect(canvas.elements).toHaveLength(1);
177
- expect(canvas.elements[0]!.title).toBe("X");
178
- expect(canvas.elements[0]!.type).toBe("task");
179
- });
180
- });
181
-
182
- describe("integration: /plan status", () => {
183
- test("/plan status foo approved → meta.json status is approved", async () => {
184
- // Create the plan first
185
- const newR = parseSlashCommand("/plan new foo", {
186
- currentSettings: DEFAULT_PLAN_SETTINGS,
187
- availablePlanSlugs: [],
188
- defaultPort: 4321,
189
- });
190
- await executeSideEffect(newR!.sideEffect!, makeCtx(), makeOpts());
191
-
192
- const statusR = parseSlashCommand("/plan status foo approved", {
193
- currentSettings: DEFAULT_PLAN_SETTINGS,
194
- availablePlanSlugs: ["foo"],
195
- defaultPort: 4321,
196
- });
197
- await executeSideEffect(statusR!.sideEffect!, makeCtx(), makeOpts());
198
-
199
- const metaPath = join(worktree, "plans", "foo", "meta.json");
200
- const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
201
- expect(meta.status).toBe("approved");
202
- });
203
- });
204
-
205
- describe("integration: /plan delete", () => {
206
- test("/plan delete foo <elementId> → element removed from plan.json", async () => {
207
- // Create plan and add an element
208
- const newR = parseSlashCommand("/plan new foo", {
209
- currentSettings: DEFAULT_PLAN_SETTINGS,
210
- availablePlanSlugs: [],
211
- defaultPort: 4321,
212
- });
213
- await executeSideEffect(newR!.sideEffect!, makeCtx(), makeOpts());
214
-
215
- const addR = parseSlashCommand('/plan add foo --title Elem1 --type task', {
216
- currentSettings: DEFAULT_PLAN_SETTINGS,
217
- availablePlanSlugs: ["foo"],
218
- defaultPort: 4321,
219
- });
220
- await executeSideEffect(addR!.sideEffect!, makeCtx(), makeOpts());
221
-
222
- // Read back to get element id
223
- const planPath = join(worktree, "plans", "foo", "plan.json");
224
- let canvas = JSON.parse(readFileSync(planPath, "utf-8")) as {
225
- elements: Array<{ id: string; title: string }>;
226
- };
227
- expect(canvas.elements).toHaveLength(1);
228
- const elementId = canvas.elements[0]!.id;
229
-
230
- // Now delete it
231
- const delR = parseSlashCommand(`/plan delete foo ${elementId}`, {
232
- currentSettings: DEFAULT_PLAN_SETTINGS,
233
- availablePlanSlugs: ["foo"],
234
- defaultPort: 4321,
235
- });
236
- await executeSideEffect(delR!.sideEffect!, makeCtx(), makeOpts());
237
-
238
- canvas = JSON.parse(readFileSync(planPath, "utf-8"));
239
- expect(canvas.elements).toHaveLength(0);
240
- });
241
- });
242
-
243
- describe("integration: /plan wait", () => {
244
- test("/plan wait foo → returns deferred response, does NOT block hook (< 100ms)", async () => {
245
- const r = parseSlashCommand("/plan wait foo", {
246
- currentSettings: DEFAULT_PLAN_SETTINGS,
247
- availablePlanSlugs: ["foo"],
248
- defaultPort: 4321,
249
- });
250
- expect(r).not.toBeNull();
251
- expect(r!.response).toMatch(/deferred/i);
252
- expect(r!.response).toMatch(/bizar_wait_for_feedback/);
253
- expect(r!.sideEffect).toBeUndefined(); // wait is NOT a tool_invocation
254
-
255
- // Verify it returns instantly (no async I/O)
256
- const start = Date.now();
257
- await executeSideEffect({ kind: "list_plans" }, makeCtx(), makeOpts()); // no-op
258
- const elapsed = Date.now() - start;
259
- expect(elapsed).toBeLessThan(100);
260
- });
261
- });
262
-
263
- describe("integration: /plan new on existing slug", () => {
264
- test("/plan new foo on existing slug → refusal response, existing files intact", async () => {
265
- // Create the plan
266
- const r1 = parseSlashCommand("/plan new foo", {
267
- currentSettings: DEFAULT_PLAN_SETTINGS,
268
- availablePlanSlugs: [],
269
- defaultPort: 4321,
270
- });
271
- await executeSideEffect(r1!.sideEffect!, makeCtx(), makeOpts());
272
-
273
- const planDir = join(worktree, "plans", "foo");
274
- const metaBefore = readFileSync(join(planDir, "meta.json"), "utf-8");
275
- const planBefore = readFileSync(join(planDir, "plan.json"), "utf-8");
276
-
277
- // Try to create again
278
- const r2 = parseSlashCommand("/plan new foo", {
279
- currentSettings: DEFAULT_PLAN_SETTINGS,
280
- availablePlanSlugs: ["foo"],
281
- defaultPort: 4321,
282
- });
283
- const execR = await executeSideEffect(r2!.sideEffect!, makeCtx(), makeOpts());
284
-
285
- // Should have refused
286
- expect(execR.responseOverride).toMatch(/already exists/);
287
-
288
- // Files should be unchanged
289
- expect(readFileSync(join(planDir, "meta.json"), "utf-8")).toBe(metaBefore);
290
- expect(readFileSync(join(planDir, "plan.json"), "utf-8")).toBe(planBefore);
291
- });
292
- });
293
-
294
- describe("integration: /plan comment", () => {
295
- test('/plan comment foo "first comment" → plan.json contains the comment', async () => {
296
- // Create the plan first
297
- const newR = parseSlashCommand("/plan new foo", {
298
- currentSettings: DEFAULT_PLAN_SETTINGS,
299
- availablePlanSlugs: [],
300
- defaultPort: 4321,
301
- });
302
- await executeSideEffect(newR!.sideEffect!, makeCtx(), makeOpts());
303
-
304
- const commentR = parseSlashCommand('/plan comment foo "first comment"', {
305
- currentSettings: DEFAULT_PLAN_SETTINGS,
306
- availablePlanSlugs: ["foo"],
307
- defaultPort: 4321,
308
- });
309
- await executeSideEffect(commentR!.sideEffect!, makeCtx(), makeOpts());
310
-
311
- const planPath = join(worktree, "plans", "foo", "plan.json");
312
- const canvas = JSON.parse(readFileSync(planPath, "utf-8")) as {
313
- comments: Array<{ id: string; text: string; author: string }>;
314
- };
315
- expect(canvas.comments).toHaveLength(1);
316
- expect(canvas.comments[0]!.text).toBe("first comment");
317
- expect(canvas.comments[0]!.author).toBe("user");
318
- });
319
- });
320
-
321
- describe("integration: /plan comments", () => {
322
- test("/plan comments foo → response lists the comment", async () => {
323
- // Create the plan first
324
- const newR = parseSlashCommand("/plan new foo", {
325
- currentSettings: DEFAULT_PLAN_SETTINGS,
326
- availablePlanSlugs: [],
327
- defaultPort: 4321,
328
- });
329
- await executeSideEffect(newR!.sideEffect!, makeCtx(), makeOpts());
330
-
331
- // Add a comment
332
- const commentR = parseSlashCommand('/plan comment foo "Hello world"', {
333
- currentSettings: DEFAULT_PLAN_SETTINGS,
334
- availablePlanSlugs: ["foo"],
335
- defaultPort: 4321,
336
- });
337
- await executeSideEffect(commentR!.sideEffect!, makeCtx(), makeOpts());
338
-
339
- // Now list comments
340
- const listR = parseSlashCommand("/plan comments foo", {
341
- currentSettings: DEFAULT_PLAN_SETTINGS,
342
- availablePlanSlugs: ["foo"],
343
- defaultPort: 4321,
344
- });
345
- const execR = await executeSideEffect(listR!.sideEffect!, makeCtx(), makeOpts());
346
- const response = execR.responseOverride ?? listR!.response;
347
- expect(response).toMatch(/Hello world/);
348
- });
349
- });
@@ -1,98 +0,0 @@
1
- /**
2
- * tool-routing.test.ts — Integration tests for the tool_invocation path
3
- * in slash commands. Phase 2 — Cline SDK port: tests the new
4
- * `AgentToolContext` shape and the Cline `createTool` API.
5
- */
6
-
7
- import { describe, test, expect, beforeAll, afterAll } from "bun:test";
8
- import { mkdtempSync, rmSync } from "node:fs";
9
- import { join } from "node:path";
10
- import { tmpdir } from "node:os";
11
-
12
- import {
13
- executeSideEffect,
14
- buildSyntheticToolContext,
15
- type ExecutorContext,
16
- type ExecuteOptions,
17
- } from "../../src/commands-impl";
18
- import { createPlanActionTool } from "../../src/tools/plan-action";
19
- import { createBgGetCommentsTool } from "../../src/tools/bg-get-comments";
20
- import { createWaitForFeedbackTool } from "../../src/tools/wait-for-feedback";
21
- import type { SideEffect } from "../../src/commands";
22
- import type { AgentTool, AgentToolContext } from "@cline/sdk";
23
-
24
- class MockLogger {
25
- messages: Array<{ level: string; message: string }> = [];
26
- debug(m: string) { this.messages.push({ level: "debug", message: m }); }
27
- info(m: string) { this.messages.push({ level: "info", message: m }); }
28
- warn(m: string) { this.messages.push({ level: "warn", message: m }); }
29
- error(m: string) { this.messages.push({ level: "error", message: m }); }
30
- log(_o: unknown) { /* swallow */ }
31
- }
32
-
33
- let worktree: string;
34
- const logger = new MockLogger();
35
-
36
- beforeAll(() => { worktree = mkdtempSync(join(tmpdir(), "bizar-tool-routing-")); });
37
- afterAll(() => { if (worktree) rmSync(worktree, { recursive: true, force: true }); });
38
-
39
- function ctx(): ExecutorContext { return { worktree, directory: worktree, logger }; }
40
-
41
- function optsWith(tools: Record<string, AgentTool>): ExecuteOptions {
42
- return { tools, defaultTemplate: "blank", defaultPort: 4321 };
43
- }
44
-
45
- const planTools = (): Record<string, AgentTool> => ({
46
- bizar_plan_action: createPlanActionTool({ worktree, logger }) as unknown as AgentTool,
47
- bizar_get_plan_comments: createBgGetCommentsTool({ worktree, logger }) as unknown as AgentTool,
48
- bizar_wait_for_feedback: createWaitForFeedbackTool({ worktree, logger }) as unknown as AgentTool,
49
- });
50
-
51
- describe("ToolContext — required fields", () => {
52
- test("synthetic context has all required fields", () => {
53
- const tctx = buildSyntheticToolContext(ctx()) as unknown as Record<string, unknown>;
54
- expect(tctx.sessionId).toBe("slash-command");
55
- expect(tctx.agentId).toBe("slash-command");
56
- expect(tctx.runId).toBeDefined();
57
- expect(tctx.iteration).toBe(0);
58
- expect(tctx.signal).toBeDefined();
59
- expect(tctx.metadata).toBeDefined();
60
- });
61
-
62
- test("abort.signal is NOT aborted", () => {
63
- const tctx = buildSyntheticToolContext(ctx()) as unknown as { signal: AbortSignal };
64
- expect(tctx.signal.aborted).toBe(false);
65
- });
66
-
67
- test("each call gets a fresh AbortSignal (not shared)", () => {
68
- const a = buildSyntheticToolContext(ctx()) as unknown as { signal: AbortSignal };
69
- const b = buildSyntheticToolContext(ctx()) as unknown as { signal: AbortSignal };
70
- expect(a.signal).not.toBe(b.signal);
71
- });
72
- });
73
-
74
- describe("ToolInvocation — args validation via Zod", () => {
75
- test("malformed args (invalid slug) → refusal response, tool NOT invoked", async () => {
76
- const sideEffect: SideEffect = { kind: "tool_invocation", toolName: "bizar_plan_action", args: { action: "get_canvas", planSlug: "UPPERCASE" } };
77
- const res = await executeSideEffect(sideEffect, ctx(), optsWith(planTools()));
78
- expect(res.responseOverride).toBeDefined();
79
- expect(res.responseOverride).toMatch(/Invalid arguments/);
80
- });
81
-
82
- test("missing required arg (no planSlug) → refusal response, tool NOT invoked", async () => {
83
- const sideEffect: SideEffect = { kind: "tool_invocation", toolName: "bizar_plan_action", args: { action: "get_canvas" } };
84
- const res = await executeSideEffect(sideEffect, ctx(), optsWith(planTools()));
85
- expect(res.responseOverride).toBeDefined();
86
- expect(res.responseOverride).toMatch(/Invalid arguments/);
87
- });
88
-
89
- test("valid args → tool IS invoked (spy verifies factory call)", async () => {
90
- // Pre-create a plan first.
91
- await executeSideEffect({ kind: "create_plan", slug: "routing-spy", template: null }, ctx(), optsWith(planTools()));
92
- const sideEffect: SideEffect = { kind: "tool_invocation", toolName: "bizar_plan_action", args: { action: "get_canvas", planSlug: "routing-spy" } };
93
- const res = await executeSideEffect(sideEffect, ctx(), optsWith(planTools()));
94
- expect(res.responseOverride).toBeDefined();
95
- // Should not be a validation error
96
- expect(res.responseOverride).not.toMatch(/Invalid arguments/);
97
- });
98
- });