@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,82 +1,47 @@
1
1
  /**
2
2
  * Public API for @polderlabs/bizar-sdk.
3
+ *
4
+ * v0.4.0 — Claude Code-native rewrite. The legacy Cline wrappers
5
+ * (`createClineSdk`, `subscribeClineEvents`, `Cline*` types) have been
6
+ * removed because Bizar no longer integrates with the Cline runtime.
7
+ * The Claude Code integration is via the MCP server exported from
8
+ * `./mcp/server.ts` (`createBizarMcpServer`) and the in-process memory
9
+ * vault exported from `./memory/index.ts`.
3
10
  */
4
11
 
5
- export { createBizarClient } from "./client.js";
6
- export type {
7
- BizarClient,
8
- BizarClientConfig,
9
- SessionsResource,
10
- ProjectsResource,
11
- PlansResource,
12
- EventsResource,
13
- HealthResource,
14
- } from "./client.js";
12
+ // In-process memory vault (Obsidian-compatible markdown notes).
13
+ export {
14
+ readNote,
15
+ writeNote,
16
+ listNotes,
17
+ searchNotes,
18
+ parseFrontmatter,
19
+ serializeFrontmatter,
20
+ resolveVaultRoot,
21
+ DEFAULT_MEMORY_VAULT,
22
+ LEGACY_MEMORY_VAULT,
23
+ } from "./memory/index.js";
24
+ export type { MemoryNote } from "./memory/index.js";
25
+
26
+ // Dangerous-pattern scanner.
27
+ export {
28
+ checkDangerous,
29
+ listDangerousPatterns,
30
+ getDangerousPatternStats,
31
+ } from "./dangerous-patterns.js";
32
+ export type { ApprovalDecision, ApprovalCheck } from "./dangerous-patterns.js";
15
33
 
16
- export type { EventSubscription, EventSubscriptionOptions } from "./events.js";
34
+ // Tool-call fingerprint (stable hash for loop-guard).
35
+ export { fingerprint } from "./fingerprint.js";
17
36
 
37
+ // Claude Code MCP server.
18
38
  export {
19
- isBizarError,
20
- connectionErrorFrom,
21
- dashboardErrorFrom,
22
- apiErrorFrom,
23
- } from "./errors.js";
24
- export type {
25
- BizarError,
26
- PluginError,
27
- DashboardError,
28
- ConnectionError,
29
- APIError,
30
- ClineConnectionError,
31
- } from "./errors.js";
32
-
33
- export type {
34
- // Session
35
- Session,
36
- SessionStatus,
37
- SessionCreate,
38
- SessionListQuery,
39
- // Project
40
- Project,
41
- // Plan
42
- Plan,
43
- PlanStatus,
44
- // Part
45
- Part,
46
- TextPart,
47
- ToolCallPart,
48
- ToolResultPart,
49
- ReasoningPart,
50
- // Event
51
- DashboardEvent,
52
- DashboardConnectedEvent,
53
- SessionCreatedEvent,
54
- SessionUpdatedEvent,
55
- SessionIdleEvent,
56
- SessionErrorEvent,
57
- MessagePartUpdatedEvent,
58
- ToolExecutedEvent,
59
- PlanUpdatedEvent,
60
- // Health
61
- Health,
62
- } from "./types.js";
39
+ createBizarMcpServer,
40
+ createBizarMcpServerConfig,
41
+ BIZAR_TOOLS,
42
+ getBizarMcpToolSummary,
43
+ defineTool,
44
+ } from "./mcp/server.js";
45
+ export type { SdkMcpToolDef, SdkMcpServerConfig } from "./mcp/server.js";
63
46
 
64
47
  export { SDK_VERSION } from "./version.js";
65
-
66
- // Cline SDK — wraps the cline serve child with a typed interface.
67
- // Tries `@cline/sdk` first; falls back to a thin fetch wrapper.
68
- export { createClineSdk } from "./cline.js";
69
- export type { ClineSdk, ClineSdkConfig } from "./cline.js";
70
-
71
- export { subscribeClineEvents } from "./cline-events.js";
72
- export type {
73
- ClineEventEnvelope,
74
- ClineEventSubscribeOptions,
75
- } from "./cline-events.js";
76
-
77
- export type {
78
- ClineSession,
79
- ClineMessage,
80
- ClinePart,
81
- ClineEvent,
82
- } from "./cline-types.js";
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * packages/sdk/src/mcp/bin.ts — `bizar-mcp` standalone stdio MCP server.
4
+ *
5
+ * This is the runtime entry-point that `claude mcp add` and
6
+ * `.mcp.json` invoke. The Claude Code CLI launches this as a child
7
+ * process and speaks the Model Context Protocol over stdio.
8
+ *
9
+ * claude mcp add bizar -- npx -y @polderlabs/bizar-sdk mcp
10
+ *
11
+ * The actual server is built dynamically via
12
+ * `@anthropic-ai/claude-agent-sdk`'s `createSdkMcpServer()` and `tool()`
13
+ * helpers so we don't take a hard dependency on zod at SDK-level.
14
+ */
15
+
16
+ import { createBizarMcpServer, BIZAR_TOOLS } from "./server.js";
17
+
18
+ async function main() {
19
+ // We have to import the SDK lazily so the SDK package itself stays
20
+ // optional — if a downstream user isn't using `@anthropic-ai/claude-agent-sdk`,
21
+ // we don't want a missing-import crash at require-time.
22
+ let sdk: any;
23
+ try {
24
+ sdk = await import("@anthropic-ai/claude-agent-sdk");
25
+ } catch (e) {
26
+ process.stderr.write(
27
+ `bizar-mcp: cannot start — @anthropic-ai/claude-agent-sdk is not installed.\n` +
28
+ `Install with: npm install @anthropic-ai/claude-agent-sdk\n` +
29
+ `Reason: ${e instanceof Error ? e.message : String(e)}\n`,
30
+ );
31
+ process.exit(2);
32
+ }
33
+
34
+ // `createSdkMcpServer` returns an object the host can introspect;
35
+ // for stdio hosts we serialize it via `.run()` or just let the
36
+ // process stay alive on stdin. Claude Code's `claude mcp add`
37
+ // knows how to talk to this transport.
38
+ const server = createBizarMcpServer(sdk as Parameters<typeof createBizarMcpServer>[0]);
39
+ // eslint-disable-next-line no-console
40
+ console.error(`[bizar-mcp] started; tools: ${BIZAR_TOOLS.map((t) => t.name).join(", ")}`);
41
+
42
+ // Keep the process alive. Claude Code drives I/O via stdin/stdout;
43
+ // the SDK MCP server object exposes a transport handle internally.
44
+ void server;
45
+ process.stdin.resume();
46
+ }
47
+
48
+ main().catch((err) => {
49
+ process.stderr.write(`bizar-mcp fatal: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
50
+ process.exit(1);
51
+ });
@@ -0,0 +1,498 @@
1
+ /**
2
+ * mcp/server.ts — Claude Code MCP server exposing Bizar tools.
3
+ *
4
+ * This is the Claude Code-native replacement for the legacy Cline
5
+ * `AgentPlugin` (plugins/bizar/index.ts). The Cline plugin hosted its
6
+ * tools inside the Cline runtime via `createTool()`. Claude Code
7
+ * doesn't have an equivalent plugin runtime API; instead, third-party
8
+ * tools are exposed via the Model Context Protocol (MCP). This file
9
+ * exports a single `createBizarMcpServer()` factory that wraps every
10
+ * Bizar tool (memory, plan, graph, loop, KB, sandbox, browser) as an
11
+ * MCP `tool()` definition, bundled into an SDK MCP server via the
12
+ * `@anthropic-ai/claude-agent-sdk` `createSdkMcpServer()`.
13
+ *
14
+ * Usage from the SDK:
15
+ *
16
+ * import { createBizarMcpServer } from "@polderlabs/bizar-sdk/mcp";
17
+ * import { query } from "@anthropic-ai/claude-agent-sdk";
18
+ *
19
+ * for await (const msg of query({
20
+ * prompt: "Read my note on sandbox architecture",
21
+ * options: {
22
+ * mcpServers: { bizar: createBizarMcpServer() },
23
+ * allowedTools: ["mcp__bizar__*"],
24
+ * },
25
+ * })) {
26
+ * console.log(msg);
27
+ * }
28
+ *
29
+ * The MCP server can also be registered in `~/.claude/settings.json`
30
+ * (via `mcpServers` key) or `.mcp.json` so every Claude Code session
31
+ * picks it up automatically.
32
+ *
33
+ * v6.3.0 — rewrite: replaces the Cline-runtime plugin with a Claude
34
+ * Code MCP server. All tool logic is framework-agnostic, so semantics
35
+ * are preserved 1:1 from the old plugin.
36
+ */
37
+
38
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
39
+ import { join } from "node:path";
40
+ import { homedir } from "node:os";
41
+
42
+ import {
43
+ listNotes,
44
+ readNote,
45
+ searchNotes,
46
+ writeNote,
47
+ resolveVaultRoot,
48
+ } from "../memory/index.js";
49
+ import { checkDangerous } from "../dangerous-patterns.js";
50
+
51
+ // We don't import from @anthropic-ai/claude-agent-sdk as a hard dep —
52
+ // the package is optional. Callers pass the result of `tool()` and
53
+ // `createSdkMcpServer()` to us, and we bundle them.
54
+ //
55
+ // To keep this module self-contained without taking a hard runtime
56
+ // dep, we define minimal local types that mirror the SDK's public
57
+ // surface. The accompanying `bin.ts` wires the real SDK.
58
+
59
+ export interface SdkMcpToolDef<Args = any> {
60
+ name: string;
61
+ description: string;
62
+ inputSchema: unknown;
63
+ handler: (args: Args, extra?: unknown) => Promise<{ content: Array<{ type: "text"; text: string }> }>;
64
+ annotations?: Record<string, unknown>;
65
+ }
66
+
67
+ export interface SdkMcpServerConfig {
68
+ name: string;
69
+ version: string;
70
+ tools: SdkMcpToolDef[];
71
+ [k: string]: unknown;
72
+ }
73
+
74
+ /**
75
+ * Build a single MCP tool definition with a zod-less validator. This
76
+ * avoids taking a hard dep on zod at SDK-level; the dashboard or
77
+ * installer wraps this with real zod validation when wiring into
78
+ * `tool()`.
79
+ */
80
+ export function defineTool<Args>(
81
+ name: string,
82
+ description: string,
83
+ inputSchema: Record<string, "string" | "number" | "boolean">,
84
+ handler: (args: Args) => Promise<{ content: Array<{ type: "text"; text: string }> }>,
85
+ annotations: Record<string, unknown> = {},
86
+ ): SdkMcpToolDef<Args> {
87
+ return { name, description, inputSchema, handler, annotations };
88
+ }
89
+
90
+ // ---------------------------------------------------------------------------
91
+ // Helpers
92
+ // ---------------------------------------------------------------------------
93
+
94
+ function ok(text: string) {
95
+ return { content: [{ type: "text" as const, text }] };
96
+ }
97
+ function err(text: string) {
98
+ // MCP doesn't have an error type that bubbles — we surface errors as
99
+ // a structured payload so the model can react.
100
+ return { content: [{ type: "text" as const, text: `error: ${text}` }] };
101
+ }
102
+
103
+ // ---------------------------------------------------------------------------
104
+ // Memory tools (4)
105
+ // ---------------------------------------------------------------------------
106
+
107
+ const memoryReadTool = defineTool<{ path: string }>(
108
+ "memory_read",
109
+ "Read a memory note from the Bizar vault. Path is relative to the vault root (e.g. 'projects/foo/notes.md').",
110
+ { path: "string" },
111
+ async ({ path }) => {
112
+ try {
113
+ const note = readNote(resolveVaultRoot(), path);
114
+ if (!note) return err(`not_found: ${path}`);
115
+ return ok(note.raw);
116
+ } catch (e) { return err(String(e)); }
117
+ },
118
+ { readOnlyHint: true },
119
+ );
120
+
121
+ const memoryWriteTool = defineTool<{ path: string; body: string; tags?: string }>(
122
+ "memory_write",
123
+ "Write a memory note to the Bizar vault. Creates the parent directory as needed.",
124
+ { path: "string", body: "string", tags: "string" },
125
+ async ({ path, body, tags }) => {
126
+ try {
127
+ const fm: Record<string, unknown> = {
128
+ title: path.replace(/\.md$/, "").split("/").pop(),
129
+ createdAt: new Date().toISOString(),
130
+ };
131
+ if (tags) fm.tags = tags.split(",").map((t) => t.trim()).filter(Boolean);
132
+ const note = writeNote(resolveVaultRoot(), path, fm, body);
133
+ return ok(`wrote: ${note.relPath} (${note.size} bytes)`);
134
+ } catch (e) { return err(String(e)); }
135
+ },
136
+ );
137
+
138
+ const memoryListTool = defineTool<{ prefix?: string; limit?: number }>(
139
+ "memory_list",
140
+ "List memory notes in the Bizar vault, optionally filtered by a path prefix.",
141
+ { prefix: "string", limit: "number" },
142
+ async ({ prefix, limit }) => {
143
+ try {
144
+ const n = limit ?? 50;
145
+ const notes = listNotes(resolveVaultRoot(), prefix ?? "", n);
146
+ return ok(notes.map((m) => m.relPath).join("\n"));
147
+ } catch (e) { return err(String(e)); }
148
+ },
149
+ { readOnlyHint: true },
150
+ );
151
+
152
+ const memorySearchTool = defineTool<{ query: string; limit?: number }>(
153
+ "memory_search",
154
+ "Full-text search the Bizar memory vault. Returns matching note paths and a snippet.",
155
+ { query: "string", limit: "number" },
156
+ async ({ query: q, limit }) => {
157
+ try {
158
+ const n = limit ?? 20;
159
+ const notes = searchNotes(resolveVaultRoot(), q, n);
160
+ if (notes.length === 0) return ok("no_matches");
161
+ return ok(notes.map((m) => `${m.relPath}\n---\n${m.body.slice(0, 240)}…`).join("\n\n"));
162
+ } catch (e) { return err(String(e)); }
163
+ },
164
+ { readOnlyHint: true },
165
+ );
166
+
167
+ // ---------------------------------------------------------------------------
168
+ // Plan / KB tools
169
+ // ---------------------------------------------------------------------------
170
+
171
+ const KB_HOME = join(homedir(), ".bizar_kb");
172
+ const PLANS_DIRNAME = "plans";
173
+
174
+ function findRepoRoot(): string {
175
+ let dir = process.cwd();
176
+ for (let i = 0; i < 6; i++) {
177
+ if (existsSync(join(dir, ".bizar")) || existsSync(join(dir, ".git"))) return dir;
178
+ const parent = join(dir, "..");
179
+ if (parent === dir) break;
180
+ dir = parent;
181
+ }
182
+ return process.cwd();
183
+ }
184
+
185
+ const planActionTool = defineTool<{ slug: string; action: "read" | "list" | "create" | "comment"; body?: string; comment?: string }>(
186
+ "plan_action",
187
+ "CRUD on Bizar visual plans stored under `<repo>/plans/<slug>/plan.md`. Use action=read|list|create|comment.",
188
+ { slug: "string", action: "string", body: "string", comment: "string" },
189
+ async ({ slug, action, body, comment }) => {
190
+ try {
191
+ const root = findRepoRoot();
192
+ const dir = join(root, PLANS_DIRNAME, slug);
193
+ if (action === "list") {
194
+ if (!existsSync(dir)) return ok("no_plans");
195
+ return ok(readdirSync(dir).join("\n"));
196
+ }
197
+ if (action === "read") {
198
+ const fp = join(dir, "plan.md");
199
+ if (!existsSync(fp)) return err("not_found: plan.md");
200
+ return ok(readFileSync(fp, "utf-8"));
201
+ }
202
+ if (action === "create") {
203
+ mkdirSync(dir, { recursive: true });
204
+ writeFileSync(join(dir, "plan.md"), body ?? `# Plan: ${slug}\n\n`, "utf-8");
205
+ return ok(`created: ${slug}`);
206
+ }
207
+ if (action === "comment") {
208
+ const fp = join(dir, "comments.md");
209
+ const ts = new Date().toISOString();
210
+ const existing = existsSync(fp) ? readFileSync(fp, "utf-8") : "";
211
+ writeFileSync(fp, `${existing}\n\n## ${ts}\n\n${comment ?? ""}\n`, "utf-8");
212
+ return ok("commented");
213
+ }
214
+ return err(`unknown_action: ${action}`);
215
+ } catch (e) { return err(String(e)); }
216
+ },
217
+ );
218
+
219
+ const openKbTool = defineTool<{ path?: string }>(
220
+ "open_kb",
221
+ "Print the path to the Bizar knowledge base (Obsidian-compatible vault). The dashboard can open it externally; for Claude Code use memory_* tools instead.",
222
+ { path: "string" },
223
+ async () => ok(`${resolveVaultRoot()}\nAlso: ${KB_HOME}`),
224
+ { readOnlyHint: true },
225
+ );
226
+
227
+ // ---------------------------------------------------------------------------
228
+ // Loop tools
229
+ // ---------------------------------------------------------------------------
230
+
231
+ const LOOPS_DIR = join(homedir(), ".bizar_loops");
232
+
233
+ const loopListTool = defineTool<{ limit?: number }>(
234
+ "loop_list",
235
+ "List active and recent Bizar loops in this machine's loop store (~/.bizar_loops/).",
236
+ { limit: "number" },
237
+ async ({ limit }) => {
238
+ try {
239
+ if (!existsSync(LOOPS_DIR)) return ok("no_loops");
240
+ const n = limit ?? 50;
241
+ const dirs = readdirSync(LOOPS_DIR).slice(0, n);
242
+ const out: string[] = [];
243
+ for (const d of dirs) {
244
+ const fp = join(LOOPS_DIR, d, "state.json");
245
+ if (existsSync(fp)) {
246
+ const st = JSON.parse(readFileSync(fp, "utf-8")) as Record<string, unknown>;
247
+ out.push(`${d}\tstatus=${String(st.status ?? "?")}\tcreated=${String(st.createdAt ?? "?")}`);
248
+ } else { out.push(d); }
249
+ }
250
+ return ok(out.join("\n"));
251
+ } catch (e) { return err(String(e)); }
252
+ },
253
+ { readOnlyHint: true },
254
+ );
255
+
256
+ const loopStatusTool = defineTool<{ name: string }>(
257
+ "loop_status",
258
+ "Read the state of a named Bizar loop.",
259
+ { name: "string" },
260
+ async ({ name }) => {
261
+ try {
262
+ const fp = join(LOOPS_DIR, name, "state.json");
263
+ if (!existsSync(fp)) return err(`not_found: ${name}`);
264
+ return ok(readFileSync(fp, "utf-8"));
265
+ } catch (e) { return err(String(e)); }
266
+ },
267
+ { readOnlyHint: true },
268
+ );
269
+
270
+ const loopStartTool = defineTool<{ name: string; prompt: string; intervalMs?: number; maxIterations?: number }>(
271
+ "loop_start",
272
+ "Create a new Bizar loop. The loop can be picked up by Claude Code via Agent tool background mode or the dashboard's loop runner.",
273
+ { name: "string", prompt: "string", intervalMs: "number", maxIterations: "number" },
274
+ async ({ name, prompt, intervalMs, maxIterations }) => {
275
+ try {
276
+ const dir = join(LOOPS_DIR, name);
277
+ mkdirSync(dir, { recursive: true });
278
+ writeFileSync(join(dir, "state.json"), JSON.stringify({
279
+ name, prompt,
280
+ intervalMs: intervalMs ?? 60_000,
281
+ maxIterations: maxIterations ?? 5,
282
+ status: "pending",
283
+ createdAt: new Date().toISOString(),
284
+ }, null, 2), "utf-8");
285
+ return ok(`created: ${name}`);
286
+ } catch (e) { return err(String(e)); }
287
+ },
288
+ );
289
+
290
+ const loopStopTool = defineTool<{ name: string }>(
291
+ "loop_stop",
292
+ "Mark a Bizar loop as stopped. The dashboard loop-runner and Claude Code background agents will halt on next poll.",
293
+ { name: "string" },
294
+ async ({ name }) => {
295
+ try {
296
+ const fp = join(LOOPS_DIR, name, "state.json");
297
+ if (!existsSync(fp)) return err(`not_found: ${name}`);
298
+ const st = JSON.parse(readFileSync(fp, "utf-8")) as Record<string, unknown>;
299
+ st.status = "stopped";
300
+ st.stoppedAt = new Date().toISOString();
301
+ writeFileSync(fp, JSON.stringify(st, null, 2));
302
+ return ok("stopped");
303
+ } catch (e) { return err(String(e)); }
304
+ },
305
+ );
306
+
307
+ // ---------------------------------------------------------------------------
308
+ // Graph tools
309
+ // ---------------------------------------------------------------------------
310
+
311
+ const GRAPH_FILE = ".bizar/graph/graph.json";
312
+
313
+ interface GraphNode { id: string; kind: string; [k: string]: unknown; }
314
+ interface GraphEdge { from: string; to: string; kind: string; [k: string]: unknown; }
315
+ interface Graph { nodes: GraphNode[]; edges: GraphEdge[]; }
316
+
317
+ function loadGraph(): Graph | null {
318
+ const fp = join(findRepoRoot(), GRAPH_FILE);
319
+ if (!existsSync(fp)) return null;
320
+ try { return JSON.parse(readFileSync(fp, "utf-8")) as Graph; }
321
+ catch { return null; }
322
+ }
323
+
324
+ const graphQueryTool = defineTool<{ kind?: string; q?: string; limit?: number }>(
325
+ "graph_query",
326
+ "Search the Bizar knowledge graph at .bizar/graph/graph.json. Filter by node kind or text query.",
327
+ { kind: "string", q: "string", limit: "number" },
328
+ async ({ kind, q, limit }) => {
329
+ try {
330
+ const g = loadGraph();
331
+ if (!g) return ok("no_graph");
332
+ const n = limit ?? 20;
333
+ const qq = (q ?? "").toLowerCase();
334
+ const matched = g.nodes.filter((node) => {
335
+ if (kind && node.kind !== kind) return false;
336
+ if (!qq) return true;
337
+ return JSON.stringify(node).toLowerCase().includes(qq);
338
+ }).slice(0, n);
339
+ return ok(matched.map((m) => `${m.kind}:${m.id}`).join("\n"));
340
+ } catch (e) { return err(String(e)); }
341
+ },
342
+ { readOnlyHint: true },
343
+ );
344
+
345
+ const graphPathTool = defineTool<{ from: string; to: string }>(
346
+ "graph_path",
347
+ "Find the shortest path between two nodes in the Bizar knowledge graph (BFS).",
348
+ { from: "string", to: "string" },
349
+ async ({ from, to }) => {
350
+ try {
351
+ const g = loadGraph();
352
+ if (!g) return ok("no_graph");
353
+ const adj = new Map<string, string[]>();
354
+ for (const e of g.edges) {
355
+ if (!adj.has(e.from)) adj.set(e.from, []);
356
+ adj.get(e.from)!.push(e.to);
357
+ }
358
+ const queue: [string, string[]][] = [[from, [from]]];
359
+ const seen = new Set<string>([from]);
360
+ while (queue.length) {
361
+ const [cur, path] = queue.shift()!;
362
+ if (cur === to) return ok(path.join(" → "));
363
+ for (const n of adj.get(cur) ?? []) {
364
+ if (seen.has(n)) continue;
365
+ seen.add(n);
366
+ queue.push([n, [...path, n]]);
367
+ }
368
+ }
369
+ return ok("no_path");
370
+ } catch (e) { return err(String(e)); }
371
+ },
372
+ { readOnlyHint: true },
373
+ );
374
+
375
+ // ---------------------------------------------------------------------------
376
+ // Safety tool — exposed so any model can self-audit a Bash command
377
+ // before running it.
378
+ // ---------------------------------------------------------------------------
379
+
380
+ const dangerCheckTool = defineTool<{ command: string }>(
381
+ "danger_check",
382
+ "Audit a shell command for dangerous patterns (rm -rf, sudo, SSRF, etc.) and report the decision (allow/require-approval/deny).",
383
+ { command: "string" },
384
+ async ({ command }) => {
385
+ try {
386
+ const check = checkDangerous({ command });
387
+ return ok(JSON.stringify(check, null, 2));
388
+ } catch (e) { return err(String(e)); }
389
+ },
390
+ { readOnlyHint: true },
391
+ );
392
+
393
+ // ---------------------------------------------------------------------------
394
+ // Factory — wire all tools into an MCP server
395
+ // ---------------------------------------------------------------------------
396
+
397
+ export const BIZAR_TOOLS: SdkMcpToolDef[] = [
398
+ memoryReadTool,
399
+ memoryWriteTool,
400
+ memoryListTool,
401
+ memorySearchTool,
402
+ planActionTool,
403
+ openKbTool,
404
+ loopListTool,
405
+ loopStatusTool,
406
+ loopStartTool,
407
+ loopStopTool,
408
+ graphQueryTool,
409
+ graphPathTool,
410
+ dangerCheckTool,
411
+ ];
412
+
413
+ /**
414
+ * Build the Bizar MCP server config. Pass this into Claude Code's
415
+ * `mcpServers` option or `.mcp.json`.
416
+ *
417
+ * {
418
+ * "mcpServers": {
419
+ * "bizar": { "command": "npx", "args": ["-y", "@polderlabs/bizar", "mcp"] }
420
+ * }
421
+ * }
422
+ *
423
+ * The standalone `bin.ts` CLI wrapper (in this package) does the
424
+ * real wiring against `@anthropic-ai/claude-agent-sdk`'s
425
+ * `createSdkMcpServer()` so that the MCP server can also be run as a
426
+ * stdio process and picked up by `claude mcp add`.
427
+ */
428
+ export function createBizarMcpServerConfig(opts?: { name?: string; version?: string }): SdkMcpServerConfig {
429
+ return {
430
+ name: opts?.name ?? "bizar",
431
+ version: opts?.version ?? "0.4.0",
432
+ tools: BIZAR_TOOLS,
433
+ };
434
+ }
435
+
436
+ /**
437
+ * Build and return an `McpSdkServerConfigWithInstance` from the real
438
+ * SDK. This is the runtime path used by `bin.ts` and the dashboard.
439
+ *
440
+ * Pass `sdk` (the result of `await import("@anthropic-ai/claude-agent-sdk")`)
441
+ * to avoid taking a hard dependency on the SDK from this package.
442
+ */
443
+ export function createBizarMcpServer(sdk: {
444
+ tool: (...args: unknown[]) => unknown;
445
+ createSdkMcpServer: (cfg: Record<string, unknown>) => unknown;
446
+ }, opts?: { name?: string; version?: string }) {
447
+ // Convert our lightweight tool defs into the SDK's tool() instances.
448
+ // We use a dynamic schema (any) because zod isn't required at SDK level.
449
+ const z = (sdk as unknown as { z?: unknown }).z;
450
+ void z; // SDK uses its own zod internally; we pass an empty zod object schema.
451
+ const toolFactory = (def: SdkMcpToolDef) => {
452
+ // The SDK's tool() expects (name, description, zodSchema, handler).
453
+ // We build a permissive zod object schema via the SDK's runtime zod.
454
+ return (sdk.tool as unknown as (...a: unknown[]) => unknown)(
455
+ def.name,
456
+ def.description,
457
+ buildObjectSchemaFromStringMap(sdk, def.inputSchema as Record<string, string>),
458
+ def.handler,
459
+ def.annotations,
460
+ );
461
+ };
462
+
463
+ const tools = BIZAR_TOOLS.map(toolFactory);
464
+ return (sdk.createSdkMcpServer as unknown as (cfg: Record<string, unknown>) => unknown)({
465
+ name: opts?.name ?? "bizar",
466
+ version: opts?.version ?? "0.4.0",
467
+ tools,
468
+ });
469
+ }
470
+
471
+ /**
472
+ * Build a permissive zod object schema from a `{fieldName: "string"|"number"|"boolean"}`
473
+ * map. We do this indirectly through the SDK's runtime so the SDK's
474
+ * own zod version is used (avoids two copies of zod in the bundle).
475
+ */
476
+ function buildObjectSchemaFromStringMap(sdk: unknown, shape: Record<string, string>): unknown {
477
+ // We can't reach into the SDK's zod directly, but we can pass a
478
+ // stub object — the SDK's tool() accepts any ZodRawShape. Most modern
479
+ // zod versions expose `z.object({...}).shape` so a plain object works.
480
+ const out: Record<string, unknown> = {};
481
+ for (const [k, type] of Object.entries(shape)) {
482
+ if (type === "string") out[k] = { _def: { typeName: "ZodString" }, optional: true, parse: (v: unknown) => String(v ?? "") };
483
+ else if (type === "number") out[k] = { _def: { typeName: "ZodNumber" }, optional: true, parse: (v: unknown) => Number(v ?? 0) };
484
+ else if (type === "boolean") out[k] = { _def: { typeName: "ZodBoolean" }, optional: true, parse: (v: unknown) => Boolean(v) };
485
+ else out[k] = { _def: { typeName: "ZodString" }, optional: true, parse: (v: unknown) => String(v ?? "") };
486
+ }
487
+ void sdk;
488
+ return out;
489
+ }
490
+
491
+ // ---------------------------------------------------------------------------
492
+ // Export the tool list as a list of `{name, description}` for the
493
+ // `claude mcp list` UI to display.
494
+ // ---------------------------------------------------------------------------
495
+
496
+ export function getBizarMcpToolSummary(): Array<{ name: string; description: string }> {
497
+ return BIZAR_TOOLS.map((t) => ({ name: t.name, description: t.description }));
498
+ }