monomind 1.7.0 → 1.9.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 (562) hide show
  1. package/.claude/agents/design/design-monodesign.md +121 -0
  2. package/.claude/agents/github/issue-tracker.md +12 -12
  3. package/.claude/agents/github/pr-manager.md +10 -10
  4. package/.claude/agents/github/release-manager.md +49 -105
  5. package/.claude/agents/github/repo-architect.md +73 -92
  6. package/.claude/agents/github/sync-coordinator.md +55 -123
  7. package/.claude/agents/marketing/marketing-competitive-content.md +155 -0
  8. package/.claude/agents/marketing/marketing-content-creator.md +13 -0
  9. package/.claude/agents/marketing/marketing-cro-specialist.md +147 -0
  10. package/.claude/agents/marketing/marketing-email-specialist.md +90 -0
  11. package/.claude/agents/marketing/marketing-launch-strategist.md +129 -0
  12. package/.claude/agents/marketing/marketing-pricing-strategist.md +127 -0
  13. package/.claude/agents/specialists/integration-architect.md +94 -0
  14. package/.claude/commands/agents/README.md +4 -0
  15. package/.claude/commands/agents/agent-capabilities.md +6 -2
  16. package/.claude/commands/agents/agent-coordination.md +4 -0
  17. package/.claude/commands/agents/agent-spawning.md +4 -0
  18. package/.claude/commands/agents/agent-types.md +6 -2
  19. package/.claude/commands/analysis/README.md +14 -5
  20. package/.claude/commands/analysis/bottleneck-detect.md +30 -123
  21. package/.claude/commands/analysis/performance-bottlenecks.md +14 -14
  22. package/.claude/commands/analysis/performance-report.md +38 -11
  23. package/.claude/commands/analysis/token-efficiency.md +13 -16
  24. package/.claude/commands/analysis/token-usage.md +34 -12
  25. package/.claude/commands/automation/README.md +15 -5
  26. package/.claude/commands/automation/auto-agent.md +49 -85
  27. package/.claude/commands/automation/self-healing.md +20 -18
  28. package/.claude/commands/automation/session-memory.md +28 -29
  29. package/.claude/commands/automation/smart-agents.md +17 -9
  30. package/.claude/commands/automation/smart-spawn.md +52 -11
  31. package/.claude/commands/automation/workflow-select.md +46 -11
  32. package/.claude/commands/browse.md +5 -0
  33. package/.claude/commands/coordination/README.md +9 -5
  34. package/.claude/commands/coordination/agent-spawn.md +53 -9
  35. package/.claude/commands/coordination/swarm-init.md +39 -42
  36. package/.claude/commands/coordination/task-orchestrate.md +65 -11
  37. package/.claude/commands/github/README.md +21 -8
  38. package/.claude/commands/github/github-modes.md +9 -5
  39. package/.claude/commands/github/issue-tracker.md +34 -33
  40. package/.claude/commands/github/pr-manager.md +20 -17
  41. package/.claude/commands/github/release-manager.md +37 -49
  42. package/.claude/commands/github/repo-architect.md +39 -41
  43. package/.claude/commands/github/sync-coordinator.md +45 -49
  44. package/.claude/commands/hive-mind/README.md +42 -17
  45. package/.claude/commands/hive-mind/hive-mind-consensus.md +68 -4
  46. package/.claude/commands/hive-mind/hive-mind-init.md +55 -5
  47. package/.claude/commands/hive-mind/hive-mind-memory.md +69 -4
  48. package/.claude/commands/hive-mind/hive-mind-spawn.md +71 -10
  49. package/.claude/commands/hive-mind/hive-mind-status.md +52 -4
  50. package/.claude/commands/hive-mind/hive-mind-stop.md +51 -4
  51. package/.claude/commands/hive-mind/hive-mind.md +74 -14
  52. package/.claude/commands/hooks/README.md +62 -7
  53. package/.claude/commands/hooks/overview.md +94 -35
  54. package/.claude/commands/hooks/post-edit.md +48 -87
  55. package/.claude/commands/hooks/post-task.md +37 -87
  56. package/.claude/commands/hooks/pre-edit.md +52 -84
  57. package/.claude/commands/hooks/pre-task.md +46 -81
  58. package/.claude/commands/hooks/session-end.md +49 -85
  59. package/.claude/commands/hooks/setup.md +87 -58
  60. package/.claude/commands/mastermind/_repeat.md +308 -0
  61. package/.claude/commands/mastermind/architect.md +49 -0
  62. package/.claude/commands/mastermind/brain.md +98 -0
  63. package/.claude/commands/mastermind/build.md +22 -0
  64. package/.claude/commands/mastermind/content.md +22 -0
  65. package/.claude/commands/mastermind/createorg.md +94 -0
  66. package/.claude/commands/mastermind/finance.md +22 -0
  67. package/.claude/commands/mastermind/idea.md +22 -0
  68. package/.claude/commands/mastermind/marketing.md +22 -0
  69. package/.claude/commands/mastermind/master.md +379 -0
  70. package/.claude/commands/mastermind/ops.md +22 -0
  71. package/.claude/commands/mastermind/release.md +22 -0
  72. package/.claude/commands/mastermind/research.md +22 -0
  73. package/.claude/commands/mastermind/review.md +22 -0
  74. package/.claude/commands/mastermind/runorg.md +106 -0
  75. package/.claude/commands/mastermind/sales.md +22 -0
  76. package/.claude/commands/mastermind/techport.md +17 -0
  77. package/.claude/commands/memory/README.md +75 -5
  78. package/.claude/commands/memory/memory-search.md +63 -11
  79. package/.claude/commands/monitoring/README.md +64 -4
  80. package/.claude/commands/monitoring/agent-metrics.md +50 -10
  81. package/.claude/commands/monitoring/agents.md +59 -32
  82. package/.claude/commands/monitoring/status.md +96 -34
  83. package/.claude/commands/monograph/README.md +102 -0
  84. package/.claude/commands/monograph/monograph-build.md +79 -0
  85. package/.claude/commands/monograph/monograph-search.md +96 -0
  86. package/.claude/commands/monograph/monograph-stats.md +53 -0
  87. package/.claude/commands/monograph/monograph-watch.md +63 -0
  88. package/.claude/commands/monograph/monograph-wiki.md +91 -0
  89. package/.claude/commands/monomind/createtask.md +277 -0
  90. package/.claude/commands/{monomind-do.md → monomind/do.md} +22 -9
  91. package/.claude/commands/monomind/help.md +118 -0
  92. package/.claude/commands/{monomind-idea.md → monomind/idea.md} +23 -29
  93. package/.claude/commands/{monomind-improve.md → monomind/improve.md} +24 -30
  94. package/.claude/commands/monomind/memory.md +230 -0
  95. package/.claude/commands/monomind/repeat.md +201 -0
  96. package/.claude/commands/monomind/review.md +313 -0
  97. package/.claude/commands/monomind/specialagents.md +125 -0
  98. package/.claude/commands/monomind/swarm.md +161 -0
  99. package/.claude/commands/monomind/understand.md +148 -0
  100. package/.claude/commands/optimization/README.md +69 -5
  101. package/.claude/commands/optimization/auto-topology.md +66 -43
  102. package/.claude/commands/optimization/parallel-execution.md +65 -39
  103. package/.claude/commands/optimization/performance-optimize.md +79 -0
  104. package/.claude/commands/pair/README.md +48 -230
  105. package/.claude/commands/pair/examples.md +85 -441
  106. package/.claude/commands/pair/modes.md +77 -303
  107. package/.claude/commands/pair/session.md +76 -359
  108. package/.claude/commands/sparc/analyzer.md +9 -26
  109. package/.claude/commands/sparc/architect.md +8 -25
  110. package/.claude/commands/sparc/ask.md +27 -68
  111. package/.claude/commands/sparc/batch-executor.md +8 -25
  112. package/.claude/commands/sparc/code.md +12 -53
  113. package/.claude/commands/sparc/coder.md +8 -25
  114. package/.claude/commands/sparc/debug.md +12 -53
  115. package/.claude/commands/sparc/debugger.md +8 -25
  116. package/.claude/commands/sparc/designer.md +8 -25
  117. package/.claude/commands/sparc/devops.md +16 -57
  118. package/.claude/commands/sparc/docs-writer.md +12 -53
  119. package/.claude/commands/sparc/documenter.md +8 -25
  120. package/.claude/commands/sparc/innovator.md +8 -25
  121. package/.claude/commands/sparc/integration.md +12 -53
  122. package/.claude/commands/sparc/mcp.md +12 -53
  123. package/.claude/commands/sparc/memory-manager.md +28 -25
  124. package/.claude/commands/sparc/optimizer.md +8 -25
  125. package/.claude/commands/sparc/orchestrator.md +35 -97
  126. package/.claude/commands/sparc/post-deployment-monitoring-mode.md +13 -54
  127. package/.claude/commands/sparc/refinement-optimization-mode.md +13 -54
  128. package/.claude/commands/sparc/researcher.md +8 -25
  129. package/.claude/commands/sparc/reviewer.md +8 -25
  130. package/.claude/commands/sparc/security-review.md +13 -54
  131. package/.claude/commands/sparc/sparc-modes.md +97 -151
  132. package/.claude/commands/sparc/sparc.md +16 -56
  133. package/.claude/commands/sparc/spec-pseudocode.md +13 -54
  134. package/.claude/commands/sparc/supabase-admin.md +19 -66
  135. package/.claude/commands/sparc/swarm-coordinator.md +21 -25
  136. package/.claude/commands/sparc/tdd.md +8 -25
  137. package/.claude/commands/sparc/tester.md +8 -25
  138. package/.claude/commands/sparc/tutorial.md +12 -53
  139. package/.claude/commands/sparc/workflow-manager.md +8 -25
  140. package/.claude/commands/sparc.md +76 -130
  141. package/.claude/commands/stream-chain/pipeline.md +72 -77
  142. package/.claude/commands/stream-chain/run.md +133 -47
  143. package/.claude/commands/swarm/README.md +37 -12
  144. package/.claude/commands/swarm/analysis.md +47 -69
  145. package/.claude/commands/swarm/development.md +45 -69
  146. package/.claude/commands/swarm/examples.md +77 -142
  147. package/.claude/commands/swarm/maintenance.md +47 -74
  148. package/.claude/commands/swarm/optimization.md +54 -87
  149. package/.claude/commands/swarm/research.md +47 -107
  150. package/.claude/commands/swarm/swarm-analysis.md +58 -4
  151. package/.claude/commands/swarm/swarm-background.md +61 -4
  152. package/.claude/commands/swarm/swarm-modes.md +63 -4
  153. package/.claude/commands/swarm/swarm-monitor.md +50 -4
  154. package/.claude/commands/swarm/swarm-status.md +40 -4
  155. package/.claude/commands/swarm/swarm-strategies.md +73 -5
  156. package/.claude/commands/swarm/swarm.md +70 -18
  157. package/.claude/commands/swarm/testing.md +51 -102
  158. package/.claude/commands/tokens.md +6 -1
  159. package/.claude/commands/training/README.md +36 -6
  160. package/.claude/commands/training/model-update.md +68 -15
  161. package/.claude/commands/training/neural-patterns.md +54 -55
  162. package/.claude/commands/training/neural-train.md +70 -16
  163. package/.claude/commands/training/pattern-learn.md +60 -16
  164. package/.claude/commands/training/specialization.md +78 -49
  165. package/.claude/commands/truth/start.md +87 -109
  166. package/.claude/commands/ts.md +7 -2
  167. package/.claude/commands/verify/check.md +90 -34
  168. package/.claude/commands/verify/start.md +71 -94
  169. package/.claude/commands/workflows/README.md +62 -6
  170. package/.claude/commands/workflows/development.md +69 -61
  171. package/.claude/commands/workflows/research.md +73 -47
  172. package/.claude/commands/workflows/workflow-create.md +75 -16
  173. package/.claude/commands/workflows/workflow-execute.md +94 -16
  174. package/.claude/commands/workflows/workflow-export.md +81 -16
  175. package/.claude/helpers/control-start.cjs +91 -0
  176. package/.claude/helpers/extras-registry.json +4104 -1991
  177. package/.claude/helpers/graphify-freshen.cjs +44 -13
  178. package/.claude/helpers/hook-handler.cjs +256 -1
  179. package/.claude/helpers/loop-tracker.cjs +107 -0
  180. package/.claude/helpers/router.cjs +48 -68
  181. package/.claude/helpers/skill-registry.json +89 -104
  182. package/.claude/helpers/statusline.cjs +33 -2
  183. package/.claude/scheduled_tasks.lock +1 -0
  184. package/.claude/settings.json +15 -0
  185. package/.claude/skills/.monomind/data/ranked-context.json +5 -0
  186. package/.claude/skills/.monomind/sessions/current.json +13 -0
  187. package/.claude/skills/.monomind/sessions/session-1777829336455.json +15 -0
  188. package/.claude/skills/.monomind/sessions/session-1777831614725.json +15 -0
  189. package/.claude/skills/.monomind/sessions/session-1777832095857.json +15 -0
  190. package/.claude/skills/.monomind/sessions/session-1777839814183.json +15 -0
  191. package/.claude/skills/.monomind/sessions/session-1777841847131.json +15 -0
  192. package/.claude/skills/.monomind/sessions/session-1777843309463.json +15 -0
  193. package/.claude/skills/.monomind/sessions/session-1777880867159.json +15 -0
  194. package/.claude/skills/.monomind/sessions/session-1777881884593.json +15 -0
  195. package/.claude/skills/.monomind/sessions/session-1777884090471.json +15 -0
  196. package/.claude/skills/.monomind/sessions/session-1777884808221.json +15 -0
  197. package/.claude/skills/.monomind/sessions/session-1777885672155.json +15 -0
  198. package/.claude/skills/.monomind/sessions/session-1777886852818.json +15 -0
  199. package/.claude/skills/.monomind/sessions/session-1777896532690.json +15 -0
  200. package/.claude/skills/agentdb-advanced/SKILL.md +11 -12
  201. package/.claude/skills/agentdb-learning/SKILL.md +20 -21
  202. package/.claude/skills/agentdb-memory-patterns/SKILL.md +28 -30
  203. package/.claude/skills/agentdb-optimization/SKILL.md +11 -12
  204. package/.claude/skills/agentdb-vector-search/SKILL.md +37 -41
  205. package/.claude/skills/{v3-integration-deep → agentic-integration}/SKILL.md +20 -13
  206. package/.claude/skills/agentic-jujutsu/SKILL.md +22 -22
  207. package/.claude/skills/{v3-cli-modernization → cli-modernization}/SKILL.md +17 -8
  208. package/.claude/skills/{v3-core-implementation → core-implementation}/SKILL.md +33 -8
  209. package/.claude/skills/{v3-ddd-architecture → ddd-architecture}/SKILL.md +18 -25
  210. package/.claude/skills/github-code-review/SKILL.md +82 -83
  211. package/.claude/skills/github-multi-repo/SKILL.md +42 -46
  212. package/.claude/skills/github-project-management/SKILL.md +83 -88
  213. package/.claude/skills/github-release-management/SKILL.md +12 -18
  214. package/.claude/skills/github-workflow-automation/SKILL.md +70 -74
  215. package/.claude/skills/hooks-automation/SKILL.md +9 -13
  216. package/.claude/skills/mastermind/_intake.md +83 -0
  217. package/.claude/skills/mastermind/_protocol.md +275 -0
  218. package/.claude/skills/mastermind/architect.md +847 -0
  219. package/.claude/skills/mastermind/build.md +158 -0
  220. package/.claude/skills/mastermind/content.md +185 -0
  221. package/.claude/skills/mastermind/createorg.md +318 -0
  222. package/.claude/skills/mastermind/finance.md +154 -0
  223. package/.claude/skills/mastermind/idea.md +158 -0
  224. package/.claude/skills/mastermind/marketing.md +216 -0
  225. package/.claude/skills/mastermind/monotask.md +350 -0
  226. package/.claude/skills/mastermind/ops.md +156 -0
  227. package/.claude/skills/mastermind/references/copywriting-frameworks.md +181 -0
  228. package/.claude/skills/mastermind/references/persuasion-psychology.md +158 -0
  229. package/.claude/skills/mastermind/release.md +156 -0
  230. package/.claude/skills/mastermind/research.md +156 -0
  231. package/.claude/skills/mastermind/review.md +157 -0
  232. package/.claude/skills/mastermind/runorg.md +308 -0
  233. package/.claude/skills/mastermind/sales.md +158 -0
  234. package/.claude/skills/mastermind/techport.md +743 -0
  235. package/.claude/skills/{v3-mcp-optimization → mcp-optimization}/SKILL.md +35 -14
  236. package/.claude/skills/{v3-memory-unification → memory-unification}/SKILL.md +20 -4
  237. package/.claude/skills/monodesign/SKILL.md +302 -0
  238. package/.claude/skills/monodesign/reference/adapt.md +190 -0
  239. package/.claude/skills/monodesign/reference/animate.md +175 -0
  240. package/.claude/skills/monodesign/reference/antipatterns-catalog.md +187 -0
  241. package/.claude/skills/monodesign/reference/audit.md +133 -0
  242. package/.claude/skills/monodesign/reference/bolder.md +113 -0
  243. package/.claude/skills/monodesign/reference/brand-workflow.md +180 -0
  244. package/.claude/skills/monodesign/reference/brand.md +114 -0
  245. package/.claude/skills/monodesign/reference/clarify.md +174 -0
  246. package/.claude/skills/monodesign/reference/cognitive-load.md +106 -0
  247. package/.claude/skills/monodesign/reference/color-and-contrast.md +105 -0
  248. package/.claude/skills/monodesign/reference/colorize.md +154 -0
  249. package/.claude/skills/monodesign/reference/component-specs.md +260 -0
  250. package/.claude/skills/monodesign/reference/component-states.md +274 -0
  251. package/.claude/skills/monodesign/reference/component-system.md +358 -0
  252. package/.claude/skills/monodesign/reference/copy-formulas.md +160 -0
  253. package/.claude/skills/monodesign/reference/craft.md +193 -0
  254. package/.claude/skills/monodesign/reference/critique.md +213 -0
  255. package/.claude/skills/monodesign/reference/delight.md +302 -0
  256. package/.claude/skills/monodesign/reference/design-principles.md +246 -0
  257. package/.claude/skills/monodesign/reference/distill.md +111 -0
  258. package/.claude/skills/monodesign/reference/document.md +427 -0
  259. package/.claude/skills/monodesign/reference/extract.md +69 -0
  260. package/.claude/skills/monodesign/reference/harden.md +347 -0
  261. package/.claude/skills/monodesign/reference/heuristics-scoring.md +234 -0
  262. package/.claude/skills/monodesign/reference/image-prompts.md +118 -0
  263. package/.claude/skills/monodesign/reference/interaction-design.md +195 -0
  264. package/.claude/skills/monodesign/reference/layout.md +141 -0
  265. package/.claude/skills/monodesign/reference/live.md +622 -0
  266. package/.claude/skills/monodesign/reference/motion-design.md +109 -0
  267. package/.claude/skills/monodesign/reference/onboard.md +234 -0
  268. package/.claude/skills/monodesign/reference/optimize.md +258 -0
  269. package/.claude/skills/monodesign/reference/overdrive.md +130 -0
  270. package/.claude/skills/monodesign/reference/personas.md +179 -0
  271. package/.claude/skills/monodesign/reference/polish.md +233 -0
  272. package/.claude/skills/monodesign/reference/pre-delivery-checklist.md +108 -0
  273. package/.claude/skills/monodesign/reference/product.md +62 -0
  274. package/.claude/skills/monodesign/reference/quieter.md +99 -0
  275. package/.claude/skills/monodesign/reference/responsive-design.md +114 -0
  276. package/.claude/skills/monodesign/reference/shape.md +151 -0
  277. package/.claude/skills/monodesign/reference/spatial-design.md +100 -0
  278. package/.claude/skills/monodesign/reference/teach.md +156 -0
  279. package/.claude/skills/monodesign/reference/token-architecture.md +222 -0
  280. package/.claude/skills/monodesign/reference/typeset.md +124 -0
  281. package/.claude/skills/monodesign/reference/typography.md +159 -0
  282. package/.claude/skills/monodesign/reference/ux-research.md +143 -0
  283. package/.claude/skills/monodesign/reference/ux-rules.md +211 -0
  284. package/.claude/skills/monodesign/reference/ux-writing.md +107 -0
  285. package/.claude/skills/monomotion/SKILL.md +145 -0
  286. package/.claude/skills/monomotion/rules/api-control.md +139 -0
  287. package/.claude/skills/monomotion/rules/effects.md +109 -0
  288. package/.claude/skills/monomotion/rules/integration.md +140 -0
  289. package/.claude/skills/monomotion/rules/scroll.md +131 -0
  290. package/.claude/skills/monomotion/rules/sequencing.md +105 -0
  291. package/.claude/skills/monomotion/rules/svg.md +101 -0
  292. package/.claude/skills/monomotion/rules/text.md +119 -0
  293. package/.claude/skills/pair-programming/SKILL.md +1 -1
  294. package/.claude/skills/performance-analysis/SKILL.md +3 -3
  295. package/.claude/skills/{v3-performance-optimization → performance-optimization}/SKILL.md +16 -8
  296. package/.claude/skills/reasoningbank-agentdb/SKILL.md +17 -19
  297. package/.claude/skills/reasoningbank-intelligence/SKILL.md +4 -6
  298. package/.claude/skills/{v3-security-overhaul → security-hardening}/SKILL.md +13 -3
  299. package/.claude/skills/skill-builder/SKILL.md +19 -19
  300. package/.claude/skills/sparc-methodology/SKILL.md +55 -211
  301. package/.claude/skills/stop-slop/SKILL.md +67 -0
  302. package/.claude/skills/stop-slop/references/examples.md +61 -0
  303. package/.claude/skills/stop-slop/references/phrases.md +130 -0
  304. package/.claude/skills/stop-slop/references/structures.md +136 -0
  305. package/.claude/skills/swarm-advanced/SKILL.md +13 -43
  306. package/.claude/skills/{v3-swarm-coordination → swarm-coordination}/SKILL.md +39 -21
  307. package/.claude/skills/swarm-orchestration/SKILL.md +12 -12
  308. package/.claude/skills/verification-quality/SKILL.md +5 -5
  309. package/README.md +5 -5
  310. package/package.json +1 -1
  311. package/packages/@monomind/cli/README.md +5 -5
  312. package/packages/@monomind/cli/bin/cli.js +78 -13
  313. package/packages/@monomind/cli/dist/src/agents/halt-signal.js +33 -7
  314. package/packages/@monomind/cli/dist/src/agents/managed-agent.js +5 -2
  315. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +3 -2
  316. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +1 -1
  317. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +5 -2
  318. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +26 -4
  319. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +17 -9
  320. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +5 -3
  321. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +58 -10
  322. package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +0 -1
  323. package/packages/@monomind/cli/dist/src/agents/version-store.js +44 -21
  324. package/packages/@monomind/cli/dist/src/autopilot-state.js +79 -28
  325. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +7 -2
  326. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +20 -8
  327. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.d.ts +2 -1
  328. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +25 -2
  329. package/packages/@monomind/cli/dist/src/commands/agent.js +6 -4
  330. package/packages/@monomind/cli/dist/src/commands/appliance-advanced.js +23 -0
  331. package/packages/@monomind/cli/dist/src/commands/autopilot.js +3 -3
  332. package/packages/@monomind/cli/dist/src/commands/benchmark.js +119 -8
  333. package/packages/@monomind/cli/dist/src/commands/claims.js +22 -14
  334. package/packages/@monomind/cli/dist/src/commands/config.js +32 -0
  335. package/packages/@monomind/cli/dist/src/commands/daemon.js +13 -11
  336. package/packages/@monomind/cli/dist/src/commands/deployment.js +21 -2
  337. package/packages/@monomind/cli/dist/src/commands/doctor.js +28 -62
  338. package/packages/@monomind/cli/dist/src/commands/embeddings.js +124 -48
  339. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +15 -14
  340. package/packages/@monomind/cli/dist/src/commands/hooks.js +45 -41
  341. package/packages/@monomind/cli/dist/src/commands/index.d.ts +2 -0
  342. package/packages/@monomind/cli/dist/src/commands/index.js +20 -7
  343. package/packages/@monomind/cli/dist/src/commands/init.js +53 -19
  344. package/packages/@monomind/cli/dist/src/commands/mcp.js +31 -44
  345. package/packages/@monomind/cli/dist/src/commands/memory.js +47 -15
  346. package/packages/@monomind/cli/dist/src/commands/migrate.js +156 -108
  347. package/packages/@monomind/cli/dist/src/commands/monograph.d.ts +8 -0
  348. package/packages/@monomind/cli/dist/src/commands/monograph.js +526 -0
  349. package/packages/@monomind/cli/dist/src/commands/neural.js +96 -56
  350. package/packages/@monomind/cli/dist/src/commands/performance.js +30 -8
  351. package/packages/@monomind/cli/dist/src/commands/plugins.js +13 -37
  352. package/packages/@monomind/cli/dist/src/commands/process.js +25 -2
  353. package/packages/@monomind/cli/dist/src/commands/providers.js +37 -5
  354. package/packages/@monomind/cli/dist/src/commands/replay.js +4 -4
  355. package/packages/@monomind/cli/dist/src/commands/route.js +37 -5
  356. package/packages/@monomind/cli/dist/src/commands/ruvector/import.js +12 -2
  357. package/packages/@monomind/cli/dist/src/commands/ruvector/init.js +15 -0
  358. package/packages/@monomind/cli/dist/src/commands/ruvector/status.js +16 -3
  359. package/packages/@monomind/cli/dist/src/commands/security.js +342 -193
  360. package/packages/@monomind/cli/dist/src/commands/session.js +51 -8
  361. package/packages/@monomind/cli/dist/src/commands/start.js +18 -4
  362. package/packages/@monomind/cli/dist/src/commands/swarm.js +47 -36
  363. package/packages/@monomind/cli/dist/src/commands/tokens.js +11 -11
  364. package/packages/@monomind/cli/dist/src/commands/transfer-store.js +1 -1
  365. package/packages/@monomind/cli/dist/src/commands/workflow.js +31 -4
  366. package/packages/@monomind/cli/dist/src/config-adapter.d.ts +2 -1
  367. package/packages/@monomind/cli/dist/src/consensus/audit-writer.js +46 -13
  368. package/packages/@monomind/cli/dist/src/consensus/vote-signer.d.ts +0 -3
  369. package/packages/@monomind/cli/dist/src/consensus/vote-signer.js +9 -1
  370. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +4 -2
  371. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +25 -8
  372. package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.d.ts +10 -3
  373. package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.js +50 -16
  374. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +27 -5
  375. package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +2 -2
  376. package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +26 -16
  377. package/packages/@monomind/cli/dist/src/eval/trace-collector.js +23 -3
  378. package/packages/@monomind/cli/dist/src/index.js +12 -10
  379. package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +8 -8
  380. package/packages/@monomind/cli/dist/src/init/executor.js +163 -137
  381. package/packages/@monomind/cli/dist/src/init/helpers-generator.js +49 -36
  382. package/packages/@monomind/cli/dist/src/init/mcp-generator.js +3 -3
  383. package/packages/@monomind/cli/dist/src/init/settings-generator.js +10 -3
  384. package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +18 -3
  385. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -1
  386. package/packages/@monomind/cli/dist/src/init/types.d.ts +35 -11
  387. package/packages/@monomind/cli/dist/src/init/types.js +5 -9
  388. package/packages/@monomind/cli/dist/src/interactive/interrupt.js +8 -3
  389. package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +38 -4
  390. package/packages/@monomind/cli/dist/src/mcp-client.js +15 -6
  391. package/packages/@monomind/cli/dist/src/mcp-server.d.ts +9 -2
  392. package/packages/@monomind/cli/dist/src/mcp-server.js +182 -35
  393. package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +66 -34
  394. package/packages/@monomind/cli/dist/src/mcp-tools/agentdb-tools.js +34 -7
  395. package/packages/@monomind/cli/dist/src/mcp-tools/analyze-tools.js +25 -16
  396. package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.js +4 -6
  397. package/packages/@monomind/cli/dist/src/mcp-tools/autopilot-tools.js +12 -2
  398. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +199 -20
  399. package/packages/@monomind/cli/dist/src/mcp-tools/claims-tools.js +68 -18
  400. package/packages/@monomind/cli/dist/src/mcp-tools/config-tools.js +33 -5
  401. package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.js +59 -4
  402. package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.js +46 -10
  403. package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +46 -5
  404. package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +29 -16
  405. package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.d.ts +4 -67
  406. package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +40 -1250
  407. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +38 -10
  408. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +96 -33
  409. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +70 -37
  410. package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +1 -0
  411. package/packages/@monomind/cli/dist/src/mcp-tools/index.js +1 -0
  412. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +29 -13
  413. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.d.ts +9 -0
  414. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +6306 -0
  415. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +121 -37
  416. package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +21 -8
  417. package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +10 -8
  418. package/packages/@monomind/cli/dist/src/mcp-tools/request-tracker.js +4 -1
  419. package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.js +19 -8
  420. package/packages/@monomind/cli/dist/src/mcp-tools/session-tools.js +57 -17
  421. package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +35 -17
  422. package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +4 -3
  423. package/packages/@monomind/cli/dist/src/mcp-tools/task-tools.js +53 -13
  424. package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.js +63 -14
  425. package/packages/@monomind/cli/dist/src/mcp-tools/transfer-tools.js +21 -16
  426. package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +92 -23
  427. package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +41 -10
  428. package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +2 -2
  429. package/packages/@monomind/cli/dist/src/memory/intelligence.js +39 -13
  430. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -0
  431. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +149 -56
  432. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +107 -45
  433. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +8 -1
  434. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +25 -8
  435. package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +40 -0
  436. package/packages/@monomind/cli/dist/src/observability/replay-reader.js +138 -0
  437. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +35 -5
  438. package/packages/@monomind/cli/dist/src/parser.d.ts +8 -0
  439. package/packages/@monomind/cli/dist/src/parser.js +48 -14
  440. package/packages/@monomind/cli/dist/src/plugins/manager.js +112 -19
  441. package/packages/@monomind/cli/dist/src/plugins/store/discovery.d.ts +1 -1
  442. package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +80 -62
  443. package/packages/@monomind/cli/dist/src/production/circuit-breaker.js +8 -1
  444. package/packages/@monomind/cli/dist/src/production/error-handler.d.ts +4 -2
  445. package/packages/@monomind/cli/dist/src/production/error-handler.js +27 -5
  446. package/packages/@monomind/cli/dist/src/production/monitoring.js +8 -4
  447. package/packages/@monomind/cli/dist/src/production/rate-limiter.js +30 -22
  448. package/packages/@monomind/cli/dist/src/ruvector/agent-wasm.js +2 -2
  449. package/packages/@monomind/cli/dist/src/ruvector/coverage-router.js +19 -9
  450. package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.d.ts +1 -0
  451. package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.js +26 -6
  452. package/packages/@monomind/cli/dist/src/ruvector/enhanced-model-router.js +24 -2
  453. package/packages/@monomind/cli/dist/src/ruvector/index.d.ts +1 -2
  454. package/packages/@monomind/cli/dist/src/ruvector/index.js +2 -2
  455. package/packages/@monomind/cli/dist/src/ruvector/model-router.d.ts +4 -2
  456. package/packages/@monomind/cli/dist/src/ruvector/model-router.js +30 -6
  457. package/packages/@monomind/cli/dist/src/ruvector/moe-router.d.ts +7 -0
  458. package/packages/@monomind/cli/dist/src/ruvector/moe-router.js +35 -12
  459. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.d.ts +7 -1
  460. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.js +40 -9
  461. package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +3 -1
  462. package/packages/@monomind/cli/dist/src/services/claim-service.js +33 -2
  463. package/packages/@monomind/cli/dist/src/services/config-file-manager.d.ts +16 -2
  464. package/packages/@monomind/cli/dist/src/services/config-file-manager.js +105 -17
  465. package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +51 -11
  466. package/packages/@monomind/cli/dist/src/services/headless-worker-executor.d.ts +7 -0
  467. package/packages/@monomind/cli/dist/src/services/headless-worker-executor.js +188 -45
  468. package/packages/@monomind/cli/dist/src/services/registry-api.js +62 -9
  469. package/packages/@monomind/cli/dist/src/services/ruvector-training.js +8 -0
  470. package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +4 -1
  471. package/packages/@monomind/cli/dist/src/services/worker-daemon.js +112 -28
  472. package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +9 -2
  473. package/packages/@monomind/cli/dist/src/services/worker-queue.js +86 -5
  474. package/packages/@monomind/cli/dist/src/suggest.js +9 -0
  475. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +5 -3
  476. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +17 -5
  477. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +3 -0
  478. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +30 -6
  479. package/packages/@monomind/cli/dist/src/transfer/anonymization/index.js +5 -3
  480. package/packages/@monomind/cli/dist/src/transfer/export.js +5 -3
  481. package/packages/@monomind/cli/dist/src/transfer/ipfs/client.js +84 -7
  482. package/packages/@monomind/cli/dist/src/transfer/ipfs/upload.js +13 -4
  483. package/packages/@monomind/cli/dist/src/transfer/storage/gcs.js +19 -10
  484. package/packages/@monomind/cli/dist/src/transfer/store/discovery.d.ts +9 -2
  485. package/packages/@monomind/cli/dist/src/transfer/store/discovery.js +68 -13
  486. package/packages/@monomind/cli/dist/src/transfer/store/download.d.ts +15 -6
  487. package/packages/@monomind/cli/dist/src/transfer/store/download.js +113 -24
  488. package/packages/@monomind/cli/dist/src/transfer/store/publish.d.ts +1 -1
  489. package/packages/@monomind/cli/dist/src/transfer/store/publish.js +13 -14
  490. package/packages/@monomind/cli/dist/src/transfer/store/registry.d.ts +3 -3
  491. package/packages/@monomind/cli/dist/src/transfer/store/registry.js +32 -16
  492. package/packages/@monomind/cli/dist/src/update/checker.js +17 -4
  493. package/packages/@monomind/cli/dist/src/update/executor.js +25 -20
  494. package/packages/@monomind/cli/dist/src/update/rate-limiter.d.ts +11 -0
  495. package/packages/@monomind/cli/dist/src/update/rate-limiter.js +23 -3
  496. package/packages/@monomind/cli/dist/src/utils/parse-jsonl.d.ts +6 -0
  497. package/packages/@monomind/cli/dist/src/utils/parse-jsonl.js +22 -0
  498. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +37 -3
  499. package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +27 -11
  500. package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +51 -13
  501. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +3 -0
  502. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +6 -2
  503. package/packages/@monomind/cli/dist/src/workflow/template-engine.js +7 -0
  504. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +95 -14
  505. package/packages/@monomind/cli/package.json +5 -2
  506. package/packages/@monomind/guidance/README.md +0 -3
  507. package/packages/@monomind/shared/README.md +0 -1
  508. package/packages/@monomind/shared/dist/types/consensus-audit.d.ts +3 -1
  509. package/packages/README.md +15 -16
  510. package/.claude/agents/design/design-brand-guardian.md +0 -323
  511. package/.claude/agents/design/design-image-prompt-engineer.md +0 -237
  512. package/.claude/agents/design/design-inclusive-visuals-specialist.md +0 -72
  513. package/.claude/agents/design/design-ui-designer.md +0 -384
  514. package/.claude/agents/design/design-ux-architect.md +0 -470
  515. package/.claude/agents/design/design-ux-researcher.md +0 -330
  516. package/.claude/agents/design/design-visual-storyteller.md +0 -150
  517. package/.claude/agents/design/design-whimsy-injector.md +0 -439
  518. package/.claude/agents/v3/integration-architect.md +0 -338
  519. package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +0 -54
  520. package/.claude/commands/coordination/init.md +0 -44
  521. package/.claude/commands/coordination/orchestrate.md +0 -43
  522. package/.claude/commands/coordination/spawn.md +0 -45
  523. package/.claude/commands/github/code-review-swarm.md +0 -550
  524. package/.claude/commands/github/code-review.md +0 -25
  525. package/.claude/commands/github/github-swarm.md +0 -121
  526. package/.claude/commands/github/issue-triage.md +0 -25
  527. package/.claude/commands/github/multi-repo-swarm.md +0 -519
  528. package/.claude/commands/github/pr-enhance.md +0 -26
  529. package/.claude/commands/github/project-board-sync.md +0 -471
  530. package/.claude/commands/github/release-swarm.md +0 -590
  531. package/.claude/commands/github/repo-analyze.md +0 -25
  532. package/.claude/commands/github/swarm-issue.md +0 -482
  533. package/.claude/commands/github/swarm-pr.md +0 -310
  534. package/.claude/commands/github/workflow-automation.md +0 -468
  535. package/.claude/commands/hive-mind/hive-mind-metrics.md +0 -8
  536. package/.claude/commands/hive-mind/hive-mind-resume.md +0 -8
  537. package/.claude/commands/hive-mind/hive-mind-sessions.md +0 -8
  538. package/.claude/commands/hive-mind/hive-mind-wizard.md +0 -8
  539. package/.claude/commands/list-agents.md +0 -17
  540. package/.claude/commands/memory/memory-persist.md +0 -25
  541. package/.claude/commands/memory/memory-usage.md +0 -25
  542. package/.claude/commands/memory/neural.md +0 -47
  543. package/.claude/commands/metrics.md +0 -11
  544. package/.claude/commands/monitoring/real-time-view.md +0 -25
  545. package/.claude/commands/monitoring/swarm-monitor.md +0 -25
  546. package/.claude/commands/monomind-createtask.md +0 -302
  547. package/.claude/commands/monomind-help.md +0 -103
  548. package/.claude/commands/monomind-memory.md +0 -107
  549. package/.claude/commands/monomind-repeat.md +0 -149
  550. package/.claude/commands/monomind-swarm.md +0 -205
  551. package/.claude/commands/optimization/cache-manage.md +0 -25
  552. package/.claude/commands/optimization/topology-optimize.md +0 -25
  553. package/.claude/commands/pair/commands.md +0 -546
  554. package/.claude/commands/pair/config.md +0 -510
  555. package/.claude/commands/pair/start.md +0 -209
  556. package/.claude/commands/use-agent.md +0 -67
  557. package/.claude/skills/monomind-createtask/SKILL.md +0 -269
  558. package/.claude/skills/monomind-task-engine/SKILL.md +0 -358
  559. /package/.claude/agents/{v3 → specialists}/memory-specialist.md +0 -0
  560. /package/.claude/agents/{v3 → specialists}/performance-engineer.md +0 -0
  561. /package/.claude/agents/{v3 → specialists}/queen-coordinator.md +0 -0
  562. /package/.claude/agents/{v3 → specialists}/security-architect.md +0 -0
@@ -4,35 +4,81 @@
4
4
  *
5
5
  * Monomind Command Line Interface
6
6
  *
7
- * Auto-detects MCP mode when stdin is piped and no args provided.
8
- * This allows: echo '{"jsonrpc":"2.0",...}' | npx @monomind/cli
7
+ * MCP mode requires explicit `mcp start` subcommand or MONOMIND_MCP_AUTODETECT=1.
8
+ * Usage: npx @monomind/cli mcp start
9
9
  */
10
10
 
11
11
  import { randomUUID } from 'crypto';
12
12
 
13
- // Check if we should run in MCP server mode
14
- // Conditions:
15
- // 1. stdin is being piped AND no CLI arguments provided (auto-detect)
16
- // 2. stdin is being piped AND args are "mcp start" (explicit, e.g. npx monomind@alpha mcp start)
13
+ // Check if we should run in MCP server mode.
14
+ // SECURITY: only accept explicit `mcp start` plus piped stdin, OR the explicit
15
+ // `MONOMIND_MCP_AUTODETECT=1` opt-in for the legacy "no args + non-TTY" path.
16
+ // Previously any `monomind` invocation with redirected stdin (CI pipes, xargs,
17
+ // editor integrations) silently flipped into MCP server mode and accepted
18
+ // JSON-RPC tools/call — privilege escalation by environment.
17
19
  const cliArgs = process.argv.slice(2);
18
20
  const isExplicitMCP = cliArgs.length >= 1 && cliArgs[0] === 'mcp' && (cliArgs.length === 1 || cliArgs[1] === 'start');
19
- const isMCPMode = !process.stdin.isTTY && (process.argv.length === 2 || isExplicitMCP);
21
+ const allowAutoDetect = process.env.MONOMIND_MCP_AUTODETECT === '1';
22
+ const isMCPMode = !process.stdin.isTTY && (isExplicitMCP || (allowAutoDetect && process.argv.length === 2));
20
23
 
21
24
  if (isMCPMode) {
22
25
  // Run MCP server mode
23
26
  const { listMCPTools, callMCPTool, hasTool } = await import('../dist/src/mcp-client.js');
24
27
 
25
- const VERSION = '3.0.0';
28
+ // Read version from package.json instead of hardcoding (prevents stale
29
+ // version drift between bin entry and the published package).
30
+ let VERSION = '0.0.0';
31
+ try {
32
+ const { readFileSync } = await import('fs');
33
+ const { fileURLToPath } = await import('url');
34
+ const { dirname, join } = await import('path');
35
+ const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
36
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
37
+ if (typeof pkg.version === 'string') VERSION = pkg.version;
38
+ } catch { /* fall back to 0.0.0 */ }
26
39
  const sessionId = `mcp-${Date.now()}-${randomUUID().slice(0, 8)}`;
27
40
 
28
- console.error(
29
- `[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Starting in stdio mode`
30
- );
41
+ // Don't leak nodeVersion/platform/arch/pid to stderr by default; gate behind
42
+ // MONOMIND_LOG_LEVEL=debug to reduce fingerprinting in shared log aggregators.
43
+ if (process.env.MONOMIND_LOG_LEVEL === 'debug') {
44
+ console.error(
45
+ `[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Starting in stdio mode (node=${process.version} platform=${process.platform} arch=${process.arch})`
46
+ );
47
+ } else {
48
+ console.error(
49
+ `[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) Starting in stdio mode`
50
+ );
51
+ }
52
+
53
+ // Top-level safety nets — without these, an unhandled async error in a tool
54
+ // handler crashes the process with no observable cleanup.
55
+ process.on('uncaughtException', (err) => {
56
+ console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] uncaughtException: ${err && err.message ? err.message : String(err)}`);
57
+ process.exit(1);
58
+ });
59
+ process.on('unhandledRejection', (reason) => {
60
+ const msg = reason instanceof Error ? reason.message : String(reason);
61
+ console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] unhandledRejection: ${msg}`);
62
+ process.exit(1);
63
+ });
64
+ const shutdown = (sig) => {
65
+ console.error(`[${new Date().toISOString()}] INFO [monomind-mcp] (${sessionId}) ${sig} received, shutting down`);
66
+ process.exit(0);
67
+ };
68
+ process.on('SIGINT', () => shutdown('SIGINT'));
69
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
31
70
 
71
+ // Cap on accumulated input buffer so a peer pumping a single multi-GB line
72
+ // (or a slow trickle without newlines) cannot OOM-kill the process.
73
+ const MAX_BUFFER_BYTES = 10 * 1024 * 1024;
32
74
  let buffer = '';
33
75
  process.stdin.setEncoding('utf8');
34
76
  process.stdin.on('data', async (chunk) => {
35
77
  buffer += chunk;
78
+ if (buffer.length > MAX_BUFFER_BYTES) {
79
+ console.error(`[${new Date().toISOString()}] FATAL [monomind-mcp] input exceeds ${MAX_BUFFER_BYTES} bytes`);
80
+ process.exit(1);
81
+ }
36
82
  let lines = buffer.split('\n');
37
83
  buffer = lines.pop() || '';
38
84
 
@@ -146,11 +192,30 @@ if (isMCPMode) {
146
192
  }
147
193
  }
148
194
  } else {
149
- // Run normal CLI mode
195
+ // Run normal CLI mode.
196
+ // Install top-level handlers so an asynchronous error fired from an event-
197
+ // loop callback does not bypass the synchronous .catch below. Default Node
198
+ // handler prints the full stack to stderr — which on this codebase includes
199
+ // attacker-influenced bytes from registry/config error messages and full
200
+ // filesystem paths. Sanitize before logging and exit non-zero.
201
+ const safeMsg = (m) =>
202
+ String(m == null ? '' : m).replace(/[\x00-\x1f\x7f-\x9f]/g, '?').slice(0, 1000);
203
+ process.on('uncaughtException', (err) => {
204
+ console.error(`[${new Date().toISOString()}] FATAL [monomind] uncaughtException: ${safeMsg(err && err.message)}`);
205
+ if (process.env.DEBUG) console.error(err && err.stack);
206
+ process.exit(1);
207
+ });
208
+ process.on('unhandledRejection', (reason) => {
209
+ const msg = reason instanceof Error ? reason.message : String(reason);
210
+ console.error(`[${new Date().toISOString()}] FATAL [monomind] unhandledRejection: ${safeMsg(msg)}`);
211
+ if (process.env.DEBUG && reason instanceof Error) console.error(reason.stack);
212
+ process.exit(1);
213
+ });
214
+
150
215
  const { CLI } = await import('../dist/src/index.js');
151
216
  const cli = new CLI();
152
217
  cli.run().catch((error) => {
153
- console.error('Fatal error:', error.message);
218
+ console.error('Fatal error:', safeMsg(error && error.message));
154
219
  process.exit(1);
155
220
  });
156
221
  }
@@ -6,14 +6,23 @@
6
6
  * can query whether a halt has been issued.
7
7
  */
8
8
  import { randomUUID } from 'crypto';
9
- import { existsSync, mkdirSync, appendFileSync, readFileSync } from 'fs';
10
- import { join, dirname } from 'path';
11
- const DEFAULT_FILE = () => join(process.cwd(), 'data', 'halt-signals.jsonl');
9
+ import { existsSync, mkdirSync, appendFileSync, readFileSync, statSync } from 'fs';
10
+ import { join, dirname, resolve, sep } from 'path';
11
+ const ALLOWED_ROOT = () => resolve(process.env.MONOMIND_DATA_DIR ?? process.cwd());
12
+ const DEFAULT_FILE = () => join(ALLOWED_ROOT(), 'data', 'halt-signals.jsonl');
13
+ function safeHaltFilePath(filePath) {
14
+ const allowedRoot = ALLOWED_ROOT();
15
+ const resolved = resolve(filePath);
16
+ if (resolved !== allowedRoot && !resolved.startsWith(allowedRoot + sep)) {
17
+ throw new Error(`Halt signal file path escapes allowed directory: ${filePath}`);
18
+ }
19
+ return resolved;
20
+ }
12
21
  /**
13
22
  * Broadcast a halt signal for a swarm.
14
23
  */
15
24
  export function broadcast(swarmId, sourceAgentId, reason, filePath) {
16
- const target = filePath ?? DEFAULT_FILE();
25
+ const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
17
26
  const dir = dirname(target);
18
27
  if (!existsSync(dir)) {
19
28
  mkdirSync(dir, { recursive: true });
@@ -32,10 +41,22 @@ export function broadcast(swarmId, sourceAgentId, reason, filePath) {
32
41
  * Check whether any halt signal exists for the given swarm.
33
42
  */
34
43
  export function isHalted(swarmId, filePath) {
35
- const target = filePath ?? DEFAULT_FILE();
44
+ const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
36
45
  if (!existsSync(target)) {
37
46
  return false;
38
47
  }
48
+ // Size cap. isHalted is on the swarm-coordination hot path; without this
49
+ // cap a planted multi-GB file (or unbounded broadcast accumulation over
50
+ // weeks) reliably OOMs the CLI on the next call. Treat oversized halt
51
+ // logs as "no halt" — fail-safe in the swarm-termination flow.
52
+ try {
53
+ const stat = statSync(target);
54
+ if (stat.size > 10 * 1024 * 1024)
55
+ return false;
56
+ }
57
+ catch {
58
+ return false;
59
+ }
39
60
  const raw = readFileSync(target, 'utf-8').trim();
40
61
  if (!raw)
41
62
  return false;
@@ -43,8 +64,13 @@ export function isHalted(swarmId, filePath) {
43
64
  .split('\n')
44
65
  .filter(Boolean)
45
66
  .some((line) => {
46
- const rec = JSON.parse(line);
47
- return rec.swarmId === swarmId;
67
+ try {
68
+ const rec = JSON.parse(line);
69
+ return rec.swarmId === swarmId;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
48
74
  });
49
75
  }
50
76
  //# sourceMappingURL=halt-signal.js.map
@@ -8,10 +8,13 @@ export async function spawnAndAwait(agentSlug, task, runner, options = {}) {
8
8
  const startedAt = Date.now();
9
9
  const taskId = `managed-${Date.now().toString(36)}-${randomBytes(4).toString('hex')}`;
10
10
  try {
11
+ let timeoutHandle;
11
12
  const output = await Promise.race([
12
13
  runner(agentSlug, taskId, task),
13
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms`)), timeoutMs)),
14
- ]);
14
+ new Promise((_, reject) => {
15
+ timeoutHandle = setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms`)), timeoutMs);
16
+ }),
17
+ ]).finally(() => clearTimeout(timeoutHandle));
15
18
  return {
16
19
  agentSlug, taskId, output, status: 'success',
17
20
  durationMs: Date.now() - startedAt,
@@ -5,9 +5,9 @@
5
5
  * routes to the candidate or control version. Falls back to the active version
6
6
  * when no experiment is running.
7
7
  *
8
- * @module @monoes/cli/agents/prompt-experiment
8
+ * @module @monomind/cli/agents/prompt-experiment
9
9
  */
10
- import type { PromptVersionStore } from '../../../memory/src/prompt-version-store.js';
10
+ type PromptVersionStore = any;
11
11
  export interface ResolvedPrompt {
12
12
  prompt: string;
13
13
  version: string;
@@ -19,4 +19,5 @@ export declare class PromptExperimentRouter {
19
19
  constructor(store: PromptVersionStore);
20
20
  resolvePromptForSpawn(agentSlug: string): ResolvedPrompt;
21
21
  }
22
+ export {};
22
23
  //# sourceMappingURL=prompt-experiment.d.ts.map
@@ -5,7 +5,7 @@
5
5
  * routes to the candidate or control version. Falls back to the active version
6
6
  * when no experiment is running.
7
7
  *
8
- * @module @monoes/cli/agents/prompt-experiment
8
+ * @module @monomind/cli/agents/prompt-experiment
9
9
  */
10
10
  export class PromptExperimentRouter {
11
11
  store;
@@ -4,9 +4,11 @@
4
4
  * Provides publish-from-file, promote, rollback, and experiment
5
5
  * start/stop workflows on top of PromptVersionStore.
6
6
  *
7
- * @module @monoes/cli/agents/prompt-version-manager
7
+ * @module @monomind/cli/agents/prompt-version-manager
8
8
  */
9
- import type { PromptVersionStore, PromptVersion, PromptExperiment } from '../../../memory/src/prompt-version-store.js';
9
+ type PromptVersionStore = any;
10
+ type PromptVersion = any;
11
+ type PromptExperiment = any;
10
12
  export declare class PromptVersionManager {
11
13
  private readonly store;
12
14
  constructor(store: PromptVersionStore);
@@ -16,4 +18,5 @@ export declare class PromptVersionManager {
16
18
  startExperiment(experiment: PromptExperiment): void;
17
19
  stopExperiment(agentSlug: string, promoteWinner?: boolean): void;
18
20
  }
21
+ export {};
19
22
  //# sourceMappingURL=prompt-version-manager.d.ts.map
@@ -4,16 +4,39 @@
4
4
  * Provides publish-from-file, promote, rollback, and experiment
5
5
  * start/stop workflows on top of PromptVersionStore.
6
6
  *
7
- * @module @monoes/cli/agents/prompt-version-manager
7
+ * @module @monomind/cli/agents/prompt-version-manager
8
8
  */
9
9
  import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
10
11
  export class PromptVersionManager {
11
12
  store;
12
13
  constructor(store) {
13
14
  this.store = store;
14
15
  }
15
16
  publishFromFile(agentSlug, filePath, newVersion, changelog) {
16
- const prompt = fs.readFileSync(filePath, 'utf-8');
17
+ // Symlink-aware containment: path.resolve does NOT follow symlinks, so
18
+ // a symlink under cwd pointing at /etc/shadow would have passed the
19
+ // prefix-check below. Use realpathSync on both sides and reject symlinks
20
+ // at the leaf so the resolved file is provably inside the project.
21
+ const allowedRoot = fs.realpathSync(process.cwd());
22
+ const requested = path.resolve(filePath);
23
+ if (!fs.existsSync(requested)) {
24
+ throw new Error(`filePath does not exist: ${requested}`);
25
+ }
26
+ if (fs.lstatSync(requested).isSymbolicLink()) {
27
+ throw new Error('filePath must not be a symlink');
28
+ }
29
+ const resolved = fs.realpathSync(requested);
30
+ const rel = path.relative(allowedRoot, resolved);
31
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
32
+ throw new Error(`filePath must be inside the project directory: ${allowedRoot}`);
33
+ }
34
+ const MAX_PROMPT_BYTES = 1 * 1024 * 1024;
35
+ const fileSize = fs.statSync(resolved).size;
36
+ if (fileSize > MAX_PROMPT_BYTES) {
37
+ throw new Error(`filePath exceeds maximum allowed size (${MAX_PROMPT_BYTES} bytes): ${resolved}`);
38
+ }
39
+ const prompt = fs.readFileSync(resolved, 'utf-8');
17
40
  const version = {
18
41
  agentSlug,
19
42
  version: newVersion,
@@ -47,8 +70,7 @@ export class PromptVersionManager {
47
70
  if (!experiment) {
48
71
  throw new Error(`No active experiment for "${agentSlug}"`);
49
72
  }
50
- // Default winner is control
51
- const winnerId = experiment.control;
73
+ const winnerId = (experiment.winner ?? experiment.control);
52
74
  this.store.concludeExperiment(agentSlug, winnerId);
53
75
  if (promoteWinner) {
54
76
  this.store.setActive(agentSlug, winnerId);
@@ -4,9 +4,11 @@
4
4
  * JSONL-based per-agent-per-task-type scoring with time-decay.
5
5
  * Enables monomind to prefer historically successful agents for specific task types.
6
6
  */
7
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs';
8
+ import { randomBytes } from 'crypto';
8
9
  import { dirname } from 'path';
9
10
  import { calculateDecayFactor } from './score-decay.js';
11
+ import { parseJsonl } from '../utils/parse-jsonl.js';
10
12
  /** Key used to identify a unique agent+taskType pair in the JSONL store. */
11
13
  function scoreKey(agentSlug, taskType) {
12
14
  return `${agentSlug}::${taskType}`;
@@ -34,17 +36,23 @@ export class SpecializationScorer {
34
36
  if (!existsSync(this.filePath)) {
35
37
  return [];
36
38
  }
37
- const raw = readFileSync(this.filePath, 'utf-8').trim();
38
- if (!raw)
39
- return [];
40
- return raw
41
- .split('\n')
42
- .filter(Boolean)
43
- .map((line) => JSON.parse(line));
39
+ // 10MB cap. readAll is on the routing hot path; without this cap a
40
+ // bloated scorer file (planted or grown via repeated recordOutcome calls
41
+ // with diverse agentSlug::taskType keys) crashes the CLI on every route.
42
+ const stat = statSync(this.filePath);
43
+ if (stat.size > 10 * 1024 * 1024) {
44
+ throw new Error('Scorer store exceeds 10MB; run compaction');
45
+ }
46
+ const raw = readFileSync(this.filePath, 'utf-8');
47
+ return parseJsonl(raw).filter((r) => r !== null && typeof r === 'object' && !Array.isArray(r) &&
48
+ Object.getPrototypeOf(r) === Object.prototype);
44
49
  }
45
50
  writeAll(records) {
46
51
  const lines = records.map((r) => JSON.stringify(r));
47
- writeFileSync(this.filePath, lines.join('\n') + '\n', 'utf-8');
52
+ // Unique tmp filename so concurrent recordOutcome calls don't collide.
53
+ const tmp = `${this.filePath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
54
+ writeFileSync(tmp, lines.join('\n') + '\n', 'utf-8');
55
+ renameSync(tmp, this.filePath);
48
56
  }
49
57
  // ---------------------------------------------------------------------------
50
58
  // Public API
@@ -9,11 +9,12 @@
9
9
  * - `inject` matches accumulate as additional candidates.
10
10
  * - Invalid regex patterns are silently skipped.
11
11
  */
12
- import type { TriggerPattern, TriggerMatch, TriggerIndex } from '../../../../@monoes/shared/src/types/trigger.js';
12
+ import type { TriggerPattern, TriggerMatch, TriggerIndex } from '../../../../@monomind/shared/src/types/trigger.js';
13
13
  export declare class TriggerScanner {
14
14
  private compiled;
15
15
  private patterns;
16
16
  private totalAgentsScanned;
17
+ private buildingIndex;
17
18
  constructor(patterns?: TriggerPattern[]);
18
19
  /**
19
20
  * Test all patterns against `taskDescription` and return matches.
@@ -29,7 +30,8 @@ export declare class TriggerScanner {
29
30
  * Reads each `.md` file, extracts YAML frontmatter, and looks for
30
31
  * `triggers:` entries with `pattern`, `mode`, and optional `priority`.
31
32
  */
32
- buildIndex(agentDir: string): TriggerIndex;
33
+ buildIndex(agentDir: string, allowedRoot?: string): TriggerIndex;
34
+ private _buildIndex;
33
35
  /** Add a pattern to the index at runtime. */
34
36
  addPattern(pattern: TriggerPattern): void;
35
37
  /**
@@ -43,7 +45,7 @@ export declare class TriggerScanner {
43
45
  get size(): number;
44
46
  private compileAndAdd;
45
47
  private sortByPriority;
46
- /** Recursively collect `.md` files. */
48
+ /** Recursively collect `.md` files (symlinks skipped, visited inodes tracked). */
47
49
  private collectMdFiles;
48
50
  /** Derive slug from filename. */
49
51
  private slugFromPath;
@@ -9,12 +9,13 @@
9
9
  * - `inject` matches accumulate as additional candidates.
10
10
  * - Invalid regex patterns are silently skipped.
11
11
  */
12
- import { readFileSync, readdirSync, statSync } from 'fs';
13
- import { join, extname } from 'path';
12
+ import { readFileSync, readdirSync, lstatSync, statSync, realpathSync } from 'fs';
13
+ import { join, extname, resolve, sep } from 'path';
14
14
  export class TriggerScanner {
15
15
  compiled = [];
16
16
  patterns = [];
17
17
  totalAgentsScanned = 0;
18
+ buildingIndex = false;
18
19
  constructor(patterns = []) {
19
20
  for (const p of patterns) {
20
21
  this.compileAndAdd(p);
@@ -59,14 +60,48 @@ export class TriggerScanner {
59
60
  * Reads each `.md` file, extracts YAML frontmatter, and looks for
60
61
  * `triggers:` entries with `pattern`, `mode`, and optional `priority`.
61
62
  */
62
- buildIndex(agentDir) {
63
+ buildIndex(agentDir, allowedRoot) {
64
+ if (this.buildingIndex) {
65
+ throw new Error('buildIndex is already running; concurrent invocations are not safe');
66
+ }
67
+ this.buildingIndex = true;
68
+ try {
69
+ return this._buildIndex(agentDir, allowedRoot);
70
+ }
71
+ finally {
72
+ this.buildingIndex = false;
73
+ }
74
+ }
75
+ _buildIndex(agentDir, allowedRoot) {
76
+ if (allowedRoot) {
77
+ let resolvedDir;
78
+ let resolvedRoot;
79
+ try {
80
+ resolvedDir = realpathSync(resolve(agentDir));
81
+ }
82
+ catch {
83
+ resolvedDir = resolve(agentDir);
84
+ }
85
+ try {
86
+ resolvedRoot = realpathSync(resolve(allowedRoot));
87
+ }
88
+ catch {
89
+ resolvedRoot = resolve(allowedRoot);
90
+ }
91
+ if (!resolvedDir.startsWith(resolvedRoot + sep) && resolvedDir !== resolvedRoot) {
92
+ throw new Error(`Agent directory escapes workspace: ${resolvedDir}`);
93
+ }
94
+ }
63
95
  const mdFiles = this.collectMdFiles(agentDir);
64
96
  this.patterns = [];
65
97
  this.compiled = [];
66
98
  this.totalAgentsScanned = mdFiles.length;
99
+ const MAX_AGENT_FILE_BYTES = 1 * 1024 * 1024;
67
100
  for (const filePath of mdFiles) {
68
101
  let content;
69
102
  try {
103
+ if (statSync(filePath).size > MAX_AGENT_FILE_BYTES)
104
+ continue;
70
105
  content = readFileSync(filePath, 'utf-8');
71
106
  }
72
107
  catch {
@@ -118,6 +153,14 @@ export class TriggerScanner {
118
153
  // Internal helpers
119
154
  // ---------------------------------------------------------------------------
120
155
  compileAndAdd(pattern) {
156
+ if (pattern.pattern.length > 200)
157
+ return;
158
+ // Reject patterns with nested/repeated quantifiers (ReDoS vectors)
159
+ // Covers: (a+)+, (a|b+)+, (a?){n}, ((a)+)+, [a-z]+{n}
160
+ if (/(\(.*[+*?].*\)|[+*?]){2,}|\{[0-9,]+\}.*[+*?]|(\[[^\]]*\]|\.)[+*?][+*?]/.test(pattern.pattern))
161
+ return;
162
+ if (/\([^)]*([+*][^)]*){2,}\)/.test(pattern.pattern))
163
+ return;
121
164
  try {
122
165
  const regex = new RegExp(pattern.pattern, 'i');
123
166
  this.patterns.push(pattern);
@@ -134,8 +177,8 @@ export class TriggerScanner {
134
177
  this.patterns = indexed.map((x) => x.p);
135
178
  this.compiled = indexed.map((x) => x.c);
136
179
  }
137
- /** Recursively collect `.md` files. */
138
- collectMdFiles(dir) {
180
+ /** Recursively collect `.md` files (symlinks skipped, visited inodes tracked). */
181
+ collectMdFiles(dir, visited = new Set()) {
139
182
  const results = [];
140
183
  let entries;
141
184
  try {
@@ -146,17 +189,22 @@ export class TriggerScanner {
146
189
  }
147
190
  for (const entry of entries) {
148
191
  const full = join(dir, entry);
149
- let stat;
192
+ let lstat;
150
193
  try {
151
- stat = statSync(full);
194
+ lstat = lstatSync(full);
152
195
  }
153
196
  catch {
154
197
  continue;
155
198
  }
156
- if (stat.isDirectory()) {
157
- results.push(...this.collectMdFiles(full));
199
+ if (lstat.isSymbolicLink())
200
+ continue;
201
+ if (lstat.isDirectory()) {
202
+ if (visited.has(lstat.ino))
203
+ continue;
204
+ visited.add(lstat.ino);
205
+ results.push(...this.collectMdFiles(full, visited));
158
206
  }
159
- else if (stat.isFile() && extname(entry) === '.md') {
207
+ else if (lstat.isFile() && extname(entry) === '.md') {
160
208
  results.push(full);
161
209
  }
162
210
  }
@@ -17,7 +17,6 @@ export declare class AgentVersionStore {
17
17
  constructor(dirPath: string);
18
18
  private readAll;
19
19
  private writeAll;
20
- private appendRecord;
21
20
  /**
22
21
  * Save a new version for the given agent slug.
23
22
  *
@@ -4,10 +4,11 @@
4
4
  * JSONL-based append-only storage for agent definition versions.
5
5
  * Supports save, list, get, rollback, and diff operations.
6
6
  */
7
- import { createHash, randomUUID } from 'crypto';
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from 'fs';
7
+ import { createHash, randomUUID, randomBytes } from 'crypto';
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs';
9
9
  import { join } from 'path';
10
10
  import { computeUnifiedDiff } from './version-diff.js';
11
+ import { parseJsonl } from '../utils/parse-jsonl.js';
11
12
  function toStored(r) {
12
13
  return {
13
14
  id: r.id,
@@ -63,21 +64,41 @@ export class AgentVersionStore {
63
64
  if (!existsSync(this.filePath)) {
64
65
  return [];
65
66
  }
66
- const raw = readFileSync(this.filePath, 'utf-8').trim();
67
- if (!raw)
68
- return [];
69
- return raw
70
- .split('\n')
71
- .filter(Boolean)
72
- .map((line) => fromStored(JSON.parse(line)));
67
+ const stat = statSync(this.filePath);
68
+ if (stat.size > 10 * 1024 * 1024) {
69
+ throw new Error('Version store exceeds size limit; run compaction');
70
+ }
71
+ const raw = readFileSync(this.filePath, 'utf-8');
72
+ // Drop any record whose stored contentHash does not match the SHA-256 of
73
+ // its content. saveVersion advertises tamper-evidence by computing the
74
+ // hash; without this verification step, an attacker who can write the
75
+ // JSONL file can swap `content` with a poisoned agent prompt while
76
+ // leaving `contentHash` unchanged, and the next getCurrent() returns
77
+ // the tampered prompt verbatim into the LLM context.
78
+ const records = parseJsonl(raw);
79
+ const verified = [];
80
+ for (const r of records) {
81
+ if (typeof r?.content !== 'string' ||
82
+ typeof r?.contentHash !== 'string' ||
83
+ typeof r?.id !== 'string' ||
84
+ typeof r?.slug !== 'string' ||
85
+ typeof r?.version !== 'string' ||
86
+ typeof r?.changelog !== 'string' ||
87
+ typeof r?.capturedBy !== 'string' ||
88
+ typeof r?.capturedAt !== 'string')
89
+ continue;
90
+ const actual = createHash('sha256').update(r.content).digest('hex');
91
+ if (actual !== r.contentHash)
92
+ continue; // silently drop tampered record
93
+ verified.push(r);
94
+ }
95
+ return verified.map(fromStored);
73
96
  }
74
97
  writeAll(records) {
75
98
  const lines = records.map((r) => JSON.stringify(toStored(r)));
76
- writeFileSync(this.filePath, lines.join('\n') + '\n', 'utf-8');
77
- }
78
- appendRecord(record) {
79
- const line = JSON.stringify(toStored(record)) + '\n';
80
- appendFileSync(this.filePath, line, 'utf-8');
99
+ const tmp = `${this.filePath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
100
+ writeFileSync(tmp, lines.join('\n') + '\n', 'utf-8');
101
+ renameSync(tmp, this.filePath);
81
102
  }
82
103
  // ---------------------------------------------------------------------------
83
104
  // Public API
@@ -89,19 +110,20 @@ export class AgentVersionStore {
89
110
  * the same slug as non-current, and appends the new record.
90
111
  */
91
112
  saveVersion(slug, content, version, changelog, opts = {}) {
113
+ const MAX_CONTENT_BYTES = 512 * 1024;
114
+ if (Buffer.byteLength(content, 'utf-8') > MAX_CONTENT_BYTES) {
115
+ throw new Error(`content exceeds maximum allowed size (${MAX_CONTENT_BYTES} bytes)`);
116
+ }
92
117
  const contentHash = createHash('sha256').update(content).digest('hex');
93
- // Mark previous versions as non-current (rewrite file)
118
+ // SINGLE-WRITER CONTRACT: version-store is written only by the daemon process.
119
+ // Concurrent saveVersion() calls from multiple processes would race on readAll/writeAll.
120
+ // If multi-writer access is needed in future, introduce an advisory lock here.
94
121
  const existing = this.readAll();
95
- let changed = false;
96
122
  for (const rec of existing) {
97
123
  if (rec.slug === slug && rec.isCurrent) {
98
124
  rec.isCurrent = false;
99
- changed = true;
100
125
  }
101
126
  }
102
- if (changed) {
103
- this.writeAll(existing);
104
- }
105
127
  const record = {
106
128
  id: randomUUID(),
107
129
  slug,
@@ -115,7 +137,8 @@ export class AgentVersionStore {
115
137
  capturedBy: opts.capturedBy ?? 'system',
116
138
  isCurrent: true,
117
139
  };
118
- this.appendRecord(record);
140
+ existing.push(record);
141
+ this.writeAll(existing);
119
142
  return record;
120
143
  }
121
144
  /**