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