@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
@@ -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
+ });