@polderlabs/bizar 6.2.5 → 7.0.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 (540) 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/hooks/worker-suggest.mjs +110 -0
  41. package/.claude/settings.json +125 -0
  42. package/.claude/skills/9router/SKILL.md +80 -0
  43. package/.claude/skills/9router-chat/SKILL.md +73 -0
  44. package/.claude/skills/9router-embeddings/SKILL.md +69 -0
  45. package/.claude/skills/9router-image/SKILL.md +86 -0
  46. package/.claude/skills/9router-stt/SKILL.md +79 -0
  47. package/.claude/skills/9router-tts/SKILL.md +80 -0
  48. package/.claude/skills/9router-web-fetch/SKILL.md +99 -0
  49. package/.claude/skills/9router-web-search/SKILL.md +91 -0
  50. package/.claude/skills/bizar/README.md +9 -0
  51. package/.claude/skills/bizar/SKILL.md +450 -0
  52. package/.claude/skills/cpp-coding-standards/README.md +28 -0
  53. package/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
  54. package/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
  55. package/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
  56. package/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
  57. package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
  58. package/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
  59. package/.claude/skills/cpp-testing/README.md +28 -0
  60. package/.claude/skills/cpp-testing/SKILL.md +304 -0
  61. package/.claude/skills/cpp-testing/references/coverage.md +370 -0
  62. package/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
  63. package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
  64. package/.claude/skills/cpp-testing/references/mocking.md +364 -0
  65. package/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
  66. package/.claude/skills/cubesandbox/SKILL.md +148 -0
  67. package/.claude/skills/embedded-esp-idf/README.md +41 -0
  68. package/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
  69. package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
  70. package/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
  71. package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
  72. package/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
  73. package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
  74. package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
  75. package/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
  76. package/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
  77. package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
  78. package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
  79. package/.claude/skills/glyph/SKILL.md +163 -0
  80. package/.claude/skills/harness-engineering/SKILL.md +143 -0
  81. package/.claude/skills/lightrag/SKILL.md +81 -0
  82. package/.claude/skills/memory-protocol/SKILL.md +105 -0
  83. package/.claude/skills/obsidian/SKILL.md +306 -0
  84. package/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
  85. package/.claude/skills/self-improvement/SKILL.md +64 -0
  86. package/README.md +87 -59
  87. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js → EnvVarsSection-CW6fWKds.js} +3 -3
  88. package/bizar-dash/dist/assets/{EnvVarsSection-DXM8gRm_.js.map → EnvVarsSection-CW6fWKds.js.map} +1 -1
  89. package/bizar-dash/dist/assets/MobileChat-D7zRhU9K.js +1 -0
  90. package/bizar-dash/dist/assets/{MobileChat-BnKN_Ks_.js.map → MobileChat-D7zRhU9K.js.map} +1 -1
  91. package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js +1 -0
  92. package/bizar-dash/dist/assets/{MobileSettings-DjCPxC-Q.js.map → MobileSettings-K-sNsn_r.js.map} +1 -1
  93. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js → Toast-WTxc3m2g.js} +1 -1
  94. package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js.map → Toast-WTxc3m2g.js.map} +1 -1
  95. package/bizar-dash/dist/assets/flow-BpU0-gK2.js +1 -0
  96. package/bizar-dash/dist/assets/flow-BpU0-gK2.js.map +1 -0
  97. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js +1 -0
  98. package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js.map +1 -0
  99. package/bizar-dash/dist/assets/{icons-Do5N2jmX.js → icons-B0AKnYI3.js} +98 -103
  100. package/bizar-dash/dist/assets/icons-B0AKnYI3.js.map +1 -0
  101. package/bizar-dash/dist/assets/main-C-Md3DaY.css +1 -0
  102. package/bizar-dash/dist/assets/main-CO8fIxQK.js +18 -0
  103. package/bizar-dash/dist/assets/main-CO8fIxQK.js.map +1 -0
  104. package/bizar-dash/dist/assets/markdown-w2bDDkAH.js +1 -0
  105. package/bizar-dash/dist/assets/{markdown-C6mXtQxD.js.map → markdown-w2bDDkAH.js.map} +1 -1
  106. package/bizar-dash/dist/assets/mobile-DXYCA0hC.js +1 -0
  107. package/bizar-dash/dist/assets/{mobile-CMHqtLV2.js.map → mobile-DXYCA0hC.js.map} +1 -1
  108. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js +2 -0
  109. package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js.map +1 -0
  110. package/bizar-dash/dist/assets/react-vendor-BnuhLJ6X.css +1 -0
  111. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js +46 -0
  112. package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js.map +1 -0
  113. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js +2 -0
  114. package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js.map +1 -0
  115. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js +45 -0
  116. package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js.map +1 -0
  117. package/bizar-dash/dist/index.html +12 -10
  118. package/bizar-dash/dist/mobile.html +7 -4
  119. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  120. package/bizar-dash/src/server/api.mjs +15 -4
  121. package/bizar-dash/src/server/background-store.mjs +15 -16
  122. package/bizar-dash/src/server/bg-poller.mjs +25 -35
  123. package/bizar-dash/src/server/bg-retry.mjs +66 -194
  124. package/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
  125. package/bizar-dash/src/server/claude-info.mjs +412 -0
  126. package/bizar-dash/src/server/{cline-runner.mjs → claude-runner.mjs} +53 -48
  127. package/bizar-dash/src/server/claude-sdk.mjs +191 -0
  128. package/bizar-dash/src/server/memory-consolidator.mjs +218 -0
  129. package/bizar-dash/src/server/memory-distillation.mjs +296 -0
  130. package/bizar-dash/src/server/providers-store.mjs +22 -49
  131. package/bizar-dash/src/server/routes/background.mjs +24 -20
  132. package/bizar-dash/src/server/routes/chat.mjs +223 -326
  133. package/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
  134. package/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
  135. package/bizar-dash/src/server/routes/distill.mjs +129 -0
  136. package/bizar-dash/src/server/routes/goal-planner.mjs +236 -0
  137. package/bizar-dash/src/server/routes/tasks.mjs +20 -28
  138. package/bizar-dash/src/server/task-delegator.mjs +76 -77
  139. package/bizar-dash/src/web/App.tsx +4 -0
  140. package/bizar-dash/src/web/components/Tag.tsx +18 -5
  141. package/bizar-dash/src/web/components/Topbar.tsx +3 -0
  142. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +126 -0
  143. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +163 -0
  144. package/bizar-dash/src/web/components/agents/QualityGates.tsx +123 -0
  145. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +127 -0
  146. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +148 -0
  147. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +160 -0
  148. package/bizar-dash/src/web/components/chat/useChat.ts +23 -27
  149. package/bizar-dash/src/web/components/goals/GoalInput.tsx +86 -0
  150. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +111 -0
  151. package/bizar-dash/src/web/lib/goapPlanner.ts +614 -0
  152. package/bizar-dash/src/web/lib/types.ts +25 -0
  153. package/bizar-dash/src/web/styles/agents-redesign.css +311 -0
  154. package/bizar-dash/src/web/styles/main.css +251 -0
  155. package/bizar-dash/src/web/styles/tasks-redesign.css +231 -0
  156. package/bizar-dash/src/web/ui/controls/Button.tsx +77 -0
  157. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +95 -0
  158. package/bizar-dash/src/web/ui/controls/IconButton.tsx +66 -0
  159. package/bizar-dash/src/web/ui/controls/Kbd.tsx +24 -0
  160. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +77 -0
  161. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +109 -0
  162. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +91 -0
  163. package/bizar-dash/src/web/ui/controls/Select.tsx +92 -0
  164. package/bizar-dash/src/web/ui/controls/Slider.tsx +70 -0
  165. package/bizar-dash/src/web/ui/controls/TextInput.tsx +67 -0
  166. package/bizar-dash/src/web/ui/controls/Toggle.tsx +79 -0
  167. package/bizar-dash/src/web/ui/controls/controls.css +454 -0
  168. package/bizar-dash/src/web/ui/controls/index.ts +33 -0
  169. package/bizar-dash/src/web/ui/data/BarChart.tsx +60 -0
  170. package/bizar-dash/src/web/ui/data/DataTable.tsx +216 -0
  171. package/bizar-dash/src/web/ui/data/EmptyState.tsx +60 -0
  172. package/bizar-dash/src/web/ui/data/ErrorState.tsx +56 -0
  173. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +106 -0
  174. package/bizar-dash/src/web/ui/data/LoadingState.tsx +65 -0
  175. package/bizar-dash/src/web/ui/data/Sparkline.tsx +87 -0
  176. package/bizar-dash/src/web/ui/data/StatTile.tsx +87 -0
  177. package/bizar-dash/src/web/ui/data/data.css +535 -0
  178. package/bizar-dash/src/web/ui/data/index.ts +31 -0
  179. package/bizar-dash/src/web/ui/feedback/Badge.tsx +49 -0
  180. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +209 -0
  181. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +69 -0
  182. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +50 -0
  183. package/bizar-dash/src/web/ui/feedback/Toast.tsx +200 -0
  184. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +126 -0
  185. package/bizar-dash/src/web/ui/feedback/feedback.css +314 -0
  186. package/bizar-dash/src/web/ui/feedback/index.ts +43 -0
  187. package/bizar-dash/src/web/ui/index.ts +56 -0
  188. package/bizar-dash/src/web/ui/layout/AppShell.tsx +51 -0
  189. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +97 -0
  190. package/bizar-dash/src/web/ui/layout/Panel.tsx +73 -0
  191. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +39 -0
  192. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +131 -0
  193. package/bizar-dash/src/web/ui/layout/Tabs.tsx +133 -0
  194. package/bizar-dash/src/web/ui/layout/Topbar.tsx +42 -0
  195. package/bizar-dash/src/web/ui/layout/index.ts +33 -0
  196. package/bizar-dash/src/web/ui/layout/layout.css +413 -0
  197. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +199 -0
  198. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +95 -0
  199. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +93 -0
  200. package/bizar-dash/src/web/ui/navigation/index.ts +17 -0
  201. package/bizar-dash/src/web/ui/navigation/navigation.css +343 -0
  202. package/bizar-dash/src/web/ui/primitives/Box.tsx +91 -0
  203. package/bizar-dash/src/web/ui/primitives/Grid.tsx +49 -0
  204. package/bizar-dash/src/web/ui/primitives/Inline.tsx +55 -0
  205. package/bizar-dash/src/web/ui/primitives/Separator.tsx +46 -0
  206. package/bizar-dash/src/web/ui/primitives/Stack.tsx +54 -0
  207. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +26 -0
  208. package/bizar-dash/src/web/ui/primitives/index.ts +23 -0
  209. package/bizar-dash/src/web/ui/primitives/primitives.css +183 -0
  210. package/bizar-dash/src/web/ui/styles/globals.css +86 -0
  211. package/bizar-dash/src/web/ui/styles/reset.css +125 -0
  212. package/bizar-dash/src/web/ui/styles/tokens.css +195 -0
  213. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +142 -0
  214. package/bizar-dash/src/web/ui/theme/tokens.ts +131 -0
  215. package/bizar-dash/src/web/ui/theme/useTheme.ts +22 -0
  216. package/bizar-dash/src/web/ui/utils/cx.ts +42 -0
  217. package/bizar-dash/src/web/views/Agents.tsx +506 -266
  218. package/bizar-dash/src/web/views/Chat.tsx +8 -8
  219. package/bizar-dash/src/web/views/GoalPlanner.tsx +158 -0
  220. package/bizar-dash/src/web/views/Overview.tsx +996 -448
  221. package/bizar-dash/src/web/views/Tasks.tsx +277 -273
  222. package/bizar-dash/tests/communication-log.test.tsx +67 -0
  223. package/bizar-dash/tests/dep-graph.test.tsx +40 -0
  224. package/bizar-dash/tests/event-log.test.tsx +61 -0
  225. package/bizar-dash/tests/goal-input.test.tsx +72 -0
  226. package/bizar-dash/tests/goap-planner.test.ts +68 -0
  227. package/bizar-dash/tests/quality-gates.test.tsx +59 -0
  228. package/bizar-dash/tests/setup.ts +31 -1
  229. package/bizar-dash/tests/ui/controls/Button.test.tsx +50 -0
  230. package/bizar-dash/tests/ui/controls/Checkbox.test.tsx +44 -0
  231. package/bizar-dash/tests/ui/controls/IconButton.test.tsx +37 -0
  232. package/bizar-dash/tests/ui/controls/Kbd.test.tsx +39 -0
  233. package/bizar-dash/tests/ui/controls/NumberInput.test.tsx +56 -0
  234. package/bizar-dash/tests/ui/controls/RadioGroup.test.tsx +58 -0
  235. package/bizar-dash/tests/ui/controls/SearchInput.test.tsx +52 -0
  236. package/bizar-dash/tests/ui/controls/Select.test.tsx +66 -0
  237. package/bizar-dash/tests/ui/controls/Slider.test.tsx +41 -0
  238. package/bizar-dash/tests/ui/controls/TextInput.test.tsx +44 -0
  239. package/bizar-dash/tests/ui/controls/Toggle.test.tsx +39 -0
  240. package/bizar-dash/tests/ui/data/BarChart.test.tsx +55 -0
  241. package/bizar-dash/tests/ui/data/DataTable.test.tsx +112 -0
  242. package/bizar-dash/tests/ui/data/EmptyState.test.tsx +57 -0
  243. package/bizar-dash/tests/ui/data/ErrorState.test.tsx +47 -0
  244. package/bizar-dash/tests/ui/data/KeyValueList.test.tsx +59 -0
  245. package/bizar-dash/tests/ui/data/LoadingState.test.tsx +37 -0
  246. package/bizar-dash/tests/ui/data/Sparkline.test.tsx +56 -0
  247. package/bizar-dash/tests/ui/data/StatTile.test.tsx +69 -0
  248. package/bizar-dash/tests/ui/feedback/Badge.test.tsx +41 -0
  249. package/bizar-dash/tests/ui/feedback/Dialog.test.tsx +99 -0
  250. package/bizar-dash/tests/ui/feedback/ProgressBar.test.tsx +66 -0
  251. package/bizar-dash/tests/ui/feedback/StatusDot.test.tsx +41 -0
  252. package/bizar-dash/tests/ui/feedback/Toast.test.tsx +124 -0
  253. package/bizar-dash/tests/ui/feedback/Tooltip.test.tsx +102 -0
  254. package/bizar-dash/tests/ui/layout/AppShell.test.tsx +50 -0
  255. package/bizar-dash/tests/ui/layout/Breadcrumbs.test.tsx +85 -0
  256. package/bizar-dash/tests/ui/layout/Panel.test.tsx +52 -0
  257. package/bizar-dash/tests/ui/layout/PanelHeader.test.tsx +32 -0
  258. package/bizar-dash/tests/ui/layout/Sidebar.test.tsx +95 -0
  259. package/bizar-dash/tests/ui/layout/Tabs.test.tsx +87 -0
  260. package/bizar-dash/tests/ui/layout/Topbar.test.tsx +41 -0
  261. package/bizar-dash/tests/ui/navigation/CommandPalette.test.tsx +105 -0
  262. package/bizar-dash/tests/ui/navigation/NavGroup.test.tsx +55 -0
  263. package/bizar-dash/tests/ui/navigation/NavLink.test.tsx +61 -0
  264. package/bizar-dash/tests/ui/primitives/Box.test.tsx +49 -0
  265. package/bizar-dash/tests/ui/primitives/Grid.test.tsx +37 -0
  266. package/bizar-dash/tests/ui/primitives/Inline.test.tsx +33 -0
  267. package/bizar-dash/tests/ui/primitives/Separator.test.tsx +34 -0
  268. package/bizar-dash/tests/ui/primitives/Stack.test.tsx +45 -0
  269. package/bizar-dash/tests/ui/primitives/VisuallyHidden.test.tsx +27 -0
  270. package/bizar-dash/tests/views/Agents.test.tsx +359 -0
  271. package/bizar-dash/tests/views/Overview.test.tsx +413 -0
  272. package/bizar-dash/tests/views/Tasks.test.tsx +250 -0
  273. package/bizar-dash/vitest.config.ts +3 -1
  274. package/cli/__tests__/cost-gate.test.mjs +301 -0
  275. package/cli/__tests__/feature-list-bridge.test.mjs +371 -0
  276. package/cli/bin.mjs +55 -18
  277. package/cli/commands/claim.mjs +282 -0
  278. package/cli/commands/claude-cmd.mjs +348 -0
  279. package/cli/commands/cost.mjs +279 -0
  280. package/cli/commands/install.mjs +12 -11
  281. package/cli/commands/validate.mjs +252 -325
  282. package/cli/cost-gate.mjs +501 -0
  283. package/cli/dev-link.test.mjs +11 -11
  284. package/cli/doctor.mjs +131 -213
  285. package/cli/feature-list-bridge.mjs +400 -0
  286. package/cli/install.mjs +33 -37
  287. package/cli/install.test.mjs +9 -9
  288. package/cli/memory-constants.mjs +17 -0
  289. package/cli/provision-claude.mjs +893 -0
  290. package/cli/provision.mjs +224 -227
  291. package/cli/utils.mjs +72 -58
  292. package/cli/worker-dispatcher.mjs +259 -0
  293. package/cli/worker-dispatcher.test.mjs +204 -0
  294. package/config/AGENTS.md +28 -28
  295. package/config/trigger-patterns.json +186 -0
  296. package/install.sh +66 -44
  297. package/package.json +19 -11
  298. package/packages/sdk/ARCHITECTURE.md +40 -36
  299. package/packages/sdk/package.json +15 -5
  300. package/packages/sdk/src/agent-registry.ts +304 -0
  301. package/packages/sdk/src/consensus/byzantine.ts +587 -0
  302. package/packages/sdk/src/consensus/index.ts +147 -0
  303. package/packages/sdk/src/consensus/queen.ts +173 -0
  304. package/packages/sdk/src/consensus/types.ts +199 -0
  305. package/{plugins/bizar → packages/sdk}/src/dangerous-patterns.ts +6 -28
  306. package/packages/sdk/src/federation/audit.ts +156 -0
  307. package/packages/sdk/src/federation/budget.ts +269 -0
  308. package/packages/sdk/src/federation/envelope.ts +144 -0
  309. package/packages/sdk/src/federation/hmac.ts +160 -0
  310. package/packages/sdk/src/federation/index.ts +443 -0
  311. package/packages/sdk/src/federation/pii.ts +241 -0
  312. package/packages/sdk/src/federation/policy.ts +112 -0
  313. package/packages/sdk/src/federation/trust.ts +146 -0
  314. package/packages/sdk/src/fingerprint.ts +0 -0
  315. package/packages/sdk/src/index.ts +101 -69
  316. package/packages/sdk/src/mcp/bin.ts +51 -0
  317. package/packages/sdk/src/mcp/server.ts +848 -0
  318. package/{plugins/bizar/src/memory-vault.ts → packages/sdk/src/memory/index.ts} +18 -21
  319. package/packages/sdk/src/router/codemod-intent.ts +125 -0
  320. package/packages/sdk/src/router/index.ts +247 -0
  321. package/packages/sdk/src/router/memory-distillation-shim.mjs +18 -0
  322. package/packages/sdk/src/router/memory-distillation.ts +249 -0
  323. package/packages/sdk/src/router/model-router.ts +235 -0
  324. package/packages/sdk/src/router/q-learning-router.ts +304 -0
  325. package/packages/sdk/src/swarm-topology.ts +279 -0
  326. package/packages/sdk/tests/agent-registry.test.ts +285 -0
  327. package/packages/sdk/tests/consensus.test.ts +376 -0
  328. package/packages/sdk/tests/federation/audit.test.ts +164 -0
  329. package/packages/sdk/tests/federation/budget.test.ts +189 -0
  330. package/packages/sdk/tests/federation/envelope.test.ts +120 -0
  331. package/packages/sdk/tests/federation/hmac.test.ts +194 -0
  332. package/packages/sdk/tests/federation/orchestrator.test.ts +176 -0
  333. package/packages/sdk/tests/federation/pii.test.ts +106 -0
  334. package/packages/sdk/tests/federation/policy.test.ts +140 -0
  335. package/packages/sdk/tests/federation/trust.test.ts +124 -0
  336. package/packages/sdk/tests/mcp-tools.test.ts +204 -0
  337. package/packages/sdk/tests/memory-distillation.test.mjs +186 -0
  338. package/packages/sdk/tests/model-router.test.mjs +108 -0
  339. package/packages/sdk/tests/q-learning-router.test.mjs +100 -0
  340. package/packages/sdk/tests/router-orchestrator.test.mjs +172 -0
  341. package/packages/sdk/tests/router.test.mjs +91 -0
  342. package/packages/sdk/tests/sdk.test.mjs +172 -0
  343. package/packages/sdk/tests/swarm-topology.test.ts +258 -0
  344. package/packages/sdk/vitest.config.ts +1 -1
  345. package/scripts/bh-full-e2e.mjs +167 -368
  346. package/scripts/check-deps.mjs +28 -46
  347. package/scripts/mirror-claude-md.sh +78 -0
  348. package/scripts/test-in-container.sh +31 -9
  349. package/templates/clean-state-checklist.md +3 -3
  350. package/templates/sprint-contract.md +2 -2
  351. package/bizar-dash/.bizar/activity.log +0 -3
  352. package/bizar-dash/.omx/logs/omx-2026-07-07.jsonl +0 -1
  353. package/bizar-dash/.omx/state/session.json +0 -10
  354. package/bizar-dash/bizar-design/EXPLANATION.md +0 -307
  355. package/bizar-dash/bizar-design/INSTRUCTIONS.md +0 -149
  356. package/bizar-dash/bizar-design/canvas.html +0 -281
  357. package/bizar-dash/bizar-design/canvas.html.artifact.json +0 -19
  358. package/bizar-dash/bizar-design/components.css +0 -1665
  359. package/bizar-dash/bizar-design/components.html +0 -557
  360. package/bizar-dash/bizar-design/components.html.artifact.json +0 -19
  361. package/bizar-dash/bizar-design/desktop/agents.html +0 -74
  362. package/bizar-dash/bizar-design/desktop/agents.html.artifact.json +0 -19
  363. package/bizar-dash/bizar-design/desktop/memory.html +0 -75
  364. package/bizar-dash/bizar-design/desktop/memory.html.artifact.json +0 -19
  365. package/bizar-dash/bizar-design/desktop/metrics.html +0 -63
  366. package/bizar-dash/bizar-design/desktop/metrics.html.artifact.json +0 -19
  367. package/bizar-dash/bizar-design/desktop/overview.html +0 -95
  368. package/bizar-dash/bizar-design/desktop/overview.html.artifact.json +0 -19
  369. package/bizar-dash/bizar-design/desktop/settings.html +0 -70
  370. package/bizar-dash/bizar-design/desktop/settings.html.artifact.json +0 -19
  371. package/bizar-dash/bizar-design/icons.svg +0 -44
  372. package/bizar-dash/bizar-design/index.html +0 -192
  373. package/bizar-dash/bizar-design/index.html.artifact.json +0 -19
  374. package/bizar-dash/bizar-design/mobile/agents.html +0 -29
  375. package/bizar-dash/bizar-design/mobile/agents.html.artifact.json +0 -19
  376. package/bizar-dash/bizar-design/mobile/memory.html +0 -28
  377. package/bizar-dash/bizar-design/mobile/memory.html.artifact.json +0 -19
  378. package/bizar-dash/bizar-design/mobile/metrics.html +0 -29
  379. package/bizar-dash/bizar-design/mobile/metrics.html.artifact.json +0 -19
  380. package/bizar-dash/bizar-design/mobile/overview.html +0 -33
  381. package/bizar-dash/bizar-design/mobile/overview.html.artifact.json +0 -19
  382. package/bizar-dash/bizar-design/mobile/settings.html +0 -28
  383. package/bizar-dash/bizar-design/mobile/settings.html.artifact.json +0 -19
  384. package/bizar-dash/bizar-design/prototype.js +0 -114
  385. package/bizar-dash/bizar-design/tokens.css +0 -106
  386. package/bizar-dash/dist/assets/MobileChat-BnKN_Ks_.js +0 -1
  387. package/bizar-dash/dist/assets/MobileSettings-DjCPxC-Q.js +0 -1
  388. package/bizar-dash/dist/assets/icons-Do5N2jmX.js.map +0 -1
  389. package/bizar-dash/dist/assets/main-DYiZqMrn.js +0 -18
  390. package/bizar-dash/dist/assets/main-DYiZqMrn.js.map +0 -1
  391. package/bizar-dash/dist/assets/main-ietCEg_R.css +0 -1
  392. package/bizar-dash/dist/assets/markdown-C6mXtQxD.js +0 -1
  393. package/bizar-dash/dist/assets/mobile-CMHqtLV2.js +0 -1
  394. package/bizar-dash/dist/assets/mobile-layout-3jIhHX_p.js +0 -2
  395. package/bizar-dash/dist/assets/mobile-layout-3jIhHX_p.js.map +0 -1
  396. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js +0 -40
  397. package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js.map +0 -1
  398. package/bizar-dash/dist/assets/useSlashCommands-DtITw8Xv.js +0 -2
  399. package/bizar-dash/dist/assets/useSlashCommands-DtITw8Xv.js.map +0 -1
  400. package/bizar-dash/dist/assets/vendor-CeHGtduv.js +0 -29
  401. package/bizar-dash/dist/assets/vendor-CeHGtduv.js.map +0 -1
  402. package/bizar-dash/node_modules/.package-lock.json +0 -6
  403. package/bizar-dash/package-lock.json +0 -6
  404. package/bizar-dash/src/server/cline-sdk.mjs +0 -132
  405. package/bizar-dash/src/server/routes/cline-session-detail.mjs +0 -559
  406. package/bizar-dash/src/server/routes/cline-sessions.mjs +0 -291
  407. package/cli/commands/cline-cmd.mjs +0 -289
  408. package/cli/commands/validate.test.mjs +0 -379
  409. package/cli/doctor.test.mjs +0 -350
  410. package/config/cline.json.template +0 -342
  411. package/packages/sdk/src/client.ts +0 -188
  412. package/packages/sdk/src/cline-events.ts +0 -134
  413. package/packages/sdk/src/cline-types.ts +0 -66
  414. package/packages/sdk/src/cline.ts +0 -339
  415. package/packages/sdk/src/errors.ts +0 -129
  416. package/packages/sdk/src/events.ts +0 -153
  417. package/packages/sdk/src/types.ts +0 -176
  418. package/packages/sdk/tests/client.test.ts +0 -217
  419. package/packages/sdk/tests/errors.test.ts +0 -108
  420. package/packages/sdk/tests/events.test.ts +0 -139
  421. package/packages/sdk/tests/fixtures/fetch-mock.ts +0 -152
  422. package/packages/sdk/tests/fixtures/sse-mock.ts +0 -30
  423. package/plugins/bizar/ARCHITECTURE.md +0 -142
  424. package/plugins/bizar/CONSTRAINTS.md +0 -67
  425. package/plugins/bizar/LICENSE +0 -21
  426. package/plugins/bizar/README.md +0 -448
  427. package/plugins/bizar/index.ts +0 -925
  428. package/plugins/bizar/package.json +0 -39
  429. package/plugins/bizar/scripts/check-forbidden-imports.sh +0 -33
  430. package/plugins/bizar/src/background-state.ts +0 -641
  431. package/plugins/bizar/src/background.ts +0 -1806
  432. package/plugins/bizar/src/cline-runner.ts +0 -203
  433. package/plugins/bizar/src/clineruntime.ts +0 -227
  434. package/plugins/bizar/src/commands-impl.ts +0 -151
  435. package/plugins/bizar/src/commands.ts +0 -1799
  436. package/plugins/bizar/src/compaction.d.mts +0 -48
  437. package/plugins/bizar/src/compaction.mjs +0 -192
  438. package/plugins/bizar/src/dashboard-client.ts +0 -233
  439. package/plugins/bizar/src/event-stream.ts +0 -606
  440. package/plugins/bizar/src/fingerprint.ts +0 -120
  441. package/plugins/bizar/src/handoff.ts +0 -79
  442. package/plugins/bizar/src/hooks/memory-flush-on-compact.ts +0 -123
  443. package/plugins/bizar/src/hooks/memory-inject.ts +0 -247
  444. package/plugins/bizar/src/hooks/memory-write-on-end.ts +0 -188
  445. package/plugins/bizar/src/hooks/skill-curator.ts +0 -180
  446. package/plugins/bizar/src/http-client.ts +0 -467
  447. package/plugins/bizar/src/key-rotation.ts +0 -218
  448. package/plugins/bizar/src/logger.ts +0 -144
  449. package/plugins/bizar/src/loop-engineering.ts +0 -241
  450. package/plugins/bizar/src/loop.ts +0 -176
  451. package/plugins/bizar/src/mistake-recovery.ts +0 -98
  452. package/plugins/bizar/src/odin.ts +0 -227
  453. package/plugins/bizar/src/options.ts +0 -470
  454. package/plugins/bizar/src/plan-fs.ts +0 -323
  455. package/plugins/bizar/src/reasoning-clean.ts +0 -454
  456. package/plugins/bizar/src/report.ts +0 -178
  457. package/plugins/bizar/src/research-prompt.ts +0 -35
  458. package/plugins/bizar/src/serve-info.ts +0 -228
  459. package/plugins/bizar/src/serve.ts +0 -496
  460. package/plugins/bizar/src/settings.ts +0 -349
  461. package/plugins/bizar/src/state.ts +0 -298
  462. package/plugins/bizar/src/tool-discipline.ts +0 -105
  463. package/plugins/bizar/src/tools/agent-browser.ts +0 -315
  464. package/plugins/bizar/src/tools/bg-collect.ts +0 -131
  465. package/plugins/bizar/src/tools/bg-get-comments.ts +0 -266
  466. package/plugins/bizar/src/tools/bg-kill.ts +0 -116
  467. package/plugins/bizar/src/tools/bg-pause.ts +0 -99
  468. package/plugins/bizar/src/tools/bg-report-progress.ts +0 -115
  469. package/plugins/bizar/src/tools/bg-resume.ts +0 -94
  470. package/plugins/bizar/src/tools/bg-send-message.ts +0 -223
  471. package/plugins/bizar/src/tools/bg-spawn.ts +0 -502
  472. package/plugins/bizar/src/tools/bg-status.ts +0 -130
  473. package/plugins/bizar/src/tools/graph-query.ts +0 -278
  474. package/plugins/bizar/src/tools/loop-engineering.ts +0 -193
  475. package/plugins/bizar/src/tools/memory-list.ts +0 -43
  476. package/plugins/bizar/src/tools/memory-read.ts +0 -69
  477. package/plugins/bizar/src/tools/memory-search.ts +0 -47
  478. package/plugins/bizar/src/tools/memory-write.ts +0 -54
  479. package/plugins/bizar/src/tools/open-kb.ts +0 -198
  480. package/plugins/bizar/src/tools/plan-action.ts +0 -785
  481. package/plugins/bizar/src/tools/read-glyph-feedback.ts +0 -191
  482. package/plugins/bizar/src/tools/sandbox.ts +0 -232
  483. package/plugins/bizar/src/tools/team-spawn.ts +0 -73
  484. package/plugins/bizar/src/tools/team-status.ts +0 -76
  485. package/plugins/bizar/src/tools/wait-for-feedback.ts +0 -415
  486. package/plugins/bizar/src/trajectory.ts +0 -104
  487. package/plugins/bizar/tests/README.md +0 -99
  488. package/plugins/bizar/tests/attach-handler-bug.test.ts +0 -169
  489. package/plugins/bizar/tests/background-state.test.ts +0 -277
  490. package/plugins/bizar/tests/background.test.ts +0 -402
  491. package/plugins/bizar/tests/block.test.ts +0 -195
  492. package/plugins/bizar/tests/canonical-key-order.test.ts +0 -75
  493. package/plugins/bizar/tests/clineruntime-config.test.ts +0 -283
  494. package/plugins/bizar/tests/commands-impl.test.ts +0 -316
  495. package/plugins/bizar/tests/commands.test.ts +0 -584
  496. package/plugins/bizar/tests/compaction.test.ts +0 -264
  497. package/plugins/bizar/tests/config.test.ts +0 -128
  498. package/plugins/bizar/tests/dashboard-client.test.ts +0 -159
  499. package/plugins/bizar/tests/dispose.test.ts +0 -336
  500. package/plugins/bizar/tests/event-stream.test.ts +0 -409
  501. package/plugins/bizar/tests/event.test.ts +0 -262
  502. package/plugins/bizar/tests/fingerprint.test.ts +0 -190
  503. package/plugins/bizar/tests/http-client.test.ts +0 -404
  504. package/plugins/bizar/tests/init-helpers.test.ts +0 -203
  505. package/plugins/bizar/tests/integration/slash-command.test.ts +0 -349
  506. package/plugins/bizar/tests/integration/tool-routing.test.ts +0 -98
  507. package/plugins/bizar/tests/key-rotation.test.ts +0 -396
  508. package/plugins/bizar/tests/loop-engineering.test.ts +0 -168
  509. package/plugins/bizar/tests/loop.test.ts +0 -397
  510. package/plugins/bizar/tests/memory-write-on-end.test.ts +0 -92
  511. package/plugins/bizar/tests/mistake-recovery.test.ts +0 -116
  512. package/plugins/bizar/tests/odin.test.ts +0 -125
  513. package/plugins/bizar/tests/options.test.ts +0 -329
  514. package/plugins/bizar/tests/reasoning-clean.test.ts +0 -422
  515. package/plugins/bizar/tests/safety.test.ts +0 -281
  516. package/plugins/bizar/tests/serve.test.ts +0 -339
  517. package/plugins/bizar/tests/settings.test.ts +0 -351
  518. package/plugins/bizar/tests/stall-think.test.ts +0 -750
  519. package/plugins/bizar/tests/state.test.ts +0 -276
  520. package/plugins/bizar/tests/tool-discipline.test.ts +0 -77
  521. package/plugins/bizar/tests/tools/agent-browser.test.ts +0 -98
  522. package/plugins/bizar/tests/tools/bg-collect.test.ts +0 -337
  523. package/plugins/bizar/tests/tools/bg-get-comments.test.ts +0 -485
  524. package/plugins/bizar/tests/tools/bg-kill.test.ts +0 -235
  525. package/plugins/bizar/tests/tools/bg-pause.test.ts +0 -61
  526. package/plugins/bizar/tests/tools/bg-report-progress.test.ts +0 -79
  527. package/plugins/bizar/tests/tools/bg-resume.test.ts +0 -40
  528. package/plugins/bizar/tests/tools/bg-send-message.test.ts +0 -116
  529. package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +0 -147
  530. package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +0 -233
  531. package/plugins/bizar/tests/tools/bg-spawn.test.ts +0 -311
  532. package/plugins/bizar/tests/tools/bg-status.test.ts +0 -217
  533. package/plugins/bizar/tests/tools/cline-runner.test.ts +0 -115
  534. package/plugins/bizar/tests/tools/plan-action.test.ts +0 -599
  535. package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +0 -253
  536. package/plugins/bizar/tests/tools/sandbox.test.ts +0 -117
  537. package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +0 -390
  538. package/plugins/bizar/tests/update-deadlock.test.ts +0 -151
  539. package/plugins/bizar/tsconfig.json +0 -29
  540. package/scripts/mirror-agents-md.sh +0 -69
@@ -0,0 +1,175 @@
1
+ # Framework Compare: GoogleTest vs Catch2 vs doctest
2
+
3
+ ## Overview
4
+
5
+ All three frameworks are C++17-compatible, header-only (or single-header), and support fixtures, parametrics, and mocking. The choice is primarily ergonomic and project-specific.
6
+
7
+ ---
8
+
9
+ ## GoogleTest
10
+
11
+ **Installation:** `apt install libgtest-dev` or `FetchContent` CMake include.
12
+
13
+ **Strengths:**
14
+ - `TEST_F` (fixture), `TEST_P` (parametric), death tests, `ScopedFakeTimer`
15
+ - Widest ecosystem: `gmock` for mocking, `gtest-param-test` for parameterized
16
+ - XML/JSON/HTML output for CI integration
17
+ - Well-understood by embedded/firmware teams
18
+
19
+ **Sample:**
20
+
21
+ ```cpp
22
+ #include <gtest/gtest.h>
23
+
24
+ class StackTest : public ::testing::Test {
25
+ protected:
26
+ void SetUp() override { stack_.clear(); }
27
+ std::vector<int> stack_;
28
+ };
29
+
30
+ TEST_F(StackTest, push_increases_size) {
31
+ stack_.push_back(1);
32
+ EXPECT_EQ(stack_.size(), 1u);
33
+ }
34
+
35
+ TEST_F(StackTest, pop_returns_last_element) {
36
+ stack_.push_back(1);
37
+ stack_.push_back(2);
38
+ EXPECT_EQ(stack_.back(), 2);
39
+ stack_.pop_back();
40
+ EXPECT_EQ(stack_.size(), 1u);
41
+ }
42
+ ```
43
+
44
+ **Parametric example:**
45
+
46
+ ```cpp
47
+ class StringEncodeTest : public ::testing::TestWithParam<const char*> {};
48
+
49
+ TEST_P(StringEncodeTest, encodes_known_formats) {
50
+ const char* fmt = GetParam();
51
+ EXPECT_NO_THROW(encode(fmt));
52
+ }
53
+
54
+ INSTANTIATE_TEST_SUITE_P(KnownFormats, StringEncodeTest,
55
+ ::testing::Values("utf-8", "iso-8859-1", "windows-1252"));
56
+ ```
57
+
58
+ **Best for:** Large codebases, embedded firmware, projects needing `gmock`, parametric tests, or death tests.
59
+
60
+ ---
61
+
62
+ ## Catch2
63
+
64
+ **Installation:** Single header: `curl -L https://github.com/catchorg/Catch2/releases/download/v3.5.4/catch2_with_main.hpp -o include/catch2_with_main.hpp`
65
+
66
+ **Strengths:**
67
+ - BDD-style `SCENARIO` / `GIVEN` / `WHEN` / `THEN` DSL available
68
+ - Minimal boilerplate — no `TEST_F` needed for simple cases
69
+ - Rich assertion syntax: `REQUIRE`, `CHECK`, `REQUIRE_THAT`, `CHECK_THAT`
70
+
71
+ **Sample:**
72
+
73
+ ```cpp
74
+ #define CATCH_CONFIG_MAIN
75
+ #include <catch2/catch_test_macros.hpp>
76
+
77
+ unsigned int factorial(unsigned int n) {
78
+ return n <= 1 ? 1 : n * factorial(n - 1);
79
+ }
80
+
81
+ TEST_CASE("factorial computes correctly", "[factorial]") {
82
+ CHECK(factorial(0) == 1);
83
+ CHECK(factorial(1) == 1);
84
+ CHECK(factorial(4) == 24);
85
+ CHECK(factorial(5) == 120);
86
+ }
87
+ ```
88
+
89
+ **BDD-style:**
90
+
91
+ ```cpp
92
+ SCENARIO("stack behavior") {
93
+ GIVEN("an empty stack") {
94
+ std::vector<int> stack;
95
+ WHEN("an element is pushed") {
96
+ stack.push_back(42);
97
+ THEN("size increases") { CHECK(stack.size() == 1); }
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ **Best for:** Quick-to-write tests, BDD-style readability, smaller utilities.
104
+
105
+ **Weakness:** Slower compile times than doctest; less ecosystem (no built-in mocking — pair with `trompeloeil` or manual fakes).
106
+
107
+ ---
108
+
109
+ ## doctest
110
+
111
+ **Installation:** Single header: `curl -L https://github.com/doctest/doctest/releases/download/v2.4.11/doctest.h -o include/doctest.h`
112
+
113
+ **Strengths:**
114
+ - Fastest compile time of the three
115
+ - Lightweight — minimal impact on build times
116
+ - `CHECK`/`REQUIRE` similar to Catch2
117
+ - Sub-test support via `SUBTEST`
118
+
119
+ **Sample:**
120
+
121
+ ```cpp
122
+ #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
123
+ #include <doctest/doctest.h>
124
+
125
+ int add(int a, int b) { return a + b; }
126
+
127
+ TEST_CASE("addition works") {
128
+ CHECK(add(2, 3) == 5);
129
+ CHECK(add(-1, 1) == 0);
130
+ REQUIRE(add(0, 0) == 0); // REQUIRE aborts on failure
131
+ }
132
+ ```
133
+
134
+ **Best for:** Compile-time-sensitive projects, small-to-medium codebases, projects that already use many headers.
135
+
136
+ **Weakness:** Smaller ecosystem; mocking requires manual fakes or `trompeloeil`.
137
+
138
+ ---
139
+
140
+ ## Side-by-Side Comparison
141
+
142
+ | Feature | GoogleTest | Catch2 | doctest |
143
+ |---------|-----------|--------|---------|
144
+ | Header-only | No (needs gtest lib) | Yes | Yes |
145
+ | Compile speed | Medium | Slow | Fast |
146
+ | `TEST_F` (fixtures) | Yes | Via `SECTION` | Via `SUBCASE` |
147
+ | `TEST_P` (parametric) | Yes | No | No |
148
+ | Death tests | Yes | No | No |
149
+ | Built-in mocking | gmock | No | No |
150
+ | BDD DSL | No | Yes | No |
151
+ | CI XML output | Yes | Yes | Yes |
152
+ | C++17 required | Yes | Yes | Yes |
153
+ | Ecosystem size | Large | Medium | Small |
154
+
155
+ ---
156
+
157
+ ## Recommendation for Embedded/Firmware Host Tests
158
+
159
+ Default to **GoogleTest** + **gmock**:
160
+ - `TEST_F` / `TEST_P` are well-suited to firmware policy modules
161
+ - `gmock` provides struct-level mocking via `MATCHER` / `ON_CALL`
162
+ - `EXPECT_DEATH` / `EXPECT_DEATH_IF_SUPPORTED` useful for error-injection tests
163
+ - Widely understood — existing firmware teams will recognize it
164
+
165
+ Use **Catch2** when you want BDD-style readability for payload parsing or protocol tests.
166
+
167
+ Use **doctest** when build time is a bottleneck and you only need simple `CHECK` assertions.
168
+
169
+ ---
170
+
171
+ ## Mixing Frameworks
172
+
173
+ It is possible to link multiple frameworks into the same binary, but avoid this — it causes confusion and doubled setup cost. Pick one framework per binary.
174
+
175
+ If you need both BDD-style and parametric tests, use GoogleTest's `TEST_F` with `DESCRIPTION` or use Catch2's `SECTION` mechanism instead of `TEST_P`.
@@ -0,0 +1,499 @@
1
+ # Host-Side Tests for Embedded Firmware
2
+
3
+ ## Goal
4
+
5
+ Build a standalone Linux binary that links and executes C++ firmware code from `main/` or `components/` — with no ESP-IDF, no FreeRTOS, and no `idf.py`. The binary runs on the host (your laptop or CI runner) and exercises the real production code, just with mocked hardware/OS boundaries.
6
+
7
+ This pattern is ideal for:
8
+ - **Policy modules:** `feature_flags.cpp`, `resp_fallback.cpp`, `rate_limiter.cpp`
9
+ - **Payload parsers:** `mqtt_payload.cpp`, `json_parser.cpp`
10
+ - **Data collectors:** `datacollector.cpp`, `telemetry.cpp`
11
+
12
+ ---
13
+
14
+ ## Why Host-Side Tests?
15
+
16
+ | On-Device (`idf.py test`) | Host-Side Binary |
17
+ |---------------------------|------------------|
18
+ | Runs on actual hardware | Runs on Linux/CI |
19
+ | Needs device flashing | No hardware required |
20
+ | Slow iteration | Fast iteration |
21
+ | FreeRTOS available | No FreeRTOS |
22
+ | ESP-IDF available | No ESP-IDF |
23
+ | HW timing real | Deterministic |
24
+
25
+ Host-side tests catch >80% of logic bugs before ever flashing. Use on-device tests only for hardware-specific behavior (interrupts, DMA, sensor drivers).
26
+
27
+ ---
28
+
29
+ ## Project Structure
30
+
31
+ ```
32
+ projects/ams7_esp32/
33
+ ├── main/
34
+ │ ├── policy/
35
+ │ │ ├── feature_flags.cpp
36
+ │ │ ├── feature_flags.h
37
+ │ │ ├── resp_fallback.cpp
38
+ │ │ └── resp_fallback.h
39
+ │ ├── payload/
40
+ │ │ ├── datacollector.cpp
41
+ │ │ └── datacollector.h
42
+ │ └── utils/
43
+ │ └── hex_utils.cpp
44
+ ├── test/ ← your host test directory
45
+ │ └── host/
46
+ │ ├── CMakeLists.txt
47
+ │ ├── test_feature_flags.cpp
48
+ │ ├── test_resp_fallback.cpp
49
+ │ └── test_datacollector.cpp
50
+ └── components/ ← if you have ESP-IDF components
51
+ ```
52
+
53
+ ---
54
+
55
+ ## CMakeLists.txt Pattern
56
+
57
+ ```cmake
58
+ # test/host/CMakeLists.txt
59
+ cmake_minimum_required(VERSION 3.16)
60
+ project(host_policy_tests)
61
+
62
+ set(CMAKE_CXX_STANDARD 17)
63
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
64
+
65
+ # --- GoogleTest ---
66
+ include(FetchContent)
67
+ FetchContent_Declare(
68
+ googletest
69
+ GIT_REPOSITORY https://github.com/google/googletest.git
70
+ GIT_TAG v1.14.0
71
+ )
72
+ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
73
+ FetchContent_MakeAvailable(googletest)
74
+
75
+ # --- Test executable ---
76
+ add_executable(test_policy
77
+ test_feature_flags.cpp
78
+ test_resp_fallback.cpp
79
+ test_datacollector.cpp
80
+ )
81
+
82
+ # --- Link firmware modules under test ---
83
+ # Point FIRMWARE_ROOT at the project root or adjust as needed
84
+ target_include_directories(test_policy PRIVATE
85
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main
86
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/policy
87
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/payload
88
+ )
89
+
90
+ # Link the real implementation files directly (no ESP-IDF)
91
+ target_sources(test_policy PRIVATE
92
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/policy/feature_flags.cpp
93
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/policy/resp_fallback.cpp
94
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/payload/datacollector.cpp
95
+ )
96
+
97
+ target_link_libraries(test_policy PRIVATE
98
+ gtest
99
+ gmock
100
+ pthread
101
+ )
102
+
103
+ # --- Optional: gcov coverage ---
104
+ if(COVERAGE)
105
+ target_compile_options(test_policy PRIVATE -fprofile-arcs -ftest-coverage)
106
+ target_link_libraries(test_policy PRIVATE gcov)
107
+ endif()
108
+ ```
109
+
110
+ **Build and run:**
111
+
112
+ ```bash
113
+ cd test/host
114
+ mkdir build && cd build
115
+ cmake .. -DCOVERAGE=ON
116
+ cmake --build . -j$(nproc)
117
+ ./test_policy
118
+ # or with coverage:
119
+ cmake --build . -j$(nproc) && lcov --capture --directory . --output coverage.info --exclude '*/test_*' --exclude '*/build/*'
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Pattern 1: Testing `feature_flags.cpp`
125
+
126
+ ### Firmware header (minimal)
127
+
128
+ ```cpp
129
+ // main/policy/feature_flags.h
130
+ #pragma once
131
+ #include <stdbool.h>
132
+ #include <stddef.h>
133
+
134
+ #ifdef __cplusplus
135
+ extern "C" {
136
+ #endif
137
+
138
+ bool feature_flags_is_active(const char* name);
139
+ const char* feature_flags_get_version(void);
140
+
141
+ #ifdef __cplusplus
142
+ }
143
+ #endif
144
+ ```
145
+
146
+ ### Firmware implementation (real code)
147
+
148
+ ```cpp
149
+ // main/policy/feature_flags.cpp
150
+ #include "feature_flags.h"
151
+ #include <string.h>
152
+
153
+ static bool debug_flag = false;
154
+ static bool trace_flag = false;
155
+ static bool legacy_mode = false;
156
+
157
+ bool feature_flags_is_active(const char* name) {
158
+ if (name == nullptr) return false;
159
+ if (strcmp(name, "debug") == 0) return debug_flag;
160
+ if (strcmp(name, "trace") == 0) return trace_flag;
161
+ if (strcmp(name, "legacy") == 0) return legacy_mode;
162
+ return false;
163
+ }
164
+
165
+ const char* feature_flags_get_version(void) {
166
+ return "1.2.0";
167
+ }
168
+ ```
169
+
170
+ ### Host test
171
+
172
+ ```cpp
173
+ // test/host/test_feature_flags.cpp
174
+ #include <gtest/gtest.h>
175
+ #include "feature_flags.h"
176
+ #include <string.h>
177
+
178
+ TEST(FeatureFlags, is_active_returns_false_for_nullptr) {
179
+ EXPECT_FALSE(feature_flags_is_active(nullptr));
180
+ }
181
+
182
+ TEST(FeatureFlags, is_active_returns_false_for_unknown_feature) {
183
+ EXPECT_FALSE(feature_flags_is_active("nonexistent"));
184
+ }
185
+
186
+ TEST(FeatureFlags, is_active_returns_true_for_known_enabled_feature) {
187
+ // In real firmware these might be set at boot; for host test
188
+ // we test the implementation directly — no mocking needed here
189
+ // because the flags are compile-time false in this build.
190
+ EXPECT_FALSE(feature_flags_is_active("debug")); // currently disabled
191
+ }
192
+
193
+ TEST(FeatureFlags, get_version_returns_semver_string) {
194
+ const char* ver = feature_flags_get_version();
195
+ ASSERT_NE(nullptr, ver);
196
+ EXPECT_STREQ("1.2.0", ver);
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Pattern 2: Testing `resp_fallback.cpp` with Mocked Response
203
+
204
+ ### Firmware header
205
+
206
+ ```cpp
207
+ // main/policy/resp_fallback.h
208
+ #pragma once
209
+ #include <stddef.h>
210
+
211
+ typedef struct {
212
+ const char* payload;
213
+ size_t payload_len;
214
+ int status_code;
215
+ } Response;
216
+
217
+ typedef enum {
218
+ FALLBACK_OK,
219
+ FALLBACK_MISSING,
220
+ FALLBACK_INVALID
221
+ } FallbackResult;
222
+
223
+ FallbackResult resp_fallback_process(const Response* req, Response* out);
224
+ ```
225
+
226
+ ### Firmware implementation
227
+
228
+ ```cpp
229
+ // main/policy/resp_fallback.cpp
230
+ #include "resp_fallback.h"
231
+ #include <string.h>
232
+
233
+ static const char* s_fallback_payload = "default_response";
234
+ static bool s_fallback_available = true;
235
+
236
+ void resp_fallback_set_fallback_available(bool available) {
237
+ s_fallback_available = available;
238
+ }
239
+
240
+ FallbackResult resp_fallback_process(const Response* req, Response* out) {
241
+ if (req == nullptr || out == nullptr) return FALLBACK_INVALID;
242
+ if (req->status_code >= 200 && req->status_code < 300) {
243
+ // Pass-through for success codes
244
+ out->payload = req->payload;
245
+ out->payload_len = req->payload_len;
246
+ out->status_code = req->status_code;
247
+ return FALLBACK_OK;
248
+ }
249
+ // Error code — try fallback
250
+ if (!s_fallback_available) return FALLBACK_MISSING;
251
+ out->payload = s_fallback_payload;
252
+ out->payload_len = strlen(s_fallback_payload);
253
+ out->status_code = 200;
254
+ return FALLBACK_OK;
255
+ }
256
+ ```
257
+
258
+ ### Host test with `std::function` injection
259
+
260
+ ```cpp
261
+ // test/host/test_resp_fallback.cpp
262
+ #include <gtest/gtest.h>
263
+ #include "resp_fallback.h"
264
+ #include <cstring>
265
+
266
+ class RespFallbackTest : public ::testing::Test {
267
+ protected:
268
+ void SetUp() override {
269
+ resp_fallback_set_fallback_available(true);
270
+ }
271
+ void TearDown() override {
272
+ resp_fallback_set_fallback_available(true);
273
+ }
274
+ };
275
+
276
+ TEST_F(RespFallbackTest, success_codes_pass_through) {
277
+ Response in = { .payload = "ok", .payload_len = 2, .status_code = 200 };
278
+ Response out;
279
+ FallbackResult r = resp_fallback_process(&in, &out);
280
+ EXPECT_EQ(r, FALLBACK_OK);
281
+ EXPECT_EQ(out.status_code, 200);
282
+ EXPECT_STREQ(out.payload, "ok");
283
+ }
284
+
285
+ TEST_F(RespFallbackTest, error_code_returns_fallback) {
286
+ Response in = { .payload = "error", .payload_len = 5, .status_code = 500 };
287
+ Response out;
288
+ FallbackResult r = resp_fallback_process(&in, &out);
289
+ EXPECT_EQ(r, FALLBACK_OK);
290
+ EXPECT_EQ(out.status_code, 200);
291
+ EXPECT_STREQ(out.payload, "default_response");
292
+ }
293
+
294
+ TEST_F(RespFallbackTest, error_code_when_fallback_unavailable_returns_missing) {
295
+ resp_fallback_set_fallback_available(false);
296
+ Response in = { .payload = "error", .payload_len = 5, .status_code = 500 };
297
+ Response out;
298
+ FallbackResult r = resp_fallback_process(&in, &out);
299
+ EXPECT_EQ(r, FALLBACK_MISSING);
300
+ }
301
+
302
+ TEST_F(RespFallbackTest, null_request_returns_invalid) {
303
+ Response out;
304
+ EXPECT_EQ(resp_fallback_process(nullptr, &out), FALLBACK_INVALID);
305
+ }
306
+
307
+ TEST_F(RespFallbackTest, null_output_returns_invalid) {
308
+ Response in = { .payload = "ok", .payload_len = 2, .status_code = 200 };
309
+ EXPECT_EQ(resp_fallback_process(&in, nullptr), FALLBACK_INVALID);
310
+ }
311
+ ```
312
+
313
+ ---
314
+
315
+ ## Pattern 3: Testing `datacollector.cpp`
316
+
317
+ ### Firmware header
318
+
319
+ ```cpp
320
+ // main/payload/datacollector.h
321
+ #pragma once
322
+ #include <stddef.h>
323
+ #include <stdint.h>
324
+
325
+ #define DATACOLLECTOR_MAX_READINGS 64
326
+
327
+ typedef struct {
328
+ double readings[DATACOLLECTOR_MAX_READINGS];
329
+ size_t count;
330
+ } Datacollector;
331
+
332
+ void datacollector_init(Datacollector* dc);
333
+ int datacollector_append(Datacollector* dc, double value);
334
+ double datacollector_latest(const Datacollector* dc);
335
+ size_t datacollector_count(const Datacollector* dc);
336
+ void datacollector_clear(Datacollector* dc);
337
+ ```
338
+
339
+ ### Firmware implementation
340
+
341
+ ```cpp
342
+ // main/payload/datacollector.cpp
343
+ #include "datacollector.h"
344
+ #include <string.h>
345
+
346
+ void datacollector_init(Datacollector* dc) {
347
+ memset(dc, 0, sizeof(*dc));
348
+ }
349
+
350
+ int datacollector_append(Datacollector* dc, double value) {
351
+ if (dc->count >= DATACOLLECTOR_MAX_READINGS) return -1;
352
+ dc->readings[dc->count++] = value;
353
+ return 0;
354
+ }
355
+
356
+ double datacollector_latest(const Datacollector* dc) {
357
+ if (dc->count == 0) return 0.0; // Note: consider throwing instead
358
+ return dc->readings[dc->count - 1];
359
+ }
360
+
361
+ size_t datacollector_count(const Datacollector* dc) {
362
+ return dc->count;
363
+ }
364
+
365
+ void datacollector_clear(Datacollector* dc) {
366
+ memset(dc, 0, sizeof(*dc));
367
+ }
368
+ ```
369
+
370
+ ### Host test
371
+
372
+ ```cpp
373
+ // test/host/test_datacollector.cpp
374
+ #include <gtest/gtest.h>
375
+ #include "datacollector.h"
376
+ #include <cmath>
377
+
378
+ class DatacollectorTest : public ::testing::Test {
379
+ protected:
380
+ void SetUp() override { datacollector_init(&dc_); }
381
+ Datacollector dc_;
382
+ };
383
+
384
+ TEST_F(DatacollectorTest, init_clears_readings) {
385
+ EXPECT_EQ(datacollector_count(&dc_), 0u);
386
+ }
387
+
388
+ TEST_F(DatacollectorTest, append_increments_count) {
389
+ EXPECT_EQ(datacollector_append(&dc_, 1.0), 0);
390
+ EXPECT_EQ(datacollector_count(&dc_), 1u);
391
+ EXPECT_EQ(datacollector_append(&dc_, 2.0), 0);
392
+ EXPECT_EQ(datacollector_count(&dc_), 2u);
393
+ }
394
+
395
+ TEST_F(DatacollectorTest, latest_returns_last_value) {
396
+ datacollector_append(&dc_, 1.0);
397
+ datacollector_append(&dc_, 2.0);
398
+ datacollector_append(&dc_, 3.0);
399
+ EXPECT_DOUBLE_EQ(datacollector_latest(&dc_), 3.0);
400
+ }
401
+
402
+ TEST_F(DatacollectorTest, latest_returns_zero_when_empty) {
403
+ // Current impl returns 0 — this documents current behavior
404
+ EXPECT_DOUBLE_EQ(datacollector_latest(&dc_), 0.0);
405
+ }
406
+
407
+ TEST_F(DatacollectorTest, append_returns_minus_one_when_full) {
408
+ for (int i = 0; i < DATACOLLECTOR_MAX_READINGS; ++i) {
409
+ EXPECT_EQ(datacollector_append(&dc_, static_cast<double>(i)), 0);
410
+ }
411
+ EXPECT_EQ(datacollector_append(&dc_, 999.0), -1); // full
412
+ }
413
+
414
+ TEST_F(DatacollectorTest, clear_resets_count) {
415
+ datacollector_append(&dc_, 1.0);
416
+ datacollector_append(&dc_, 2.0);
417
+ datacollector_clear(&dc_);
418
+ EXPECT_EQ(datacollector_count(&dc_), 0u);
419
+ }
420
+ ```
421
+
422
+ ---
423
+
424
+ ## Handling FreeRTOS Dependencies
425
+
426
+ If a firmware module calls FreeRTOS APIs (e.g., `vTaskDelay`, `xQueueSend`), create a **stub library** that provides no-op or fake implementations:
427
+
428
+ ```cpp
429
+ // test/host/stubs/freertos_stubs.cpp
430
+ #include "freertos/FreeRTOS.h"
431
+ #include "freertos/task.h"
432
+
433
+ extern "C" {
434
+
435
+ void vTaskDelay(const TickType_t xTicksToDelay) {
436
+ (void)xTicksToDelay; // no-op on host
437
+ }
438
+
439
+ BaseType_t xQueueSend(QueueHandle_t, const void*, TickType_t) {
440
+ return pdTRUE; // fake success
441
+ }
442
+
443
+ } // extern "C"
444
+ ```
445
+
446
+ Then in `CMakeLists.txt`:
447
+
448
+ ```cmake
449
+ target_sources(test_policy PRIVATE
450
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../main/policy/feature_flags.cpp
451
+ ${CMAKE_CURRENT_SOURCE_DIR}/stubs/freertos_stubs.cpp # link stubs
452
+ )
453
+ ```
454
+
455
+ Keep stubs minimal. If a module requires extensive FreeRTOS mocking, consider testing it as an integration test on-device instead.
456
+
457
+ ---
458
+
459
+ ## CI Integration
460
+
461
+ ```yaml
462
+ # .github/workflows/host-tests.yml (GitHub Actions example)
463
+ name: Host-Side Tests
464
+
465
+ on: [push, pull_request]
466
+
467
+ jobs:
468
+ host-tests:
469
+ runs-on: ubuntu-latest
470
+ steps:
471
+ - uses: actions/checkout@v4
472
+ - name: Install deps
473
+ run: sudo apt-get update && sudo apt-get install -y cmake g++ lcov
474
+ - name: Build and test
475
+ run: |
476
+ cd test/host
477
+ mkdir -p build && cd build
478
+ cmake .. -DCOVERAGE=ON
479
+ cmake --build . -j$(nproc)
480
+ ./test_policy || exit 1
481
+ lcov --capture --directory . --output coverage.info \
482
+ --exclude '*/test_*' --exclude '*/build/*' --exclude '*/stubs/*'
483
+ lcov --filter coverage.info --output filtered.info \
484
+ --exclude '*/test_*' --exclude '*/stubs/*'
485
+ lcov --list filtered.info
486
+ # 80% gate:
487
+ lcov --filter filtered.info --output-filtered.info \
488
+ | grep -q "lines\.\.\.\." || true
489
+ ```
490
+
491
+ ---
492
+
493
+ ## Key Principles
494
+
495
+ 1. **Link real `.cpp` files** — not headers only. You want to test the compiled implementation.
496
+ 2. **No ESP-IDF includes** in test sources — if a header pulls in `esp_log.h`, create a local stub or use `-D` flags to mock it out.
497
+ 3. **Use `extern "C"`** when linking firmware `.cpp` files that have C linkage.
498
+ 4. **Test behavior, not structure** — assert on return values, state changes, and side effects visible through the public API.
499
+ 5. **Deterministic only** — host tests must be free of timing, threading races, and hardware dependencies.