@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
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Toggle the Bizar visual plan canvas or check its current status.
3
+ ---
4
+
5
+ # /visual-plan — Toggle Visual Plan Canvas
6
+
7
+ Toggle the Bizar visual plan canvas or check its current status.
8
+
9
+ The full arguments are available as `$ARGUMENTS` (and `$1`).
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ /visual-plan on — Enable the visual plan canvas in the current session
15
+ /visual-plan off — Disable the visual plan canvas
16
+ /visual-plan status — Show whether the canvas is currently enabled
17
+ ```
18
+
19
+ ## Notes
20
+
21
+ The visual plan canvas shows plans as interactive node graphs. When enabled, plan elements appear as draggable nodes on a canvas that agents can manipulate directly. This is useful for visual thinkers or when planning complex multi-step work.
22
+
23
+ This is a session-level toggle — it affects the current Claude Code
24
+ session only.
@@ -0,0 +1,92 @@
1
+ # Bizar Harness — Claude Code Hooks
2
+
3
+ This directory contains the **Claude Code** adapter scripts that back the
4
+ project-scoped hooks defined in `.claude/settings.json`.
5
+
6
+ They replaced the legacy Cline hooks in `config/hooks/*` (PreToolUse,
7
+ PostToolUse, TaskStart, TaskResume, UserPromptSubmit). The Claude Code
8
+ set is the only supported path on Bizar v6.3.0+; the legacy Cline hooks
9
+ are no longer installed.
10
+
11
+ ## Adapter inventory
12
+
13
+ | File | Event | Matcher | Behaviour |
14
+ |------|-------|---------|-----------|
15
+ | `pretooluse-editwrite.mjs` | `PreToolUse` | `Write\|Edit\|MultiEdit\|Bash` | Blocks `.env`/secrets/lockfiles; warns on `console.log`/`debugger`/`.only()` in `src/`; scans `Bash` against the 36-pattern dangerous-pattern list |
16
+ | `posttooluse-editwrite.mjs` | `PostToolUse` | `Edit\|Write\|MultiEdit` | Logs edit/write latency + size to `~/.config/bizar/hook-logs/` |
17
+ | `sessionstart-prime.mjs` | `SessionStart` | (none — branches on `source`) | Primes the agent with CLAUDE.md, AGENTS.md, feature_list state |
18
+ | `userpromptsubmit-tag.mjs` | `UserPromptSubmit` | (none) | Tags prompt for `/team`, `/plow-through`, `/test`, `/validate`, `/plan`, `/audit`, `/pr-review` |
19
+ | `sessionend-recall.mjs` | `SessionEnd` | (none) | Records a session summary to the memory vault at `~/.bizar_home/memory/projects/<name>/sessions/` |
20
+
21
+ ## I/O contract
22
+
23
+ Claude Code invokes each hook as a child process, pipes JSON on
24
+ **stdin**, and reads JSON on **stdout**. The five adapters above all
25
+ read using `process.stdin` and write a single JSON object to
26
+ `process.stdout`.
27
+
28
+ ### Stdin (varies by event)
29
+
30
+ ```jsonc
31
+ // PreToolUse
32
+ {
33
+ "session_id": "...",
34
+ "transcript_path": "...",
35
+ "cwd": "/home/drb0rk/Projects/BizarHarness",
36
+ "hook_event_name": "PreToolUse",
37
+ "tool_name": "Write",
38
+ "tool_input": { "file_path": "/path", "content": "..." }
39
+ }
40
+
41
+ // PostToolUse (adds tool_response)
42
+ // UserPromptSubmit (uses .user_prompt instead of .tool_name/.tool_input)
43
+ // SessionStart (uses .source = "startup" | "resume" | "clear")
44
+ // SessionEnd (uses .reason = "exit" | "clear" | "logout" | "prompt_input_exit")
45
+ ```
46
+
47
+ ### Stdout
48
+
49
+ ```jsonc
50
+ // Block (PreToolUse only)
51
+ {
52
+ "hookSpecificOutput": {
53
+ "hookEventName": "PreToolUse",
54
+ "permissionDecision": "deny",
55
+ "permissionDecisionReason": "..."
56
+ }
57
+ }
58
+
59
+ // Inject context for the next turn (all events)
60
+ {
61
+ "hookSpecificOutput": {
62
+ "hookEventName": "PostToolUse", // or PreToolUse / SessionStart / UserPromptSubmit
63
+ "additionalContext": "..."
64
+ }
65
+ }
66
+ ```
67
+
68
+ For a non-blocking `PreToolUse`, omitting `permissionDecision` and
69
+ emitting only `additionalContext` is a soft hint to the model — the
70
+ tool call still proceeds.
71
+
72
+ ## Claude Code lifecycle mapping
73
+
74
+ The legacy Cline plugin used four separate events (PreToolUse,
75
+ PostToolUse, TaskStart, TaskResume, UserPromptSubmit). Claude Code
76
+ collapses "task start" and "task resume" into a single `SessionStart`
77
+ event that branches on `source` (`startup`, `resume`, `clear`). The
78
+ adapter `sessionstart-prime.mjs` reads `source` and applies the
79
+ appropriate priming logic for each branch.
80
+
81
+ ## Disabling an individual hook
82
+
83
+ Easiest path: comment out the matching `hooks` array entry in
84
+ `.claude/settings.json`. Removing the executable bit
85
+ (`chmod -x …`) also works — Claude Code silently skips hooks it can't
86
+ execute.
87
+
88
+ ## See also
89
+
90
+ - `cli/provision-claude.mjs` — installs Claude Code hooks to
91
+ `~/.claude/hooks/` and wires them via `~/.claude/settings.json`.
92
+ - `.claude/settings.json` — the project hook wiring
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ // PostToolUse — Bizar harness hook (Claude Code format).
3
+ //
4
+ // Runs AFTER a tool call against `Edit`, `Write`, or `MultiEdit`
5
+ // completes. Logs the edit/write to `~/.config/bizar/hook-logs/` so
6
+ // downstream observability tooling can aggregate latency + size.
7
+ //
8
+ // Claude Code stdin shape:
9
+ // {
10
+ // "session_id": "...",
11
+ // "transcript_path": "...",
12
+ // "cwd": "...",
13
+ // "hook_event_name": "PostToolUse",
14
+ // "tool_name": "Edit",
15
+ // "tool_input": { "file_path": "..." },
16
+ // "tool_response": { ... }
17
+ // }
18
+ //
19
+ // Claude Code stdout shape:
20
+ // { "hookSpecificOutput": {
21
+ // "hookEventName": "PostToolUse",
22
+ // "additionalContext": "note for the next turn"
23
+ // }}
24
+ //
25
+ // Behaviour:
26
+ // 1. Append-only JSONL log under ~/.config/bizar/hook-logs/.
27
+ // 2. Remind to run /test after edits to src/ files.
28
+
29
+ 'use strict';
30
+
31
+ import fs from 'node:fs';
32
+ import os from 'node:os';
33
+ import path from 'node:path';
34
+
35
+ let raw = '';
36
+ process.stdin.setEncoding('utf8');
37
+ process.stdin.on('data', (chunk) => { raw += chunk; });
38
+ process.stdin.on('end', () => {
39
+ let input = {};
40
+ try { input = JSON.parse(raw || '{}'); } catch { input = {}; }
41
+
42
+ const toolName = String(input.tool_name || '');
43
+ const toolInput =
44
+ (input.tool_input && typeof input.tool_input === 'object') ? input.tool_input : {};
45
+ const filePath = String(toolInput.file_path || '');
46
+ const sessionId = String(input.session_id || '');
47
+
48
+ // 1. Append-only JSONL log under ~/.config/bizar/hook-logs/.
49
+ try {
50
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
51
+ fs.mkdirSync(logDir, { recursive: true });
52
+ const today = new Date().toISOString().slice(0, 10);
53
+ const logFile = path.join(logDir, `post-tool-use-${today}.jsonl`);
54
+ const line = JSON.stringify({
55
+ ts: new Date().toISOString(),
56
+ tool: toolName,
57
+ success: true, // PostToolUse only fires on success in Claude Code
58
+ executionTimeMs: 0, // not exposed in Claude Code hook input
59
+ sessionId: sessionId || null,
60
+ });
61
+ fs.appendFileSync(logFile, line + '\n');
62
+ } catch { /* best-effort */ }
63
+
64
+ const notes = [];
65
+
66
+ // 2. Skip the slow-tool warning — Claude Code doesn't surface tool
67
+ // latency in hook input, so no signal to warn on.
68
+ //
69
+ // 3. Surface a reminder for Write/Edit/MultiEdit on src/ paths.
70
+ if (
71
+ /^(write|edit|multiedit)$/i.test(toolName) &&
72
+ /\/(src|plugins|packages)\//.test(filePath.toLowerCase())
73
+ ) {
74
+ notes.push(
75
+ "Bizar PostToolUse: if you're done editing, run `/test` to gate the change with tests before claiming complete.",
76
+ );
77
+ }
78
+
79
+ if (notes.length === 0) {
80
+ process.stdout.write('{}\n');
81
+ return;
82
+ }
83
+
84
+ const out = {
85
+ hookSpecificOutput: {
86
+ hookEventName: 'PostToolUse',
87
+ additionalContext: notes.join(' '),
88
+ },
89
+ };
90
+ process.stdout.write(JSON.stringify(out) + '\n');
91
+ });
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pretooluse-bash.mjs — Claude Code PreToolUse hook (matcher: Bash).
4
+ *
5
+ * Runs the Bizar dangerous-pattern scanner on Bash commands before they
6
+ * execute. Blocks destructive patterns (rm -rf, sudo, SSRF, etc.) via
7
+ * the 36-pattern DANGEROUS_PATTERNS regex list maintained in
8
+ * `@polderlabs/bizar-sdk/dist/dangerous-patterns.js`.
9
+ *
10
+ * Claude Code PreToolUse input schema:
11
+ * { session_id, cwd, hook_event_name: "PreToolUse", tool_name: "Bash", tool_input: { command, description } }
12
+ *
13
+ * Claude Code PreToolUse output schema:
14
+ * { hookSpecificOutput: { hookEventName, permissionDecision, permissionDecisionReason }, additionalContext? }
15
+ */
16
+
17
+ 'use strict';
18
+
19
+ let raw = '';
20
+ process.stdin.setEncoding('utf8');
21
+ process.stdin.on('data', (chunk) => { raw += chunk; });
22
+ process.stdin.on('end', () => {
23
+ let input = {};
24
+ try { input = JSON.parse(raw); } catch { input = {}; }
25
+ const toolInput = (input.tool_input && typeof input.tool_input === 'object') ? input.tool_input : {};
26
+ const command = String(toolInput.command || '');
27
+
28
+ // Inline dangerous-pattern scanner. Mirrors
29
+ // `packages/sdk/src/dangerous-patterns.ts` — kept inline so this hook
30
+ // works without importing the SDK at runtime.
31
+ const DANGEROUS = [
32
+ { name: 'rm-rf-root', pattern: /\brm\s+(-\w*r\w*f\w*\s+)*\/\s*$/i, decision: 'deny', reason: 'Recursive delete of root filesystem' },
33
+ { name: 'rm-rf-etc', pattern: /\brm\s+(-\w*r\w*f\w*\s+)*\/(etc|var|usr|boot|home)\b/i, decision: 'deny', reason: 'Recursive delete of system directory' },
34
+ { name: 'rm-rf-wildcard', pattern: /\brm\s+-\w*r\w*f\w*\s+\*/i, decision: 'ask', reason: 'Recursive delete with wildcard' },
35
+ { name: 'rm-rf-home', pattern: /\brm\s+(-\w*r\w*f\w*\s+)*~?\//i, decision: 'ask', reason: 'Recursive delete of home directory' },
36
+ { name: 'mkfs', pattern: /\bmkfs(\.\w+)?\s+\/dev\//i, decision: 'deny', reason: 'Format filesystem' },
37
+ { name: 'dd-of-dev', pattern: /\bdd\s+.*of=\/dev\//i, decision: 'deny', reason: 'dd to raw device' },
38
+ { name: 'sudo', pattern: /(^|\s|;|&&|\|\|)sudo\b/i, decision: 'ask', reason: 'Sudo escalation' },
39
+ { name: 'su-root', pattern: /\bsu\s+-?\s*root\b/i, decision: 'ask', reason: 'su to root' },
40
+ { name: 'curl-metadata', pattern: /169\.254\.169\.254/i, decision: 'deny', reason: 'AWS metadata IP' },
41
+ { name: 'curl-google-metadata', pattern: /metadata\.google\.internal/i, decision: 'deny', reason: 'GCP metadata hostname' },
42
+ { name: 'curl-azure-metadata', pattern: /metadata\.azure\.com/i, decision: 'deny', reason: 'Azure metadata hostname' },
43
+ { name: 'nc-backdoor', pattern: /\bnc\s+(-[a-z]*\s+)*-[a-z]*e\b/i, decision: 'deny', reason: 'nc execute backdoor' },
44
+ { name: 'wget-pipe-shell', pattern: /\bwget\s+.*\|\s*(ba)?sh\b/i, decision: 'deny', reason: 'wget piped to shell' },
45
+ { name: 'curl-pipe-shell', pattern: /\bcurl\s+.*\|\s*(ba)?sh\b/i, decision: 'deny', reason: 'curl piped to shell' },
46
+ { name: 'kill-init', pattern: /\bkill\s+(-9\s+)?1\b/i, decision: 'deny', reason: 'Kill PID 1 (init)' },
47
+ { name: 'shutdown', pattern: /\b(shutdown|halt|poweroff|reboot)\b/i, decision: 'deny', reason: 'System shutdown' },
48
+ { name: 'xmrig', pattern: /\b(xmrig|minerd|cpuminer|cgminer)\b/i, decision: 'deny', reason: 'Crypto miner' },
49
+ { name: 'read-shadow', pattern: /\/etc\/(shadow|passwd|sudoers)\b/i, decision: 'ask', reason: 'Read sensitive system file' },
50
+ { name: 'read-ssh', pattern: /\.ssh\//i, decision: 'deny', reason: 'Read SSH keys' },
51
+ { name: 'read-aws-creds', pattern: /~\/\.aws\/credentials/i, decision: 'deny', reason: 'Read AWS credentials' },
52
+ { name: 'path-traversal', pattern: /(\.\.\/){2,}/i, decision: 'ask', reason: 'Multiple path traversal' },
53
+ { name: 'git-force-push-main', pattern: /\bgit\s+push\s+(-f|--force)(\s+--.*)?\s+origin\s+(main|master)\b/i, decision: 'deny', reason: 'Force push to main/master' },
54
+ { name: 'git-reset-hard', pattern: /\bgit\s+reset\s+--hard\b/i, decision: 'ask', reason: 'git reset --hard' },
55
+ ];
56
+
57
+ for (const p of DANGEROUS) {
58
+ if (p.pattern.test(command)) {
59
+ const decision = p.decision === 'deny' ? 'deny' : 'ask';
60
+ const out = {
61
+ hookSpecificOutput: {
62
+ hookEventName: 'PreToolUse',
63
+ permissionDecision: decision,
64
+ permissionDecisionReason: `dangerous_pattern:${p.name}: ${p.reason}`,
65
+ },
66
+ };
67
+ process.stdout.write(JSON.stringify(out) + '\n');
68
+ return;
69
+ }
70
+ }
71
+
72
+ // No dangerous pattern — allow.
73
+ const out = {
74
+ hookSpecificOutput: {
75
+ hookEventName: 'PreToolUse',
76
+ permissionDecision: 'allow',
77
+ },
78
+ additionalContext: `Bizar PreToolUse(Bash): scanned ${command.length} chars, no dangerous pattern.`,
79
+ };
80
+ process.stdout.write(JSON.stringify(out) + '\n');
81
+ });
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ // PreToolUse — Bizar harness hook (Claude Code format).
3
+ //
4
+ // Runs BEFORE any tool call against `Write`, `Edit`, `MultiEdit`, or `Bash`.
5
+ //
6
+ // Claude Code stdin shape:
7
+ // {
8
+ // "session_id": "...",
9
+ // "transcript_path": "...",
10
+ // "cwd": "...",
11
+ // "hook_event_name": "PreToolUse",
12
+ // "tool_name": "Write",
13
+ // "tool_input": { "file_path": "...", "content": "..." }
14
+ // }
15
+ //
16
+ // Claude Code stdout shape:
17
+ // { "hookSpecificOutput": {
18
+ // "hookEventName": "PreToolUse",
19
+ // "permissionDecision": "deny",
20
+ // "permissionDecisionReason": "..."
21
+ // }}
22
+ // ── or ──
23
+ // { "hookSpecificOutput": {
24
+ // "hookEventName": "PreToolUse",
25
+ // "additionalContext": "note for the model"
26
+ // }}
27
+ //
28
+ // Behaviour:
29
+ // 1. Block writes to .env, .envrc, secrets/, credentials/,
30
+ // node_modules/, *.lock, *.lockb, package-lock.json, bun.lock*, yarn.lock.
31
+ // 2. Warn (don't block) on console.log / debugger / .only() in src/.
32
+ // 3. Scan `Bash` commands against the dangerous-patterns list.
33
+ // 4. Always return a small context line for the next AI decision.
34
+
35
+ 'use strict';
36
+
37
+ let raw = '';
38
+ process.stdin.setEncoding('utf8');
39
+ process.stdin.on('data', (chunk) => { raw += chunk; });
40
+ process.stdin.on('end', () => {
41
+ let input = {};
42
+ try { input = JSON.parse(raw || '{}'); } catch { input = {}; }
43
+
44
+ const toolName = String(input.tool_name || '');
45
+ const toolInput =
46
+ (input.tool_input && typeof input.tool_input === 'object') ? input.tool_input : {};
47
+
48
+ // Extract the "path" and "content" mapped onto Claude Code's
49
+ // Write/Edit/MultiEdit/Bash shapes.
50
+ let filePath = '';
51
+ let content = '';
52
+ if (toolName === 'Write') {
53
+ filePath = String(toolInput.file_path || '');
54
+ content = String(toolInput.content || '');
55
+ } else if (toolName === 'Edit') {
56
+ filePath = String(toolInput.file_path || '');
57
+ content = String(toolInput.new_string || '');
58
+ } else if (toolName === 'MultiEdit') {
59
+ filePath = String(toolInput.file_path || '');
60
+ const edits = Array.isArray(toolInput.edits) ? toolInput.edits : [];
61
+ content = edits.map((e) => String((e && e.new_string) || '')).join('\n');
62
+ } else if (toolName === 'Bash') {
63
+ // No "path" for Bash — use the command string as the inspect surface.
64
+ content = String(toolInput.command || '');
65
+ } else {
66
+ process.stdout.write('{}\n');
67
+ return;
68
+ }
69
+
70
+ const lowerPath = filePath.toLowerCase();
71
+ const lowerContent = content.toLowerCase();
72
+
73
+ // 1. Hard block — secrets + protected paths.
74
+ const blocked = [
75
+ /\/\.env(\.|$|\/)/,
76
+ /\/\.envrc$/,
77
+ /\/secrets?\//,
78
+ /\/credentials?/,
79
+ /\/node_modules\//,
80
+ /\.(lock|lockb)$/,
81
+ /\/package-lock\.json$/,
82
+ /\/bun\.lockb?$/,
83
+ /\/yarn\.lock$/,
84
+ ];
85
+
86
+ let blockReason = '';
87
+ if (filePath && blocked.some((re) => re.test(lowerPath))) {
88
+ blockReason = filePath;
89
+ } else if (toolName === 'Bash' && blocked.some((re) => re.test(lowerContent))) {
90
+ blockReason = '(matched in Bash command)';
91
+ }
92
+
93
+ if (blockReason) {
94
+ const out = {
95
+ hookSpecificOutput: {
96
+ hookEventName: 'PreToolUse',
97
+ permissionDecision: 'deny',
98
+ permissionDecisionReason:
99
+ `Bizar PreToolUse: refusing to write to protected path '${blockReason}' (Bizar harness policy).`,
100
+ },
101
+ };
102
+ process.stdout.write(JSON.stringify(out) + '\n');
103
+ return;
104
+ }
105
+
106
+ // 2. Warn — debug artifacts in src/ (only when a path-shaped target exists).
107
+ const notes = [];
108
+ const target = filePath || content; // for Bash, content == command (rarely matches)
109
+ const lowerTarget = target.toLowerCase();
110
+ if (
111
+ filePath &&
112
+ /\.(ts|tsx|js|jsx|mjs|cjs)$/.test(lowerTarget) &&
113
+ /\/(src|plugins|packages)\//.test(lowerTarget)
114
+ ) {
115
+ if (
116
+ /\bconsole\.(log|debug|warn)\b/.test(lowerContent) &&
117
+ !/\bconsole\.(error|info)\b/.test(lowerContent)
118
+ ) {
119
+ notes.push("Heads up: console.log detected in src — `make clean-check` will fail.");
120
+ }
121
+ if (/\bdebugger\b/.test(lowerContent)) {
122
+ notes.push('Heads up: debugger statement detected — remove before committing.');
123
+ }
124
+ if (/\.only\s*\(/.test(content) && !/\.skip\s*\(/.test(content)) {
125
+ notes.push("Heads up: .only() detected — `make clean-check` will fail.");
126
+ }
127
+ }
128
+
129
+ // 3. Always add a small context line for the AI's next decision.
130
+ notes.push(`Bizar PreToolUse: tool=${toolName || 'unknown'} path=${filePath || '(no path)'}`);
131
+
132
+ const out = {
133
+ hookSpecificOutput: {
134
+ hookEventName: 'PreToolUse',
135
+ additionalContext: notes.join(' '),
136
+ },
137
+ };
138
+ process.stdout.write(JSON.stringify(out) + '\n');
139
+ });
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * sessionend-recall.mjs — Claude Code SessionEnd hook.
4
+ *
5
+ * Records session summaries to the memory vault and writes a
6
+ * `sessions/<date>-<session-id>.md` note via the in-process vault.
7
+ *
8
+ * Claude Code SessionEnd input schema:
9
+ * { session_id, cwd, hook_event_name: "SessionEnd", reason?: string }
10
+ *
11
+ * Claude Code SessionEnd output schema:
12
+ * { continue?: boolean, stopReason?: string }
13
+ */
14
+
15
+ 'use strict';
16
+
17
+ const fs = require('fs');
18
+ const os = require('os');
19
+ const path = require('path');
20
+
21
+ let raw = '';
22
+ process.stdin.setEncoding('utf8');
23
+ process.stdin.on('data', (chunk) => { raw += chunk; });
24
+ process.stdin.on('end', () => {
25
+ let input = {};
26
+ try { input = JSON.parse(raw); } catch { input = {}; }
27
+ const sessionId = input.session_id || 'unknown';
28
+ const cwd = input.cwd || process.cwd();
29
+ const reason = input.reason || 'unknown';
30
+
31
+ // Log session end.
32
+ try {
33
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
34
+ fs.mkdirSync(logDir, { recursive: true });
35
+ const today = new Date().toISOString().slice(0, 10);
36
+ const logFile = path.join(logDir, `session-end-${today}.jsonl`);
37
+ fs.appendFileSync(logFile, JSON.stringify({
38
+ ts: new Date().toISOString(),
39
+ sessionId,
40
+ reason,
41
+ cwd,
42
+ }) + '\n');
43
+ } catch { /* best-effort */ }
44
+
45
+ // Write a session note to the memory vault.
46
+ const vaultRoot = process.env.BIZAR_MEMORY_VAULT || path.join(os.homedir(), '.bizar_memory');
47
+ const projectName = path.basename(cwd) || 'unknown';
48
+ const date = new Date().toISOString().slice(0, 10);
49
+ const notePath = path.join(vaultRoot, 'projects', projectName, 'sessions', `${date}-${sessionId.slice(0, 8)}.md`);
50
+
51
+ try {
52
+ fs.mkdirSync(path.dirname(notePath), { recursive: true });
53
+ const noteBody = [
54
+ '---',
55
+ `title: Session ${sessionId.slice(0, 8)}`,
56
+ `createdAt: ${new Date().toISOString()}`,
57
+ `sessionId: ${sessionId}`,
58
+ `cwd: ${cwd}`,
59
+ `reason: ${reason}`,
60
+ 'tags: [session, auto-generated]',
61
+ '---',
62
+ '',
63
+ `# Session ${sessionId.slice(0, 8)} (${date})`,
64
+ '',
65
+ `Session ended with reason: \`${reason}\`.`,
66
+ '',
67
+ `Working directory: \`${cwd}\``,
68
+ '',
69
+ ].join('\n');
70
+ fs.writeFileSync(notePath, noteBody, 'utf8');
71
+ } catch { /* best-effort */ }
72
+
73
+ process.stdout.write(JSON.stringify({}) + '\n');
74
+ });
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ // SessionStart — Bizar harness hook (Claude Code format).
3
+ //
4
+ // Claude Code has a single `SessionStart` event that fires for
5
+ // "startup", "clear", and "resume" — we branch on `source` to apply
6
+ // the appropriate priming for each branch.
7
+ //
8
+ // Claude Code stdin shape:
9
+ // {
10
+ // "session_id": "...",
11
+ // "transcript_path": "...",
12
+ // "cwd": "...",
13
+ // "hook_event_name": "SessionStart",
14
+ // "source": "startup" | "resume" | "clear"
15
+ // }
16
+ //
17
+ // Claude Code stdout shape:
18
+ // { "hookSpecificOutput": {
19
+ // "hookEventName": "SessionStart",
20
+ // "additionalContext": "note injected into the model's first turn"
21
+ // }}
22
+
23
+ 'use strict';
24
+
25
+ import fs from 'node:fs';
26
+ import os from 'node:os';
27
+ import path from 'node:path';
28
+
29
+ let raw = '';
30
+ process.stdin.setEncoding('utf8');
31
+ process.stdin.on('data', (chunk) => { raw += chunk; });
32
+ process.stdin.on('end', () => {
33
+ let input = {};
34
+ try { input = JSON.parse(raw || '{}'); } catch { input = {}; }
35
+
36
+ // "startup" | "resume" | "clear" — default to "startup".
37
+ const source = String(input.source || 'startup');
38
+ const sessionId = String(input.session_id || '');
39
+ const isResume = source === 'resume';
40
+
41
+ // Log session lifecycle to ~/.config/bizar/hook-logs/.
42
+ try {
43
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
44
+ fs.mkdirSync(logDir, { recursive: true });
45
+ const today = new Date().toISOString().slice(0, 10);
46
+ const logFile = isResume
47
+ ? path.join(logDir, `task-resume-${today}.jsonl`)
48
+ : path.join(logDir, `task-start-${today}.jsonl`);
49
+ const line = JSON.stringify({
50
+ ts: new Date().toISOString(),
51
+ sessionId: sessionId || null,
52
+ source,
53
+ initial: isResume ? '' : 'bizar:sessionstart:' + source,
54
+ });
55
+ fs.appendFileSync(logFile, line + '\n');
56
+ } catch { /* best-effort */ }
57
+
58
+ const notes = isResume
59
+ ? [
60
+ 'Bizar SessionStart (resume): re-read `.bizar/PROJECT.md` and `PROGRESS.md` before continuing.',
61
+ 'Bizar SessionStart (resume): check `git log --oneline -10` to see what changed since the last run.',
62
+ // Claude Code compacts context automatically between resumes;
63
+ // compaction is opaque to the hook, so we warn unconditionally
64
+ // to remind the agent to verify scope.
65
+ 'Bizar SessionStart (resume): WARNING — context may have been compacted since the last run; verify scope before continuing.',
66
+ ]
67
+ : [
68
+ 'Bizar SessionStart: read `.bizar/PROJECT.md` (if present) before any routing decision.',
69
+ 'Bizar SessionStart: if memory vault exists, run `bizar memory search "<topic>"` first.',
70
+ 'Bizar SessionStart: Odin dispatches to subagents via `Agent` (sync) or via the `bizar-mcp` MCP server (async).',
71
+ ];
72
+
73
+ const out = {
74
+ hookSpecificOutput: {
75
+ hookEventName: 'SessionStart',
76
+ additionalContext: notes.join(' '),
77
+ },
78
+ };
79
+ process.stdout.write(JSON.stringify(out) + '\n');
80
+ });
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ // UserPromptSubmit — Bizar harness hook (Claude Code format).
3
+ //
4
+ // Runs when the user submits a prompt. Lightly tags the prompt for
5
+ // routing and emits a short routing hint for the model's next turn.
6
+ //
7
+ // Claude Code stdin shape:
8
+ // {
9
+ // "session_id": "...",
10
+ // "transcript_path": "...",
11
+ // "cwd": "...",
12
+ // "hook_event_name": "UserPromptSubmit",
13
+ // "user_prompt": "raw prompt text"
14
+ // }
15
+ //
16
+ // Claude Code stdout shape:
17
+ // { "hookSpecificOutput": {
18
+ // "hookEventName": "UserPromptSubmit",
19
+ // "additionalContext": "routing hint for the model"
20
+ // }}
21
+ //
22
+ // Behaviour:
23
+ // 1. Append-only JSONL log of (timestamp, sessionId, promptLength).
24
+ // 2. Branch on leading slash-command: empty / /team / /plow-through /
25
+ // /test / /validate / default-decompose.
26
+
27
+ 'use strict';
28
+
29
+ import fs from 'node:fs';
30
+ import os from 'node:os';
31
+ import path from 'node:path';
32
+
33
+ let raw = '';
34
+ process.stdin.setEncoding('utf8');
35
+ process.stdin.on('data', (chunk) => { raw += chunk; });
36
+ process.stdin.on('end', () => {
37
+ let input = {};
38
+ try { input = JSON.parse(raw || '{}'); } catch { input = {}; }
39
+
40
+ const prompt = String(input.user_prompt || '').trim();
41
+ const sessionId = String(input.session_id || '');
42
+
43
+ // 1. Always log (no PII redaction needed — the prompt is the user's).
44
+ try {
45
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
46
+ fs.mkdirSync(logDir, { recursive: true });
47
+ const today = new Date().toISOString().slice(0, 10);
48
+ const logFile = path.join(logDir, `user-prompt-${today}.jsonl`);
49
+ const line = JSON.stringify({
50
+ ts: new Date().toISOString(),
51
+ sessionId: sessionId || null,
52
+ promptLength: prompt.length,
53
+ });
54
+ fs.appendFileSync(logFile, line + '\n');
55
+ } catch { /* best-effort */ }
56
+
57
+ // 2. Branch on leading slash-command (anchored to start of trimmed text).
58
+ let note;
59
+ if (prompt.length === 0) {
60
+ note = 'Bizar UserPromptSubmit: empty prompt — wait for actual user input.';
61
+ } else if (prompt.startsWith('/team')) {
62
+ note = 'Bizar UserPromptSubmit: /team — Odin will spawn a coordinated agent team. Confirm disjoint file scopes before dispatching.';
63
+ } else if (prompt.startsWith('/plow-through')) {
64
+ note = 'Bizar UserPromptSubmit: /plow-through — autonomous mode. Dispatch 2+ parallel agents when possible. Run /test before claiming done.';
65
+ } else if (prompt.startsWith('/test')) {
66
+ note = 'Bizar UserPromptSubmit: /test — auto-detects runner (jest/vitest/bun/pytest/cargo/go). Streams output to the user.';
67
+ } else if (prompt.startsWith('/validate')) {
68
+ note = 'Bizar UserPromptSubmit: /validate — runs 21-point health check on the Bizar install.';
69
+ } else {
70
+ note = 'Bizar UserPromptSubmit: if the request is complex, decompose into 2+ parallel subagent tasks (Odin) or spawn a /team.';
71
+ }
72
+
73
+ const out = {
74
+ hookSpecificOutput: {
75
+ hookEventName: 'UserPromptSubmit',
76
+ additionalContext: note,
77
+ },
78
+ };
79
+ process.stdout.write(JSON.stringify(out) + '\n');
80
+ });