@polderlabs/bizar 6.2.5 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) 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 +17 -18
  125. package/cli/commands/claude-cmd.mjs +348 -0
  126. package/cli/commands/install.mjs +12 -11
  127. package/cli/commands/validate.mjs +252 -325
  128. package/cli/dev-link.test.mjs +11 -11
  129. package/cli/doctor.mjs +131 -213
  130. package/cli/install.mjs +33 -37
  131. package/cli/install.test.mjs +9 -9
  132. package/cli/provision-claude.mjs +893 -0
  133. package/cli/provision.mjs +224 -227
  134. package/cli/utils.mjs +72 -58
  135. package/config/AGENTS.md +28 -28
  136. package/install.sh +66 -44
  137. package/package.json +19 -11
  138. package/packages/sdk/ARCHITECTURE.md +40 -36
  139. package/packages/sdk/package-lock.json +32 -0
  140. package/packages/sdk/package.json +15 -5
  141. package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
  142. package/packages/sdk/src/fingerprint.ts +0 -0
  143. package/packages/sdk/src/index.ts +38 -73
  144. package/packages/sdk/src/mcp/bin.ts +51 -0
  145. package/packages/sdk/src/mcp/server.ts +498 -0
  146. package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
  147. package/packages/sdk/tests/sdk.test.mjs +148 -0
  148. package/packages/sdk/vitest.config.ts +1 -1
  149. package/scripts/bh-full-e2e.mjs +166 -363
  150. package/scripts/check-deps.mjs +28 -46
  151. package/scripts/mirror-claude-md.sh +78 -0
  152. package/scripts/test-in-container.sh +31 -9
  153. package/templates/clean-state-checklist.md +3 -3
  154. package/templates/sprint-contract.md +2 -2
  155. package/bizar-dash/.bizar/activity.log +0 -3
  156. package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
  157. package/bizar-dash/.omx/state/session.json +0 -10
  158. package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
  159. package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
  160. package/bizar-dash/bizar-design/canvas.html +0 -281
  161. package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
  162. package/bizar-dash/bizar-design/components.css +0 -1665
  163. package/bizar-dash/bizar-design/components.html +0 -557
  164. package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
  165. package/bizar-dash/bizar-design/desktop/agents.html +0 -74
  166. package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
  167. package/bizar-dash/bizar-design/desktop/memory.html +0 -75
  168. package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
  169. package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
  170. package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
  171. package/bizar-dash/bizar-design/desktop/overview.html +0 -95
  172. package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
  173. package/bizar-dash/bizar-design/desktop/settings.html +0 -70
  174. package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
  175. package/bizar-dash/bizar-design/icons.svg +0 -44
  176. package/bizar-dash/bizar-design/index.html +0 -192
  177. package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
  178. package/bizar-dash/bizar-design/mobile/agents.html +0 -29
  179. package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
  180. package/bizar-dash/bizar-design/mobile/memory.html +0 -28
  181. package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
  182. package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
  183. package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
  184. package/bizar-dash/bizar-design/mobile/overview.html +0 -33
  185. package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
  186. package/bizar-dash/bizar-design/mobile/settings.html +0 -28
  187. package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
  188. package/bizar-dash/bizar-design/prototype.js +0 -114
  189. package/bizar-dash/bizar-design/tokens.css +0 -106
  190. package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
  191. package/bizar-dash/node_modules/.package-lock.json +0 -6
  192. package/bizar-dash/package-lock.json +0 -6
  193. package/bizar-dash/src/server/cline-sdk.mjs +0 -132
  194. package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
  195. package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
  196. package/cli/commands/cline-cmd.mjs +0 -289
  197. package/cli/commands/validate.test.mjs +0 -379
  198. package/cli/doctor.test.mjs +0 -350
  199. package/config/cline.json.template +0 -342
  200. package/packages/sdk/src/client.ts +0 -188
  201. package/packages/sdk/src/cline-events.ts +0 -134
  202. package/packages/sdk/src/cline-types.ts +0 -66
  203. package/packages/sdk/src/cline.ts +0 -339
  204. package/packages/sdk/src/errors.ts +0 -129
  205. package/packages/sdk/src/events.ts +0 -153
  206. package/packages/sdk/src/types.ts +0 -176
  207. package/packages/sdk/tests/client.test.ts +0 -217
  208. package/packages/sdk/tests/errors.test.ts +0 -108
  209. package/packages/sdk/tests/events.test.ts +0 -139
  210. package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
  211. package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
  212. package/plugins/bizar/ARCHITECTURE.md +0 -142
  213. package/plugins/bizar/CONSTRAINTS.md +0 -67
  214. package/plugins/bizar/LICENSE +0 -21
  215. package/plugins/bizar/README.md +0 -448
  216. package/plugins/bizar/index.ts +0 -925
  217. package/plugins/bizar/package.json +0 -39
  218. package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
  219. package/plugins/bizar/src/background-state.ts +0 -641
  220. package/plugins/bizar/src/background.ts +0 -1806
  221. package/plugins/bizar/src/cline-runner.ts +0 -203
  222. package/plugins/bizar/src/clineruntime.ts +0 -227
  223. package/plugins/bizar/src/commands-impl.ts +0 -151
  224. package/plugins/bizar/src/commands.ts +0 -1799
  225. package/plugins/bizar/src/compaction.d.mts +0 -48
  226. package/plugins/bizar/src/compaction.mjs +0 -192
  227. package/plugins/bizar/src/dashboard-client.ts +0 -233
  228. package/plugins/bizar/src/event-stream.ts +0 -606
  229. package/plugins/bizar/src/fingerprint.ts +0 -120
  230. package/plugins/bizar/src/handoff.ts +0 -79
  231. package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
  232. package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
  233. package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
  234. package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
  235. package/plugins/bizar/src/http-client.ts +0 -467
  236. package/plugins/bizar/src/key-rotation.ts +0 -218
  237. package/plugins/bizar/src/logger.ts +0 -144
  238. package/plugins/bizar/src/loop-engineering.ts +0 -241
  239. package/plugins/bizar/src/loop.ts +0 -176
  240. package/plugins/bizar/src/mistake-recovery.ts +0 -98
  241. package/plugins/bizar/src/odin.ts +0 -227
  242. package/plugins/bizar/src/options.ts +0 -470
  243. package/plugins/bizar/src/plan-fs.ts +0 -323
  244. package/plugins/bizar/src/reasoning-clean.ts +0 -454
  245. package/plugins/bizar/src/report.ts +0 -178
  246. package/plugins/bizar/src/research-prompt.ts +0 -35
  247. package/plugins/bizar/src/serve-info.ts +0 -228
  248. package/plugins/bizar/src/serve.ts +0 -496
  249. package/plugins/bizar/src/settings.ts +0 -349
  250. package/plugins/bizar/src/state.ts +0 -298
  251. package/plugins/bizar/src/tool-discipline.ts +0 -105
  252. package/plugins/bizar/src/tools/agent-browser.ts +0 -315
  253. package/plugins/bizar/src/tools/bg-collect.ts +0 -131
  254. package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
  255. package/plugins/bizar/src/tools/bg-kill.ts +0 -116
  256. package/plugins/bizar/src/tools/bg-pause.ts +0 -99
  257. package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
  258. package/plugins/bizar/src/tools/bg-resume.ts +0 -94
  259. package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
  260. package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
  261. package/plugins/bizar/src/tools/bg-status.ts +0 -130
  262. package/plugins/bizar/src/tools/graph-query.ts +0 -278
  263. package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
  264. package/plugins/bizar/src/tools/memory-list.ts +0 -43
  265. package/plugins/bizar/src/tools/memory-read.ts +0 -69
  266. package/plugins/bizar/src/tools/memory-search.ts +0 -47
  267. package/plugins/bizar/src/tools/memory-write.ts +0 -54
  268. package/plugins/bizar/src/tools/open-kb.ts +0 -198
  269. package/plugins/bizar/src/tools/plan-action.ts +0 -785
  270. package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
  271. package/plugins/bizar/src/tools/sandbox.ts +0 -232
  272. package/plugins/bizar/src/tools/team-spawn.ts +0 -73
  273. package/plugins/bizar/src/tools/team-status.ts +0 -76
  274. package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
  275. package/plugins/bizar/src/trajectory.ts +0 -104
  276. package/plugins/bizar/tests/README.md +0 -99
  277. package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
  278. package/plugins/bizar/tests/background-state.test.ts +0 -277
  279. package/plugins/bizar/tests/background.test.ts +0 -402
  280. package/plugins/bizar/tests/block.test.ts +0 -195
  281. package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
  282. package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
  283. package/plugins/bizar/tests/commands-impl.test.ts +0 -316
  284. package/plugins/bizar/tests/commands.test.ts +0 -584
  285. package/plugins/bizar/tests/compaction.test.ts +0 -264
  286. package/plugins/bizar/tests/config.test.ts +0 -128
  287. package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
  288. package/plugins/bizar/tests/dispose.test.ts +0 -336
  289. package/plugins/bizar/tests/event-stream.test.ts +0 -409
  290. package/plugins/bizar/tests/event.test.ts +0 -262
  291. package/plugins/bizar/tests/fingerprint.test.ts +0 -190
  292. package/plugins/bizar/tests/http-client.test.ts +0 -404
  293. package/plugins/bizar/tests/init-helpers.test.ts +0 -203
  294. package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
  295. package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
  296. package/plugins/bizar/tests/key-rotation.test.ts +0 -396
  297. package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
  298. package/plugins/bizar/tests/loop.test.ts +0 -397
  299. package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
  300. package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
  301. package/plugins/bizar/tests/odin.test.ts +0 -125
  302. package/plugins/bizar/tests/options.test.ts +0 -329
  303. package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
  304. package/plugins/bizar/tests/safety.test.ts +0 -281
  305. package/plugins/bizar/tests/serve.test.ts +0 -339
  306. package/plugins/bizar/tests/settings.test.ts +0 -351
  307. package/plugins/bizar/tests/stall-think.test.ts +0 -750
  308. package/plugins/bizar/tests/state.test.ts +0 -276
  309. package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
  310. package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
  311. package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
  312. package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
  313. package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
  314. package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
  315. package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
  316. package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
  317. package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
  318. package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
  319. package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
  320. package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
  321. package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
  322. package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
  323. package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
  324. package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
  325. package/plugins/bizar/tests/tools/sandbox.test.ts +0 -117
  326. package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
  327. package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
  328. package/plugins/bizar/tsconfig.json +0 -29
  329. package/scripts/mirror-agents-md.sh +0 -69
@@ -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
- }