@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,216 @@
1
+ # Memory Safety in Modern C++
2
+
3
+ This reference covers RAII, smart pointers, and the Rule of Five/Zero.
4
+
5
+ ## RAII — Resource Acquisition Is Initialization
6
+
7
+ Every resource (heap memory, file handle, mutex, socket, etc.) must be owned by an object whose destructor performs cleanup. This guarantees cleanup even when exceptions are thrown.
8
+
9
+ ```cpp
10
+ // GOOD — file closes automatically at scope exit
11
+ void read_file(const std::string& path) {
12
+ std::ifstream in(path);
13
+ std::string line;
14
+ while (std::getline(in, line)) {
15
+ process(line);
16
+ }
17
+ } // destructor closes file, no matter how we exit
18
+
19
+ // BAD — manual cleanup, error-prone
20
+ void read_file_bad(const std::string& path) {
21
+ std::ifstream* in = new std::ifstream(path);
22
+ std::string line;
23
+ while (std::getline(*in, line)) { // throws? leaks *in
24
+ process(line);
25
+ }
26
+ delete in;
27
+ }
28
+ ```
29
+
30
+ ### Common RAII Types in the Standard Library
31
+
32
+ | Type | Resource |
33
+ |---|---|
34
+ | `std::unique_ptr` | Heap memory (single owner) |
35
+ | `std::shared_ptr` | Heap memory (shared owner) |
36
+ | `std::ifstream` / `std::ofstream` | File handles |
37
+ | `std::lock_guard` / `std::scoped_lock` | Mutex lock |
38
+ | `std::jthread` (C++20) | Thread join on destruction |
39
+
40
+ ## Smart Pointers
41
+
42
+ ### `std::unique_ptr<T>`
43
+
44
+ Exclusive ownership. The default choice. Zero overhead over raw pointer.
45
+
46
+ ```cpp
47
+ #include <memory>
48
+
49
+ // Creation
50
+ auto p1 = std::make_unique<int>(42);
51
+ auto p2 = std::make_unique<std::vector<int>>(10, 0);
52
+
53
+ // Custom deleter (rare — only when type needs special cleanup)
54
+ auto file_deleter = [](FILE* f) { if (f) fclose(f); };
55
+ std::unique_ptr<FILE, decltype(file_deleter)> fp(fopen("data.txt", "r"), file_deleter);
56
+
57
+ // Transfer ownership
58
+ std::unique_ptr<int> source = std::make_unique<int>(1);
59
+ std::unique_ptr<int> dest = std::move(source); // source is now nullptr
60
+ assert(!source);
61
+ assert(*dest == 1);
62
+
63
+ // Release the raw pointer (rare — only for C interop)
64
+ int* raw = p1.release();
65
+ delete raw; // you now own it — avoid this
66
+ ```
67
+
68
+ ### `std::shared_ptr<T>`
69
+
70
+ Shared ownership via reference counting. Use **only** when ownership genuinely must be shared. Prefer `unique_ptr` otherwise.
71
+
72
+ ```cpp
73
+ auto shared = std::make_shared<int>(100);
74
+
75
+ // Copy increases ref count
76
+ auto shared2 = shared; // ref count = 2
77
+
78
+ // shared_ptr can be created from unique_ptr
79
+ auto unique = std::make_unique<double>(3.14);
80
+ std::shared_ptr<double> from_unique = std::move(unique);
81
+
82
+ // Weak pointer — breaks cycles
83
+ std::weak_ptr<int> weak = shared;
84
+ if (auto locked = weak.lock()) {
85
+ // use *locked safely
86
+ } // locked goes out of scope, ref count unchanged
87
+
88
+ // Custom deleter — stored separately from the control block
89
+ auto deleter = [](FILE* f) { fclose(f); };
90
+ std::shared_ptr<FILE> f(fopen("x.txt", "r"), deleter);
91
+ ```
92
+
93
+ **Performance notes:**
94
+ - `shared_ptr` is twice the size of a raw pointer (control block + pointer)
95
+ - Atomic reference count increments/decrements on copy/destroy
96
+ - `make_shared` allocates the object and control block in one allocation (preferred)
97
+
98
+ ### `std::weak_ptr<T>`
99
+
100
+ Non-owning observer of a `shared_ptr`. Use to break reference cycles (A owns B, B observes A without owning).
101
+
102
+ ```cpp
103
+ class Observer;
104
+ class Subject {
105
+ std::vector<std::weak_ptr<Observer>> observers_;
106
+ public:
107
+ void notify() {
108
+ for (auto& w : observers_) {
109
+ if (auto o = w.lock()) o->on_update();
110
+ }
111
+ }
112
+ };
113
+ ```
114
+
115
+ ## Rule of Five
116
+
117
+ If you define **any one** of the five special member functions below, you likely need to define **all five**:
118
+
119
+ 1. Destructor
120
+ 2. Copy constructor
121
+ 3. Copy assignment operator
122
+ 4. Move constructor
123
+ 5. Move assignment operator
124
+
125
+ ```cpp
126
+ class Buffer {
127
+ int* data_ = nullptr;
128
+ size_t size_ = 0;
129
+ public:
130
+ explicit Buffer(size_t n) : data_(new int[n]), size_(n) {}
131
+
132
+ ~Buffer() { delete[] data_; }
133
+
134
+ // Copy constructor
135
+ Buffer(const Buffer& o) : data_(new int[o.size_]), size_(o.size_) {
136
+ std::copy(o.data_, o.data_ + o.size_, data_);
137
+ }
138
+
139
+ // Copy assignment operator
140
+ Buffer& operator=(const Buffer& o) {
141
+ if (this != &o) {
142
+ delete[] data_;
143
+ data_ = new int[o.size_];
144
+ size_ = o.size_;
145
+ std::copy(o.data_, o.data_ + o.size_, data_);
146
+ }
147
+ return *this;
148
+ }
149
+
150
+ // Move constructor
151
+ Buffer(Buffer&& o) noexcept : data_(std::exchange(o.data_, nullptr)), size_(std::exchange(o.size_, 0)) {}
152
+
153
+ // Move assignment operator
154
+ Buffer& operator=(Buffer&& o) noexcept {
155
+ if (this != &o) {
156
+ delete[] data_;
157
+ data_ = std::exchange(o.data_, nullptr);
158
+ size_ = std::exchange(o.size_, 0);
159
+ }
160
+ return *this;
161
+ }
162
+ };
163
+ ```
164
+
165
+ ## Rule of Zero
166
+
167
+ Prefer **not** defining any special members and letting the compiler generate them correctly. Use standard library containers and smart pointers to manage resources.
168
+
169
+ ```cpp
170
+ // Rule of Zero — no manual resource management needed
171
+ class Point {
172
+ double x_ = 0, y_ = 0;
173
+ public:
174
+ Point() = default;
175
+ Point(double x, double y) : x_(x), y_(y) {}
176
+ double distance_to(const Point& o) const {
177
+ double dx = x_ - o.x_, dy = y_ - o.y_;
178
+ return std::sqrt(dx*dx + dy*dy);
179
+ }
180
+ };
181
+ // Compiler-generated copy/move/dtor are all correct here
182
+ ```
183
+
184
+ ## Common Mistakes
185
+
186
+ ```cpp
187
+ // WRONG: Shared ownership where unique ownership suffices
188
+ auto widget = std::make_shared<Widget>();
189
+ process(std::shared_ptr<Widget>(widget)); // unnecessary ref count bump
190
+
191
+ // WRONG: Memory leak via raw new in container
192
+ std::vector<int*> v;
193
+ v.push_back(new int(1)); // who deletes these?
194
+
195
+ // RIGHT: Smart pointers in containers
196
+ std::vector<std::unique_ptr<int>> v;
197
+ v.push_back(std::make_unique<int>(1)); // auto-deleted
198
+
199
+ // WRONG: Missing virtual destructor in base class
200
+ struct Base {
201
+ virtual void foo() {}
202
+ // Missing virtual destructor — deleting through base pointer is UB
203
+ };
204
+ struct Derived : Base {
205
+ std::vector<int> data;
206
+ };
207
+
208
+ Base* b = new Derived;
209
+ delete b; // UB: Derived's destructor not called
210
+
211
+ // RIGHT: Virtual destructor
212
+ struct Base {
213
+ virtual ~Base() = default; // polymorphic bases need virtual dtor
214
+ virtual void foo() {}
215
+ };
216
+ ```
@@ -0,0 +1,282 @@
1
+ # Modern C++17/20 Idioms
2
+
3
+ This reference covers the most impactful modern C++ features with minimal examples.
4
+
5
+ ## Structured Bindings
6
+
7
+ Unpack tuples, pairs, structs, and arrays into named variables.
8
+
9
+ ```cpp
10
+ #include <tuple>
11
+ #include <map>
12
+
13
+ // Pair/tuple
14
+ auto [key, value] = std::pair{1, std::string("hello")};
15
+
16
+ // Array
17
+ auto [a, b, c] = std::array{1, 2, 3};
18
+
19
+ // Struct — works if all members are public
20
+ struct Point { double x, y, z; };
21
+ Point p{1.0, 2.0, 3.0};
22
+ auto [px, py, pz] = p;
23
+
24
+ // Map iteration
25
+ std::map<std::string, int> ages{{"Alice", 30}, {"Bob", 25}};
26
+ for (const auto& [name, age] : ages) {
27
+ std::cout << name << ": " << age << '\n';
28
+ }
29
+
30
+ // Multiple return values
31
+ std::tuple<int, std::string, double> compute() { return {42, "answer", 3.14}; }
32
+ auto [code, label, score] = compute();
33
+ ```
34
+
35
+ ## `if constexpr`
36
+
37
+ Compile-time conditional code execution — the unselected branch is not instantiated.
38
+
39
+ ```cpp
40
+ #include <type_traits>
41
+
42
+ template <typename T>
43
+ auto inspect(const T& val) {
44
+ if constexpr (std::is_integral_v<T>) {
45
+ return "integer";
46
+ } else if constexpr (std::is_floating_point_v<T>) {
47
+ return "floating-point";
48
+ } else {
49
+ return "other";
50
+ }
51
+ }
52
+
53
+ // Works where SFINAE would require complex enable_if
54
+ template <typename T>
55
+ T doubled(T x) {
56
+ if constexpr (std::is_integral_v<T>) {
57
+ return x + x; // valid only for integral T
58
+ } else {
59
+ return x * 2.0; // valid only for floating-point T
60
+ }
61
+ }
62
+ ```
63
+
64
+ ## `std::optional`
65
+
66
+ Represents a value that may or may not be present. Alternative to pointer-returning APIs.
67
+
68
+ ```cpp
69
+ #include <optional>
70
+
71
+ // Return optional
72
+ std::optional<int> find_index(const std::vector<int>& v, int target) {
73
+ for (auto it = v.begin(); it != v.end(); ++it) {
74
+ if (*it == target)
75
+ return {static_cast<int>(std::distance(v.begin(), it))};
76
+ }
77
+ return std::nullopt;
78
+ }
79
+
80
+ // Check and use
81
+ if (auto idx = find_index(vec, 42)) {
82
+ std::cout << "Found at " << *idx << '\n';
83
+ } else {
84
+ std::cout << "Not found\n";
85
+ }
86
+
87
+ // Transform an optional without unwrapping
88
+ std::optional<std::string> name = /* ... */;
89
+ auto greeting = name.transform([](const std::string& n) { return "Hello, " + n; });
90
+ ```
91
+
92
+ ## `std::string_view`
93
+
94
+ Non-owning view into a string. Use for read-only string operations without copying.
95
+
96
+ ```cpp
97
+ #include <string_view>
98
+
99
+ // Function takes a view — no ownership, no allocation
100
+ bool ends_with(std::string_view s, std::string_view suffix) {
101
+ return s.size() >= suffix.size() && s.substr(s.size() - suffix.size()) == suffix;
102
+ }
103
+
104
+ // Calling with different string types — no conversion/copy
105
+ std::string s = "filename.txt";
106
+ std::string_view sv = s;
107
+ ends_with(sv, ".txt"); // string_view
108
+ ends_with("literal", ".txt"); // const char* converts to string_view
109
+ ends_with(sv, std::string(".log")); // string converts to string_view
110
+
111
+ // AVOID: storing string_view as a class member — it doesn't own the data
112
+ // (only safe if another owning string keeps the data alive)
113
+ ```
114
+
115
+ ## `std::variant` (C++17)
116
+
117
+ Type-safe union — an object that holds one of several specified types.
118
+
119
+ ```cpp
120
+ #include <variant>
121
+
122
+ std::variant<int, std::string, double> v = 42;
123
+
124
+ // Check and access
125
+ if (std::holds_alternative<int>(v)) {
126
+ int i = std::get<int>(v);
127
+ }
128
+
129
+ // Visitor pattern
130
+ std::visit([](const auto& val) {
131
+ std::cout << val << '\n';
132
+ }, v);
133
+
134
+ // Overload helper (C++17 doesn't have std::visit overload; use this pattern)
135
+ template <class... Ts> struct overload : Ts... { using Ts::operator()...; };
136
+ template <class... Ts> overload(Ts...) -> overload<Ts...>;
137
+
138
+ std::visit(overload{
139
+ [](int i) { std::cout << "int: " << i << '\n'; },
140
+ [](const std::string& s) { std::cout << "string: " << s << '\n'; },
141
+ [](double d) { std::cout << "double: " << d << '\n'; }
142
+ }, v);
143
+ ```
144
+
145
+ ## `std::any` (C++17)
146
+
147
+ Holds any single value of any type. Use when the set of possible types is open-ended.
148
+
149
+ ```cpp
150
+ #include <any>
151
+
152
+ std::any a = 42;
153
+ a = std::string("hello");
154
+ a = 3.14;
155
+
156
+ if (a.type() == typeid(double)) {
157
+ double d = std::any_cast<double>(a);
158
+ }
159
+
160
+ // Safer: check before cast
161
+ if (auto* pd = std::any_cast<double>(&a)) {
162
+ std::cout << *pd << '\n';
163
+ }
164
+ ```
165
+
166
+ ## Ranges (C++20)
167
+
168
+ ```cpp
169
+ #include <ranges>
170
+ #include <algorithm>
171
+
172
+ std::vector<int> v = {1, 2, 3, 4, 5, 6};
173
+
174
+ // Filter and transform lazily — no new vector allocation
175
+ auto evens = v | std::views::filter([](int x) { return x % 2 == 0; });
176
+ auto doubled = evens | std::views::transform([](int x) { return x * 2; });
177
+
178
+ for (int x : doubled) std::cout << x << ' '; // 4 8 12
179
+
180
+ // Range-based sort (C++20 — simpler than iterators)
181
+ std::ranges::sort(v);
182
+
183
+ // Find
184
+ auto it = std::ranges::find(v, 3);
185
+
186
+ // All / any / none
187
+ bool has_negative = std::ranges::any_of(v, [](int x) { return x < 0; });
188
+
189
+ // Projections — sort by member without lambda boilerplate
190
+ struct Employee { std::string name; int level; };
191
+ std::vector<Employee> emps{{"Bob", 3}, {"Alice", 1}, {"Carol", 2}};
192
+ std::ranges::sort(emps, {}, &Employee::level); // sort by .level
193
+ ```
194
+
195
+ ## Concepts (C++20)
196
+
197
+ Explicit, named constraints on template parameters. Replace SFINAE with readable syntax.
198
+
199
+ ```cpp
200
+ #include <concepts>
201
+ #include <type_traits>
202
+
203
+ // Define a concept
204
+ template <typename T>
205
+ concept Numeric = std::integral<T> || std::floating_point<T>;
206
+
207
+ // Use in template parameters
208
+ template <Numeric T>
209
+ T add(T a, T b) { return a + b; }
210
+
211
+ static_assert(add(1, 2) == 3);
212
+ static_assert(add(1.5, 2.5) == 4.0);
213
+ // add("a", "b") — fails to instantiate: const char* is not Numeric
214
+
215
+ // Built-in concepts
216
+ static_assert(std::ranges::range<std::vector<int>>);
217
+ static_assert(std::copyable<int>);
218
+
219
+ // Combining concepts
220
+ template <typename T>
221
+ concept Comparable = requires(T a, T b) {
222
+ { a < b } -> std::convertible_to<bool>;
223
+ { a == b } -> std::convertible_to<bool>;
224
+ };
225
+ ```
226
+
227
+ ## `std::format` (C++20)
228
+
229
+ Type-safe, Python-style string formatting.
230
+
231
+ ```cpp
232
+ #include <format>
233
+ #include <chrono>
234
+
235
+ // Instead of printf/sprintf/cout combos
236
+ std::string s = std::format("{} + {} = {}", 1, 2, 3); // "1 + 2 = 3"
237
+ std::string t = std::format("{:>10}", 42); // right-aligned, width 10
238
+ std::string u = std::format("{:.2f}", 3.14159); // "3.14"
239
+ std::string v = std::format("{:02x}", 255); // "ff"
240
+
241
+ // Named arguments
242
+ std::cout << std::format("Hello, {name}! You are {age} years old.\n",
243
+ std::format_args::arg("name", "Alice"), /* arg */);
244
+ ```
245
+
246
+ ## `std::span` (C++20)
247
+
248
+ Non-owning view into a contiguous sequence — replacement for pointer+length pairs.
249
+
250
+ ```cpp
251
+ #include <span>
252
+
253
+ // Instead of (T* ptr, size_t count)
254
+ void print_all(std::span<const int> data) {
255
+ for (int x : data) std::cout << x << ' ';
256
+ }
257
+
258
+ std::vector<int> vec{1, 2, 3};
259
+ std::array<int, 3> arr{4, 5, 6};
260
+ int raw[] = {7, 8, 9};
261
+
262
+ print_all(vec); // works
263
+ print_all(arr); // works
264
+ print_all(raw); // works — decays to span<int, 3>
265
+ print_all({raw, 2}); // explicit length
266
+ ```
267
+
268
+ ## `[[likely]]` / `[[unlikely]]` (C++20)
269
+
270
+ Branch prediction hints for performance-critical paths.
271
+
272
+ ```cpp
273
+ bool process(int x) {
274
+ if (x > 0) [[likely]] {
275
+ // compiler may rearrange code for the common case
276
+ return do_positive(x);
277
+ }
278
+ [[unlikely]] {
279
+ return do_non_positive(x);
280
+ }
281
+ }
282
+ ```
@@ -0,0 +1,96 @@
1
+ # C++ Code Review Checklist
2
+
3
+ Use this checklist when reviewing C++ pull requests or before committing.
4
+
5
+ ## Memory Safety
6
+
7
+ - [ ] No raw `new` or `delete` — use `std::unique_ptr` / `std::make_unique`
8
+ - [ ] No owning raw pointers as class members (prefer `std::unique_ptr`)
9
+ - [ ] Shared ownership genuinely needed? Consider if `unique_ptr` suffices
10
+ - [ ] `shared_ptr` cycles broken with `weak_ptr`?
11
+ - [ ] Virtual destructor declared on any polymorphic base class
12
+ - [ ] All special member functions (Rule of Five) declared if needed
13
+ - [ ] No use-after-free: references/pointers outlive the data they refer to
14
+ - [ ] Arrays allocated with `new Type[n]` are `delete[]`d (or better, use `vector`)
15
+
16
+ ## RAII and Resource Management
17
+
18
+ - [ ] File handles, mutexes, sockets use RAII wrappers (destructor cleans up)
19
+ - [ ] `std::lock_guard` / `std::scoped_lock` used for mutex locking — not raw `.lock()/.unlock()`
20
+ - [ ] Every `std::thread` has `.join()` or `.detach()` called before destruction
21
+ - [ ] Prefer `std::jthread` (C++20) for automatic stop and join
22
+
23
+ ## Const Correctness
24
+
25
+ - [ ] Member functions that don't modify state are marked `const`
26
+ - [ ] Non-modifying parameters passed by `const&` (or by value if cheap-to-copy)
27
+ - [ ] `const` variables used where data doesn't change after init
28
+ - [ ] `const_iterator` used when iteration doesn't modify
29
+
30
+ ## Modern C++ Usage
31
+
32
+ - [ ] Uses C++17/20 features where appropriate (structured bindings, `if constexpr`, `std::optional`, `string_view`)
33
+ - [ ] No C-style casts — uses `static_cast`, `reinterpret_cast`, `const_cast`
34
+ - [ ] `[[nodiscard]]` on functions returning values that must not be ignored
35
+ - [ ] `override` used on all virtual method overrides
36
+ - [ ] `noexcept` used correctly (only on functions that truly cannot throw)
37
+ - [ ] `std::make_unique` / `std::make_shared` used instead of direct `new`
38
+
39
+ ## Headers and Includes
40
+
41
+ - [ ] No `using namespace std;` in header files
42
+ - [ ] No unused `#include` directives
43
+ - [ ] Include order: related header first, then standard library, then external libs
44
+ - [ ] Header is self-contained (includes everything it uses)
45
+
46
+ ## Containers and Types
47
+
48
+ - [ ] `std::vector` preferred over raw arrays for dynamic sequences
49
+ - [ ] `std::vector::reserve()` called when size is known ahead of time
50
+ - [ ] `std::array` used for fixed-size compile-time-known arrays
51
+ - [ ] `std::string_view` used for read-only string params (no ownership)
52
+ - [ ] `std::optional` used instead of sentinel values (e.g., `-1`, `nullptr`) for optional values
53
+ - [ ] No `std::endl` in hot paths (flushes the stream)
54
+
55
+ ## Error Handling
56
+
57
+ - [ ] Expected failures (not found, invalid input) handled without exceptions
58
+ - [ ] Exceptions used only for truly exceptional/unrecoverable conditions
59
+ - [ ] No exception thrown from destructors (use `noexcept` and `std::terminate` instead if needed)
60
+ - [ ] Exception safety level appropriate for the function (at minimum: no resource leaks)
61
+ - [ ] `std::expected<T, E>` (C++23) or error codes used in library/API code
62
+
63
+ ## Concurrency
64
+
65
+ - [ ] Shared mutable state protected by `std::mutex` / `std::lock_guard`
66
+ - [ ] No data races on shared variables
67
+ - [ ] `std::atomic` used for simple shared counters and flags
68
+ - [ ] Thread lifecycle managed correctly (`join()`/`detach()` or `jthread`)
69
+ - [ ] No passing of references to locals into detached threads
70
+
71
+ ## Performance Considerations
72
+
73
+ - [ ] No unnecessary copies (pass by `const&`, use `std::move`, prefer move over copy)
74
+ - [ ] No hidden allocations in hot paths (e.g., `s + "text"` inside a loop)
75
+ - [ ] Vector `reserve()` before known-size loops
76
+ - [ ] Emplacement used when inserting into containers: `vec.emplace_back(args...)` over `vec.push_back(Type(args...))`
77
+
78
+ ## Initialization
79
+
80
+ - [ ] All variables initialized before use
81
+ - [ ] Member variables initialized in initializer list or with default member initializers
82
+ - [ ] No use of default-initialized built-in types without assignment
83
+
84
+ ## Code Quality
85
+
86
+ - [ ] No `goto` statements
87
+ - [ ] No macros for anything that can be a `constexpr`, `inline`, or template
88
+ - [ ] Template code in headers uses explicit `typename T` or `class T`
89
+ - [ ] No hardcoded magic numbers — use named constants or `constexpr`
90
+ - [ ] `auto` used appropriately (not hiding intent)
91
+
92
+ ## Testing
93
+
94
+ - [ ] New code has corresponding unit tests
95
+ - [ ] Edge cases covered: empty containers, zero/negative values, boundary conditions
96
+ - [ ] No commented-out test code committed
@@ -0,0 +1,28 @@
1
+ # C++ Testing Skill
2
+
3
+ C++ testing patterns for Claude Code. Covers unit, integration, and host-side tests, framework selection (GoogleTest / Catch2 / doctest), mocking strategies, TDD workflow, and the 80% coverage gate.
4
+
5
+ ## What it provides
6
+
7
+ - **SKILL.md** — framework selection + 5 deep-dive references
8
+ - **references/framework-compare.md** — GoogleTest vs Catch2 vs doctest with code samples
9
+ - **references/host-test-for-embedded.md** — pure-CMake host test for firmware `.cpp` without `idf.py`/FreeRTOS
10
+ - **references/mocking.md** — abstract interfaces, link-time seam, `std::function` injection, gmock
11
+ - **references/tdd-workflow.md** — red-green-refactor in C++
12
+ - **references/coverage.md** — gcov/lcov, 80% gate on `main/` and `components/`
13
+
14
+ ## When it triggers
15
+
16
+ - Writing a new C++ unit or host test
17
+ - Choosing a test framework
18
+ - Setting up a host-side test binary that links firmware code without ESP-IDF
19
+ - Running a test-gate before merging
20
+ - Applying TDD to firmware policy/payload modules
21
+
22
+ ## Manual install
23
+
24
+ ```bash
25
+ cp -R SKILL.md references ~/.claude/skills/cpp-testing/
26
+ ```
27
+
28
+ The BizarHarness installer can also install this automatically — select the **C++ testing** component.