@polderlabs/bizar 6.2.4 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) 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/settings.json +116 -0
  41. package/.claude/skills/9router/SKILL.md +80 -0
  42. package/.claude/skills/9router-chat/SKILL.md +73 -0
  43. package/.claude/skills/9router-embeddings/SKILL.md +69 -0
  44. package/.claude/skills/9router-image/SKILL.md +86 -0
  45. package/.claude/skills/9router-stt/SKILL.md +79 -0
  46. package/.claude/skills/9router-tts/SKILL.md +80 -0
  47. package/.claude/skills/9router-web-fetch/SKILL.md +99 -0
  48. package/.claude/skills/9router-web-search/SKILL.md +91 -0
  49. package/.claude/skills/bizar/README.md +9 -0
  50. package/.claude/skills/bizar/SKILL.md +450 -0
  51. package/.claude/skills/cpp-coding-standards/README.md +28 -0
  52. package/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
  53. package/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
  54. package/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
  55. package/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
  56. package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
  57. package/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
  58. package/.claude/skills/cpp-testing/README.md +28 -0
  59. package/.claude/skills/cpp-testing/SKILL.md +304 -0
  60. package/.claude/skills/cpp-testing/references/coverage.md +370 -0
  61. package/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
  62. package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
  63. package/.claude/skills/cpp-testing/references/mocking.md +364 -0
  64. package/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
  65. package/.claude/skills/cubesandbox/SKILL.md +148 -0
  66. package/.claude/skills/embedded-esp-idf/README.md +41 -0
  67. package/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
  68. package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
  69. package/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
  70. package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
  71. package/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
  72. package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
  73. package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
  74. package/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
  75. package/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
  76. package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
  77. package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
  78. package/.claude/skills/glyph/SKILL.md +163 -0
  79. package/.claude/skills/harness-engineering/SKILL.md +143 -0
  80. package/.claude/skills/lightrag/SKILL.md +81 -0
  81. package/.claude/skills/memory-protocol/SKILL.md +105 -0
  82. package/.claude/skills/obsidian/SKILL.md +306 -0
  83. package/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
  84. package/.claude/skills/self-improvement/SKILL.md +64 -0
  85. package/README.md +87 -59
  86. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js → EnvVarsSection-B58aiJiE.js} +1 -1
  87. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js.map → EnvVarsSection-B58aiJiE.js.map} +1 -1
  88. package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js → MobileChat-BJrqwVDd.js} +1 -1
  89. package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js.map → MobileChat-BJrqwVDd.js.map} +1 -1
  90. package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js → MobileSettings-CEQNJNLJ.js} +1 -1
  91. package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js.map → MobileSettings-CEQNJNLJ.js.map} +1 -1
  92. package/bizar-dash/dist/assets/{main-DYiZqMrn.js → main-IvfQAOfy.js} +1 -1
  93. package/bizar-dash/dist/assets/{main-DYiZqMrn.js.map → main-IvfQAOfy.js.map} +1 -1
  94. package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js → markdown-tOLaD6nm.js} +1 -1
  95. package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js.map → markdown-tOLaD6nm.js.map} +1 -1
  96. package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js → mobile-DYCHcUpq.js} +1 -1
  97. package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js.map → mobile-DYCHcUpq.js.map} +1 -1
  98. package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js → mobile-layout-CBHjpwsb.js} +2 -2
  99. package/bizar-dash/dist/assets/{mobile-layout-3jIhHX_p.js.map → mobile-layout-CBHjpwsb.js.map} +1 -1
  100. package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js → useSlashCommands-Bd7_FA6U.js} +2 -2
  101. package/bizar-dash/dist/assets/{useSlashCommands-DtITw8Xv.js.map → useSlashCommands-Bd7_FA6U.js.map} +1 -1
  102. package/bizar-dash/dist/assets/{vendor-CeHGtduv.js → vendor-C843201K.js} +12 -12
  103. package/bizar-dash/dist/assets/vendor-C843201K.js.map +1 -0
  104. package/bizar-dash/dist/index.html +6 -6
  105. package/bizar-dash/dist/mobile.html +2 -2
  106. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  107. package/bizar-dash/src/server/api.mjs +4 -4
  108. package/bizar-dash/src/server/background-store.mjs +15 -16
  109. package/bizar-dash/src/server/bg-poller.mjs +25 -35
  110. package/bizar-dash/src/server/bg-retry.mjs +66 -194
  111. package/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
  112. package/bizar-dash/src/server/claude-info.mjs +412 -0
  113. package/bizar-dash/src/server/{cline-runner.mjs → claude-runner.mjs} +53 -48
  114. package/bizar-dash/src/server/claude-sdk.mjs +191 -0
  115. package/bizar-dash/src/server/providers-store.mjs +22 -49
  116. package/bizar-dash/src/server/routes/background.mjs +24 -20
  117. package/bizar-dash/src/server/routes/chat.mjs +223 -326
  118. package/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
  119. package/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
  120. package/bizar-dash/src/server/routes/tasks.mjs +20 -28
  121. package/bizar-dash/src/server/task-delegator.mjs +76 -77
  122. package/bizar-dash/src/web/components/chat/useChat.ts +23 -27
  123. package/bizar-dash/src/web/views/Chat.tsx +8 -8
  124. package/cli/bin.mjs +31 -18
  125. package/cli/commands/claude-cmd.mjs +348 -0
  126. package/cli/commands/install.mjs +12 -11
  127. package/cli/commands/sandbox.mjs +220 -0
  128. package/cli/commands/validate.mjs +252 -288
  129. package/cli/dev-link.test.mjs +11 -11
  130. package/cli/doctor.mjs +131 -213
  131. package/cli/install.mjs +33 -37
  132. package/cli/install.test.mjs +9 -9
  133. package/cli/provision-claude.mjs +893 -0
  134. package/cli/provision.mjs +330 -226
  135. package/cli/provision.test.mjs +102 -0
  136. package/cli/utils.mjs +72 -58
  137. package/config/AGENTS.md +28 -28
  138. package/config/agents/_shared/AGENT_BASELINE.md +104 -684
  139. package/config/skills/bizar/SKILL.md +197 -0
  140. package/config/skills/cubesandbox/SKILL.md +148 -0
  141. package/config/skills/harness-engineering/SKILL.md +142 -0
  142. package/install.sh +66 -44
  143. package/package.json +19 -11
  144. package/packages/sdk/ARCHITECTURE.md +40 -36
  145. package/packages/sdk/package-lock.json +32 -0
  146. package/packages/sdk/package.json +15 -5
  147. package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
  148. package/packages/sdk/src/fingerprint.ts +0 -0
  149. package/packages/sdk/src/index.ts +38 -73
  150. package/packages/sdk/src/mcp/bin.ts +51 -0
  151. package/packages/sdk/src/mcp/server.ts +498 -0
  152. package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
  153. package/packages/sdk/tests/sdk.test.mjs +148 -0
  154. package/packages/sdk/vitest.config.ts +1 -1
  155. package/scripts/bh-full-e2e.mjs +166 -363
  156. package/scripts/check-deps.mjs +28 -46
  157. package/scripts/mirror-claude-md.sh +78 -0
  158. package/scripts/test-in-container.sh +157 -0
  159. package/templates/clean-state-checklist.md +3 -3
  160. package/templates/sprint-contract.md +2 -2
  161. package/bizar-dash/.bizar/activity.log +0 -3
  162. package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
  163. package/bizar-dash/.omx/state/session.json +0 -10
  164. package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
  165. package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
  166. package/bizar-dash/bizar-design/canvas.html +0 -281
  167. package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
  168. package/bizar-dash/bizar-design/components.css +0 -1665
  169. package/bizar-dash/bizar-design/components.html +0 -557
  170. package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
  171. package/bizar-dash/bizar-design/desktop/agents.html +0 -74
  172. package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
  173. package/bizar-dash/bizar-design/desktop/memory.html +0 -75
  174. package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
  175. package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
  176. package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
  177. package/bizar-dash/bizar-design/desktop/overview.html +0 -95
  178. package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
  179. package/bizar-dash/bizar-design/desktop/settings.html +0 -70
  180. package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
  181. package/bizar-dash/bizar-design/icons.svg +0 -44
  182. package/bizar-dash/bizar-design/index.html +0 -192
  183. package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
  184. package/bizar-dash/bizar-design/mobile/agents.html +0 -29
  185. package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
  186. package/bizar-dash/bizar-design/mobile/memory.html +0 -28
  187. package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
  188. package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
  189. package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
  190. package/bizar-dash/bizar-design/mobile/overview.html +0 -33
  191. package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
  192. package/bizar-dash/bizar-design/mobile/settings.html +0 -28
  193. package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
  194. package/bizar-dash/bizar-design/prototype.js +0 -114
  195. package/bizar-dash/bizar-design/tokens.css +0 -106
  196. package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
  197. package/bizar-dash/node_modules/.package-lock.json +0 -6
  198. package/bizar-dash/package-lock.json +0 -6
  199. package/bizar-dash/src/server/cline-sdk.mjs +0 -132
  200. package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
  201. package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
  202. package/cli/commands/cline-cmd.mjs +0 -289
  203. package/cli/commands/validate.test.mjs +0 -344
  204. package/cli/doctor.test.mjs +0 -350
  205. package/config/cline.json.template +0 -342
  206. package/packages/sdk/src/client.ts +0 -188
  207. package/packages/sdk/src/cline-events.ts +0 -134
  208. package/packages/sdk/src/cline-types.ts +0 -66
  209. package/packages/sdk/src/cline.ts +0 -339
  210. package/packages/sdk/src/errors.ts +0 -129
  211. package/packages/sdk/src/events.ts +0 -153
  212. package/packages/sdk/src/types.ts +0 -176
  213. package/packages/sdk/tests/client.test.ts +0 -217
  214. package/packages/sdk/tests/errors.test.ts +0 -108
  215. package/packages/sdk/tests/events.test.ts +0 -139
  216. package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
  217. package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
  218. package/plugins/bizar/ARCHITECTURE.md +0 -142
  219. package/plugins/bizar/CONSTRAINTS.md +0 -67
  220. package/plugins/bizar/LICENSE +0 -21
  221. package/plugins/bizar/README.md +0 -448
  222. package/plugins/bizar/index.ts +0 -872
  223. package/plugins/bizar/package.json +0 -39
  224. package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
  225. package/plugins/bizar/src/background-state.ts +0 -641
  226. package/plugins/bizar/src/background.ts +0 -1806
  227. package/plugins/bizar/src/cline-runner.ts +0 -203
  228. package/plugins/bizar/src/clineruntime.ts +0 -227
  229. package/plugins/bizar/src/commands-impl.ts +0 -151
  230. package/plugins/bizar/src/commands.ts +0 -1799
  231. package/plugins/bizar/src/compaction.d.mts +0 -48
  232. package/plugins/bizar/src/compaction.mjs +0 -192
  233. package/plugins/bizar/src/dashboard-client.ts +0 -233
  234. package/plugins/bizar/src/event-stream.ts +0 -606
  235. package/plugins/bizar/src/fingerprint.ts +0 -120
  236. package/plugins/bizar/src/handoff.ts +0 -79
  237. package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
  238. package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
  239. package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
  240. package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
  241. package/plugins/bizar/src/http-client.ts +0 -467
  242. package/plugins/bizar/src/key-rotation.ts +0 -218
  243. package/plugins/bizar/src/logger.ts +0 -144
  244. package/plugins/bizar/src/loop-engineering.ts +0 -241
  245. package/plugins/bizar/src/loop.ts +0 -176
  246. package/plugins/bizar/src/mistake-recovery.ts +0 -98
  247. package/plugins/bizar/src/odin.ts +0 -227
  248. package/plugins/bizar/src/options.ts +0 -470
  249. package/plugins/bizar/src/plan-fs.ts +0 -323
  250. package/plugins/bizar/src/reasoning-clean.ts +0 -454
  251. package/plugins/bizar/src/report.ts +0 -178
  252. package/plugins/bizar/src/research-prompt.ts +0 -35
  253. package/plugins/bizar/src/serve-info.ts +0 -228
  254. package/plugins/bizar/src/serve.ts +0 -496
  255. package/plugins/bizar/src/settings.ts +0 -349
  256. package/plugins/bizar/src/state.ts +0 -298
  257. package/plugins/bizar/src/tool-discipline.ts +0 -105
  258. package/plugins/bizar/src/tools/agent-browser.ts +0 -315
  259. package/plugins/bizar/src/tools/bg-collect.ts +0 -131
  260. package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
  261. package/plugins/bizar/src/tools/bg-kill.ts +0 -116
  262. package/plugins/bizar/src/tools/bg-pause.ts +0 -99
  263. package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
  264. package/plugins/bizar/src/tools/bg-resume.ts +0 -94
  265. package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
  266. package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
  267. package/plugins/bizar/src/tools/bg-status.ts +0 -130
  268. package/plugins/bizar/src/tools/graph-query.ts +0 -278
  269. package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
  270. package/plugins/bizar/src/tools/memory-list.ts +0 -43
  271. package/plugins/bizar/src/tools/memory-read.ts +0 -69
  272. package/plugins/bizar/src/tools/memory-search.ts +0 -47
  273. package/plugins/bizar/src/tools/memory-write.ts +0 -54
  274. package/plugins/bizar/src/tools/open-kb.ts +0 -198
  275. package/plugins/bizar/src/tools/plan-action.ts +0 -785
  276. package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
  277. package/plugins/bizar/src/tools/team-spawn.ts +0 -73
  278. package/plugins/bizar/src/tools/team-status.ts +0 -76
  279. package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
  280. package/plugins/bizar/src/trajectory.ts +0 -104
  281. package/plugins/bizar/tests/README.md +0 -99
  282. package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
  283. package/plugins/bizar/tests/background-state.test.ts +0 -277
  284. package/plugins/bizar/tests/background.test.ts +0 -402
  285. package/plugins/bizar/tests/block.test.ts +0 -195
  286. package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
  287. package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
  288. package/plugins/bizar/tests/commands-impl.test.ts +0 -316
  289. package/plugins/bizar/tests/commands.test.ts +0 -584
  290. package/plugins/bizar/tests/compaction.test.ts +0 -264
  291. package/plugins/bizar/tests/config.test.ts +0 -128
  292. package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
  293. package/plugins/bizar/tests/dispose.test.ts +0 -336
  294. package/plugins/bizar/tests/event-stream.test.ts +0 -409
  295. package/plugins/bizar/tests/event.test.ts +0 -262
  296. package/plugins/bizar/tests/fingerprint.test.ts +0 -162
  297. package/plugins/bizar/tests/http-client.test.ts +0 -404
  298. package/plugins/bizar/tests/init-helpers.test.ts +0 -203
  299. package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
  300. package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
  301. package/plugins/bizar/tests/key-rotation.test.ts +0 -396
  302. package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
  303. package/plugins/bizar/tests/loop.test.ts +0 -397
  304. package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
  305. package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
  306. package/plugins/bizar/tests/odin.test.ts +0 -125
  307. package/plugins/bizar/tests/options.test.ts +0 -329
  308. package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
  309. package/plugins/bizar/tests/safety.test.ts +0 -256
  310. package/plugins/bizar/tests/serve.test.ts +0 -339
  311. package/plugins/bizar/tests/settings.test.ts +0 -351
  312. package/plugins/bizar/tests/stall-think.test.ts +0 -750
  313. package/plugins/bizar/tests/state.test.ts +0 -276
  314. package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
  315. package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
  316. package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
  317. package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
  318. package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
  319. package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
  320. package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
  321. package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
  322. package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
  323. package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
  324. package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
  325. package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
  326. package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
  327. package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
  328. package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
  329. package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
  330. package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
  331. package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
  332. package/plugins/bizar/tsconfig.json +0 -29
@@ -1,105 +0,0 @@
1
- /**
2
- * tool-discipline.ts
3
- *
4
- * v6.0.1 — Tool-call discipline + preference directive injected into
5
- * every Cline system prompt produced by the Bizar harness.
6
- *
7
- * Why this exists:
8
- *
9
- * Cline's runtime aborts sessions when the model emits consecutive
10
- * tool calls that fail Zod schema validation (e.g. `editor({ new_text:
11
- * undefined })`, `ask_question({ options: null })`,
12
- * `run_commands({ ... })`). The defaults in `mistake-recovery.ts` keep
13
- * the session alive — but the cheaper fix is preventing the bad tool
14
- * calls in the first place.
15
- *
16
- * We also steer the model away from over-using `run_commands` for
17
- * things that have a dedicated built-in tool. Built-in tools give
18
- * better diffs, easier approval, richer error context, and don't
19
- * require shell quoting. Bash is for things that genuinely need a
20
- * shell — anything else should hit a specialized tool.
21
- *
22
- * This directive is appended to the system prompt by the harness's
23
- * `beforeModel` hook (idempotent: detected via a marker). It is short
24
- * enough to stay cheap (~220 tokens) and only fires once per session,
25
- * so it does not bloat every turn's context.
26
- */
27
-
28
- export const TOOL_DISCIPLINE_MARKER = "BIZAR_TOOL_DISCIPLINE_v0.6.3";
29
-
30
- /**
31
- * The directive body. Kept compact; details are in the linked recovery
32
- * notice so we don't duplicate instructions between the system prompt
33
- * and the recovery callback.
34
- */
35
- export const TOOL_DISCIPLINE_DIRECTIVE = [
36
- TOOL_DISCIPLINE_MARKER,
37
- "",
38
- "## Tool-call discipline",
39
- "",
40
- "• Required fields are required. Populate every field declared in the",
41
- " tool's input schema, with a value of the right type. Do not omit",
42
- " fields; Cline rejects the call before any side effect runs.",
43
- "• `editor.new_text` must be a non-empty string. To clear content, use",
44
- " `applyPatch` or `delete_file`. To create a new file, pass the",
45
- " full intended contents as `new_text`.",
46
- "• `ask_question.options` must be an array of ≥2 non-empty strings.",
47
- " Passing `null`, `undefined`, or arrays of length <2 fails schema",
48
- " validation.",
49
- "• `run_commands.commands` must be a non-empty array of strings.",
50
- "• If a tool call fails validation twice in a row, switch tools or",
51
- " describe the problem in plain text before retrying. Do not loop on",
52
- " the same mistake.",
53
- "",
54
- "## Prefer built-in tools over bash",
55
- "",
56
- "Cline ships dedicated tools for most file/shell work. Reach for them",
57
- "before reaching for `run_commands`:",
58
- "",
59
- "| If you want to… | Use this, not bash |",
60
- "| ------------------------------------- | ---------------------------- |",
61
- "| read a file | `read_file` |",
62
- "| search a workspace | `search_codebase` / `search` |",
63
- "| edit a file in place | `editor` or `apply_patch` |",
64
- "| create a new file | `editor` (new_text = full) |",
65
- "| list a directory | `list_files` |",
66
- "| fetch a URL | `web_fetch` |",
67
- "| run a build / test / lint / script | `run_commands` |",
68
- "",
69
- "Reaching for bash first creates two problems:",
70
- " 1. Shell quoting bugs (quotes-in-quotes-in-quotes) are the most",
71
- " common cause of malformed tool calls.",
72
- " 2. Each bash command lands in tool history as opaque output; a",
73
- " dedicated tool keeps diffs, error context, and approval gates",
74
- " intact.",
75
- "",
76
- "When you DO call `run_commands`, keep it small:",
77
- "",
78
- "• One logical command per call. Do not chain unrelated segments with",
79
- " `&&`. Use multiple `run_commands` turns instead — each turn's output",
80
- " is easier to debug and re-run.",
81
- "• Pass file paths via the tool's structured fields (`editor.path`,",
82
- " `read_file.path`) — never as `cd ... && <cmd>` chdir hacks.",
83
- "• Hard cap: do not emit a single command longer than ~600 chars. If",
84
- " the command doesn't fit, it's a sign you should use a built-in tool",
85
- " or split it across turns.",
86
- "• No `for i in $(seq 1 100)` loops for batching work that has a tool",
87
- " (`read_file`, `editor`). Loops in bash hide per-file failures.",
88
- "• No `xargs`, no `sed -i`, no heredocs to write files — these all",
89
- " have a dedicated tool that produces a richer record.",
90
- "",
91
- "These conventions avoid both the consecutive-mistake abort and the",
92
- "common shell-quoting trap.",
93
- ].join("\n");
94
-
95
- /**
96
- * Bump this constant when the directive body changes in a way that
97
- * warrants re-injection into existing sessions. The harness uses the
98
- * marker to detect "already injected", so an updated directive will
99
- * only land if a fresh session starts (or marker changes).
100
- */
101
- export const TOOL_DISCIPLINE_VERSION = "0.6.3";
102
-
103
- export function hasToolDiscipline(systemPrompt: string | undefined): boolean {
104
- return typeof systemPrompt === "string" && systemPrompt.includes(TOOL_DISCIPLINE_MARKER);
105
- }
@@ -1,315 +0,0 @@
1
- /**
2
- * agent-browser.ts — v6.0.0 agent-browser CLI wrapper tools.
3
- *
4
- * Replaces the v5.x `browser-harness` (Python CDP wrapper) with
5
- * agent-browser (native Rust CLI from vercel-labs).
6
- *
7
- * Pattern: thin wrappers around `agent-browser <cmd> ...`. The CLI
8
- * is installed via npm (`npm install -g agent-browser`) and exposes
9
- * 100+ typed commands. The MCP stdio server (`agent-browser mcp`)
10
- * is exposed separately at the Cline level via `.cline/mcp.json`.
11
- *
12
- * Six tools:
13
- * - bizar_browser_open open a URL (auto-launches daemon)
14
- * - bizar_browser_snapshot accessibility tree with refs (@e1..)
15
- * - bizar_browser_click click by ref @e2 or selector
16
- * - bizar_browser_fill fill an input by ref or selector
17
- * - bizar_browser_screenshot screenshot to a file (returned by path)
18
- * - bizar_browser_command escape hatch for any agent-browser command
19
- *
20
- * The plugin invokes `agent-browser ...` via execFile (no shell, no
21
- * injection). All tool calls go through `checkDangerous()` for the
22
- * DANGEROUS_PATTERNS approval gate.
23
- *
24
- * The browser-primary agent that uses these tools lives at
25
- * config/agents/agent-browser.md.
26
- */
27
-
28
- import { createTool, type AgentTool } from "@cline/sdk";
29
- import { z } from "zod";
30
-
31
- import type { Logger } from "../logger.js";
32
-
33
- export const BIZAR_BROWSER_OPEN_TOOL_NAME = "bizar_browser_open";
34
- export const BIZAR_BROWSER_SNAPSHOT_TOOL_NAME = "bizar_browser_snapshot";
35
- export const BIZAR_BROWSER_CLICK_TOOL_NAME = "bizar_browser_click";
36
- export const BIZAR_BROWSER_FILL_TOOL_NAME = "bizar_browser_fill";
37
- export const BIZAR_BROWSER_SCREENSHOT_TOOL_NAME = "bizar_browser_screenshot";
38
- export const BIZAR_BROWSER_COMMAND_TOOL_NAME = "bizar_browser_command";
39
-
40
- export interface AgentBrowserDeps {
41
- logger: Logger;
42
- /** Override the agent-browser binary path. Default: "agent-browser" on PATH. */
43
- bin?: string;
44
- /** Default browser profile directory. */
45
- profile?: string;
46
- /** Default daemon host. */
47
- host?: string;
48
- /** Default daemon port. */
49
- port?: number;
50
- }
51
-
52
- function resolveBin(deps: AgentBrowserDeps): string {
53
- if (deps.bin) return deps.bin;
54
- return process.env.AGENT_BROWSER_BIN ?? "agent-browser";
55
- }
56
-
57
- /**
58
- * Run an agent-browser CLI subcommand and capture stdout/stderr/exitCode.
59
- *
60
- * Returns the parsed JSON object when `--json` is passed and the output
61
- * is valid JSON; otherwise returns a `{ stdout, stderr, exitCode }`
62
- * envelope.
63
- */
64
- async function runAgentBrowser(
65
- deps: AgentBrowserDeps,
66
- args: string[],
67
- opts: { json?: boolean; cwd?: string; timeoutMs?: number } = {},
68
- ): Promise<{ ok: boolean; exitCode: number; stdout: string; stderr: string; json?: unknown }> {
69
- const bin = resolveBin(deps);
70
- const json = opts.json ?? args.includes("--json");
71
- const finalArgs = json && !args.includes("--json") ? [...args, "--json"] : args;
72
-
73
- const { execFile } = await import("node:child_process");
74
- const { promisify } = await import("node:util");
75
- const pExecFile = promisify(execFile);
76
-
77
- try {
78
- const { stdout, stderr } = await pExecFile(bin, finalArgs, {
79
- cwd: opts.cwd ?? process.cwd(),
80
- timeout: opts.timeoutMs ?? 30_000,
81
- maxBuffer: 16 * 1024 * 1024,
82
- });
83
- if (json) {
84
- try {
85
- return { ok: true, exitCode: 0, stdout, stderr, json: JSON.parse(stdout) };
86
- } catch {
87
- return { ok: true, exitCode: 0, stdout, stderr };
88
- }
89
- }
90
- return { ok: true, exitCode: 0, stdout, stderr };
91
- } catch (err) {
92
- const e = err as { code?: number | string; stdout?: string; stderr?: string };
93
- return {
94
- ok: false,
95
- exitCode: typeof e.code === "number" ? e.code : 1,
96
- stdout: e.stdout ?? "",
97
- stderr: e.stderr ?? (err instanceof Error ? err.message : String(err)),
98
- };
99
- }
100
- }
101
-
102
- // ─── tool: bizar_browser_open ────────────────────────────────────────────
103
- export type BizarBrowserOpenInput = z.infer<typeof bizarBrowserOpenSchema>;
104
- export type BizarBrowserOpenOutput =
105
- | { ok: true; url: string; snapshot?: unknown; stdout: string }
106
- | { ok: false; error: string; stderr: string };
107
-
108
- const bizarBrowserOpenSchema = z.object({
109
- url: z.string().url().describe("URL to open in the browser."),
110
- headless: z.boolean().optional().describe("Default true. Set false for visual debugging."),
111
- profile: z.string().optional().describe("Override profile dir for this session."),
112
- });
113
-
114
- export function createBrowserOpenTool(
115
- deps: AgentBrowserDeps,
116
- ): AgentTool<BizarBrowserOpenInput, BizarBrowserOpenOutput> {
117
- return createTool({
118
- name: BIZAR_BROWSER_OPEN_TOOL_NAME,
119
- description:
120
- "Launch agent-browser and navigate to a URL. Auto-starts the daemon if not running. " +
121
- "Returns the initial accessibility-tree snapshot as JSON for immediate element discovery.",
122
- inputSchema: bizarBrowserOpenSchema.shape,
123
- execute: async (input) => {
124
- const args = ["open", input.url];
125
- if (input.headless === false) args.push("--headed");
126
- if (input.profile ?? deps.profile) args.push("--profile", input.profile ?? deps.profile!);
127
- const r = await runAgentBrowser(deps, args, { json: true });
128
- if (!r.ok) {
129
- deps.logger.warn(`bizar_browser_open failed: ${r.stderr}`);
130
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
131
- }
132
- return { ok: true as const, url: input.url, snapshot: r.json, stdout: r.stdout };
133
- },
134
- });
135
- }
136
-
137
- // ─── tool: bizar_browser_snapshot ────────────────────────────────────────
138
- export type BizarBrowserSnapshotInput = z.infer<typeof bizarBrowserSnapshotSchema>;
139
- export type BizarBrowserSnapshotOutput =
140
- | { ok: true; snapshot: unknown; stdout: string }
141
- | { ok: false; error: string; stderr: string };
142
-
143
- const bizarBrowserSnapshotSchema = z.object({
144
- max_depth: z.number().int().positive().optional().describe("Optional subtree depth limit."),
145
- format: z.enum(["json", "ai"]).optional().describe("Output format. Default: json."),
146
- });
147
-
148
- export function createBrowserSnapshotTool(
149
- deps: AgentBrowserDeps,
150
- ): AgentTool<BizarBrowserSnapshotInput, BizarBrowserSnapshotOutput> {
151
- return createTool({
152
- name: BIZAR_BROWSER_SNAPSHOT_TOOL_NAME,
153
- description:
154
- "Get the current page's accessibility tree with stable refs (@e1, @e2, …). " +
155
- "Ref-based selectors survive page-snapshot churn better than CSS selectors. " +
156
- "Returns structured JSON by default; pass format='ai' for a compact text variant.",
157
- inputSchema: bizarBrowserSnapshotSchema.shape,
158
- execute: async (input) => {
159
- const format = input.format ?? "json";
160
- const args = ["snapshot", format === "ai" ? "--ai" : "--json"];
161
- if (input.max_depth) args.push("--max-depth", String(input.max_depth));
162
- const r = await runAgentBrowser(deps, args, { json: true });
163
- if (!r.ok) {
164
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
165
- }
166
- return { ok: true as const, snapshot: r.json, stdout: r.stdout };
167
- },
168
- });
169
- }
170
-
171
- // ─── tool: bizar_browser_click ──────────────────────────────────────────
172
- export type BizarBrowserClickInput = z.infer<typeof bizarBrowserClickSchema>;
173
- export type BizarBrowserClickOutput =
174
- | { ok: true; clicked: string; stdout: string }
175
- | { ok: false; error: string; stderr: string };
176
-
177
- const bizarBrowserClickSchema = z.object({
178
- selector: z.string().min(1).describe("Element to click. Prefer a ref from snapshot (e.g. '@e2'); CSS selectors and role/name tuples also accepted."),
179
- new_tab: z.boolean().optional().describe("Open the link in a new tab."),
180
- });
181
-
182
- export function createBrowserClickTool(
183
- deps: AgentBrowserDeps,
184
- ): AgentTool<BizarBrowserClickInput, BizarBrowserClickOutput> {
185
- return createTool({
186
- name: BIZAR_BROWSER_CLICK_TOOL_NAME,
187
- description:
188
- "Click an element identified by ref (preferred) or selector. " +
189
- "Ref-based selectors (@e2) are stable across snapshots; CSS selectors and " +
190
- "role/name tuples are also accepted. Pass new_tab=true to open link targets in a new tab.",
191
- inputSchema: bizarBrowserClickSchema.shape,
192
- execute: async (input) => {
193
- const args = ["click", input.selector];
194
- if (input.new_tab) args.push("--new-tab");
195
- const r = await runAgentBrowser(deps, args);
196
- if (!r.ok) {
197
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
198
- }
199
- return { ok: true as const, clicked: input.selector, stdout: r.stdout };
200
- },
201
- });
202
- }
203
-
204
- // ─── tool: bizar_browser_fill ───────────────────────────────────────────
205
- export type BizarBrowserFillInput = z.infer<typeof bizarBrowserFillSchema>;
206
- export type BizarBrowserFillOutput =
207
- | { ok: true; filled: string; value: string; stdout: string }
208
- | { ok: false; error: string; stderr: string };
209
-
210
- const bizarBrowserFillSchema = z.object({
211
- selector: z.string().min(1).describe("Element to fill (ref like '@e3' or CSS selector)."),
212
- value: z.string().describe("Value to fill."),
213
- submit: z.boolean().optional().describe("If true, press Enter after filling."),
214
- });
215
-
216
- export function createBrowserFillTool(
217
- deps: AgentBrowserDeps,
218
- ): AgentTool<BizarBrowserFillInput, BizarBrowserFillOutput> {
219
- return createTool({
220
- name: BIZAR_BROWSER_FILL_TOOL_NAME,
221
- description:
222
- "Clear and fill an input. Uses ref or selector. The agent-browser " +
223
- "fill command replaces text content (unlike `type` which appends).",
224
- inputSchema: bizarBrowserFillSchema.shape,
225
- execute: async (input) => {
226
- const args = ["fill", input.selector, input.value];
227
- if (input.submit) args.push("--submit");
228
- const r = await runAgentBrowser(deps, args);
229
- if (!r.ok) {
230
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
231
- }
232
- return { ok: true as const, filled: input.selector, value: input.value, stdout: r.stdout };
233
- },
234
- });
235
- }
236
-
237
- // ─── tool: bizar_browser_screenshot ─────────────────────────────────────
238
- export type BizarBrowserScreenshotInput = z.infer<typeof bizarBrowserScreenshotSchema>;
239
- export type BizarBrowserScreenshotOutput =
240
- | { ok: true; path: string; bytes?: number; stdout: string }
241
- | { ok: false; error: string; stderr: string };
242
-
243
- const bizarBrowserScreenshotSchema = z.object({
244
- path: z.string().min(1).describe("Output file path (relative paths resolve to the worktree)."),
245
- full_page: z.boolean().optional().describe("Capture the entire scrollable area."),
246
- element: z.string().optional().describe("Capture only this ref (e.g. '@e4')."),
247
- });
248
-
249
- export function createBrowserScreenshotTool(
250
- deps: AgentBrowserDeps,
251
- ): AgentTool<BizarBrowserScreenshotInput, BizarBrowserScreenshotOutput> {
252
- return createTool({
253
- name: BIZAR_BROWSER_SCREENSHOT_TOOL_NAME,
254
- description:
255
- "Take a screenshot of the current page (or an element) and save it to `path`. " +
256
- "Use full_page=true to capture the entire scrollable area, or pass element='@eN' " +
257
- "to capture a single element. Returns the absolute path of the written file.",
258
- inputSchema: bizarBrowserScreenshotSchema.shape,
259
- execute: async (input) => {
260
- const args = ["screenshot", input.path];
261
- if (input.full_page) args.push("--full-page");
262
- if (input.element) args.push("--element", input.element);
263
- const r = await runAgentBrowser(deps, args);
264
- if (!r.ok) {
265
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
266
- }
267
- return { ok: true as const, path: input.path, stdout: r.stdout };
268
- },
269
- });
270
- }
271
-
272
- // ─── tool: bizar_browser_command (escape hatch) ─────────────────────────
273
- export type BizarBrowserCommandInput = z.infer<typeof bizarBrowserCommandSchema>;
274
- export type BizarBrowserCommandOutput =
275
- | { ok: true; stdout: string; stderr: string; exitCode: number; json?: unknown }
276
- | { ok: false; error: string; stderr: string };
277
-
278
- const bizarBrowserCommandSchema = z.object({
279
- args: z.array(z.string()).describe(
280
- "Argv to pass to agent-browser (e.g. ['eval', 'document.title']). " +
281
- "Use this escape hatch for the 100+ commands not exposed as dedicated tools " +
282
- "(eval, wait, press, find role, hover, scroll, tab list/open/switch, etc.)."
283
- ),
284
- json: z.boolean().optional().describe("If true, agent-browser is invoked with --json and stdout is parsed as JSON."),
285
- timeoutMs: z.number().int().positive().optional().describe("Max execution time, default 30s."),
286
- });
287
-
288
- export function createBrowserCommandTool(
289
- deps: AgentBrowserDeps,
290
- ): AgentTool<BizarBrowserCommandInput, BizarBrowserCommandOutput> {
291
- return createTool({
292
- name: BIZAR_BROWSER_COMMAND_TOOL_NAME,
293
- description:
294
- "Escape hatch: invoke any agent-browser CLI command by argv. Returns stdout, stderr, " +
295
- "and exit code. Use the dedicated tools (bizar_browser_open/snapshot/click/fill/screenshot) " +
296
- "for common operations; this is for the 100+ commands they don't cover.",
297
- inputSchema: bizarBrowserCommandSchema.shape,
298
- execute: async (input) => {
299
- const r = await runAgentBrowser(deps, input.args, {
300
- json: input.json,
301
- timeoutMs: input.timeoutMs,
302
- });
303
- if (!r.ok) {
304
- return { ok: false as const, error: `agent-browser exited ${r.exitCode}`, stderr: r.stderr };
305
- }
306
- return {
307
- ok: true as const,
308
- stdout: r.stdout,
309
- stderr: r.stderr,
310
- exitCode: r.exitCode,
311
- json: r.json,
312
- };
313
- },
314
- });
315
- }
@@ -1,131 +0,0 @@
1
- /**
2
- * bg-collect.ts
3
- *
4
- * `bizar_collect` tool (v0.4.2 spec §7.1, §4.4).
5
- *
6
- * Odin-only — only Odin may collect. Blocks until the instance reaches a
7
- * terminal state or `timeoutMs` elapses. On timeout, returns
8
- * `status: "running"` with the last known `resultPreview`.
9
- *
10
- * Returns:
11
- * `{ instanceId, status, result, toolCallCount, durationMs, error? }`
12
- *
13
- * The `result` field is the concatenated text of all assistant messages
14
- * (TextPart only). If the instance ended with a threshold-12 loop-guard
15
- * error, the marker `[loop guard: 12 identical calls to <tool>]` is
16
- * prepended (MEDIUM-30).
17
- *
18
- * Cline SDK port (Phase 2):
19
- * - Uses `createTool` from `@cline/sdk` directly.
20
- * - Adds `name: BIZAR_COLLECT_TOOL_NAME`.
21
- * - `inputSchema` is `z.object(...)` over the same fields as before.
22
- * - Returns structured `{ ok, instanceId, status, ... }` instead of
23
- * `{ output: JSON.stringify(...) }`.
24
- * - `ctx.agent` becomes `context.metadata.parentAgent` look-up.
25
- */
26
-
27
- import { createTool, type AgentTool } from "@cline/sdk";
28
- import { z } from "zod";
29
-
30
- import type { InstanceManager } from "../background.js";
31
- import type { Logger } from "../logger.js";
32
-
33
- const TIMEOUT_MIN_MS = 1000;
34
- const TIMEOUT_MAX_MS = 1_800_000;
35
- const TIMEOUT_DEFAULT_MS = 60_000;
36
-
37
- export const BIZAR_COLLECT_TOOL_NAME = "bizar_collect";
38
-
39
- export interface BgCollectDeps {
40
- instanceManager: InstanceManager;
41
- logger: Logger;
42
- }
43
-
44
- export type BizarCollectInput = z.infer<typeof bizarCollectSchema>;
45
- export type BizarCollectOutput =
46
- | {
47
- ok: true;
48
- instanceId: string;
49
- status: string;
50
- result: string;
51
- toolCallCount: number;
52
- durationMs: number;
53
- error?: string;
54
- }
55
- | { ok: false; error: string; instanceId?: string };
56
-
57
- const bizarCollectSchema = z.object({
58
- instanceId: z
59
- .string()
60
- .min(1)
61
- .describe("Instance id returned by bizar_spawn_background."),
62
- timeoutMs: z
63
- .number()
64
- .int()
65
- .positive()
66
- .optional()
67
- .describe("Collect-time timeout in ms (1s..30min, default 60s)."),
68
- });
69
-
70
- /**
71
- * Build the `bizar_collect` tool. The plugin wires the result into
72
- * `api.registerTool()` from `AgentExtensionApi`. The `deps` closure
73
- * carries the InstanceManager.
74
- */
75
- export function createBgCollectTool(
76
- deps: BgCollectDeps,
77
- ): AgentTool<BizarCollectInput, BizarCollectOutput> {
78
- return createTool({
79
- name: BIZAR_COLLECT_TOOL_NAME,
80
- description:
81
- "Wait for a background instance to complete and return its result. " +
82
- "Only Odin may collect. Blocks until the instance reaches a terminal state or the timeout fires.",
83
- inputSchema: bizarCollectSchema.shape,
84
- execute: async (input, context) => {
85
- // Odin-only (§6.3).
86
- const parentAgent =
87
- (context.metadata as { parentAgent?: string } | undefined)?.parentAgent ?? null;
88
- if (parentAgent !== "odin") {
89
- return {
90
- ok: false as const,
91
- error:
92
- "Only Odin can collect background agent results. Use bizar_status to inspect or ask Odin to collect.",
93
- };
94
- }
95
-
96
- // Clamp timeoutMs (MEDIUM-33 / §7.3).
97
- const requested = input.timeoutMs ?? TIMEOUT_DEFAULT_MS;
98
- if (requested < TIMEOUT_MIN_MS || requested > TIMEOUT_MAX_MS) {
99
- return {
100
- ok: false as const,
101
- error: `timeoutMs must be between ${TIMEOUT_MIN_MS} (1s) and ${TIMEOUT_MAX_MS} (30min). Got ${requested}.`,
102
- };
103
- }
104
- const timeoutMs = requested;
105
-
106
- try {
107
- const result = await deps.instanceManager.collect(input.instanceId, timeoutMs);
108
- return {
109
- ok: true as const,
110
- instanceId: input.instanceId,
111
- status: result.status,
112
- result: result.result,
113
- toolCallCount: result.toolCallCount,
114
- durationMs: result.durationMs,
115
- ...(result.error !== undefined ? { error: result.error } : {}),
116
- };
117
- } catch (err: unknown) {
118
- deps.logger.warn(
119
- `bizar: collect(${input.instanceId}) failed: ${
120
- err instanceof Error ? err.message : String(err)
121
- }`,
122
- );
123
- return {
124
- ok: false as const,
125
- error: `collect failed: ${err instanceof Error ? err.message : String(err)}`,
126
- instanceId: input.instanceId,
127
- };
128
- }
129
- },
130
- });
131
- }