@polderlabs/bizar 8.1.0 → 9.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 (872) hide show
  1. package/.claude/worktrees/kanban-overhaul/.claude/CLAUDE.md +15 -0
  2. package/.claude/worktrees/kanban-overhaul/.claude/agents/_shared/AGENT_BASELINE.md +168 -0
  3. package/.claude/worktrees/kanban-overhaul/.claude/agents/_shared/CLAUDE_TOOLS.md +412 -0
  4. package/.claude/worktrees/kanban-overhaul/.claude/agents/_shared/SKILLS.md +109 -0
  5. package/.claude/worktrees/kanban-overhaul/.claude/agents/agent-browser.md +80 -0
  6. package/.claude/worktrees/kanban-overhaul/.claude/agents/baldr.md +49 -0
  7. package/.claude/worktrees/kanban-overhaul/.claude/agents/forseti.md +51 -0
  8. package/.claude/worktrees/kanban-overhaul/.claude/agents/frigg.md +42 -0
  9. package/.claude/worktrees/kanban-overhaul/.claude/agents/heimdall.md +33 -0
  10. package/.claude/worktrees/kanban-overhaul/.claude/agents/hermod.md +53 -0
  11. package/.claude/worktrees/kanban-overhaul/.claude/agents/mimir.md +49 -0
  12. package/.claude/worktrees/kanban-overhaul/.claude/agents/odin.md +287 -0
  13. package/.claude/worktrees/kanban-overhaul/.claude/agents/quick.md +34 -0
  14. package/.claude/worktrees/kanban-overhaul/.claude/agents/semble-search.md +50 -0
  15. package/.claude/worktrees/kanban-overhaul/.claude/agents/thor.md +53 -0
  16. package/.claude/worktrees/kanban-overhaul/.claude/agents/tyr.md +56 -0
  17. package/.claude/worktrees/kanban-overhaul/.claude/agents/vidarr.md +54 -0
  18. package/.claude/worktrees/kanban-overhaul/.claude/agents/vor.md +53 -0
  19. package/.claude/worktrees/kanban-overhaul/.claude/commands/audit.md +25 -0
  20. package/.claude/worktrees/kanban-overhaul/.claude/commands/bizar.md +22 -0
  21. package/.claude/worktrees/kanban-overhaul/.claude/commands/explain.md +17 -0
  22. package/.claude/worktrees/kanban-overhaul/.claude/commands/init.md +29 -0
  23. package/.claude/worktrees/kanban-overhaul/.claude/commands/learn.md +44 -0
  24. package/.claude/worktrees/kanban-overhaul/.claude/commands/plan.md +35 -0
  25. package/.claude/worktrees/kanban-overhaul/.claude/commands/plow-through.md +50 -0
  26. package/.claude/worktrees/kanban-overhaul/.claude/commands/pr-review.md +49 -0
  27. package/.claude/worktrees/kanban-overhaul/.claude/commands/setup-provider.md +96 -0
  28. package/.claude/worktrees/kanban-overhaul/.claude/commands/tailscale-serve.md +100 -0
  29. package/.claude/worktrees/kanban-overhaul/.claude/commands/team.md +132 -0
  30. package/.claude/worktrees/kanban-overhaul/.claude/commands/test.md +62 -0
  31. package/.claude/worktrees/kanban-overhaul/.claude/commands/validate.md +68 -0
  32. package/.claude/worktrees/kanban-overhaul/.claude/commands/visual-plan.md +24 -0
  33. package/.claude/worktrees/kanban-overhaul/.claude/hooks/README.md +92 -0
  34. package/.claude/worktrees/kanban-overhaul/.claude/hooks/posttooluse-editwrite.mjs +91 -0
  35. package/.claude/worktrees/kanban-overhaul/.claude/hooks/pretooluse-bash.mjs +81 -0
  36. package/.claude/worktrees/kanban-overhaul/.claude/hooks/pretooluse-editwrite.mjs +139 -0
  37. package/.claude/worktrees/kanban-overhaul/.claude/hooks/sessionend-recall.mjs +74 -0
  38. package/.claude/worktrees/kanban-overhaul/.claude/hooks/sessionstart-prime.mjs +80 -0
  39. package/.claude/worktrees/kanban-overhaul/.claude/hooks/userpromptsubmit-tag.mjs +80 -0
  40. package/.claude/worktrees/kanban-overhaul/.claude/hooks/worker-suggest.mjs +110 -0
  41. package/.claude/worktrees/kanban-overhaul/.claude/settings.json +125 -0
  42. package/.claude/worktrees/kanban-overhaul/.claude/settings.local.json +8 -0
  43. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router/SKILL.md +80 -0
  44. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-chat/SKILL.md +73 -0
  45. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-embeddings/SKILL.md +69 -0
  46. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-image/SKILL.md +86 -0
  47. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-stt/SKILL.md +79 -0
  48. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-tts/SKILL.md +80 -0
  49. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-web-fetch/SKILL.md +99 -0
  50. package/.claude/worktrees/kanban-overhaul/.claude/skills/9router-web-search/SKILL.md +91 -0
  51. package/.claude/worktrees/kanban-overhaul/.claude/skills/bizar/README.md +9 -0
  52. package/.claude/worktrees/kanban-overhaul/.claude/skills/bizar/SKILL.md +450 -0
  53. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/README.md +28 -0
  54. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/SKILL.md +634 -0
  55. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/references/concurrency.md +320 -0
  56. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/references/error-handling.md +229 -0
  57. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/references/memory-safety.md +216 -0
  58. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
  59. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-coding-standards/references/review-checklist.md +96 -0
  60. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/README.md +28 -0
  61. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/SKILL.md +304 -0
  62. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/references/coverage.md +370 -0
  63. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/references/framework-compare.md +175 -0
  64. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
  65. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/references/mocking.md +364 -0
  66. package/.claude/worktrees/kanban-overhaul/.claude/skills/cpp-testing/references/tdd-workflow.md +308 -0
  67. package/.claude/worktrees/kanban-overhaul/.claude/skills/cubesandbox/SKILL.md +148 -0
  68. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/README.md +41 -0
  69. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/SKILL.md +439 -0
  70. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
  71. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/host-tests.md +164 -0
  72. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
  73. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/kconfig.md +159 -0
  74. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
  75. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
  76. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/nvs.md +121 -0
  77. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/references/packed-structs.md +192 -0
  78. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
  79. package/.claude/worktrees/kanban-overhaul/.claude/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
  80. package/.claude/worktrees/kanban-overhaul/.claude/skills/glyph/SKILL.md +163 -0
  81. package/.claude/worktrees/kanban-overhaul/.claude/skills/harness-engineering/SKILL.md +143 -0
  82. package/.claude/worktrees/kanban-overhaul/.claude/skills/lightrag/SKILL.md +81 -0
  83. package/.claude/worktrees/kanban-overhaul/.claude/skills/memory-protocol/SKILL.md +105 -0
  84. package/.claude/worktrees/kanban-overhaul/.claude/skills/obsidian/SKILL.md +306 -0
  85. package/.claude/worktrees/kanban-overhaul/.claude/skills/read-the-damn-docs/SKILL.md +113 -0
  86. package/.claude/worktrees/kanban-overhaul/.claude/skills/self-improvement/SKILL.md +64 -0
  87. package/.claude/worktrees/kanban-overhaul/.dockerignore +31 -0
  88. package/.claude/worktrees/kanban-overhaul/.gitattributes +27 -0
  89. package/.claude/worktrees/kanban-overhaul/.harness/agents.json +17 -0
  90. package/.claude/worktrees/kanban-overhaul/.harness/arch-rules.json +69 -0
  91. package/.claude/worktrees/kanban-overhaul/.harness/topology.json +4 -0
  92. package/.claude/worktrees/kanban-overhaul/.nvmrc +1 -0
  93. package/.claude/worktrees/kanban-overhaul/.serena/project.yml +159 -0
  94. package/.claude/worktrees/kanban-overhaul/AGENTS.md +250 -0
  95. package/.claude/worktrees/kanban-overhaul/CHANGELOG.md +5410 -0
  96. package/.claude/worktrees/kanban-overhaul/CLAUDE.md +260 -0
  97. package/.claude/worktrees/kanban-overhaul/CURRENT_ISSUES_ AND_NEW_FEATURES.md +18 -0
  98. package/.claude/worktrees/kanban-overhaul/DECISIONS.md +66 -0
  99. package/.claude/worktrees/kanban-overhaul/Dockerfile +48 -0
  100. package/.claude/worktrees/kanban-overhaul/FINAL_GOAL.md +397 -0
  101. package/.claude/worktrees/kanban-overhaul/IMPLEMENTATION_PLAN.md +250 -0
  102. package/.claude/worktrees/kanban-overhaul/LICENSE +21 -0
  103. package/.claude/worktrees/kanban-overhaul/MILESTONES.md +257 -0
  104. package/.claude/worktrees/kanban-overhaul/Makefile +93 -0
  105. package/.claude/worktrees/kanban-overhaul/PROGRESS.md +1406 -0
  106. package/.claude/worktrees/kanban-overhaul/README.md +483 -0
  107. package/.claude/worktrees/kanban-overhaul/ROADMAP.md +609 -0
  108. package/.claude/worktrees/kanban-overhaul/bizar-dash/.graphifyignore +40 -0
  109. package/.claude/worktrees/kanban-overhaul/bizar-dash/.obsidian/README.md +14 -0
  110. package/.claude/worktrees/kanban-overhaul/bizar-dash/.obsidian/daily/2026-06-25.md +9 -0
  111. package/.claude/worktrees/kanban-overhaul/bizar-dash/.obsidian/vault.json +7 -0
  112. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/SKILL.md +103 -0
  113. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/assets/template.html +338 -0
  114. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/example.html +81 -0
  115. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/open-design.json +172 -0
  116. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/references/checklist.md +44 -0
  117. package/.claude/worktrees/kanban-overhaul/bizar-dash/.od-skills/web-prototype-e1429c1737/references/layouts.md +247 -0
  118. package/.claude/worktrees/kanban-overhaul/bizar-dash/ARCHITECTURE.md +197 -0
  119. package/.claude/worktrees/kanban-overhaul/bizar-dash/CHANGELOG.md +235 -0
  120. package/.claude/worktrees/kanban-overhaul/bizar-dash/DESIGN.md +912 -0
  121. package/.claude/worktrees/kanban-overhaul/bizar-dash/GLYPH.md +418 -0
  122. package/.claude/worktrees/kanban-overhaul/bizar-dash/PLAN.md +1135 -0
  123. package/.claude/worktrees/kanban-overhaul/bizar-dash/critique.json +26 -0
  124. package/.claude/worktrees/kanban-overhaul/bizar-dash/plans/debug-plan/comments.json +1 -0
  125. package/.claude/worktrees/kanban-overhaul/bizar-dash/plans/debug-plan/meta.json +10 -0
  126. package/.claude/worktrees/kanban-overhaul/bizar-dash/plans/debug-plan/plan.json +174 -0
  127. package/.claude/worktrees/kanban-overhaul/bizar-dash/scripts/smoke-bg-retry.mjs +246 -0
  128. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/agent-baseline/SKILL.md +80 -0
  129. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/agent-browser/SKILL.md +181 -0
  130. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/bizar/SKILL.md +116 -0
  131. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/chat/SKILL.md +74 -0
  132. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/eval/SKILL.md +237 -0
  133. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/headroom/SKILL.md +94 -0
  134. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/lightrag/SKILL.md +86 -0
  135. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/minimax/SKILL.md +80 -0
  136. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/obsidian/SKILL.md +68 -0
  137. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/providers/SKILL.md +75 -0
  138. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/publishing/SKILL.md +146 -0
  139. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/sdk/SKILL.md +138 -0
  140. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/self-improvement/SKILL.md +53 -0
  141. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/skills-cli/SKILL.md +94 -0
  142. package/.claude/worktrees/kanban-overhaul/bizar-dash/skills/usage/SKILL.md +62 -0
  143. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/cli/dashboard-ports.mjs +488 -0
  144. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/cli.mjs +537 -0
  145. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/activity-log.mjs +174 -0
  146. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/agents-store.mjs +465 -0
  147. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/api.mjs +223 -0
  148. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/artifact-template.html +810 -0
  149. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/artifacts-store.mjs +733 -0
  150. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/auth.mjs +548 -0
  151. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/background-store.mjs +446 -0
  152. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/backup-store.mjs +530 -0
  153. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/bg-poller.mjs +375 -0
  154. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/bg-retry.mjs +446 -0
  155. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/bg-spawner.mjs +390 -0
  156. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/browser.mjs +40 -0
  157. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/claude-bg-spawner.mjs +390 -0
  158. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/claude-info.mjs +412 -0
  159. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/claude-runner.mjs +284 -0
  160. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/claude-sdk.mjs +191 -0
  161. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/diagnostics-store.mjs +598 -0
  162. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/dialog-poller.mjs +105 -0
  163. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/dialog-store.mjs +177 -0
  164. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/digest-store.mjs +558 -0
  165. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/eval-store.mjs +281 -0
  166. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/eval.mjs +500 -0
  167. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/glyphs/mdx-compiler.mjs +596 -0
  168. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/headroom.mjs +649 -0
  169. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/lib/path-safe.mjs +283 -0
  170. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/lib/rate-limit.mjs +122 -0
  171. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/logger.mjs +71 -0
  172. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-consolidator.mjs +225 -0
  173. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-distillation.mjs +296 -0
  174. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-git.mjs +473 -0
  175. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-lightrag.mjs +1478 -0
  176. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-obsidian.mjs +230 -0
  177. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-schema.mjs +145 -0
  178. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-secrets.mjs +84 -0
  179. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/memory-store.mjs +1093 -0
  180. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/metrics.mjs +268 -0
  181. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/minimax-usage-store.mjs +372 -0
  182. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/minimax.mjs +683 -0
  183. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/mod-security.mjs +398 -0
  184. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/mods-loader.mjs +1243 -0
  185. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/notifications-store.mjs +243 -0
  186. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/obsidian-store.mjs +318 -0
  187. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/ocr.mjs +55 -0
  188. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/otel.mjs +260 -0
  189. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/pair-store.mjs +138 -0
  190. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/progress-parser.mjs +221 -0
  191. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/projects-store.mjs +364 -0
  192. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/providers-store.mjs +1801 -0
  193. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/_shared.mjs +447 -0
  194. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/activity.mjs +195 -0
  195. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/agents-cc.mjs +194 -0
  196. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/agents.mjs +134 -0
  197. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/artifacts.mjs +279 -0
  198. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/auth.mjs +69 -0
  199. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/background.mjs +422 -0
  200. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/backup.mjs +112 -0
  201. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/chat.mjs +727 -0
  202. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/claude-session-detail.mjs +329 -0
  203. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/claude-sessions.mjs +259 -0
  204. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/clipboard.mjs +173 -0
  205. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/config.mjs +180 -0
  206. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/diagnostics.mjs +50 -0
  207. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/dialogs.mjs +86 -0
  208. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/digests.mjs +82 -0
  209. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/distill.mjs +129 -0
  210. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/doctor.mjs +71 -0
  211. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/env-vars.mjs +231 -0
  212. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/eval.mjs +187 -0
  213. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/fs.mjs +429 -0
  214. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/goal-planner.mjs +236 -0
  215. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/goals.mjs +212 -0
  216. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/headroom.mjs +126 -0
  217. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/history.mjs +78 -0
  218. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/lightrag.mjs +169 -0
  219. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/memory.mjs +1524 -0
  220. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/minimax.mjs +133 -0
  221. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/misc.mjs +90 -0
  222. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/mods.mjs +359 -0
  223. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/notifications.mjs +54 -0
  224. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/obsidian.mjs +239 -0
  225. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/ocr.mjs +182 -0
  226. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/overview.mjs +92 -0
  227. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/pair.mjs +67 -0
  228. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/projects.mjs +175 -0
  229. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/providers.mjs +308 -0
  230. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/schedules.mjs +159 -0
  231. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/settings.mjs +51 -0
  232. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/skills.mjs +65 -0
  233. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/tailscale.mjs +46 -0
  234. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/tasks.mjs +518 -0
  235. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/themes.mjs +51 -0
  236. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/update.mjs +340 -0
  237. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/usage.mjs +136 -0
  238. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/users.mjs +102 -0
  239. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/voice.mjs +167 -0
  240. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes/workspaces.mjs +299 -0
  241. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes-v2/auth.mjs +59 -0
  242. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes-v2/events.mjs +121 -0
  243. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes-v2/health.mjs +21 -0
  244. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes-v2/index.mjs +90 -0
  245. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/routes-v2/sessions.mjs +111 -0
  246. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/schedules-runner.mjs +556 -0
  247. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/schedules-store.mjs +268 -0
  248. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/search-store.mjs +220 -0
  249. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/serve-info.mjs +1110 -0
  250. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/server.mjs +966 -0
  251. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/settings-store.mjs +45 -0
  252. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/skills-store.mjs +190 -0
  253. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/state.mjs +437 -0
  254. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/tailscale-store.mjs +113 -0
  255. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/task-delegator.mjs +969 -0
  256. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/tasks-store.mjs +556 -0
  257. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/tui.mjs +923 -0
  258. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/update-store.mjs +168 -0
  259. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/v2-auth-file.mjs +99 -0
  260. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/v2-event-bus.mjs +128 -0
  261. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/voice-store.mjs +229 -0
  262. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/voice-transcribe.mjs +72 -0
  263. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/watcher.mjs +81 -0
  264. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/workers/transcription-worker.mjs +213 -0
  265. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/workspaces.mjs +626 -0
  266. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/server/yaml.mjs +238 -0
  267. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/App.tsx +200 -0
  268. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/data/fetcher.ts +59 -0
  269. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/data/types.ts +168 -0
  270. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/data/useFetch.ts +62 -0
  271. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/data/useWebSocket.ts +153 -0
  272. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/main.tsx +28 -0
  273. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/AppShell.tsx +90 -0
  274. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/PageSkeleton.tsx +29 -0
  275. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/Sidebar.tsx +361 -0
  276. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/StatusBar.tsx +63 -0
  277. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/Topbar.tsx +113 -0
  278. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/shell/index.ts +15 -0
  279. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/activity/ActivityFeed.tsx +137 -0
  280. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/agents/AgentActivity.tsx +101 -0
  281. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/agents/AgentCard.tsx +158 -0
  282. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/agents/AgentDetail.tsx +232 -0
  283. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Button.tsx +141 -0
  284. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/ButtonGroup.tsx +32 -0
  285. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Checkbox.tsx +49 -0
  286. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Field.tsx +78 -0
  287. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Form.tsx +23 -0
  288. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/IconButton.tsx +112 -0
  289. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Input.tsx +94 -0
  290. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/RadioGroup.tsx +74 -0
  291. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Select.tsx +171 -0
  292. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Slider.tsx +68 -0
  293. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Switch.tsx +56 -0
  294. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Textarea.tsx +64 -0
  295. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/Toggle.tsx +36 -0
  296. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/controls/ToggleGroup.tsx +85 -0
  297. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Accordion.tsx +134 -0
  298. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Avatar.tsx +175 -0
  299. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Badge.tsx +93 -0
  300. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/BarList.tsx +101 -0
  301. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Card.tsx +140 -0
  302. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Chip.tsx +96 -0
  303. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Kbd.tsx +42 -0
  304. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/ProgressBar.tsx +93 -0
  305. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Sparkline.tsx +98 -0
  306. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/StatTile.tsx +150 -0
  307. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Table.tsx +170 -0
  308. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/Timeline.tsx +130 -0
  309. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/data/ViewHeader.tsx +122 -0
  310. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Alert.tsx +95 -0
  311. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Banner.tsx +39 -0
  312. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/ContextMenu.tsx +143 -0
  313. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Dialog.tsx +149 -0
  314. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Drawer.tsx +8 -0
  315. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/DropdownMenu.tsx +231 -0
  316. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/EmptyState.tsx +48 -0
  317. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Popover.tsx +56 -0
  318. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Sheet.tsx +103 -0
  319. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Skeleton.tsx +67 -0
  320. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Spinner.tsx +30 -0
  321. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Toast.tsx +66 -0
  322. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/feedback/Tooltip.tsx +89 -0
  323. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/goals/GoalCard.tsx +176 -0
  324. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/goals/GoalDetail.tsx +245 -0
  325. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/goals/KeyResult.tsx +115 -0
  326. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/index.ts +349 -0
  327. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanBoard.tsx +115 -0
  328. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanCard.tsx +391 -0
  329. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanCardBadges.tsx +111 -0
  330. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanColumn.tsx +181 -0
  331. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanContextMenu.tsx +126 -0
  332. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanDetailDialog.tsx +638 -0
  333. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanEmptyColumn.tsx +43 -0
  334. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanProgress.tsx +130 -0
  335. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanQuickAdd.tsx +141 -0
  336. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/KanbanToolbar.tsx +291 -0
  337. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/kanban/useKanbanSelection.ts +90 -0
  338. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/libraries/LibraryGrid.tsx +30 -0
  339. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/libraries/LibraryItem.tsx +161 -0
  340. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/memory/MemoryVault.tsx +144 -0
  341. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +224 -0
  342. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/navigation/NavLink.tsx +81 -0
  343. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/navigation/Pagination.tsx +164 -0
  344. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/navigation/Tabs.tsx +128 -0
  345. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Box.tsx +144 -0
  346. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Center.tsx +40 -0
  347. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Cluster.tsx +67 -0
  348. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Grid.tsx +104 -0
  349. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Inline.tsx +77 -0
  350. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Portal.tsx +33 -0
  351. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/ScrollArea.tsx +62 -0
  352. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Separator.tsx +42 -0
  353. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/Stack.tsx +73 -0
  354. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/primitives/VisuallyHidden.tsx +49 -0
  355. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/settings/SettingsNav.tsx +91 -0
  356. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/settings/SettingsRow.tsx +88 -0
  357. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/settings/SettingsSection.tsx +109 -0
  358. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/styles/globals.css +220 -0
  359. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/styles/reset.css +57 -0
  360. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/styles/tokens.css +217 -0
  361. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/theme/DensityProvider.tsx +66 -0
  362. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/theme/ThemeProvider.tsx +94 -0
  363. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +88 -0
  364. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/theme/useDensity.ts +15 -0
  365. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/theme/useTheme.ts +16 -0
  366. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/ui/utils/cx.ts +19 -0
  367. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +71 -0
  368. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +172 -0
  369. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +247 -0
  370. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +137 -0
  371. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +108 -0
  372. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +77 -0
  373. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +152 -0
  374. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Router.tsx +72 -0
  375. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +330 -0
  376. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Tasks/CommandPalettePlaceholder.tsx +106 -0
  377. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +792 -0
  378. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8/vite-env.d.ts +15 -0
  379. package/.claude/worktrees/kanban-overhaul/bizar-dash/src/web/v8.html +17 -0
  380. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/FORMAT.md +76 -0
  381. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/README.md +19 -0
  382. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/agents/greeter.md +8 -0
  383. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/commands/hello.md +6 -0
  384. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/mod.json +20 -0
  385. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/routes/ping.mjs +9 -0
  386. package/.claude/worktrees/kanban-overhaul/bizar-dash/templates/mod/hello-mod/views/HelloView.tsx +10 -0
  387. package/.claude/worktrees/kanban-overhaul/bizar-dash/tests/setup.ts +63 -0
  388. package/.claude/worktrees/kanban-overhaul/bizar-dash/tests/smoke-v2.mjs +212 -0
  389. package/.claude/worktrees/kanban-overhaul/bizar-dash/tsconfig.json +23 -0
  390. package/.claude/worktrees/kanban-overhaul/bizar-dash/vite.config.ts +66 -0
  391. package/.claude/worktrees/kanban-overhaul/bizar-dash/vitest.config.ts +20 -0
  392. package/.claude/worktrees/kanban-overhaul/bizar-plugins/registry.json +62 -0
  393. package/.claude/worktrees/kanban-overhaul/bookmarklet/bizar-clipper.js +48 -0
  394. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/README.md +43 -0
  395. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/background.js +95 -0
  396. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/content.js +170 -0
  397. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/icons/icon-128.png +0 -0
  398. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/icons/icon-16.png +0 -0
  399. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/icons/icon-48.png +0 -0
  400. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/icons/icon.svg +4 -0
  401. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/manifest.json +32 -0
  402. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/popup.html +66 -0
  403. package/.claude/worktrees/kanban-overhaul/browser-extensions/bizar-clipper/popup.js +110 -0
  404. package/.claude/worktrees/kanban-overhaul/bun.lock +1558 -0
  405. package/.claude/worktrees/kanban-overhaul/cli/agent-browser-up.sh +152 -0
  406. package/.claude/worktrees/kanban-overhaul/cli/agent-browser-update.mjs +322 -0
  407. package/.claude/worktrees/kanban-overhaul/cli/artifact-cli.mjs +605 -0
  408. package/.claude/worktrees/kanban-overhaul/cli/artifact-render.mjs +621 -0
  409. package/.claude/worktrees/kanban-overhaul/cli/artifact-server.mjs +847 -0
  410. package/.claude/worktrees/kanban-overhaul/cli/artifact-templates.mjs +523 -0
  411. package/.claude/worktrees/kanban-overhaul/cli/artifact.mjs +63 -0
  412. package/.claude/worktrees/kanban-overhaul/cli/atomic.mjs +73 -0
  413. package/.claude/worktrees/kanban-overhaul/cli/audit.mjs +141 -0
  414. package/.claude/worktrees/kanban-overhaul/cli/banner.mjs +41 -0
  415. package/.claude/worktrees/kanban-overhaul/cli/bg.mjs +471 -0
  416. package/.claude/worktrees/kanban-overhaul/cli/bin.mjs +698 -0
  417. package/.claude/worktrees/kanban-overhaul/cli/bootstrap.mjs +77 -0
  418. package/.claude/worktrees/kanban-overhaul/cli/commands/artifact.mjs +20 -0
  419. package/.claude/worktrees/kanban-overhaul/cli/commands/claim.mjs +282 -0
  420. package/.claude/worktrees/kanban-overhaul/cli/commands/claude-cmd.mjs +348 -0
  421. package/.claude/worktrees/kanban-overhaul/cli/commands/clip.mjs +163 -0
  422. package/.claude/worktrees/kanban-overhaul/cli/commands/cost.mjs +279 -0
  423. package/.claude/worktrees/kanban-overhaul/cli/commands/dash.mjs +193 -0
  424. package/.claude/worktrees/kanban-overhaul/cli/commands/deploy/cloudflare.mjs +250 -0
  425. package/.claude/worktrees/kanban-overhaul/cli/commands/deploy/docker.mjs +222 -0
  426. package/.claude/worktrees/kanban-overhaul/cli/commands/deploy/fly.mjs +161 -0
  427. package/.claude/worktrees/kanban-overhaul/cli/commands/deploy/vercel.mjs +225 -0
  428. package/.claude/worktrees/kanban-overhaul/cli/commands/deploy.mjs +240 -0
  429. package/.claude/worktrees/kanban-overhaul/cli/commands/eval.mjs +396 -0
  430. package/.claude/worktrees/kanban-overhaul/cli/commands/headroom.mjs +204 -0
  431. package/.claude/worktrees/kanban-overhaul/cli/commands/install.mjs +170 -0
  432. package/.claude/worktrees/kanban-overhaul/cli/commands/lightrag.mjs +170 -0
  433. package/.claude/worktrees/kanban-overhaul/cli/commands/marketplace.mjs +64 -0
  434. package/.claude/worktrees/kanban-overhaul/cli/commands/memory.mjs +25 -0
  435. package/.claude/worktrees/kanban-overhaul/cli/commands/minimax.mjs +288 -0
  436. package/.claude/worktrees/kanban-overhaul/cli/commands/mod.mjs +185 -0
  437. package/.claude/worktrees/kanban-overhaul/cli/commands/ocr.mjs +182 -0
  438. package/.claude/worktrees/kanban-overhaul/cli/commands/plugin.mjs +358 -0
  439. package/.claude/worktrees/kanban-overhaul/cli/commands/rca.mjs +198 -0
  440. package/.claude/worktrees/kanban-overhaul/cli/commands/sandbox.mjs +220 -0
  441. package/.claude/worktrees/kanban-overhaul/cli/commands/service.mjs +79 -0
  442. package/.claude/worktrees/kanban-overhaul/cli/commands/setup-provider.mjs +466 -0
  443. package/.claude/worktrees/kanban-overhaul/cli/commands/tailscale.mjs +258 -0
  444. package/.claude/worktrees/kanban-overhaul/cli/commands/usage.mjs +113 -0
  445. package/.claude/worktrees/kanban-overhaul/cli/commands/util.mjs +577 -0
  446. package/.claude/worktrees/kanban-overhaul/cli/commands/validate.mjs +541 -0
  447. package/.claude/worktrees/kanban-overhaul/cli/commands/voice.mjs +211 -0
  448. package/.claude/worktrees/kanban-overhaul/cli/commands/workspace.mjs +247 -0
  449. package/.claude/worktrees/kanban-overhaul/cli/copy.mjs +586 -0
  450. package/.claude/worktrees/kanban-overhaul/cli/cost-gate.mjs +501 -0
  451. package/.claude/worktrees/kanban-overhaul/cli/dev-link.mjs +191 -0
  452. package/.claude/worktrees/kanban-overhaul/cli/digest.mjs +149 -0
  453. package/.claude/worktrees/kanban-overhaul/cli/doctor.mjs +217 -0
  454. package/.claude/worktrees/kanban-overhaul/cli/export.mjs +95 -0
  455. package/.claude/worktrees/kanban-overhaul/cli/feature-list-bridge.mjs +400 -0
  456. package/.claude/worktrees/kanban-overhaul/cli/heads-up.mjs +295 -0
  457. package/.claude/worktrees/kanban-overhaul/cli/init.mjs +368 -0
  458. package/.claude/worktrees/kanban-overhaul/cli/install.mjs +640 -0
  459. package/.claude/worktrees/kanban-overhaul/cli/memory-constants.mjs +76 -0
  460. package/.claude/worktrees/kanban-overhaul/cli/memory.mjs +1850 -0
  461. package/.claude/worktrees/kanban-overhaul/cli/plugin-runtime-deps.mjs +250 -0
  462. package/.claude/worktrees/kanban-overhaul/cli/post-install-smoke.mjs +256 -0
  463. package/.claude/worktrees/kanban-overhaul/cli/prompts.mjs +168 -0
  464. package/.claude/worktrees/kanban-overhaul/cli/providers-detect.mjs +233 -0
  465. package/.claude/worktrees/kanban-overhaul/cli/provision-claude.mjs +1176 -0
  466. package/.claude/worktrees/kanban-overhaul/cli/provision.mjs +2233 -0
  467. package/.claude/worktrees/kanban-overhaul/cli/repair.mjs +209 -0
  468. package/.claude/worktrees/kanban-overhaul/cli/service-controller.mjs +927 -0
  469. package/.claude/worktrees/kanban-overhaul/cli/service-env.mjs +139 -0
  470. package/.claude/worktrees/kanban-overhaul/cli/service.mjs +492 -0
  471. package/.claude/worktrees/kanban-overhaul/cli/update.mjs +29 -0
  472. package/.claude/worktrees/kanban-overhaul/cli/utils.mjs +221 -0
  473. package/.claude/worktrees/kanban-overhaul/cli/worker-dispatcher.mjs +259 -0
  474. package/.claude/worktrees/kanban-overhaul/config/AGENTS.md +595 -0
  475. package/.claude/worktrees/kanban-overhaul/config/agents/_shared/AGENT_BASELINE.md +155 -0
  476. package/.claude/worktrees/kanban-overhaul/config/agents/_shared/CLINE_TOOLS.md +398 -0
  477. package/.claude/worktrees/kanban-overhaul/config/agents/_shared/SKILLS.md +109 -0
  478. package/.claude/worktrees/kanban-overhaul/config/agents/agent-browser.md +90 -0
  479. package/.claude/worktrees/kanban-overhaul/config/agents/baldr.md +60 -0
  480. package/.claude/worktrees/kanban-overhaul/config/agents/forseti.md +60 -0
  481. package/.claude/worktrees/kanban-overhaul/config/agents/frigg.md +52 -0
  482. package/.claude/worktrees/kanban-overhaul/config/agents/heimdall.md +44 -0
  483. package/.claude/worktrees/kanban-overhaul/config/agents/hermod.md +64 -0
  484. package/.claude/worktrees/kanban-overhaul/config/agents/mimir.md +60 -0
  485. package/.claude/worktrees/kanban-overhaul/config/agents/odin.md +310 -0
  486. package/.claude/worktrees/kanban-overhaul/config/agents/quick.md +47 -0
  487. package/.claude/worktrees/kanban-overhaul/config/agents/semble-search.md +59 -0
  488. package/.claude/worktrees/kanban-overhaul/config/agents/thor.md +64 -0
  489. package/.claude/worktrees/kanban-overhaul/config/agents/tyr.md +67 -0
  490. package/.claude/worktrees/kanban-overhaul/config/agents/vidarr.md +65 -0
  491. package/.claude/worktrees/kanban-overhaul/config/agents/vor.md +62 -0
  492. package/.claude/worktrees/kanban-overhaul/config/commands/audit.md +5 -0
  493. package/.claude/worktrees/kanban-overhaul/config/commands/bizar.md +22 -0
  494. package/.claude/worktrees/kanban-overhaul/config/commands/explain.md +5 -0
  495. package/.claude/worktrees/kanban-overhaul/config/commands/init.md +26 -0
  496. package/.claude/worktrees/kanban-overhaul/config/commands/learn.md +5 -0
  497. package/.claude/worktrees/kanban-overhaul/config/commands/plan.md +30 -0
  498. package/.claude/worktrees/kanban-overhaul/config/commands/plow-through.md +47 -0
  499. package/.claude/worktrees/kanban-overhaul/config/commands/pr-review.md +5 -0
  500. package/.claude/worktrees/kanban-overhaul/config/commands/setup-provider.md +95 -0
  501. package/.claude/worktrees/kanban-overhaul/config/commands/tailscale-serve.md +97 -0
  502. package/.claude/worktrees/kanban-overhaul/config/commands/team.md +124 -0
  503. package/.claude/worktrees/kanban-overhaul/config/commands/test.md +60 -0
  504. package/.claude/worktrees/kanban-overhaul/config/commands/validate.md +66 -0
  505. package/.claude/worktrees/kanban-overhaul/config/commands/visual-plan.md +19 -0
  506. package/.claude/worktrees/kanban-overhaul/config/hooks/PostToolUse +66 -0
  507. package/.claude/worktrees/kanban-overhaul/config/hooks/PreToolUse +82 -0
  508. package/.claude/worktrees/kanban-overhaul/config/hooks/README.md +68 -0
  509. package/.claude/worktrees/kanban-overhaul/config/hooks/TaskResume +48 -0
  510. package/.claude/worktrees/kanban-overhaul/config/hooks/TaskStart +47 -0
  511. package/.claude/worktrees/kanban-overhaul/config/hooks/UserPromptSubmit +55 -0
  512. package/.claude/worktrees/kanban-overhaul/config/rules/general.md +9 -0
  513. package/.claude/worktrees/kanban-overhaul/config/rules/git.md +11 -0
  514. package/.claude/worktrees/kanban-overhaul/config/rules/javascript.md +10 -0
  515. package/.claude/worktrees/kanban-overhaul/config/rules/python.md +10 -0
  516. package/.claude/worktrees/kanban-overhaul/config/rules/testing.md +10 -0
  517. package/.claude/worktrees/kanban-overhaul/config/rules/thinking.md +56 -0
  518. package/.claude/worktrees/kanban-overhaul/config/rules/uncertainty.md +70 -0
  519. package/.claude/worktrees/kanban-overhaul/config/skills/9router/SKILL.md +80 -0
  520. package/.claude/worktrees/kanban-overhaul/config/skills/9router-chat/SKILL.md +73 -0
  521. package/.claude/worktrees/kanban-overhaul/config/skills/9router-embeddings/SKILL.md +69 -0
  522. package/.claude/worktrees/kanban-overhaul/config/skills/9router-image/SKILL.md +86 -0
  523. package/.claude/worktrees/kanban-overhaul/config/skills/9router-stt/SKILL.md +79 -0
  524. package/.claude/worktrees/kanban-overhaul/config/skills/9router-tts/SKILL.md +80 -0
  525. package/.claude/worktrees/kanban-overhaul/config/skills/9router-web-fetch/SKILL.md +99 -0
  526. package/.claude/worktrees/kanban-overhaul/config/skills/9router-web-search/SKILL.md +91 -0
  527. package/.claude/worktrees/kanban-overhaul/config/skills/bizar/README.md +9 -0
  528. package/.claude/worktrees/kanban-overhaul/config/skills/bizar/SKILL.md +447 -0
  529. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/README.md +28 -0
  530. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/SKILL.md +634 -0
  531. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/agents/openai.yaml +4 -0
  532. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/references/concurrency.md +320 -0
  533. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/references/error-handling.md +229 -0
  534. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/references/memory-safety.md +216 -0
  535. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/references/modern-idioms.md +282 -0
  536. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-coding-standards/references/review-checklist.md +96 -0
  537. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/README.md +28 -0
  538. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/SKILL.md +304 -0
  539. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/agents/openai.yaml +4 -0
  540. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/references/coverage.md +370 -0
  541. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/references/framework-compare.md +175 -0
  542. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/references/host-test-for-embedded.md +499 -0
  543. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/references/mocking.md +364 -0
  544. package/.claude/worktrees/kanban-overhaul/config/skills/cpp-testing/references/tdd-workflow.md +308 -0
  545. package/.claude/worktrees/kanban-overhaul/config/skills/cubesandbox/SKILL.md +148 -0
  546. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/README.md +41 -0
  547. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/SKILL.md +439 -0
  548. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/agents/openai.yaml +4 -0
  549. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/freertos-patterns.md +214 -0
  550. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/host-tests.md +164 -0
  551. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/idf-py-commands.md +157 -0
  552. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/kconfig.md +159 -0
  553. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/logging-discipline.md +118 -0
  554. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/memory-and-iram.md +137 -0
  555. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/nvs.md +121 -0
  556. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/references/packed-structs.md +192 -0
  557. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/scripts/idf_env.sh +47 -0
  558. package/.claude/worktrees/kanban-overhaul/config/skills/embedded-esp-idf/scripts/size_check.sh +77 -0
  559. package/.claude/worktrees/kanban-overhaul/config/skills/glyph/SKILL.md +163 -0
  560. package/.claude/worktrees/kanban-overhaul/config/skills/harness-engineering/SKILL.md +142 -0
  561. package/.claude/worktrees/kanban-overhaul/config/skills/lightrag/SKILL.md +81 -0
  562. package/.claude/worktrees/kanban-overhaul/config/skills/memory-protocol/SKILL.md +105 -0
  563. package/.claude/worktrees/kanban-overhaul/config/skills/obsidian/SKILL.md +306 -0
  564. package/.claude/worktrees/kanban-overhaul/config/skills/read-the-damn-docs/SKILL.md +113 -0
  565. package/.claude/worktrees/kanban-overhaul/config/skills/self-improvement/SKILL.md +64 -0
  566. package/.claude/worktrees/kanban-overhaul/config/trigger-patterns.json +186 -0
  567. package/.claude/worktrees/kanban-overhaul/docker-compose.yml +50 -0
  568. package/.claude/worktrees/kanban-overhaul/docs/A11Y.md +81 -0
  569. package/.claude/worktrees/kanban-overhaul/docs/DEPLOY.md +360 -0
  570. package/.claude/worktrees/kanban-overhaul/docs/DOCKER.md +250 -0
  571. package/.claude/worktrees/kanban-overhaul/docs/INDEX.md +223 -0
  572. package/.claude/worktrees/kanban-overhaul/docs/PLUGIN_REGISTRY.md +107 -0
  573. package/.claude/worktrees/kanban-overhaul/docs/RELEASING.md +693 -0
  574. package/.claude/worktrees/kanban-overhaul/docs/architecture.md +317 -0
  575. package/.claude/worktrees/kanban-overhaul/docs/code-review.md +242 -0
  576. package/.claude/worktrees/kanban-overhaul/docs/curator.md +144 -0
  577. package/.claude/worktrees/kanban-overhaul/docs/dashboard-ui-migration.md +807 -0
  578. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-001-cline-rewrite.md +114 -0
  579. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-002-in-process-clinecore.md +139 -0
  580. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-003-in-process-memory-vault.md +101 -0
  581. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-004-cline-agent-teams.md +112 -0
  582. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-005-bg-agents-via-dashboard.md +77 -0
  583. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-006-kanban-board.md +69 -0
  584. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-007-tool-approval-gate.md +147 -0
  585. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-008-skill-curator.md +100 -0
  586. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-009-pre-compaction-flush.md +106 -0
  587. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-010-knowledge-graph-tools.md +95 -0
  588. package/.claude/worktrees/kanban-overhaul/docs/decisions/DEC-011-claude-code-migration.md +172 -0
  589. package/.claude/worktrees/kanban-overhaul/docs/graph-tools.md +130 -0
  590. package/.claude/worktrees/kanban-overhaul/docs/migration-guide.md +471 -0
  591. package/.claude/worktrees/kanban-overhaul/docs/migrations/cline-replacement.md +118 -0
  592. package/.claude/worktrees/kanban-overhaul/docs/postmortems/2026-06-18-plugin-state-deadlock.md +250 -0
  593. package/.claude/worktrees/kanban-overhaul/docs/quality-document.md +74 -0
  594. package/.claude/worktrees/kanban-overhaul/docs/releases/v0.5.2.md +66 -0
  595. package/.claude/worktrees/kanban-overhaul/docs/releases/v0.5.4.md +85 -0
  596. package/.claude/worktrees/kanban-overhaul/docs/releases/v2.3.0.md +96 -0
  597. package/.claude/worktrees/kanban-overhaul/docs/releases/v3.24.0.md +155 -0
  598. package/.claude/worktrees/kanban-overhaul/docs/releases/v4.0.0.md +123 -0
  599. package/.claude/worktrees/kanban-overhaul/docs/releases/v7.0.0.md +173 -0
  600. package/.claude/worktrees/kanban-overhaul/docs/safety.md +216 -0
  601. package/.claude/worktrees/kanban-overhaul/feature_list.json +1297 -0
  602. package/.claude/worktrees/kanban-overhaul/init.sh +211 -0
  603. package/.claude/worktrees/kanban-overhaul/install.sh +498 -0
  604. package/.claude/worktrees/kanban-overhaul/mods-examples/impeccable/INSTRUCTIONS.md +82 -0
  605. package/.claude/worktrees/kanban-overhaul/mods-examples/impeccable/mod.json +37 -0
  606. package/.claude/worktrees/kanban-overhaul/mods-examples/impeccable/route.mjs +136 -0
  607. package/.claude/worktrees/kanban-overhaul/mods-examples/impeccable/web/index.html +180 -0
  608. package/.claude/worktrees/kanban-overhaul/mods-examples/lightrag/INSTRUCTIONS.md +81 -0
  609. package/.claude/worktrees/kanban-overhaul/mods-examples/lightrag/mod.json +61 -0
  610. package/.claude/worktrees/kanban-overhaul/mods-examples/lightrag/route.mjs +461 -0
  611. package/.claude/worktrees/kanban-overhaul/mods-examples/lightrag/web/index.html +263 -0
  612. package/.claude/worktrees/kanban-overhaul/mods-examples/ponytail/INSTRUCTIONS.md +87 -0
  613. package/.claude/worktrees/kanban-overhaul/mods-examples/ponytail/agents/thor.md +64 -0
  614. package/.claude/worktrees/kanban-overhaul/mods-examples/ponytail/mod.json +36 -0
  615. package/.claude/worktrees/kanban-overhaul/mods-examples/ponytail/route.mjs +98 -0
  616. package/.claude/worktrees/kanban-overhaul/mods-examples/ponytail/web/index.html +126 -0
  617. package/.claude/worktrees/kanban-overhaul/package.json +154 -0
  618. package/.claude/worktrees/kanban-overhaul/packages/sdk/ARCHITECTURE.md +70 -0
  619. package/.claude/worktrees/kanban-overhaul/packages/sdk/LICENSE +21 -0
  620. package/.claude/worktrees/kanban-overhaul/packages/sdk/README.md +80 -0
  621. package/.claude/worktrees/kanban-overhaul/packages/sdk/package.json +30 -0
  622. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/agent-registry.ts +304 -0
  623. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/consensus/byzantine.ts +587 -0
  624. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/consensus/index.ts +147 -0
  625. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/consensus/queen.ts +173 -0
  626. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/consensus/types.ts +199 -0
  627. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/dangerous-patterns.ts +127 -0
  628. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/audit.ts +156 -0
  629. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/budget.ts +269 -0
  630. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/envelope.ts +144 -0
  631. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/hmac.ts +160 -0
  632. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/index.ts +443 -0
  633. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/pii.ts +241 -0
  634. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/policy.ts +112 -0
  635. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/federation/trust.ts +146 -0
  636. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/fingerprint.ts +0 -0
  637. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/index.ts +114 -0
  638. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/mcp/bin.ts +51 -0
  639. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/mcp/server.ts +848 -0
  640. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/memory/index.ts +160 -0
  641. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/codemod-intent.ts +125 -0
  642. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/index.ts +247 -0
  643. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/memory-distillation-shim.mjs +18 -0
  644. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/memory-distillation.ts +249 -0
  645. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/model-router.ts +235 -0
  646. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/router/q-learning-router.ts +304 -0
  647. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/swarm-topology.ts +279 -0
  648. package/.claude/worktrees/kanban-overhaul/packages/sdk/src/version.ts +4 -0
  649. package/.claude/worktrees/kanban-overhaul/packages/sdk/tsconfig.json +25 -0
  650. package/.claude/worktrees/kanban-overhaul/packages/sdk/vitest.config.ts +9 -0
  651. package/.claude/worktrees/kanban-overhaul/plugins/bizar/ARCHITECTURE.md +72 -0
  652. package/.claude/worktrees/kanban-overhaul/plugins/bizar/CONSTRAINTS.md +62 -0
  653. package/.claude/worktrees/kanban-overhaul/plugins/bizar/LICENSE +21 -0
  654. package/.claude/worktrees/kanban-overhaul/plugins/bizar/README.md +46 -0
  655. package/.claude/worktrees/kanban-overhaul/plugins/bizar/index.ts +50 -0
  656. package/.claude/worktrees/kanban-overhaul/plugins/bizar/package.json +18 -0
  657. package/.claude/worktrees/kanban-overhaul/plugins/bizar/tsconfig.json +29 -0
  658. package/.claude/worktrees/kanban-overhaul/scripts/bh-full-e2e.mjs +298 -0
  659. package/.claude/worktrees/kanban-overhaul/scripts/check-agents.mjs +73 -0
  660. package/.claude/worktrees/kanban-overhaul/scripts/check-arch.sh +80 -0
  661. package/.claude/worktrees/kanban-overhaul/scripts/check-deps.mjs +492 -0
  662. package/.claude/worktrees/kanban-overhaul/scripts/clean-state-check.sh +81 -0
  663. package/.claude/worktrees/kanban-overhaul/scripts/git-hooks/pre-commit +59 -0
  664. package/.claude/worktrees/kanban-overhaul/scripts/git-hooks/pre-push +54 -0
  665. package/.claude/worktrees/kanban-overhaul/scripts/install-hooks.sh +29 -0
  666. package/.claude/worktrees/kanban-overhaul/scripts/install-service.mjs +190 -0
  667. package/.claude/worktrees/kanban-overhaul/scripts/mirror-claude-md.sh +78 -0
  668. package/.claude/worktrees/kanban-overhaul/scripts/session-trace.sh +52 -0
  669. package/.claude/worktrees/kanban-overhaul/scripts/test-in-container.sh +157 -0
  670. package/.claude/worktrees/kanban-overhaul/scripts/verify-feature.sh +102 -0
  671. package/.claude/worktrees/kanban-overhaul/skills-lock.json +11 -0
  672. package/.claude/worktrees/kanban-overhaul/templates/clean-state-checklist.md +55 -0
  673. package/.claude/worktrees/kanban-overhaul/templates/deploy/cloudflare/README.md +32 -0
  674. package/.claude/worktrees/kanban-overhaul/templates/deploy/cloudflare/functions-index.template.js +15 -0
  675. package/.claude/worktrees/kanban-overhaul/templates/deploy/cloudflare/wrangler.toml.template +9 -0
  676. package/.claude/worktrees/kanban-overhaul/templates/deploy/docker/.env.template +16 -0
  677. package/.claude/worktrees/kanban-overhaul/templates/deploy/docker/README.md +58 -0
  678. package/.claude/worktrees/kanban-overhaul/templates/deploy/docker/docker-compose.template.yml +23 -0
  679. package/.claude/worktrees/kanban-overhaul/templates/deploy/fly/README.md +35 -0
  680. package/.claude/worktrees/kanban-overhaul/templates/deploy/fly/fly.toml.template +28 -0
  681. package/.claude/worktrees/kanban-overhaul/templates/deploy/vercel/README.md +29 -0
  682. package/.claude/worktrees/kanban-overhaul/templates/deploy/vercel/api-index.template.js +18 -0
  683. package/.claude/worktrees/kanban-overhaul/templates/deploy/vercel/vercel.json.template +16 -0
  684. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/README.md +58 -0
  685. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/citation.json +16 -0
  686. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/code-review.json +16 -0
  687. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/code-search-basic.json +28 -0
  688. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/concise-output.json +16 -0
  689. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/context-window.json +16 -0
  690. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/error-recovery.json +16 -0
  691. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/json-output.json +20 -0
  692. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/latency-bounds.json +16 -0
  693. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/multi-language.json +16 -0
  694. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/regression-suite.json +79 -0
  695. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/response-format.json +30 -0
  696. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/safe-paths.json +16 -0
  697. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/tool-call-correctness.json +24 -0
  698. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/tool-call-multi-step.json +18 -0
  699. package/.claude/worktrees/kanban-overhaul/templates/eval-fixtures/unicode-handling.json +16 -0
  700. package/.claude/worktrees/kanban-overhaul/templates/evaluator-rubric.md +50 -0
  701. package/.claude/worktrees/kanban-overhaul/templates/plan/htmx.min.js +1 -0
  702. package/.claude/worktrees/kanban-overhaul/templates/plan/library/bug-investigation.mdx +79 -0
  703. package/.claude/worktrees/kanban-overhaul/templates/plan/library/decision-record.mdx +71 -0
  704. package/.claude/worktrees/kanban-overhaul/templates/plan/library/feature-design.mdx +92 -0
  705. package/.claude/worktrees/kanban-overhaul/templates/plan/meta.json.template +8 -0
  706. package/.claude/worktrees/kanban-overhaul/templates/plan/plan.mdx.template +46 -0
  707. package/.claude/worktrees/kanban-overhaul/templates/plugin-template/README.md +121 -0
  708. package/.claude/worktrees/kanban-overhaul/templates/plugin-template/index.js +66 -0
  709. package/.claude/worktrees/kanban-overhaul/templates/plugin-template/plugin.json +42 -0
  710. package/.claude/worktrees/kanban-overhaul/templates/plugin-template/tests/plugin.test.js +83 -0
  711. package/.claude/worktrees/kanban-overhaul/templates/schedules/daily-backup.json +12 -0
  712. package/.claude/worktrees/kanban-overhaul/templates/schedules/daily-cleanup.json +12 -0
  713. package/.claude/worktrees/kanban-overhaul/templates/schedules/hourly-health-check.json +12 -0
  714. package/.claude/worktrees/kanban-overhaul/templates/schedules/webhook-on-push.json +13 -0
  715. package/.claude/worktrees/kanban-overhaul/templates/schedules/weekly-digest.json +13 -0
  716. package/.claude/worktrees/kanban-overhaul/templates/sprint-contract.md +47 -0
  717. package/.claude/worktrees/kanban-overhaul/tsconfig.json +44 -0
  718. package/.claude/worktrees/kanban-overhaul/vite.config.ts +51 -0
  719. package/bizar-dash/dist/assets/ActivityFeed-BXIkGGQ1.js +16 -0
  720. package/bizar-dash/dist/assets/ActivityFeed-BXIkGGQ1.js.map +1 -0
  721. package/bizar-dash/dist/assets/ActivityView-CBxNNrZa.js +12 -0
  722. package/bizar-dash/dist/assets/ActivityView-CBxNNrZa.js.map +1 -0
  723. package/bizar-dash/dist/assets/AgentsView-uv4l21AH.js +23 -0
  724. package/bizar-dash/dist/assets/AgentsView-uv4l21AH.js.map +1 -0
  725. package/bizar-dash/dist/assets/BackgroundJobsView-CB4WXIpk.js +6 -0
  726. package/bizar-dash/dist/assets/BackgroundJobsView-CB4WXIpk.js.map +1 -0
  727. package/bizar-dash/dist/assets/{Card-BzJeYR2D.js → Card-CeZsWlcP.js} +1 -1
  728. package/bizar-dash/dist/assets/{Card-BzJeYR2D.js.map → Card-CeZsWlcP.js.map} +1 -1
  729. package/bizar-dash/dist/assets/{Chip-CN2bvm7a.js → Chip-OPjSKl2I.js} +1 -1
  730. package/bizar-dash/dist/assets/{Chip-CN2bvm7a.js.map → Chip-OPjSKl2I.js.map} +1 -1
  731. package/bizar-dash/dist/assets/{EmptyState-DEiBv4-r.js → EmptyState-BrLA8mbE.js} +1 -1
  732. package/bizar-dash/dist/assets/{EmptyState-DEiBv4-r.js.map → EmptyState-BrLA8mbE.js.map} +1 -1
  733. package/bizar-dash/dist/assets/GoalsView-B8R-kxQr.js +11 -0
  734. package/bizar-dash/dist/assets/GoalsView-B8R-kxQr.js.map +1 -0
  735. package/bizar-dash/dist/assets/Grid-B7NgNtff.js +1 -0
  736. package/bizar-dash/dist/assets/Grid-B7NgNtff.js.map +1 -0
  737. package/bizar-dash/dist/assets/Input-BW_5Sl6N.js +1 -0
  738. package/bizar-dash/dist/assets/Input-BW_5Sl6N.js.map +1 -0
  739. package/bizar-dash/dist/assets/{KanbanCard-DZEaAiEr.js → KanbanCard-B-NOSfMN.js} +1 -1
  740. package/bizar-dash/dist/assets/{KanbanCard-DZEaAiEr.js.map → KanbanCard-B-NOSfMN.js.map} +1 -1
  741. package/bizar-dash/dist/assets/{LibrariesView-CPgKGPpM.js → LibrariesView-D6eB7B2A.js} +6 -6
  742. package/bizar-dash/dist/assets/{LibrariesView-CPgKGPpM.js.map → LibrariesView-D6eB7B2A.js.map} +1 -1
  743. package/bizar-dash/dist/assets/MemoryView-MK4m1KbR.js +13 -0
  744. package/bizar-dash/dist/assets/MemoryView-MK4m1KbR.js.map +1 -0
  745. package/bizar-dash/dist/assets/OverviewView-CHavfYBa.js +1 -0
  746. package/bizar-dash/dist/assets/{OverviewView-BDegBWgg.js.map → OverviewView-CHavfYBa.js.map} +1 -1
  747. package/bizar-dash/dist/assets/SchedulesView-zV-0pbsz.js +1 -0
  748. package/bizar-dash/dist/assets/SchedulesView-zV-0pbsz.js.map +1 -0
  749. package/bizar-dash/dist/assets/{Select-xwxbK8Ed.js → Select-B6Ho36Tq.js} +3 -8
  750. package/bizar-dash/dist/assets/Select-B6Ho36Tq.js.map +1 -0
  751. package/bizar-dash/dist/assets/SettingsRow-Br21uRFz.js +1 -0
  752. package/bizar-dash/dist/assets/SettingsRow-Br21uRFz.js.map +1 -0
  753. package/bizar-dash/dist/assets/SettingsView-Cx3uJrus.js +38 -0
  754. package/bizar-dash/dist/assets/SettingsView-Cx3uJrus.js.map +1 -0
  755. package/bizar-dash/dist/assets/{Sheet-C_sIEw35.js → Sheet-Cmu_4Zea.js} +1 -1
  756. package/bizar-dash/dist/assets/{Sheet-C_sIEw35.js.map → Sheet-Cmu_4Zea.js.map} +1 -1
  757. package/bizar-dash/dist/assets/Slider-B_jPr-SR.js +1 -0
  758. package/bizar-dash/dist/assets/Slider-B_jPr-SR.js.map +1 -0
  759. package/bizar-dash/dist/assets/{Sparkline-D664vGWW.js → Sparkline-Cmqw0N39.js} +1 -1
  760. package/bizar-dash/dist/assets/{Sparkline-D664vGWW.js.map → Sparkline-Cmqw0N39.js.map} +1 -1
  761. package/bizar-dash/dist/assets/Switch-C7Qyu50Y.js +10 -0
  762. package/bizar-dash/dist/assets/Switch-C7Qyu50Y.js.map +1 -0
  763. package/bizar-dash/dist/assets/TasksView-BXADmjgb.js +1 -0
  764. package/bizar-dash/dist/assets/TasksView-BXADmjgb.js.map +1 -0
  765. package/bizar-dash/dist/assets/{Textarea-Dk97nmjO.js → Textarea-KIN98DVH.js} +1 -1
  766. package/bizar-dash/dist/assets/{Textarea-Dk97nmjO.js.map → Textarea-KIN98DVH.js.map} +1 -1
  767. package/bizar-dash/dist/assets/{ViewHeader-dPd4zAyj.js → ViewHeader-CPbqI-w8.js} +1 -1
  768. package/bizar-dash/dist/assets/{ViewHeader-dPd4zAyj.js.map → ViewHeader-CPbqI-w8.js.map} +1 -1
  769. package/bizar-dash/dist/assets/{brain-BajPVibR.js → brain-jN_ldx3U.js} +1 -1
  770. package/bizar-dash/dist/assets/{brain-BajPVibR.js.map → brain-jN_ldx3U.js.map} +1 -1
  771. package/bizar-dash/dist/assets/{calendar-CaP_Bbgc.js → calendar-DZGgPP2_.js} +1 -1
  772. package/bizar-dash/dist/assets/{calendar-CaP_Bbgc.js.map → calendar-DZGgPP2_.js.map} +1 -1
  773. package/bizar-dash/dist/assets/circle-check-XhUtiACZ.js +6 -0
  774. package/bizar-dash/dist/assets/circle-check-XhUtiACZ.js.map +1 -0
  775. package/bizar-dash/dist/assets/clock-BXBnSbox.js +6 -0
  776. package/bizar-dash/dist/assets/clock-BXBnSbox.js.map +1 -0
  777. package/bizar-dash/dist/assets/{cmdk-BLWIhKrV.js → cmdk-D15rXxc5.js} +2 -2
  778. package/bizar-dash/dist/assets/{cmdk-BLWIhKrV.js.map → cmdk-D15rXxc5.js.map} +1 -1
  779. package/bizar-dash/dist/assets/{dnd-kit-DU8GZk7s.js → dnd-kit-Bormfg7j.js} +1 -1
  780. package/bizar-dash/dist/assets/{dnd-kit-DU8GZk7s.js.map → dnd-kit-Bormfg7j.js.map} +1 -1
  781. package/bizar-dash/dist/assets/{git-pull-request-CFRRwdxp.js → git-pull-request-BCt0CEjc.js} +1 -1
  782. package/bizar-dash/dist/assets/{git-pull-request-CFRRwdxp.js.map → git-pull-request-BCt0CEjc.js.map} +1 -1
  783. package/bizar-dash/dist/assets/index-C0JBGB5M.js +1 -0
  784. package/bizar-dash/dist/assets/index-C0JBGB5M.js.map +1 -0
  785. package/bizar-dash/dist/assets/index-CrWI7sQR.js +1 -0
  786. package/bizar-dash/dist/assets/index-CrWI7sQR.js.map +1 -0
  787. package/bizar-dash/dist/assets/main-CCimEcWH.js +134 -0
  788. package/bizar-dash/dist/assets/main-CCimEcWH.js.map +1 -0
  789. package/bizar-dash/dist/assets/play-B0rTjpSg.js +6 -0
  790. package/bizar-dash/dist/assets/play-B0rTjpSg.js.map +1 -0
  791. package/bizar-dash/dist/assets/{plus-CVH1JB04.js → plus-BaTQsS9G.js} +1 -1
  792. package/bizar-dash/dist/assets/{plus-CVH1JB04.js.map → plus-BaTQsS9G.js.map} +1 -1
  793. package/bizar-dash/dist/assets/refresh-cw-CoatVcs3.js +6 -0
  794. package/bizar-dash/dist/assets/refresh-cw-CoatVcs3.js.map +1 -0
  795. package/bizar-dash/dist/assets/{terminal-B2sSd5t7.js → terminal-k-1HFHcN.js} +1 -1
  796. package/bizar-dash/dist/assets/{terminal-B2sSd5t7.js.map → terminal-k-1HFHcN.js.map} +1 -1
  797. package/bizar-dash/dist/assets/{trash-2-JtYRQ79q.js → trash-2-DtpKnAn2.js} +1 -1
  798. package/bizar-dash/dist/assets/{trash-2-JtYRQ79q.js.map → trash-2-DtpKnAn2.js.map} +1 -1
  799. package/bizar-dash/dist/assets/{triangle-alert-Nzbrm0I2.js → triangle-alert-FHSs_e5b.js} +1 -1
  800. package/bizar-dash/dist/assets/{triangle-alert-Nzbrm0I2.js.map → triangle-alert-FHSs_e5b.js.map} +1 -1
  801. package/bizar-dash/dist/assets/{wrench-B7go551L.js → wrench-CbBE0oQ0.js} +2 -2
  802. package/bizar-dash/dist/assets/{wrench-B7go551L.js.map → wrench-CbBE0oQ0.js.map} +1 -1
  803. package/bizar-dash/dist/v8.html +2 -2
  804. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  805. package/bizar-dash/src/server/api.mjs +5 -0
  806. package/bizar-dash/src/server/progress-parser.mjs +20 -4
  807. package/bizar-dash/src/server/routes/goals.mjs +10 -10
  808. package/bizar-dash/src/server/routes/spawn.mjs +59 -0
  809. package/bizar-dash/src/server/server.mjs +1 -1
  810. package/bizar-dash/src/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  811. package/bizar-dash/src/web/v8/App.tsx +56 -7
  812. package/bizar-dash/src/web/v8/__tests__/BackgroundJobsView.test.tsx +172 -0
  813. package/bizar-dash/src/web/v8/__tests__/MemoryView.test.tsx +91 -0
  814. package/bizar-dash/src/web/v8/__tests__/NotificationsPopover.test.tsx +91 -0
  815. package/bizar-dash/src/web/v8/__tests__/SchedulesView.test.tsx +157 -0
  816. package/bizar-dash/src/web/v8/__tests__/Topbar.test.tsx +86 -0
  817. package/bizar-dash/src/web/v8/__tests__/changelog.test.tsx +79 -0
  818. package/bizar-dash/src/web/v8/__tests__/theme.test.tsx +10 -4
  819. package/bizar-dash/src/web/v8/__tests__/views.test.tsx +6 -0
  820. package/bizar-dash/src/web/v8/data/types.ts +2 -0
  821. package/bizar-dash/src/web/v8/data/useWebSocket.ts +9 -1
  822. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +46 -12
  823. package/bizar-dash/src/web/v8/shell/Topbar.tsx +30 -4
  824. package/bizar-dash/src/web/v8/ui/agents/AgentDetail.tsx +34 -3
  825. package/bizar-dash/src/web/v8/ui/agents/AgentStreamPanel.tsx +1 -1
  826. package/bizar-dash/src/web/v8/ui/feedback/NotificationsPopover.tsx +239 -0
  827. package/bizar-dash/src/web/v8/ui/goals/GoalDetail.tsx +7 -1
  828. package/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +393 -32
  829. package/bizar-dash/src/web/v8/views/BackgroundJobs/BackgroundJobsView.tsx +442 -0
  830. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +22 -7
  831. package/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +1 -1
  832. package/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +174 -20
  833. package/bizar-dash/src/web/v8/views/Router.tsx +10 -0
  834. package/bizar-dash/src/web/v8/views/Schedules/SchedulesView.tsx +395 -0
  835. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +21 -5
  836. package/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +9 -7
  837. package/bizar-dash/tests/goals-decompose.test.mjs +5 -3
  838. package/package.json +1 -1
  839. package/packages/sdk/.harness/agents.json +17 -0
  840. package/packages/sdk/.harness/topology.json +4 -0
  841. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js +0 -6
  842. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js.map +0 -1
  843. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js +0 -1
  844. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js.map +0 -1
  845. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js +0 -28
  846. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js.map +0 -1
  847. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js +0 -1
  848. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js.map +0 -1
  849. package/bizar-dash/dist/assets/Button-RmN1RKhE.js +0 -6
  850. package/bizar-dash/dist/assets/Button-RmN1RKhE.js.map +0 -1
  851. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js +0 -6
  852. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js.map +0 -1
  853. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js +0 -13
  854. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js.map +0 -1
  855. package/bizar-dash/dist/assets/OverviewView-BDegBWgg.js +0 -1
  856. package/bizar-dash/dist/assets/Select-xwxbK8Ed.js.map +0 -1
  857. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js +0 -10
  858. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js.map +0 -1
  859. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js +0 -43
  860. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js.map +0 -1
  861. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js +0 -16
  862. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js.map +0 -1
  863. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js +0 -1
  864. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js.map +0 -1
  865. package/bizar-dash/dist/assets/index-AL3OLUfz.js +0 -1
  866. package/bizar-dash/dist/assets/index-AL3OLUfz.js.map +0 -1
  867. package/bizar-dash/dist/assets/main-LxX9zTRk.js +0 -109
  868. package/bizar-dash/dist/assets/main-LxX9zTRk.js.map +0 -1
  869. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js +0 -1
  870. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js.map +0 -1
  871. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js +0 -1
  872. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js.map +0 -1
@@ -0,0 +1,1093 @@
1
+ /**
2
+ * src/server/memory-store.mjs
3
+ *
4
+ * MarkdownMemoryStore — reads/writes Obsidian-compatible `.md` notes with YAML
5
+ * frontmatter for the Bizar Memory Service. Supports three modes:
6
+ * local-only — vault at <projectRoot>/.obsidian/
7
+ * managed — vault at ~/.bizar_memory/<repoName>/projects/<projectId>/
8
+ * linked — alias for managed
9
+ *
10
+ * The project namespace directory is created LAZY on first writeNote, not at
11
+ * initVault time (F7 invariant).
12
+ *
13
+ * v5.x — Default vault root relocated from `~/.local/share/bizar/memory` to
14
+ * `~/.bizar_memory` per issue #5. The old path still works if `BIZAR_MEMORY_VAULT`
15
+ * is set; on first run, `ensureVaultExists()` emits a one-time notice when the
16
+ * old path exists and the new one doesn't, but does NOT auto-migrate (too
17
+ * risky to move user data without consent).
18
+ */
19
+
20
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, lstatSync, unlinkSync } from 'node:fs';
21
+ import { execFileSync as _execFileSync } from 'node:child_process';
22
+ import { join, dirname, relative, resolve as pathResolve, sep } from 'node:path';
23
+ import { homedir } from 'node:os';
24
+ import { parseFrontmatter, serializeFrontmatter } from './yaml.mjs';
25
+ import { validateNote } from './memory-schema.mjs';
26
+ import { scan as scanSecrets, hasHighFindings } from './memory-secrets.mjs';
27
+ import { atomicWriteJson, safeReadJSON, safeReadText } from '../../../cli/atomic.mjs';
28
+ import * as memoryGit from './memory-git.mjs';
29
+ import { warn as loggerWarn } from './logger.mjs';
30
+
31
+ /**
32
+ * Resolve the `git` binary path once at module load time.
33
+ *
34
+ * When the dashboard runs under systemd, PATH typically does not include
35
+ * /usr/bin — this helper finds git's absolute path so that all
36
+ * execFileSync calls work regardless of the process's environment.
37
+ *
38
+ * @returns {string} absolute path to git, or 'git' as a best-effort fallback
39
+ */
40
+ function resolveGitBinary() {
41
+ try {
42
+ const out = _execFileSync('which', ['git'], {
43
+ encoding: 'utf8',
44
+ stdio: ['pipe', 'pipe', 'pipe'],
45
+ }).trim();
46
+ if (out) return out;
47
+ } catch { /* which not available or failed */ }
48
+
49
+ const fallbacks = ['/usr/bin/git', '/usr/local/bin/git', '/opt/homebrew/bin/git', '/opt/git/bin/git'];
50
+ for (const f of fallbacks) {
51
+ try {
52
+ _execFileSync(f, ['--version'], { stdio: ['pipe', 'pipe', 'pipe'] });
53
+ return f;
54
+ } catch { /* keep looking */ }
55
+ }
56
+
57
+ return 'git';
58
+ }
59
+
60
+ /** Cached absolute path to the git binary. */
61
+ const GIT_BIN = resolveGitBinary();
62
+
63
+ /** Wrapper that always uses the resolved GIT_BIN path. */
64
+ function execFileSync(args, opts) {
65
+ return _execFileSync(GIT_BIN, args, opts);
66
+ }
67
+
68
+ const HOME = homedir();
69
+
70
+ /**
71
+ * Default vault root — auto-created on first use.
72
+ * Override with BIZAR_MEMORY_VAULT env var.
73
+ *
74
+ * v5.x — moved from `~/.local/share/bizar/memory` to `~/.bizar_memory` so the
75
+ * vault lives at a memorable, top-level location in the user's home.
76
+ */
77
+ export const DEFAULT_MEMORY_VAULT = join(HOME, '.bizar_memory');
78
+
79
+ /**
80
+ * v5.x — Legacy vault path kept for migration detection only. The old
81
+ * `~/.local/share/bizar/memory` location is no longer the default; if a
82
+ * user still has notes there, `ensureVaultExists()` logs a one-time
83
+ * notice pointing them at the migration command.
84
+ */
85
+ export const LEGACY_MEMORY_VAULT = join(HOME, '.local', 'share', 'bizar', 'memory');
86
+
87
+ /**
88
+ * Default git remote — set via BIZAR_MEMORY_GIT_REMOTE to enable sync.
89
+ */
90
+ export const DEFAULT_GIT_REMOTE = process.env.BIZAR_MEMORY_GIT_REMOTE || null;
91
+
92
+ const BIZAR_MEMORY_ROOT = join(HOME, '.bizar_memory');
93
+
94
+ /**
95
+ * Return the effective vault root for the default memory vault.
96
+ * Override with BIZAR_MEMORY_VAULT env var.
97
+ *
98
+ * @returns {string}
99
+ */
100
+ export function currentVault() {
101
+ return process.env.BIZAR_MEMORY_VAULT || DEFAULT_MEMORY_VAULT;
102
+ }
103
+
104
+ /**
105
+ * Ensure the default memory vault directory exists and is git-initialised.
106
+ * Idempotent — calling multiple times is safe.
107
+ *
108
+ * v5.x — On first call with a fresh default vault, if the legacy
109
+ * `~/.local/share/bizar/memory` path exists and the new
110
+ * `~/.bizar_memory` doesn't, log a one-time migration notice. We do
111
+ * NOT auto-migrate: the user owns the data and may have already moved
112
+ * it, or may want to keep the old path via `BIZAR_MEMORY_VAULT`.
113
+ *
114
+ * @returns {string} the vault path that was ensured
115
+ */
116
+ export function ensureVaultExists() {
117
+ const vault = currentVault();
118
+ if (!existsSync(vault)) {
119
+ // v5.x — Migration notice: legacy path exists, new default does not.
120
+ // Only emit when the user is using the default (no env override) and
121
+ // the new path doesn't exist yet.
122
+ if (
123
+ !process.env.BIZAR_MEMORY_VAULT &&
124
+ vault === DEFAULT_MEMORY_VAULT &&
125
+ existsSync(LEGACY_MEMORY_VAULT)
126
+ ) {
127
+ console.warn(
128
+ `[memory-store] Detected a legacy memory vault at ${LEGACY_MEMORY_VAULT}.\n` +
129
+ `[memory-store] The default location has moved to ${DEFAULT_MEMORY_VAULT}.\n` +
130
+ `[memory-store] To keep using the old vault, set BIZAR_MEMORY_VAULT=${LEGACY_MEMORY_VAULT}.\n` +
131
+ `[memory-store] To migrate, move the contents manually: ` +
132
+ `mv ${LEGACY_MEMORY_VAULT}/* ${DEFAULT_MEMORY_VAULT}/\n` +
133
+ `[memory-store] (not auto-migrated — please review before moving user data).`,
134
+ );
135
+ }
136
+ mkdirSync(vault, { recursive: true, mode: 0o700 });
137
+ if (!existsSync(join(vault, '.git'))) {
138
+ try {
139
+ execFileSync(['init'], { cwd: vault, stdio: 'pipe' });
140
+ execFileSync(['config', 'user.email', 'bizar@localhost'], { cwd: vault, stdio: 'pipe' });
141
+ execFileSync(['config', 'user.name', 'BizarHarness'], { cwd: vault, stdio: 'pipe' });
142
+ } catch (err) {
143
+ loggerWarn('failed to init git in vault', { vault, err: err.message });
144
+ }
145
+ }
146
+ }
147
+ return vault;
148
+ }
149
+
150
+ /**
151
+ * Path safety: reject any relPath that would escape the vault root.
152
+ *
153
+ * Defenses (in order):
154
+ * 1. Empty / null-byte injection → reject.
155
+ * 2. Explicit segment check for `..` and absolute path prefixes → reject
156
+ * before path.resolve normalizes them away. The check is on SEGMENTS
157
+ * (`..` separated by `/` or `\`), so filenames like `my..note.md` are
158
+ * still allowed.
159
+ * 3. Post-resolve check: the resulting absolute path must be inside
160
+ * vaultRoot (relative path must not start with `..`).
161
+ * 4. Symlink guard: if the resolved path is a pre-existing symlink, refuse.
162
+ * This blocks an attacker who placed a symlink inside the vault pointing
163
+ * outside from writing/reading through it.
164
+ *
165
+ * Known limitation: the symlink guard is not TOCTOU-safe. A swap between
166
+ * lstatSync and the subsequent read/write/delete is still possible. For a
167
+ * full TOCTOU fix the read/write/delete would need to use O_NOFOLLOW and
168
+ * operate on an open fd, not a path. This is acceptable for the current
169
+ * threat model (the vault is a per-user directory, not a multi-tenant FS).
170
+ *
171
+ * @param {string} vaultRoot
172
+ * @param {string} relPath
173
+ * @returns {string | null} — resolved absolute path, or null if unsafe
174
+ */
175
+ function resolveSafe(vaultRoot, relPath) {
176
+ if (!relPath || relPath.includes('\0')) return null;
177
+ // Segment-level check: reject any `..` segment or absolute-path prefix
178
+ // BEFORE path.resolve normalizes them away. This explicitly rejects
179
+ // paths like `notes/../escape.md`, while still allowing filenames like
180
+ // `my..note.md` (the substring `..` inside a single segment is fine).
181
+ const segments = relPath.split(/[\\/]+/);
182
+ if (segments.includes('..') || segments[0] === '') return null;
183
+ const abs = pathResolve(vaultRoot, relPath);
184
+ const rel = relative(vaultRoot, abs);
185
+ if (rel.startsWith('..') || abs !== pathResolve(abs)) return null;
186
+ // Symlink guard (see note above re: TOCTOU). Note: existsSync follows
187
+ // symlinks, so we MUST use lstatSync directly — existsSync + isSymbolicLink
188
+ // misses dangling symlinks (target doesn't exist). lstatSync returns a
189
+ // Stats object even for dangling symlinks; catch only unexpected errors
190
+ // (e.g. EACCES on the parent directory).
191
+ try {
192
+ if (lstatSync(abs).isSymbolicLink()) return null;
193
+ } catch {
194
+ // Path doesn't exist or parent dir inaccessible — not a symlink,
195
+ // proceed. (A fresh write won't traverse a symlink because the
196
+ // symlink itself doesn't exist yet at write time.)
197
+ }
198
+ return abs;
199
+ }
200
+
201
+ /**
202
+ * Read the per-project memory config file (.bizar/memory.json).
203
+ *
204
+ * @param {string} projectRoot
205
+ * @returns {{ exists: boolean, config: Record<string, unknown>, error?: string }}
206
+ */
207
+ export function loadConfig(projectRoot) {
208
+ const configPath = join(projectRoot, '.bizar', 'memory.json');
209
+ const raw = safeReadJSON(configPath, null);
210
+ if (raw === null) {
211
+ return {
212
+ exists: false,
213
+ config: {
214
+ mode: 'local-only',
215
+ projectId: projectRoot.split('/').pop() || 'unknown',
216
+ repoName: '',
217
+ },
218
+ };
219
+ }
220
+ return { exists: true, config: raw };
221
+ }
222
+
223
+ /**
224
+ * Write the per-project memory config file.
225
+ *
226
+ * @param {string} projectRoot
227
+ * @param {Record<string, unknown>} config
228
+ * @returns {{ ok: boolean, error?: string }}
229
+ */
230
+ export function saveConfig(projectRoot, config) {
231
+ try {
232
+ const configDir = join(projectRoot, '.bizar');
233
+ if (!existsSync(configDir)) {
234
+ mkdirSync(configDir, { recursive: true });
235
+ }
236
+ const configPath = join(configDir, 'memory.json');
237
+ atomicWriteJson(configPath, config);
238
+ return { ok: true };
239
+ } catch (err) {
240
+ return { ok: false, error: err.message };
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Resolve the effective vault root, namespaces, and related paths based on mode.
246
+ *
247
+ * v6.x — `vaultRoot` is now always the GENERAL vault root (e.g. `~/.bizar_memory`).
248
+ * A new `projectVaultRoot` field carries the project-specific subdirectory for
249
+ * note storage in managed/linked mode (`~/.bizar_memory/projects/<projectId>`).
250
+ * This distinction lets the UI display the general root while the store still
251
+ * writes notes to the correct project subdirectory.
252
+ *
253
+ * @param {string} projectRoot
254
+ * @returns {{ mode: string, projectId: string, vaultRoot: string, projectVaultRoot: string, repoPath: string | null, configDir: string, gitRemote: string | null, branch: string, lightragDir: string, namespaces: object }}
255
+ */
256
+ export function resolveVault(projectRoot) {
257
+ const { config } = loadConfig(projectRoot);
258
+ const mr = config.memoryRepo || {};
259
+ const mode = mr.mode || config.mode || 'local-only';
260
+ const projectId = config.projectId || projectRoot.split('/').pop() || 'unknown';
261
+ const branch = mr.branch || config.branch || 'main';
262
+ const gitRemote = mr.remote || config.gitRemote || null;
263
+
264
+ let vaultRoot;
265
+ let projectVaultRoot;
266
+ let repoPath;
267
+ if (mode === 'local-only') {
268
+ vaultRoot = join(projectRoot, '.obsidian');
269
+ projectVaultRoot = vaultRoot;
270
+ repoPath = null;
271
+ } else {
272
+ // managed or linked — path may be absolute, ~-relative, or a sibling of projectRoot
273
+ const rawPath = mr.path || config.repoName || join(projectRoot, '.bizar', 'memory');
274
+ const expanded = rawPath.startsWith('~') ? join(HOME, rawPath.slice(1)) : rawPath;
275
+ repoPath = expanded;
276
+ vaultRoot = expanded; // v6.x — general root, e.g. ~/.bizar_memory
277
+ projectVaultRoot = join(expanded, 'projects', projectId); // project-specific subdirectory
278
+ }
279
+
280
+ const configDir = join(projectRoot, '.bizar');
281
+ const lightragDir = join(projectRoot, '.bizar', 'memory-cache');
282
+ const namespaces = config.namespaces || {
283
+ project: `projects/${projectId}`,
284
+ global: 'global/bizar',
285
+ user: `users/${process.env.USER || process.env.USERNAME || 'local'}`,
286
+ };
287
+
288
+ return { mode, projectId, vaultRoot, projectVaultRoot, repoPath, configDir, gitRemote, branch, lightragDir, namespaces };
289
+ }
290
+
291
+ /**
292
+ * Resolve the absolute path of a namespace root.
293
+ *
294
+ * For `project`, returns projectVaultRoot (the directory where project notes
295
+ * are stored: `<vaultRoot>/projects/<projectId>` in managed mode, or
296
+ * `<projectRoot>/.obsidian` in local-only mode). For `global` and `user`,
297
+ * returns `<vaultRoot>/<namespaces.X>` — these namespaces live at the vault
298
+ * root level, not inside the project subdirectory.
299
+ *
300
+ * Routing: writeNote/readNote/deleteNote use this to determine where files
301
+ * live. Project relPaths go to projectVaultRoot; global/ and users/ relPaths
302
+ * go to vaultRoot-based paths.
303
+ *
304
+ * @param {{ mode: string, vaultRoot: string, projectVaultRoot: string, namespaces: object }} vaultInfo
305
+ * @param {'project'|'global'|'user'} namespace
306
+ * @returns {string|null} absolute path, or null if the namespace is unknown
307
+ */
308
+ export function resolveNamespaceRoot(vaultInfo, namespace) {
309
+ if (namespace === 'project') return vaultInfo.projectVaultRoot;
310
+ const ns = vaultInfo.namespaces?.[namespace];
311
+ if (!ns) return null;
312
+ return join(vaultInfo.vaultRoot, ns);
313
+ }
314
+
315
+ /**
316
+ * Initialize the vault for a project. In local-only mode, creates .obsidian/
317
+ * and standard subdirectories. In managed mode, the shared repo is assumed to
318
+ * already exist; this function only ensures the .bizar/memory.json is set up.
319
+ *
320
+ * NOTE: The project namespace directory (projects/<id>/) is NOT created here.
321
+ * It is created lazily on first writeNote (F7 invariant).
322
+ *
323
+ * @param {string} projectRoot
324
+ * @returns {{ ok: boolean, vaultRoot: string, created: string[], error?: string }}
325
+ */
326
+ export function initVault(projectRoot) {
327
+ const { config } = loadConfig(projectRoot);
328
+ const mr = config.memoryRepo || {};
329
+ const mode = mr.mode || config.mode || 'local-only';
330
+ const created = [];
331
+
332
+ if (mode === 'local-only') {
333
+ const vaultRoot = join(projectRoot, '.obsidian');
334
+ const subdirs = ['daily', 'decisions', 'patterns', 'api', 'tasks', 'global', 'users'];
335
+ if (!existsSync(vaultRoot)) {
336
+ mkdirSync(vaultRoot, { recursive: true });
337
+ created.push('.obsidian/');
338
+ }
339
+ for (const sub of subdirs) {
340
+ const subPath = join(vaultRoot, sub);
341
+ if (!existsSync(subPath)) {
342
+ mkdirSync(subPath, { recursive: true });
343
+ created.push(`.obsidian/${sub}/`);
344
+ }
345
+ }
346
+ return { ok: true, vaultRoot, created };
347
+ } else {
348
+ // managed / linked — create the shared repo at repoPath with `git init`
349
+ const { repoPath, vaultRoot } = resolveVault(projectRoot);
350
+ if (!existsSync(repoPath)) {
351
+ mkdirSync(repoPath, { recursive: true });
352
+ created.push(repoPath);
353
+ }
354
+ // git init if not already a git repo
355
+ const isGit = existsSync(join(repoPath, '.git'));
356
+ if (!isGit) {
357
+ try {
358
+ execFileSync(['init', '-b', 'main'], { cwd: repoPath, stdio: 'pipe' });
359
+ created.push(`${repoPath}/.git/`);
360
+ } catch (err) {
361
+ return { ok: false, vaultRoot, created, error: `git init failed: ${err.message}` };
362
+ }
363
+ // Write and commit a .gitignore for runtime artifacts
364
+ const gitignorePath = join(repoPath, '.gitignore');
365
+ if (!existsSync(gitignorePath)) {
366
+ writeFileSync(gitignorePath,
367
+ '# Lock files — runtime state, not memory\n' +
368
+ '**/.sync.lock\n' +
369
+ '**/*.pid\n' +
370
+ '**/*.log\n' +
371
+ '**/.DS_Store\n' +
372
+ '\n' +
373
+ '# Local-only metadata\n' +
374
+ '**/.bizar-memory/cache/\n' +
375
+ '**/.bizar-memory/index-ledger.local.json\n',
376
+ 'utf8');
377
+ created.push(`${repoPath}/.gitignore`);
378
+ try {
379
+ execFileSync(['add', '.gitignore'], { cwd: repoPath });
380
+ execFileSync(['commit', '-m', 'chore: initial .gitignore for memory repo'], {
381
+ cwd: repoPath,
382
+ env: {
383
+ ...process.env,
384
+ GIT_AUTHOR_NAME: 'Bizar Memory',
385
+ GIT_AUTHOR_EMAIL: 'bizar-memory@local',
386
+ GIT_COMMITTER_NAME: 'Bizar Memory',
387
+ GIT_COMMITTER_EMAIL: 'bizar-memory@local',
388
+ },
389
+ });
390
+ } catch (e) {
391
+ // best-effort; not fatal
392
+ }
393
+ }
394
+ }
395
+ // Ensure projects/, global/, users/ exist so writeNote can find them without
396
+ // creating the project-specific namespace (F7 invariant — only the projects/<id>
397
+ // subdirectory is created lazily on first writeNote)
398
+ const projectsDir = join(repoPath, 'projects');
399
+ if (!existsSync(projectsDir)) {
400
+ mkdirSync(projectsDir, { recursive: true });
401
+ created.push(`${repoPath}/projects/`);
402
+ }
403
+ const globalDir = join(repoPath, 'global', 'bizar');
404
+ if (!existsSync(globalDir)) {
405
+ mkdirSync(globalDir, { recursive: true });
406
+ created.push(`${repoPath}/global/bizar/`);
407
+ }
408
+ const usersDir = join(repoPath, 'users');
409
+ if (!existsSync(usersDir)) {
410
+ mkdirSync(usersDir, { recursive: true });
411
+ created.push(`${repoPath}/users/`);
412
+ }
413
+ return { ok: true, vaultRoot, created };
414
+ }
415
+ }
416
+
417
+ /**
418
+ * List all notes in the vault. Returns enriched note metadata.
419
+ *
420
+ * @param {string} projectRoot
421
+ * @param {{ namespace?: string, root?: string }} [opts]
422
+ * `namespace`: subdirectory under `root` to walk (e.g. `projects/<id>`).
423
+ * `root`: override the root used as the walking base. Defaults to
424
+ * `vaultRoot` from resolveVault. Used by namespace helpers
425
+ * in cli/memory.mjs to list global / user notes.
426
+ * @returns {Array<{ relPath: string, mtime: number, size: number, frontmatter: Record<string, unknown>, body: string, schemaValid: boolean }>}
427
+ */
428
+ export function listNotes(projectRoot, opts = {}) {
429
+ const { projectVaultRoot } = resolveVault(projectRoot);
430
+ const root = opts.root || projectVaultRoot;
431
+ if (!existsSync(root)) return [];
432
+
433
+ const namespace = opts.namespace || '';
434
+ const searchRoot = namespace ? join(root, namespace) : root;
435
+ if (!existsSync(searchRoot)) return [];
436
+
437
+ const out = [];
438
+ function walk(dir, prefix) {
439
+ let entries;
440
+ try { entries = readdirSync(dir, { withFileTypes: true }); }
441
+ catch { return; }
442
+ for (const e of entries) {
443
+ const full = join(dir, e.name);
444
+ const rel = prefix ? `${prefix}/${e.name}` : e.name;
445
+ if (e.isDirectory()) {
446
+ if (e.name === 'node_modules' || e.name.startsWith('.')) continue;
447
+ walk(full, rel);
448
+ } else if (e.name.endsWith('.md')) {
449
+ try {
450
+ const st = statSync(full);
451
+ const raw = readFileSync(full, 'utf8');
452
+ const { frontmatter, body } = parseFrontmatter(raw);
453
+ const { valid } = validateNote(frontmatter, body);
454
+ out.push({ relPath: rel, mtime: st.mtimeMs, size: st.size, frontmatter, body, schemaValid: valid });
455
+ } catch { /* skip unreadable */ }
456
+ }
457
+ }
458
+ }
459
+ walk(searchRoot, '');
460
+ return out.sort((a, b) => b.mtime - a.mtime);
461
+ }
462
+
463
+ /**
464
+ * Read a single note by relative path. Returns null if not found.
465
+ *
466
+ * @param {string} projectRoot
467
+ * @param {string} relPath
468
+ * @param {{ root?: string }} [opts] optional override for the root used by
469
+ * resolveSafe; defaults to vaultRoot
470
+ * @returns {{ relPath: string, frontmatter: Record<string, unknown>, body: string, raw: string, mtime: number, size: number, schemaValid: boolean } | null}
471
+ */
472
+ export function readNote(projectRoot, relPath, opts = {}) {
473
+ const { vaultRoot, projectVaultRoot } = resolveVault(projectRoot);
474
+ // When opts.root is explicitly provided, use it. Otherwise route based on
475
+ // namespace so reads find notes where writeNote placed them.
476
+ let root;
477
+ if (opts.root) {
478
+ root = opts.root;
479
+ } else {
480
+ const isProjectNamespace = !relPath.startsWith('global/') && !relPath.startsWith('users/');
481
+ root = isProjectNamespace ? projectVaultRoot : vaultRoot;
482
+ }
483
+ const filePath = resolveSafe(root, relPath);
484
+ if (!filePath || !existsSync(filePath)) return null;
485
+ try {
486
+ const raw = readFileSync(filePath, 'utf8');
487
+ const st = statSync(filePath);
488
+ const { frontmatter, body } = parseFrontmatter(raw);
489
+ const { valid } = validateNote(frontmatter, body);
490
+ return { relPath, frontmatter, body, raw, mtime: st.mtimeMs, size: st.size, schemaValid: valid };
491
+ } catch {
492
+ return null;
493
+ }
494
+ }
495
+
496
+ /**
497
+ * Write a note. Validates frontmatter, scans for secrets, writes the file.
498
+ *
499
+ * @param {string} projectRoot
500
+ * @param {string} relPath
501
+ * @param {{ frontmatter: Record<string, unknown>, body: string }} note
502
+ * @returns {{ relPath: string, frontmatter: Record<string, unknown>, body: string, raw: string, mtime: number, size: number, schemaValid: boolean }}
503
+ * @throws {Error} if schema validation fails or HIGH-severity secret found
504
+ */
505
+ export function writeNote(projectRoot, relPath, { frontmatter, body }) {
506
+ const { vaultRoot, projectVaultRoot } = resolveVault(projectRoot);
507
+
508
+ // Validate frontmatter
509
+ const { valid, errors, warnings } = validateNote(frontmatter, body);
510
+ if (!valid) {
511
+ const err = new Error(`schema validation failed: ${errors.join('; ')}`);
512
+ err.code = 'SCHEMA_VALIDATION_FAILED';
513
+ throw err;
514
+ }
515
+
516
+ // Scan for secrets
517
+ const secretResult = scanSecrets(body);
518
+ if (hasHighFindings(secretResult)) {
519
+ const snippets = secretResult.findings
520
+ .filter((f) => f.severity === 'HIGH')
521
+ .map((f) => `line ${f.line}: ${f.snippet}`)
522
+ .join('\n');
523
+ const err = new Error(`HIGH-severity secret detected:\n${snippets}`);
524
+ err.code = 'SECRET_DETECTED';
525
+ err.findings = secretResult.findings;
526
+ throw err;
527
+ }
528
+
529
+ // Determine the effective vault root based on namespace.
530
+ // Project notes (relPaths that don't start with global/ or users/) go under
531
+ // projectVaultRoot. Global and user notes go under vaultRoot.
532
+ // This matches the layout resolveNamespaceRoot returns for each namespace.
533
+ const isProjectNamespace = !relPath.startsWith('global/') && !relPath.startsWith('users/');
534
+ const noteVaultRoot = isProjectNamespace ? projectVaultRoot : vaultRoot;
535
+
536
+ // Build file content
537
+ const filePath = resolveSafe(noteVaultRoot, relPath);
538
+ if (!filePath) {
539
+ throw new Error(`Invalid note path: ${relPath}`);
540
+ }
541
+
542
+ // Lazily create the namespace directory (not created at initVault)
543
+ const nsDir = dirname(filePath);
544
+ if (!existsSync(nsDir)) {
545
+ mkdirSync(nsDir, { recursive: true });
546
+ }
547
+
548
+ const yamlBlock = serializeFrontmatter(frontmatter);
549
+ const content = `---\n${yamlBlock}\n---\n\n${body}`;
550
+ writeFileSync(filePath, content, 'utf8');
551
+
552
+ // Auto-commit the written file to git (if configured).
553
+ // The lock serializes commits, not writes — concurrent writes will each
554
+ // trigger their own commit, which is the intended behaviour.
555
+ (() => {
556
+ try {
557
+ if (!memoryGit.isGitInstalled()) return;
558
+ const { config } = loadConfig(projectRoot);
559
+ if (config.mode === 'local-only') return;
560
+ if (config.git?.autoCommitOnMemoryWrite !== true) return;
561
+ const lockResult = memoryGit.acquireLock(vaultRoot);
562
+ if (!lockResult || lockResult.error) return; // skip if locked or error
563
+ try {
564
+ memoryGit.addFile(vaultRoot, relPath);
565
+ const summary = frontmatter.title || relPath;
566
+ const message = (config.git.commitMessageTemplate || 'memory(BizarHarness): {summary}')
567
+ .replace('{summary}', summary);
568
+ memoryGit.commit(vaultRoot, message, { author: config.git.commitAuthor });
569
+ } finally {
570
+ lockResult.release();
571
+ }
572
+ } catch (err) {
573
+ // Log but never re-throw — the write already succeeded; a failed
574
+ // auto-commit is recoverable on next write or manual commit.
575
+ console.error('[memory-store] autoCommitOnMemoryWrite failed:', err?.message || err);
576
+ }
577
+ })();
578
+
579
+ const st = statSync(filePath);
580
+ return {
581
+ relPath,
582
+ frontmatter,
583
+ body,
584
+ raw: content,
585
+ mtime: st.mtimeMs,
586
+ size: st.size,
587
+ schemaValid: true,
588
+ };
589
+ }
590
+
591
+ /**
592
+ * Delete a note by relative path.
593
+ *
594
+ * @param {string} projectRoot
595
+ * @param {string} relPath
596
+ * @param {{ root?: string }} [opts] optional override for the root used by
597
+ * resolveSafe; defaults to vaultRoot
598
+ * @returns {boolean}
599
+ */
600
+ export function deleteNote(projectRoot, relPath, opts = {}) {
601
+ const { vaultRoot, projectVaultRoot } = resolveVault(projectRoot);
602
+ // When opts.root is explicitly provided, use it. Otherwise route based on
603
+ // namespace so deletes find notes where writeNote placed them.
604
+ let root;
605
+ if (opts.root) {
606
+ root = opts.root;
607
+ } else {
608
+ const isProjectNamespace = !relPath.startsWith('global/') && !relPath.startsWith('users/');
609
+ root = isProjectNamespace ? projectVaultRoot : vaultRoot;
610
+ }
611
+ const filePath = resolveSafe(root, relPath);
612
+ if (!filePath || !existsSync(filePath)) return false;
613
+ unlinkSync(filePath);
614
+ return true;
615
+ }
616
+
617
+ /**
618
+ * Full-text search across vault notes.
619
+ *
620
+ * @param {string} projectRoot
621
+ * @param {string} query
622
+ * @param {{ limit?: number }} [opts]
623
+ * @returns {Array<{ relPath: string, snippet: string, score: number, mtime: number }>}
624
+ */
625
+ export function searchVault(projectRoot, query, { limit = 25 } = {}) {
626
+ if (!query || typeof query !== 'string') return [];
627
+ const q = query.toLowerCase();
628
+ const tokens = q.split(/\s+/).filter((t) => t.length >= 2);
629
+ if (tokens.length === 0) return [];
630
+
631
+ const { vaultRoot, projectVaultRoot } = resolveVault(projectRoot);
632
+
633
+ // Collect notes from all namespaces by walking vaultRoot (which contains
634
+ // projects/<id>/, global/, and users/ as siblings). This finds project,
635
+ // global, and user notes in a single scan. relPaths returned are vaultRoot-
636
+ // relative (e.g. "projects/<id>/decisions/foo.md" or "global/bizar/foo.md").
637
+ // For project notes, strip the "projects/<id>/" prefix so the relPath matches
638
+ // what writeNote uses (projectVaultRoot-relative).
639
+ const projectPrefix = join('projects', projectVaultRoot.split('/').pop());
640
+ const allNotes = listNotes(projectRoot, { root: vaultRoot });
641
+
642
+ const results = [];
643
+ for (const note of allNotes) {
644
+ let relPath = note.relPath;
645
+ if (relPath.startsWith(projectPrefix)) {
646
+ relPath = relPath.slice(projectPrefix.length + 1);
647
+ }
648
+ const lower = (note.body + ' ' + JSON.stringify(note.frontmatter)).toLowerCase();
649
+ let score = 0;
650
+ for (const t of tokens) {
651
+ if (lower.includes(t)) score += (lower.split(t).length - 1);
652
+ }
653
+ if (score === 0) continue;
654
+ const idx = lower.indexOf(tokens[0]);
655
+ const start = Math.max(0, idx - 60);
656
+ const end = Math.min(lower.length, idx + 160);
657
+ const snippet = (start > 0 ? '…' : '') + lower.slice(start, end).replace(/\s+/g, ' ').trim();
658
+ results.push({ relPath, snippet, score, mtime: note.mtime });
659
+ }
660
+
661
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
662
+ }
663
+
664
+ /**
665
+ * Scan a single note for secrets.
666
+ *
667
+ * @param {string} projectRoot
668
+ * @param {string} relPath
669
+ * @returns {{ safe: boolean, findings: Array<{ id: string, severity: string, line: number, snippet: string }> }}
670
+ */
671
+ export function scanForSecrets(projectRoot, relPath) {
672
+ const note = readNote(projectRoot, relPath);
673
+ if (!note) return { safe: true, findings: [] };
674
+ return scanSecrets(note.body);
675
+ }
676
+
677
+ /**
678
+ * Validate all notes in the vault against the schema.
679
+ *
680
+ * @param {string} projectRoot
681
+ * @returns {Array<{ relPath: string, errors: string[] }>}
682
+ */
683
+ export function validateAll(projectRoot) {
684
+ const notes = listNotes(projectRoot);
685
+ const results = [];
686
+ for (const note of notes) {
687
+ const { errors } = validateNote(note.frontmatter, note.body);
688
+ if (errors.length > 0) {
689
+ results.push({ relPath: note.relPath, errors });
690
+ }
691
+ }
692
+ return results;
693
+ }
694
+
695
+ // ── v4.7.0 — Memory tab helpers ─────────────────────────────────────────────
696
+ //
697
+ // Lightweight helpers used by the dedicated Memory view: backlinks (wikilink
698
+ // reverse index) and a vault-stats summary for the overview card.
699
+
700
+ /**
701
+ * Find every note in the vault that links TO `targetRelPath` via a wikilink.
702
+ *
703
+ * A wikilink matches one of:
704
+ * - `[[target]]`
705
+ * - `[[target|alias]]`
706
+ * - `[[target#heading]]`
707
+ * - `[[target#heading|alias]]`
708
+ *
709
+ * The match is by basename without extension (Obsidian's wikilink semantics)
710
+ * AND by full relPath-without-extension, so `[[notes/foo]]` matches
711
+ * `notes/foo.md` and `[[foo]]` matches `foo.md` anywhere in the vault.
712
+ *
713
+ * @param {string} projectRoot
714
+ * @param {string} targetRelPath — the note we want backlinks for
715
+ * @returns {Array<{ fromRelPath: string, fromTitle: string, snippet: string, mtime: number }>}
716
+ */
717
+ export function findBacklinks(projectRoot, targetRelPath) {
718
+ if (!targetRelPath) return [];
719
+ const targetBase = basenameOf(targetRelPath).replace(/\.md$/i, '');
720
+ const targetStripped = targetRelPath.replace(/\.md$/i, '');
721
+ if (!targetBase && !targetStripped) return [];
722
+
723
+ const out = [];
724
+ const WIKILINK_RE = /\[\[([^\]\n|]+?)(?:\|[^\]\n]+?)?(?:#[^\]\n]+?)?\]\]/g;
725
+
726
+ for (const note of listNotes(projectRoot)) {
727
+ if (note.relPath === targetRelPath) continue; // skip self
728
+ const body = note.body || '';
729
+ const matches = [];
730
+ let m;
731
+ WIKILINK_RE.lastIndex = 0;
732
+ while ((m = WIKILINK_RE.exec(body)) !== null) {
733
+ const raw = (m[1] || '').trim();
734
+ if (!raw) continue;
735
+ const stripped = raw.split('#')[0].trim();
736
+ if (!stripped) continue;
737
+ const baseOnly = stripped.split('/').pop() || stripped;
738
+ if (baseOnly === targetBase || stripped === targetStripped) {
739
+ matches.push({ raw, idx: m.index });
740
+ }
741
+ }
742
+ if (matches.length === 0) continue;
743
+
744
+ // Build a snippet around the FIRST match — 80 chars each side.
745
+ const first = matches[0];
746
+ const start = Math.max(0, first.idx - 80);
747
+ const end = Math.min(body.length, first.idx + first.raw.length + 80);
748
+ const snippet = (start > 0 ? '…' : '') +
749
+ body.slice(start, end).replace(/\s+/g, ' ').trim() +
750
+ (end < body.length ? '…' : '');
751
+
752
+ out.push({
753
+ fromRelPath: note.relPath,
754
+ fromTitle: note.frontmatter?.title || basenameOf(note.relPath).replace(/\.md$/i, ''),
755
+ snippet,
756
+ mtime: note.mtime,
757
+ });
758
+ }
759
+
760
+ return out.sort((a, b) => b.mtime - a.mtime);
761
+ }
762
+
763
+ /** Minimal basename helper — avoids pulling `path.basename` into the bundle. */
764
+ function basenameOf(p) {
765
+ if (!p) return '';
766
+ const idx = Math.max(p.lastIndexOf('/'), p.lastIndexOf('\\'));
767
+ return idx >= 0 ? p.slice(idx + 1) : p;
768
+ }
769
+
770
+ /**
771
+ * High-level stats used by the Memory tab and Overview status card.
772
+ *
773
+ * @param {string} projectRoot
774
+ * @returns {{ exists: boolean, vaultRoot: string, mode: string, noteCount: number, totalSize: number, folderCount: number, folders: string[], lastModified: number|null, gitClean: boolean|null, gitBranch: string|null }}
775
+ */
776
+ export function vaultStats(projectRoot) {
777
+ const { exists, config } = loadConfig(projectRoot);
778
+ if (!exists) {
779
+ return {
780
+ exists: false,
781
+ vaultRoot: '',
782
+ mode: 'local-only',
783
+ noteCount: 0,
784
+ totalSize: 0,
785
+ folderCount: 0,
786
+ folders: [],
787
+ lastModified: null,
788
+ gitClean: null,
789
+ gitBranch: null,
790
+ };
791
+ }
792
+
793
+ const { vaultRoot, projectVaultRoot, mode, branch } = resolveVault(projectRoot);
794
+ if (!projectVaultRoot || !existsSync(projectVaultRoot)) {
795
+ return {
796
+ exists: true,
797
+ vaultRoot: vaultRoot || '',
798
+ mode,
799
+ noteCount: 0,
800
+ totalSize: 0,
801
+ folderCount: 0,
802
+ folders: [],
803
+ lastModified: null,
804
+ gitClean: null,
805
+ gitBranch: branch || config?.branch || 'main',
806
+ };
807
+ }
808
+
809
+ const notes = listNotes(projectRoot);
810
+ const totalSize = notes.reduce((acc, n) => acc + (n.size || 0), 0);
811
+ const folders = new Set();
812
+ for (const n of notes) {
813
+ const seg = n.relPath.split('/');
814
+ if (seg.length > 1) folders.add(seg[0]);
815
+ }
816
+
817
+ let gitClean = null;
818
+ let gitBranch = null;
819
+ if (mode === 'managed' || mode === 'linked') {
820
+ try {
821
+ const { isGitInstalled, status: gitStatus } = memoryGit;
822
+ if (isGitInstalled()) {
823
+ const gs = gitStatus(projectVaultRoot);
824
+ gitClean = gs.clean;
825
+ gitBranch = gs.branch;
826
+ }
827
+ } catch {
828
+ // ignore — git is optional
829
+ }
830
+ }
831
+
832
+ return {
833
+ exists: true,
834
+ vaultRoot,
835
+ mode,
836
+ noteCount: notes.length,
837
+ totalSize,
838
+ folderCount: folders.size,
839
+ folders: [...folders].sort(),
840
+ lastModified: notes[0]?.mtime || null,
841
+ gitClean,
842
+ gitBranch: gitBranch || branch || config?.branch || 'main',
843
+ };
844
+ }
845
+
846
+ // ── v5.5.2 Legacy config migration ─────────────────────────────────────────
847
+ //
848
+ // When the user upgrades from pre-v5.5.2, their `.bizar/memory.json` may
849
+ // still point `git.repoPath` at the legacy path
850
+ // (`~/.local/share/bizar/memory/bizar-memory`). The new default vault root
851
+ // is `~/.bizar_memory/bizar-memory`. This helper detects the stale path and
852
+ // auto-corrects the config so all git checks work immediately after upgrade.
853
+ //
854
+ // Behaviour:
855
+ // - Only migrates if the legacy path doesn't exist but the new one does.
856
+ // - Only migrates if `git.repoPath` is explicitly set in the config.
857
+ // - Idempotent — once migrated, the new path exists and the check is a
858
+ // no-op on subsequent boots.
859
+ // - Returns { migrated: true } only on actual change; { migrated: false }
860
+ // for all other cases (already correct, not applicable, or failure).
861
+ //
862
+ // Called once at dashboard startup from server.mjs.
863
+
864
+ /**
865
+ * Detect and fix a stale `git.repoPath` pointing at the legacy vault location.
866
+ *
867
+ * @param {string} projectRoot — project root (where `.bizar/memory.json` lives)
868
+ * @returns {{ migrated: boolean, from?: string, to?: string, error?: string }}
869
+ */
870
+ export function migrateLegacyGitRepoPath(projectRoot) {
871
+ const configPath = join(projectRoot, '.bizar', 'memory.json');
872
+ let raw;
873
+ try {
874
+ raw = safeReadJSON(configPath, null);
875
+ } catch {
876
+ return { migrated: false };
877
+ }
878
+ if (!raw) return { migrated: false };
879
+
880
+ const gitBlock = raw.git || raw.memoryRepo || {};
881
+ const currentRepoPath = gitBlock.repoPath;
882
+ if (!currentRepoPath || typeof currentRepoPath !== 'string') return { migrated: false };
883
+
884
+ const expanded = currentRepoPath.startsWith('~')
885
+ ? join(HOME, currentRepoPath.slice(1))
886
+ : currentRepoPath;
887
+
888
+ // Only migrate when the configured path doesn't exist but the new default does.
889
+ if (existsSync(expanded)) return { migrated: false };
890
+
891
+ const newDefault = join(DEFAULT_MEMORY_VAULT, 'bizar-memory');
892
+ if (!existsSync(newDefault)) return { migrated: false };
893
+
894
+ // Verify the new path is actually a git repo before migrating.
895
+ if (!existsSync(join(newDefault, '.git'))) return { migrated: false };
896
+
897
+ // Apply the fix: update gitBlock.repoPath (or memoryRepo.repoPath) to newDefault.
898
+ try {
899
+ const updated = JSON.parse(JSON.stringify(raw));
900
+ if (!updated.git) updated.git = {};
901
+ if (!updated.memoryRepo) updated.memoryRepo = {};
902
+ updated.git.repoPath = newDefault;
903
+ updated.memoryRepo.path = newDefault;
904
+ atomicWriteJson(configPath, updated);
905
+ console.warn(
906
+ `[memory-store] Auto-migrated git.repoPath from legacy path\n` +
907
+ `[memory-store] FROM: ${expanded}\n` +
908
+ `[memory-store] TO: ${newDefault}\n` +
909
+ `[memory-store] Please restart the dashboard to pick up the new path.`,
910
+ );
911
+ return { migrated: true, from: expanded, to: newDefault };
912
+ } catch (err) {
913
+ return { migrated: false, error: err.message };
914
+ }
915
+ }
916
+
917
+ // ── LightRAG integration (v4.1.0) ──────────────────────────────────────────
918
+ //
919
+ // Re-export the LightRAG orchestrator from the memory-store module so the
920
+ // dashboard, CLI, and tests have a single import surface. The actual
921
+ // implementation lives in `memory-lightrag.mjs`.
922
+
923
+ export {
924
+ resolveLightRAGConfig,
925
+ isInstalled as isLightRAGInstalled,
926
+ isRunning as isLightRAGRunning,
927
+ startServer as startLightRAG,
928
+ stopServer as stopLightRAG,
929
+ ensureRunning as ensureLightRAGRunning,
930
+ insertNote as insertLightRAGNote,
931
+ insertAllNotes as insertLightRAGAll,
932
+ reindexVault,
933
+ query as queryLightRAG,
934
+ } from './memory-lightrag.mjs';
935
+
936
+ // ── v4.6.0 LightRAG default model helpers ──────────────────────────────────
937
+ //
938
+ // Free cline Zen defaults — no API key required for free-tier models.
939
+ // Operators can override per-project via:
940
+ // - env: BIZAR_LIGHTRAG_LLM, BIZAR_LIGHTRAG_EMBEDDING
941
+ // - config: .bizar/memory.json#lightrag.llmModel / .embeddingModel
942
+ //
943
+ // The dashboard surfaces these via /api/lightrag/defaults so the
944
+ // settings view can show "currently using: cline/gpt-5-nano (free)".
945
+
946
+ export const LIGHTRAG_DEFAULT_LLM = 'cline/gpt-5-nano';
947
+ export const LIGHTRAG_DEFAULT_EMBEDDING = 'cline/text-embedding-3-small';
948
+
949
+ /**
950
+ * Build a wikilink link graph from all .md notes in the vault.
951
+ *
952
+ * Nodes: one per note (id = relPath, label = title or basename).
953
+ * Edges: one per wikilink [[Target]] found in note bodies.
954
+ *
955
+ * @param {{ projectRoot: string, vaultPath?: string|null, limit?: number }} opts
956
+ * @returns {{ nodes: Array<{id:string,label:string,type:string,size:number,group:string}>, edges: Array<{source:string,target:string,type:string,weight:number}> }}
957
+ */
958
+ export function getObsidianLinkGraph({ projectRoot, vaultPath = null, limit = 200 }) {
959
+ const { vaultRoot } = resolveVault(projectRoot);
960
+ const root = vaultPath || vaultRoot;
961
+ const nodesMap = new Map(); // id → node
962
+ const edges = [];
963
+
964
+ // Collect all notes.
965
+ const notes = listNotesForGraph(root);
966
+ const sliced = notes.slice(0, limit);
967
+
968
+ for (const note of sliced) {
969
+ if (!nodesMap.has(note.relPath)) {
970
+ nodesMap.set(note.relPath, {
971
+ id: note.relPath,
972
+ label: note.frontmatter?.title || note.relPath.split('/').pop()?.replace(/\.md$/i, '') || note.relPath,
973
+ type: 'note',
974
+ size: 1,
975
+ group: note.relPath.split('/')[0] || 'root',
976
+ });
977
+ }
978
+
979
+ // Extract wikilinks from body.
980
+ const WIKILINK_RE = /\[\[([^\]\n|]+?)(?:\|[^\]\n]+?)?(?:#[^\]\n]+?)?\]\]/g;
981
+ const body = note.body || '';
982
+ let m;
983
+ WIKILINK_RE.lastIndex = 0;
984
+ while ((m = WIKILINK_RE.exec(body)) !== null) {
985
+ const raw = (m[1] || '').trim();
986
+ if (!raw) continue;
987
+ const target = raw.split('#')[0].trim().split('/').pop() || raw;
988
+ // Resolve to a note id (basename match).
989
+ const targetId = resolveWikilinkTarget(target, notes);
990
+ if (targetId && targetId !== note.relPath) {
991
+ edges.push({
992
+ source: note.relPath,
993
+ target: targetId,
994
+ type: 'links_to',
995
+ weight: 1,
996
+ });
997
+ // Ensure target node exists.
998
+ if (!nodesMap.has(targetId)) {
999
+ nodesMap.set(targetId, {
1000
+ id: targetId,
1001
+ label: target,
1002
+ type: 'note',
1003
+ size: 1,
1004
+ group: targetId.split('/')[0] || 'root',
1005
+ });
1006
+ }
1007
+ }
1008
+ }
1009
+ }
1010
+
1011
+ return {
1012
+ nodes: [...nodesMap.values()].slice(0, limit),
1013
+ edges: edges.slice(0, limit * 3),
1014
+ };
1015
+ }
1016
+
1017
+ /**
1018
+ * List notes from a specific root path (not the project vault root).
1019
+ * Used by getObsidianLinkGraph for scanning arbitrary vaults.
1020
+ */
1021
+ function listNotesForGraph(scanRoot) {
1022
+ if (!existsSync(scanRoot)) return [];
1023
+ const out = [];
1024
+ function walk(dir, prefix) {
1025
+ let entries;
1026
+ try { entries = readdirSync(dir, { withFileTypes: true }); }
1027
+ catch { return; }
1028
+ for (const e of entries) {
1029
+ if (e.name.startsWith('.')) continue;
1030
+ const full = join(dir, e.name);
1031
+ const rel = prefix ? `${prefix}/${e.name}` : e.name;
1032
+ if (e.isDirectory()) {
1033
+ walk(full, rel);
1034
+ } else if (e.name.endsWith('.md')) {
1035
+ try {
1036
+ const raw = readFileSync(full, 'utf8');
1037
+ const { frontmatter, body } = parseFrontmatter(raw);
1038
+ out.push({ relPath: rel, frontmatter, body });
1039
+ } catch { /* skip */ }
1040
+ }
1041
+ }
1042
+ }
1043
+ walk(scanRoot, '');
1044
+ return out;
1045
+ }
1046
+
1047
+ /**
1048
+ * Resolve a wikilink target (e.g. "My Note" or "subdir/My Note") to a note id.
1049
+ * Uses basename matching (Obsidian semantics).
1050
+ */
1051
+ function resolveWikilinkTarget(targetName, notes) {
1052
+ const normalized = targetName.replace(/\.md$/i, '').toLowerCase();
1053
+ // Try exact relPath match first.
1054
+ for (const n of notes) {
1055
+ const base = n.relPath.replace(/\.md$/i, '').toLowerCase();
1056
+ if (base === normalized || base.endsWith('/' + normalized)) {
1057
+ return n.relPath;
1058
+ }
1059
+ }
1060
+ // Fallback: basename-only match.
1061
+ for (const n of notes) {
1062
+ const base = n.relPath.split('/').pop()?.replace(/\.md$/i, '').toLowerCase();
1063
+ if (base === normalized) {
1064
+ return n.relPath;
1065
+ }
1066
+ }
1067
+ return null;
1068
+ }
1069
+
1070
+ /**
1071
+ * Return the effective LightRAG model defaults, applying env-var
1072
+ * overrides on top of the built-in cline-Zen-free defaults.
1073
+ *
1074
+ * @returns {{ llm: string, embedding: string, source: 'cline-free' | 'env', llmSource: 'default' | 'env', embeddingSource: 'default' | 'env' }}
1075
+ */
1076
+ export function getDefaultLightRAGConfig() {
1077
+ const llmEnv = typeof process.env.BIZAR_LIGHTRAG_LLM === 'string' && process.env.BIZAR_LIGHTRAG_LLM.trim()
1078
+ ? process.env.BIZAR_LIGHTRAG_LLM.trim()
1079
+ : null;
1080
+ const embEnv = typeof process.env.BIZAR_LIGHTRAG_EMBEDDING === 'string' && process.env.BIZAR_LIGHTRAG_EMBEDDING.trim()
1081
+ ? process.env.BIZAR_LIGHTRAG_EMBEDDING.trim()
1082
+ : null;
1083
+ const llm = llmEnv || LIGHTRAG_DEFAULT_LLM;
1084
+ const embedding = embEnv || LIGHTRAG_DEFAULT_EMBEDDING;
1085
+ const source = (llmEnv || embEnv) ? 'env' : 'cline-free';
1086
+ return {
1087
+ llm,
1088
+ embedding,
1089
+ source,
1090
+ llmSource: llmEnv ? 'env' : 'default',
1091
+ embeddingSource: embEnv ? 'env' : 'default',
1092
+ };
1093
+ }