monomind 1.11.13 → 1.12.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 (389) hide show
  1. package/.claude/agents/generated/channel-intelligence-director.md +87 -0
  2. package/.claude/agents/generated/chief-growth-officer.md +88 -0
  3. package/.claude/agents/generated/content-seo-strategist.md +90 -0
  4. package/.claude/agents/generated/developer-community-strategist.md +91 -0
  5. package/.claude/agents/generated/outreach-partnership-strategist.md +90 -0
  6. package/.claude/agents/generated/social-media-strategist.md +91 -0
  7. package/.claude/agents/generated/video-visual-strategist.md +90 -0
  8. package/.claude/commands/mastermind/idea.md +1 -1
  9. package/.claude/helpers/auto-memory-hook.mjs +13 -4
  10. package/.claude/helpers/control-start.cjs +5 -0
  11. package/.claude/helpers/event-logger.cjs +114 -0
  12. package/.claude/helpers/handlers/adr-draft-handler.cjs +19 -5
  13. package/.claude/helpers/handlers/agent-start-handler.cjs +13 -4
  14. package/.claude/helpers/handlers/compact-handler.cjs +2 -0
  15. package/.claude/helpers/handlers/edit-handler.cjs +1 -1
  16. package/.claude/helpers/handlers/gates-handler.cjs +3 -0
  17. package/.claude/helpers/handlers/graph-status-handler.cjs +14 -8
  18. package/.claude/helpers/handlers/loops-status-handler.cjs +5 -2
  19. package/.claude/helpers/handlers/route-handler.cjs +13 -6
  20. package/.claude/helpers/handlers/session-handler.cjs +11 -4
  21. package/.claude/helpers/handlers/session-restore-handler.cjs +21 -11
  22. package/.claude/helpers/handlers/task-handler.cjs +13 -5
  23. package/.claude/helpers/intelligence.cjs +7 -2
  24. package/.claude/helpers/loop-tracker.cjs +15 -3
  25. package/.claude/helpers/memory.cjs +6 -1
  26. package/.claude/helpers/router.cjs +5 -2
  27. package/.claude/helpers/session.cjs +2 -0
  28. package/.claude/helpers/statusline.cjs +10 -2
  29. package/.claude/helpers/utils/micro-agents.cjs +20 -4
  30. package/.claude/scheduled_tasks.lock +1 -1
  31. package/.claude/settings.json +92 -1
  32. package/.claude/skills/mastermind/_protocol.md +23 -13
  33. package/.claude/skills/mastermind/architect.md +6 -9
  34. package/.claude/skills/mastermind/build.md +3 -3
  35. package/.claude/skills/mastermind/content.md +3 -3
  36. package/.claude/skills/mastermind/createorg.md +2 -2
  37. package/.claude/skills/mastermind/finance.md +3 -3
  38. package/.claude/skills/mastermind/idea.md +5 -3
  39. package/.claude/skills/mastermind/marketing.md +3 -3
  40. package/.claude/skills/mastermind/monitor.md +2 -2
  41. package/.claude/skills/mastermind/release.md +3 -3
  42. package/.claude/skills/mastermind/research.md +3 -3
  43. package/.claude/skills/mastermind/review.md +3 -3
  44. package/.claude/skills/mastermind/runorg.md +153 -86
  45. package/.claude/skills/mastermind/sales.md +3 -3
  46. package/README.md +286 -129
  47. package/package.json +19 -2
  48. package/packages/@monomind/cli/README.md +286 -129
  49. package/packages/@monomind/cli/bundled-graph/dist/src/build.js +73 -0
  50. package/packages/@monomind/cli/bundled-graph/dist/src/cluster.js +120 -0
  51. package/packages/@monomind/cli/bundled-graph/package.json +57 -0
  52. package/packages/@monomind/cli/dist/src/agents/halt-signal.d.ts +25 -0
  53. package/packages/@monomind/cli/dist/src/agents/halt-signal.js +76 -0
  54. package/packages/@monomind/cli/dist/src/agents/index.d.ts +18 -0
  55. package/packages/@monomind/cli/dist/src/agents/index.js +13 -0
  56. package/packages/@monomind/cli/dist/src/agents/managed-agent.d.ts +41 -0
  57. package/packages/@monomind/cli/dist/src/agents/managed-agent.js +69 -0
  58. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +23 -0
  59. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +49 -0
  60. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +22 -0
  61. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +80 -0
  62. package/packages/@monomind/cli/dist/src/agents/registry-builder.js +2 -0
  63. package/packages/@monomind/cli/dist/src/agents/registry-query.d.ts +71 -0
  64. package/packages/@monomind/cli/dist/src/agents/registry-query.js +125 -0
  65. package/packages/@monomind/cli/dist/src/agents/score-decay.d.ts +19 -0
  66. package/packages/@monomind/cli/dist/src/agents/score-decay.js +22 -0
  67. package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.d.ts +13 -0
  68. package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.js +40 -0
  69. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.d.ts +54 -0
  70. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +212 -0
  71. package/packages/@monomind/cli/dist/src/agents/termination-watcher.d.ts +30 -0
  72. package/packages/@monomind/cli/dist/src/agents/termination-watcher.js +84 -0
  73. package/packages/@monomind/cli/dist/src/agents/trigger-index.d.ts +20 -0
  74. package/packages/@monomind/cli/dist/src/agents/trigger-index.js +38 -0
  75. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +64 -0
  76. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +308 -0
  77. package/packages/@monomind/cli/dist/src/agents/version-diff.d.ts +18 -0
  78. package/packages/@monomind/cli/dist/src/agents/version-diff.js +64 -0
  79. package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +60 -0
  80. package/packages/@monomind/cli/dist/src/agents/version-store.js +235 -0
  81. package/packages/@monomind/cli/dist/src/autopilot-state.js +10 -5
  82. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +13 -0
  83. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +20 -9
  84. package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.d.ts +45 -0
  85. package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.js +404 -0
  86. package/packages/@monomind/cli/dist/src/browser/actions.js +10 -3
  87. package/packages/@monomind/cli/dist/src/browser/browser.js +12 -2
  88. package/packages/@monomind/cli/dist/src/browser/cdp.js +21 -3
  89. package/packages/@monomind/cli/dist/src/browser/har.js +27 -5
  90. package/packages/@monomind/cli/dist/src/commands/agent-wasm.d.ts +14 -0
  91. package/packages/@monomind/cli/dist/src/commands/agent-wasm.js +333 -0
  92. package/packages/@monomind/cli/dist/src/commands/agent.js +11 -8
  93. package/packages/@monomind/cli/dist/src/commands/analyze.js +36 -21
  94. package/packages/@monomind/cli/dist/src/commands/autopilot.js +12 -4
  95. package/packages/@monomind/cli/dist/src/commands/benchmark.js +51 -8
  96. package/packages/@monomind/cli/dist/src/commands/browse.js +5 -2
  97. package/packages/@monomind/cli/dist/src/commands/claims.js +29 -11
  98. package/packages/@monomind/cli/dist/src/commands/cleanup.js +25 -5
  99. package/packages/@monomind/cli/dist/src/commands/config.js +15 -7
  100. package/packages/@monomind/cli/dist/src/commands/daemon.js +6 -0
  101. package/packages/@monomind/cli/dist/src/commands/deployment.js +34 -19
  102. package/packages/@monomind/cli/dist/src/commands/doctor.js +151 -20
  103. package/packages/@monomind/cli/dist/src/commands/guidance.js +15 -2
  104. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +37 -14
  105. package/packages/@monomind/cli/dist/src/commands/hooks.js +42 -25
  106. package/packages/@monomind/cli/dist/src/commands/init.js +9 -4
  107. package/packages/@monomind/cli/dist/src/commands/issues.js +29 -26
  108. package/packages/@monomind/cli/dist/src/commands/mcp.js +11 -5
  109. package/packages/@monomind/cli/dist/src/commands/memory.js +10 -0
  110. package/packages/@monomind/cli/dist/src/commands/migrate.js +5 -5
  111. package/packages/@monomind/cli/dist/src/commands/monograph.js +18 -5
  112. package/packages/@monomind/cli/dist/src/commands/monovector/backup.js +8 -2
  113. package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.js +20 -7
  114. package/packages/@monomind/cli/dist/src/commands/monovector/import.js +15 -0
  115. package/packages/@monomind/cli/dist/src/commands/monovector/migrate.js +4 -1
  116. package/packages/@monomind/cli/dist/src/commands/monovector/optimize.js +11 -0
  117. package/packages/@monomind/cli/dist/src/commands/monovector/setup.js +11 -1
  118. package/packages/@monomind/cli/dist/src/commands/neural.js +1 -1
  119. package/packages/@monomind/cli/dist/src/commands/performance.js +20 -7
  120. package/packages/@monomind/cli/dist/src/commands/platforms.js +90 -8
  121. package/packages/@monomind/cli/dist/src/commands/plugins.js +12 -5
  122. package/packages/@monomind/cli/dist/src/commands/process.js +33 -10
  123. package/packages/@monomind/cli/dist/src/commands/progress.js +5 -3
  124. package/packages/@monomind/cli/dist/src/commands/providers.js +5 -5
  125. package/packages/@monomind/cli/dist/src/commands/replay.js +8 -2
  126. package/packages/@monomind/cli/dist/src/commands/route.js +27 -7
  127. package/packages/@monomind/cli/dist/src/commands/security.js +4 -0
  128. package/packages/@monomind/cli/dist/src/commands/session.js +12 -1
  129. package/packages/@monomind/cli/dist/src/commands/start.js +11 -4
  130. package/packages/@monomind/cli/dist/src/commands/status.js +7 -4
  131. package/packages/@monomind/cli/dist/src/commands/swarm.js +27 -13
  132. package/packages/@monomind/cli/dist/src/commands/task.js +26 -11
  133. package/packages/@monomind/cli/dist/src/commands/tokens.js +7 -2
  134. package/packages/@monomind/cli/dist/src/commands/transfer-store.js +36 -22
  135. package/packages/@monomind/cli/dist/src/commands/ui.js +68 -0
  136. package/packages/@monomind/cli/dist/src/commands/update.js +15 -3
  137. package/packages/@monomind/cli/dist/src/commands/workflow.js +39 -6
  138. package/packages/@monomind/cli/dist/src/consensus/audit-writer.js +18 -7
  139. package/packages/@monomind/cli/dist/src/consensus/index.d.ts +7 -0
  140. package/packages/@monomind/cli/dist/src/consensus/index.js +6 -0
  141. package/packages/@monomind/cli/dist/src/consensus/vote-signer.js +25 -8
  142. package/packages/@monomind/cli/dist/src/context/context-provider.d.ts +44 -0
  143. package/packages/@monomind/cli/dist/src/context/context-provider.js +25 -0
  144. package/packages/@monomind/cli/dist/src/context/git-state-provider.d.ts +12 -0
  145. package/packages/@monomind/cli/dist/src/context/git-state-provider.js +34 -0
  146. package/packages/@monomind/cli/dist/src/context/index.d.ts +12 -0
  147. package/packages/@monomind/cli/dist/src/context/index.js +12 -0
  148. package/packages/@monomind/cli/dist/src/context/project-conventions-provider.d.ts +15 -0
  149. package/packages/@monomind/cli/dist/src/context/project-conventions-provider.js +19 -0
  150. package/packages/@monomind/cli/dist/src/context/prompt-assembler.d.ts +26 -0
  151. package/packages/@monomind/cli/dist/src/context/prompt-assembler.js +93 -0
  152. package/packages/@monomind/cli/dist/src/context/task-history-provider.d.ts +24 -0
  153. package/packages/@monomind/cli/dist/src/context/task-history-provider.js +32 -0
  154. package/packages/@monomind/cli/dist/src/context/user-preferences-provider.d.ts +14 -0
  155. package/packages/@monomind/cli/dist/src/context/user-preferences-provider.js +27 -0
  156. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +31 -0
  157. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +81 -0
  158. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.d.ts +24 -0
  159. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +65 -0
  160. package/packages/@monomind/cli/dist/src/dlq/index.d.ts +10 -0
  161. package/packages/@monomind/cli/dist/src/dlq/index.js +7 -0
  162. package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +33 -0
  163. package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +107 -0
  164. package/packages/@monomind/cli/dist/src/eval/dataset-runner.d.ts +23 -0
  165. package/packages/@monomind/cli/dist/src/eval/dataset-runner.js +59 -0
  166. package/packages/@monomind/cli/dist/src/eval/index.d.ts +10 -0
  167. package/packages/@monomind/cli/dist/src/eval/index.js +7 -0
  168. package/packages/@monomind/cli/dist/src/eval/trace-collector.d.ts +40 -0
  169. package/packages/@monomind/cli/dist/src/eval/trace-collector.js +102 -0
  170. package/packages/@monomind/cli/dist/src/index.js +7 -3
  171. package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
  172. package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.js +264 -0
  173. package/packages/@monomind/cli/dist/src/init/executor.js +14 -11
  174. package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +20 -4
  175. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +33 -12
  176. package/packages/@monomind/cli/dist/src/interactive/interrupt.d.ts +22 -0
  177. package/packages/@monomind/cli/dist/src/interactive/interrupt.js +71 -0
  178. package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.d.ts +25 -0
  179. package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.js +48 -0
  180. package/packages/@monomind/cli/dist/src/mcp/tool-registry.d.ts +61 -0
  181. package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +246 -0
  182. package/packages/@monomind/cli/dist/src/mcp-tools/a2a-tools.js +98 -13
  183. package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +16 -3
  184. package/packages/@monomind/cli/dist/src/mcp-tools/analyze-tools.js +80 -17
  185. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +84 -22
  186. package/packages/@monomind/cli/dist/src/mcp-tools/claims-tools.js +35 -7
  187. package/packages/@monomind/cli/dist/src/mcp-tools/config-tools.js +82 -17
  188. package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.js +37 -4
  189. package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.js +49 -7
  190. package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +45 -18
  191. package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +75 -25
  192. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +32 -10
  193. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +91 -20
  194. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +188 -29
  195. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +25 -7
  196. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +11 -2
  197. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +148 -26
  198. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +44 -9
  199. package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +45 -10
  200. package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +7 -4
  201. package/packages/@monomind/cli/dist/src/mcp-tools/request-tracker.js +15 -1
  202. package/packages/@monomind/cli/dist/src/mcp-tools/security-tools.js +61 -9
  203. package/packages/@monomind/cli/dist/src/mcp-tools/session-tools.js +45 -14
  204. package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +15 -3
  205. package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +14 -7
  206. package/packages/@monomind/cli/dist/src/mcp-tools/task-tools.js +52 -10
  207. package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.js +40 -6
  208. package/packages/@monomind/cli/dist/src/mcp-tools/transfer-tools.js +37 -4
  209. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.d.ts +9 -0
  210. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.js +230 -0
  211. package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +29 -6
  212. package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +26 -10
  213. package/packages/@monomind/cli/dist/src/memory/intelligence.js +80 -19
  214. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +21 -2
  215. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +67 -3
  216. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +14 -4
  217. package/packages/@monomind/cli/dist/src/model/complexity-scorer.d.ts +21 -0
  218. package/packages/@monomind/cli/dist/src/model/complexity-scorer.js +106 -0
  219. package/packages/@monomind/cli/dist/src/model/index.d.ts +4 -0
  220. package/packages/@monomind/cli/dist/src/model/index.js +4 -0
  221. package/packages/@monomind/cli/dist/src/model/model-settings.d.ts +22 -0
  222. package/packages/@monomind/cli/dist/src/model/model-settings.js +33 -0
  223. package/packages/@monomind/cli/dist/src/model/model-tier-resolver.d.ts +24 -0
  224. package/packages/@monomind/cli/dist/src/model/model-tier-resolver.js +65 -0
  225. package/packages/@monomind/cli/dist/src/monovector/capabilities.d.ts +34 -0
  226. package/packages/@monomind/cli/dist/src/monovector/capabilities.js +37 -0
  227. package/packages/@monomind/cli/dist/src/monovector/command-outcomes.js +43 -7
  228. package/packages/@monomind/cli/dist/src/monovector/coverage-router.js +8 -4
  229. package/packages/@monomind/cli/dist/src/monovector/coverage-tools.js +6 -3
  230. package/packages/@monomind/cli/dist/src/monovector/diff-classifier.js +13 -0
  231. package/packages/@monomind/cli/dist/src/monovector/route-outcomes.d.ts +2 -1
  232. package/packages/@monomind/cli/dist/src/monovector/route-outcomes.js +46 -4
  233. package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +1 -1
  234. package/packages/@monomind/cli/dist/src/orchestration/index.d.ts +7 -0
  235. package/packages/@monomind/cli/dist/src/orchestration/index.js +6 -0
  236. package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.d.ts +11 -0
  237. package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.js +31 -0
  238. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.d.ts +68 -0
  239. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +180 -0
  240. package/packages/@monomind/cli/dist/src/plugins/manager.js +8 -3
  241. package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +46 -2
  242. package/packages/@monomind/cli/dist/src/plugins/store/search.js +5 -4
  243. package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.d.ts +7 -0
  244. package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.js +126 -0
  245. package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.d.ts +12 -0
  246. package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.js +188 -0
  247. package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.d.ts +7 -0
  248. package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.js +206 -0
  249. package/packages/@monomind/cli/dist/src/production/circuit-breaker.js +17 -3
  250. package/packages/@monomind/cli/dist/src/production/error-handler.js +3 -0
  251. package/packages/@monomind/cli/dist/src/production/monitoring.js +20 -3
  252. package/packages/@monomind/cli/dist/src/production/rate-limiter.js +13 -4
  253. package/packages/@monomind/cli/dist/src/production/retry.js +17 -9
  254. package/packages/@monomind/cli/dist/src/routing/embed-worker.js +6 -2
  255. package/packages/@monomind/cli/dist/src/routing/embedder.js +0 -0
  256. package/packages/@monomind/cli/dist/src/routing/llm-caller.js +13 -2
  257. package/packages/@monomind/cli/dist/src/routing/route-layer-factory.js +18 -3
  258. package/packages/@monomind/cli/dist/src/runtime/headless.d.ts +60 -0
  259. package/packages/@monomind/cli/dist/src/runtime/headless.js +284 -0
  260. package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.d.ts +50 -0
  261. package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.js +95 -0
  262. package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +1 -0
  263. package/packages/@monomind/cli/dist/src/services/claim-service.js +8 -0
  264. package/packages/@monomind/cli/dist/src/services/config-file-manager.js +14 -2
  265. package/packages/@monomind/cli/dist/src/services/container-worker-pool.d.ts +197 -0
  266. package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +623 -0
  267. package/packages/@monomind/cli/dist/src/services/headless-worker-executor.js +18 -2
  268. package/packages/@monomind/cli/dist/src/services/index.d.ts +13 -0
  269. package/packages/@monomind/cli/dist/src/services/index.js +11 -0
  270. package/packages/@monomind/cli/dist/src/services/worker-daemon.js +53 -12
  271. package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +201 -0
  272. package/packages/@monomind/cli/dist/src/services/worker-queue.js +594 -0
  273. package/packages/@monomind/cli/dist/src/swarm/communication-graph.d.ts +25 -0
  274. package/packages/@monomind/cli/dist/src/swarm/communication-graph.js +77 -0
  275. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +31 -0
  276. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +61 -0
  277. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +19 -0
  278. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +68 -0
  279. package/packages/@monomind/cli/dist/src/transfer/anonymization/index.d.ts +0 -3
  280. package/packages/@monomind/cli/dist/src/transfer/anonymization/index.js +16 -1
  281. package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.d.ts +13 -0
  282. package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.js +205 -0
  283. package/packages/@monomind/cli/dist/src/transfer/export.js +8 -0
  284. package/packages/@monomind/cli/dist/src/transfer/ipfs/upload.js +33 -3
  285. package/packages/@monomind/cli/dist/src/transfer/serialization/cfp.js +9 -3
  286. package/packages/@monomind/cli/dist/src/transfer/storage/gcs.js +37 -3
  287. package/packages/@monomind/cli/dist/src/transfer/store/discovery.js +45 -3
  288. package/packages/@monomind/cli/dist/src/transfer/store/download.js +5 -0
  289. package/packages/@monomind/cli/dist/src/transfer/store/publish.js +13 -1
  290. package/packages/@monomind/cli/dist/src/transfer/store/registry.d.ts +8 -0
  291. package/packages/@monomind/cli/dist/src/transfer/store/registry.js +30 -5
  292. package/packages/@monomind/cli/dist/src/transfer/store/search.js +20 -5
  293. package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.d.ts +12 -0
  294. package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.js +190 -0
  295. package/packages/@monomind/cli/dist/src/transfer/test-seraphine.d.ts +6 -0
  296. package/packages/@monomind/cli/dist/src/transfer/test-seraphine.js +105 -0
  297. package/packages/@monomind/cli/dist/src/transfer/tests/test-store.d.ts +7 -0
  298. package/packages/@monomind/cli/dist/src/transfer/tests/test-store.js +214 -0
  299. package/packages/@monomind/cli/dist/src/update/checker.js +59 -7
  300. package/packages/@monomind/cli/dist/src/update/executor.js +50 -3
  301. package/packages/@monomind/cli/dist/src/update/index.js +18 -1
  302. package/packages/@monomind/cli/dist/src/update/rate-limiter.d.ts +6 -0
  303. package/packages/@monomind/cli/dist/src/update/rate-limiter.js +79 -7
  304. package/packages/@monomind/cli/dist/src/update/validator.js +52 -1
  305. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.d.ts +10 -0
  306. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +82 -0
  307. package/packages/@monomind/cli/dist/src/workflow/context-resolver.d.ts +12 -0
  308. package/packages/@monomind/cli/dist/src/workflow/context-resolver.js +23 -0
  309. package/packages/@monomind/cli/dist/src/workflow/dag-builder.d.ts +17 -0
  310. package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +129 -0
  311. package/packages/@monomind/cli/dist/src/workflow/dag-executor.d.ts +9 -0
  312. package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +116 -0
  313. package/packages/@monomind/cli/dist/src/workflow/dag-types.d.ts +41 -0
  314. package/packages/@monomind/cli/dist/src/workflow/dag-types.js +8 -0
  315. package/packages/@monomind/cli/dist/src/workflow/dsl-parser.d.ts +12 -0
  316. package/packages/@monomind/cli/dist/src/workflow/dsl-parser.js +20 -0
  317. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +165 -0
  318. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +82 -0
  319. package/packages/@monomind/cli/dist/src/workflow/index.d.ts +13 -0
  320. package/packages/@monomind/cli/dist/src/workflow/index.js +11 -0
  321. package/packages/@monomind/cli/dist/src/workflow/template-engine.d.ts +11 -0
  322. package/packages/@monomind/cli/dist/src/workflow/template-engine.js +40 -0
  323. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.d.ts +29 -0
  324. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +227 -0
  325. package/packages/@monomind/cli/package.json +9 -10
  326. package/packages/@monomind/guidance/dist/adversarial.d.ts +284 -0
  327. package/packages/@monomind/guidance/dist/adversarial.js +572 -0
  328. package/packages/@monomind/guidance/dist/analyzer.d.ts +530 -0
  329. package/packages/@monomind/guidance/dist/analyzer.js +2518 -0
  330. package/packages/@monomind/guidance/dist/artifacts.d.ts +283 -0
  331. package/packages/@monomind/guidance/dist/artifacts.js +356 -0
  332. package/packages/@monomind/guidance/dist/authority.d.ts +290 -0
  333. package/packages/@monomind/guidance/dist/authority.js +558 -0
  334. package/packages/@monomind/guidance/dist/capabilities.d.ts +209 -0
  335. package/packages/@monomind/guidance/dist/capabilities.js +485 -0
  336. package/packages/@monomind/guidance/dist/coherence.d.ts +233 -0
  337. package/packages/@monomind/guidance/dist/coherence.js +372 -0
  338. package/packages/@monomind/guidance/dist/compiler.d.ts +87 -0
  339. package/packages/@monomind/guidance/dist/compiler.js +419 -0
  340. package/packages/@monomind/guidance/dist/conformance-kit.d.ts +225 -0
  341. package/packages/@monomind/guidance/dist/conformance-kit.js +629 -0
  342. package/packages/@monomind/guidance/dist/continue-gate.d.ts +214 -0
  343. package/packages/@monomind/guidance/dist/continue-gate.js +353 -0
  344. package/packages/@monomind/guidance/dist/crypto-utils.d.ts +17 -0
  345. package/packages/@monomind/guidance/dist/crypto-utils.js +24 -0
  346. package/packages/@monomind/guidance/dist/evolution.d.ts +282 -0
  347. package/packages/@monomind/guidance/dist/evolution.js +500 -0
  348. package/packages/@monomind/guidance/dist/gates.d.ts +79 -0
  349. package/packages/@monomind/guidance/dist/gates.js +302 -0
  350. package/packages/@monomind/guidance/dist/gateway.d.ts +206 -0
  351. package/packages/@monomind/guidance/dist/gateway.js +452 -0
  352. package/packages/@monomind/guidance/dist/generators.d.ts +153 -0
  353. package/packages/@monomind/guidance/dist/generators.js +682 -0
  354. package/packages/@monomind/guidance/dist/headless.d.ts +177 -0
  355. package/packages/@monomind/guidance/dist/headless.js +342 -0
  356. package/packages/@monomind/guidance/dist/hooks.d.ts +109 -0
  357. package/packages/@monomind/guidance/dist/hooks.js +347 -0
  358. package/packages/@monomind/guidance/dist/index.d.ts +205 -0
  359. package/packages/@monomind/guidance/dist/index.js +321 -0
  360. package/packages/@monomind/guidance/dist/ledger.d.ts +162 -0
  361. package/packages/@monomind/guidance/dist/ledger.js +375 -0
  362. package/packages/@monomind/guidance/dist/manifest-validator.d.ts +289 -0
  363. package/packages/@monomind/guidance/dist/manifest-validator.js +838 -0
  364. package/packages/@monomind/guidance/dist/memory-gate.d.ts +222 -0
  365. package/packages/@monomind/guidance/dist/memory-gate.js +382 -0
  366. package/packages/@monomind/guidance/dist/meta-governance.d.ts +265 -0
  367. package/packages/@monomind/guidance/dist/meta-governance.js +348 -0
  368. package/packages/@monomind/guidance/dist/optimizer.d.ts +104 -0
  369. package/packages/@monomind/guidance/dist/optimizer.js +329 -0
  370. package/packages/@monomind/guidance/dist/persistence.d.ts +189 -0
  371. package/packages/@monomind/guidance/dist/persistence.js +464 -0
  372. package/packages/@monomind/guidance/dist/proof.d.ts +185 -0
  373. package/packages/@monomind/guidance/dist/proof.js +238 -0
  374. package/packages/@monomind/guidance/dist/retriever.d.ts +116 -0
  375. package/packages/@monomind/guidance/dist/retriever.js +394 -0
  376. package/packages/@monomind/guidance/dist/ruvbot-integration.d.ts +370 -0
  377. package/packages/@monomind/guidance/dist/ruvbot-integration.js +738 -0
  378. package/packages/@monomind/guidance/dist/temporal.d.ts +426 -0
  379. package/packages/@monomind/guidance/dist/temporal.js +658 -0
  380. package/packages/@monomind/guidance/dist/trust.d.ts +283 -0
  381. package/packages/@monomind/guidance/dist/trust.js +473 -0
  382. package/packages/@monomind/guidance/dist/truth-anchors.d.ts +276 -0
  383. package/packages/@monomind/guidance/dist/truth-anchors.js +488 -0
  384. package/packages/@monomind/guidance/dist/types.d.ts +378 -0
  385. package/packages/@monomind/guidance/dist/types.js +10 -0
  386. package/packages/@monomind/guidance/dist/uncertainty.d.ts +372 -0
  387. package/packages/@monomind/guidance/dist/uncertainty.js +619 -0
  388. package/packages/@monomind/guidance/dist/wasm-kernel.d.ts +48 -0
  389. package/packages/@monomind/guidance/dist/wasm-kernel.js +158 -0
@@ -1,5 +1,5 @@
1
1
  import { getProjectCwd } from './types.js';
2
- import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
2
+ import { existsSync, readFileSync, statSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  // Storage paths
5
5
  const STORAGE_DIR = '.monomind';
@@ -17,10 +17,11 @@ function ensureCoordDir() {
17
17
  mkdirSync(dir, { recursive: true });
18
18
  }
19
19
  }
20
+ const MAX_COORD_STORE_BYTES = 10 * 1024 * 1024; // 10 MB
20
21
  function loadCoordStore() {
21
22
  try {
22
23
  const path = getCoordPath();
23
- if (existsSync(path)) {
24
+ if (existsSync(path) && statSync(path).size <= MAX_COORD_STORE_BYTES) {
24
25
  return JSON.parse(readFileSync(path, 'utf-8'));
25
26
  }
26
27
  }
@@ -417,6 +418,10 @@ export const coordinationTools = [
417
418
  }
418
419
  if (action === 'status') {
419
420
  if (args.proposalId) {
421
+ // Validate proposalId length before O(n) .find() scan.
422
+ if (typeof args.proposalId !== 'string' || args.proposalId.length > 256) {
423
+ return { success: false, error: 'proposalId must be a string (max 256 chars)' };
424
+ }
420
425
  // Status for specific proposal
421
426
  const p = consensus.pending.find(x => x.proposalId === args.proposalId);
422
427
  if (p) {
@@ -513,10 +518,34 @@ export const coordinationTools = [
513
518
  };
514
519
  }
515
520
  if (action === 'vote') {
516
- const p = consensus.pending.find(x => x.proposalId === args.proposalId);
521
+ // Validate proposalId before using it in .find() to prevent DoS via
522
+ // oversized string comparisons across all pending proposals.
523
+ const rawProposalIdVote = args.proposalId;
524
+ if (typeof rawProposalIdVote !== 'string' || rawProposalIdVote.length === 0 || rawProposalIdVote.length > 256) {
525
+ return { success: false, error: 'proposalId must be a non-empty string (max 256 chars)' };
526
+ }
527
+ const p = consensus.pending.find(x => x.proposalId === rawProposalIdVote);
517
528
  if (!p)
518
529
  return { success: false, error: 'Proposal not found or already resolved' };
519
- const voterId = args.voterId;
530
+ const rawVoterId = args.voterId;
531
+ // Validate voterId — it becomes a key in p.votes (a plain object).
532
+ // Without these checks an attacker can supply "__proto__", "constructor",
533
+ // or "prototype" to corrupt the object's inherited properties, or supply
534
+ // a very long string to cause O(n) comparisons, or flood the votes dict
535
+ // with thousands of unique IDs to inflate store.json indefinitely.
536
+ const FORBIDDEN_VOTER_IDS = new Set(['__proto__', 'constructor', 'prototype']);
537
+ const MAX_VOTER_ID_LEN = 256;
538
+ const MAX_VOTERS_PER_PROPOSAL = 10_000;
539
+ if (!rawVoterId || typeof rawVoterId !== 'string' || rawVoterId.length > MAX_VOTER_ID_LEN) {
540
+ return { success: false, error: `voterId must be a non-empty string (max ${MAX_VOTER_ID_LEN} chars)` };
541
+ }
542
+ if (FORBIDDEN_VOTER_IDS.has(rawVoterId)) {
543
+ return { success: false, error: 'Forbidden voterId' };
544
+ }
545
+ if (!Object.hasOwn(p.votes, rawVoterId) && Object.keys(p.votes).length >= MAX_VOTERS_PER_PROPOSAL) {
546
+ return { success: false, error: `Voter limit per proposal (${MAX_VOTERS_PER_PROPOSAL}) reached` };
547
+ }
548
+ const voterId = rawVoterId;
520
549
  if (!voterId)
521
550
  return { success: false, error: 'voterId is required' };
522
551
  const voteValue = args.vote === 'accept';
@@ -616,6 +645,10 @@ export const coordinationTools = [
616
645
  if (action === 'commit') {
617
646
  // Commit is a no-op confirmation for already-resolved proposals
618
647
  if (args.proposalId) {
648
+ // Validate proposalId length before O(n) .find() scan.
649
+ if (typeof args.proposalId !== 'string' || args.proposalId.length > 256) {
650
+ return { success: false, error: 'proposalId must be a string (max 256 chars)' };
651
+ }
619
652
  const h = consensus.history.find(x => x.proposalId === args.proposalId);
620
653
  if (h) {
621
654
  return {
@@ -73,16 +73,41 @@ export const daaTools = [
73
73
  },
74
74
  handler: async (input) => {
75
75
  const store = loadDAAStore();
76
- const id = input.id;
76
+ // Cap all string inputs before storing to disk and before they flow into
77
+ // bridgeStoreEntry → generateEmbedding (hash fallback is O(n)).
78
+ const MAX_DAA_ID_LEN = 256;
79
+ const MAX_DAA_NAME_LEN = 512;
80
+ const MAX_DAA_TYPE_LEN = 128;
81
+ const MAX_DAA_CAPABILITIES = 50;
82
+ const MAX_DAA_CAPABILITY_LEN = 128;
83
+ const MAX_DAA_AGENTS = 10_000;
84
+ const rawId = input.id;
85
+ const id = typeof rawId === 'string' && rawId.length > MAX_DAA_ID_LEN
86
+ ? rawId.slice(0, MAX_DAA_ID_LEN) : rawId;
87
+ if (Object.keys(store.agents ?? {}).length >= MAX_DAA_AGENTS && !Object.hasOwn(store.agents, id)) {
88
+ return { success: false, error: `Agent store full (max ${MAX_DAA_AGENTS})` };
89
+ }
90
+ const rawName = input.name || `DAA-${id}`;
91
+ const agentName = typeof rawName === 'string' && rawName.length > MAX_DAA_NAME_LEN
92
+ ? rawName.slice(0, MAX_DAA_NAME_LEN) : rawName;
93
+ const rawType = input.type || 'autonomous';
94
+ const agentType = typeof rawType === 'string' && rawType.length > MAX_DAA_TYPE_LEN
95
+ ? rawType.slice(0, MAX_DAA_TYPE_LEN) : rawType;
96
+ const rawCaps = input.capabilities || ['reasoning', 'learning'];
97
+ const capabilities = Array.isArray(rawCaps)
98
+ ? rawCaps
99
+ .slice(0, MAX_DAA_CAPABILITIES)
100
+ .map(c => typeof c === 'string' && c.length > MAX_DAA_CAPABILITY_LEN ? c.slice(0, MAX_DAA_CAPABILITY_LEN) : c)
101
+ : ['reasoning', 'learning'];
77
102
  const agent = {
78
103
  id,
79
- name: input.name || `DAA-${id}`,
80
- type: input.type || 'autonomous',
104
+ name: agentName,
105
+ type: agentType,
81
106
  status: 'active',
82
107
  cognitivePattern: input.cognitivePattern || 'adaptive',
83
108
  learningRate: input.learningRate || 0.01,
84
109
  memory: input.enableMemory ?? true,
85
- capabilities: input.capabilities || ['reasoning', 'learning'],
110
+ capabilities,
86
111
  metrics: {
87
112
  tasksCompleted: 0,
88
113
  successRate: 1.0,
@@ -202,12 +227,19 @@ export const daaTools = [
202
227
  ['__proto__', 'constructor', 'prototype'].includes(id)) {
203
228
  return { success: false, error: 'Invalid workflow id' };
204
229
  }
230
+ const MAX_DAA_WF_NAME_LEN = 512;
231
+ const MAX_DAA_WF_STEPS = 500;
205
232
  const store = loadDAAStore();
233
+ const rawWfName = input.name;
234
+ const wfName = typeof rawWfName === 'string' && rawWfName.length > MAX_DAA_WF_NAME_LEN
235
+ ? rawWfName.slice(0, MAX_DAA_WF_NAME_LEN) : rawWfName;
236
+ const rawSteps = input.steps || [];
237
+ const cappedSteps = Array.isArray(rawSteps) ? rawSteps.slice(0, MAX_DAA_WF_STEPS) : [];
206
238
  const workflow = {
207
239
  id,
208
- name: input.name,
240
+ name: wfName,
209
241
  status: 'pending',
210
- steps: (input.steps || []).map((s, i) => ({
242
+ steps: cappedSteps.map((s, i) => ({
211
243
  name: typeof s === 'string' ? s : `Step ${i + 1}`,
212
244
  status: 'pending',
213
245
  })),
@@ -292,7 +324,17 @@ export const daaTools = [
292
324
  handler: async (input) => {
293
325
  const store = loadDAAStore();
294
326
  const sourceId = input.sourceAgentId;
295
- const targetIds = input.targetAgentIds;
327
+ // Cap targetIds to prevent a large array from inflating the JSON store
328
+ // entry and the AgentDB tags blob. 100 target agents is already very
329
+ // generous for any realistic swarm configuration.
330
+ const MAX_TARGET_IDS = 100;
331
+ const MAX_TARGET_ID_LEN = 256;
332
+ const rawTargetIds = input.targetAgentIds;
333
+ const targetIds = Array.isArray(rawTargetIds)
334
+ ? rawTargetIds
335
+ .slice(0, MAX_TARGET_IDS)
336
+ .map(id => (typeof id === 'string' && id.length > MAX_TARGET_ID_LEN ? id.slice(0, MAX_TARGET_ID_LEN) : id))
337
+ : [];
296
338
  const domain = input.knowledgeDomain || 'general';
297
339
  const knowledgeId = `knowledge-${Date.now()}`;
298
340
  const knowledgeEntry = {
@@ -4,7 +4,7 @@
4
4
  * Tool definitions for ONNX embeddings with hyperbolic support and neural substrate.
5
5
  * Implements ADR-024: Embeddings MCP Tools
6
6
  */
7
- import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'fs';
7
+ import { existsSync, readFileSync, statSync, writeFileSync, renameSync, mkdirSync } from 'fs';
8
8
  import { join, resolve } from 'path';
9
9
  // Configuration paths
10
10
  const CONFIG_DIR = '.monomind';
@@ -45,10 +45,11 @@ function ensureConfigDir() {
45
45
  mkdirSync(dir, { recursive: true });
46
46
  }
47
47
  }
48
+ const MAX_EMBEDDINGS_CONFIG_BYTES = 10 * 1024 * 1024; // 10 MB
48
49
  function loadConfig() {
49
50
  try {
50
51
  const path = getConfigPath();
51
- if (existsSync(path)) {
52
+ if (existsSync(path) && statSync(path).size <= MAX_EMBEDDINGS_CONFIG_BYTES) {
52
53
  return JSON.parse(readFileSync(path, 'utf-8'));
53
54
  }
54
55
  }
@@ -413,8 +414,20 @@ export const embeddingsTools = [
413
414
  error: 'Embeddings not initialized. Run embeddings/init first.',
414
415
  };
415
416
  }
416
- const query = input.query;
417
- const topK = input.topK || 5;
417
+ // Cap query length: generateRealEmbedding has a hash-fallback that is
418
+ // O(n) over the text length, so an unbounded query is a DoS vector.
419
+ // Cap topK to prevent requesting a huge result set from searchEntries.
420
+ let query;
421
+ try {
422
+ query = validateText(input.query, 'query');
423
+ }
424
+ catch (e) {
425
+ return { success: false, error: e.message };
426
+ }
427
+ const MAX_SEARCH_TOP_K = 100;
428
+ const rawTopK = input.topK || 5;
429
+ const topK = Number.isFinite(rawTopK) && rawTopK > 0
430
+ ? Math.min(Math.floor(rawTopK), MAX_SEARCH_TOP_K) : 5;
418
431
  const threshold = input.threshold || 0.5;
419
432
  const namespace = input.namespace;
420
433
  const startTime = performance.now();
@@ -711,10 +724,15 @@ export const embeddingsTools = [
711
724
  const action = input.action || 'status';
712
725
  const curvature = config.hyperbolic.curvature;
713
726
  switch (action) {
714
- case 'convert':
715
- const embedding = input.embedding;
716
- if (!embedding || !Array.isArray(embedding)) {
717
- return { success: false, error: 'Embedding array required for convert action' };
727
+ case 'convert': {
728
+ // validateVector caps at MAX_VECTOR_DIM (8192) — prevents O(n) DoS
729
+ // in toPoincare (reduce + map over the full array).
730
+ let embedding;
731
+ try {
732
+ embedding = validateVector(input.embedding, 'embedding');
733
+ }
734
+ catch (e) {
735
+ return { success: false, error: e.message };
718
736
  }
719
737
  const poincare = toPoincare(embedding, curvature);
720
738
  return {
@@ -725,11 +743,15 @@ export const embeddingsTools = [
725
743
  curvature,
726
744
  poincareNorm: Math.sqrt(poincare.reduce((sum, x) => sum + x * x, 0)),
727
745
  };
728
- case 'distance':
729
- const emb1 = input.embedding1;
730
- const emb2 = input.embedding2;
731
- if (!emb1 || !emb2) {
732
- return { success: false, error: 'embedding1 and embedding2 required for distance action' };
746
+ }
747
+ case 'distance': {
748
+ let emb1, emb2;
749
+ try {
750
+ emb1 = validateVector(input.embedding1, 'embedding1');
751
+ emb2 = validateVector(input.embedding2, 'embedding2');
752
+ }
753
+ catch (e) {
754
+ return { success: false, error: e.message };
733
755
  }
734
756
  const dist = poincareDistance(emb1, emb2, curvature);
735
757
  return {
@@ -739,11 +761,15 @@ export const embeddingsTools = [
739
761
  curvature,
740
762
  interpretation: dist < 1 ? 'close' : dist < 2 ? 'moderate' : 'far',
741
763
  };
742
- case 'midpoint':
743
- const e1 = input.embedding1;
744
- const e2 = input.embedding2;
745
- if (!e1 || !e2) {
746
- return { success: false, error: 'embedding1 and embedding2 required for midpoint action' };
764
+ }
765
+ case 'midpoint': {
766
+ let e1, e2;
767
+ try {
768
+ e1 = validateVector(input.embedding1, 'embedding1');
769
+ e2 = validateVector(input.embedding2, 'embedding2');
770
+ }
771
+ catch (e) {
772
+ return { success: false, error: e.message };
747
773
  }
748
774
  // Simplified midpoint (proper Möbius midpoint is more complex)
749
775
  const mid = e1.map((_, i) => (e1[i] + e2[i]) / 2);
@@ -755,6 +781,7 @@ export const embeddingsTools = [
755
781
  midpoint: scaledMid,
756
782
  curvature,
757
783
  };
784
+ }
758
785
  default: // status
759
786
  return {
760
787
  success: true,
@@ -64,6 +64,21 @@ function runSafe(cmd, args, cwd) {
64
64
  function hasGhCli() {
65
65
  return run('gh --version') !== null;
66
66
  }
67
+ /**
68
+ * Validate that a MCP input value is a safe positive integer suitable for use
69
+ * as a GitHub PR/issue number in CLI arguments. Returns the integer value on
70
+ * success, or null if the input is missing, non-finite, negative, zero, or
71
+ * non-integer. Using this guard before string-interpolating the value into a
72
+ * command template prevents argument-injection attacks where an MCP client
73
+ * sends a non-numeric string (e.g. "1 --label evil") that gets split into
74
+ * extra CLI flags when `run()` tokenises the command on whitespace.
75
+ */
76
+ function safeGitHubNumber(raw) {
77
+ const n = typeof raw === 'number' ? raw : Number(raw);
78
+ if (!Number.isFinite(n) || n <= 0 || n !== Math.floor(n))
79
+ return null;
80
+ return n;
81
+ }
67
82
  export const githubTools = [
68
83
  {
69
84
  name: 'github_repo_analyze',
@@ -179,11 +194,21 @@ export const githubTools = [
179
194
  return { success: true, source: 'local-store', pullRequests: prs, total: prs.length, open: prs.filter(pr => pr.status === 'open').length };
180
195
  }
181
196
  if (action === 'create') {
197
+ // Cap PR fields: title/branch/baseBranch are passed as CLI args to gh
198
+ // (runSafe — no injection risk) and stored in the local JSON store on
199
+ // disk; body is also stored and can be very large.
200
+ const MAX_PR_TITLE_LEN = 256;
201
+ const MAX_PR_BRANCH_LEN = 256;
202
+ const MAX_PR_BODY_LEN = 64 * 1024; // 64 KB — typical PR body limit
203
+ const rawPrTitle = input.title || 'New PR';
204
+ const title = rawPrTitle.length > MAX_PR_TITLE_LEN ? rawPrTitle.slice(0, MAX_PR_TITLE_LEN) : rawPrTitle;
205
+ const rawHeadBranch = input.branch || run('git rev-parse --abbrev-ref HEAD') || 'feature';
206
+ const headBranch = rawHeadBranch.length > MAX_PR_BRANCH_LEN ? rawHeadBranch.slice(0, MAX_PR_BRANCH_LEN) : rawHeadBranch;
207
+ const rawBaseBranch = input.baseBranch || 'main';
208
+ const baseBranch = rawBaseBranch.length > MAX_PR_BRANCH_LEN ? rawBaseBranch.slice(0, MAX_PR_BRANCH_LEN) : rawBaseBranch;
209
+ const rawPrBody = input.body || '';
210
+ const body = rawPrBody.length > MAX_PR_BODY_LEN ? rawPrBody.slice(0, MAX_PR_BODY_LEN) : rawPrBody;
182
211
  if (gh) {
183
- const title = input.title || 'New PR';
184
- const headBranch = input.branch || run('git rev-parse --abbrev-ref HEAD') || 'feature';
185
- const baseBranch = input.baseBranch || 'main';
186
- const body = input.body || '';
187
212
  const result = runSafe('gh', ['pr', 'create', '--title', title, '--base', baseBranch, '--head', headBranch, '--body', body]);
188
213
  if (result) {
189
214
  return { success: true, _real: true, action: 'created', url: result };
@@ -191,15 +216,17 @@ export const githubTools = [
191
216
  }
192
217
  // Fallback: local store
193
218
  const prId = `pr-${Date.now()}`;
194
- const pr = { id: prId, title: input.title || 'New PR', status: 'open', branch: input.branch || 'feature', baseBranch: input.baseBranch || 'main', createdAt: new Date().toISOString() };
219
+ const pr = { id: prId, title, status: 'open', branch: headBranch, baseBranch, createdAt: new Date().toISOString() };
195
220
  store.prs[prId] = pr;
196
221
  saveGitHubStore(store);
197
222
  return { success: true, source: 'local-store', action: 'created', pullRequest: pr };
198
223
  }
199
224
  if (action === 'review') {
200
- const prNumber = input.prNumber;
201
- if (gh && prNumber) {
202
- const raw = run(`gh pr view ${prNumber} --json number,title,state,body,additions,deletions,changedFiles,reviews,mergeable,statusCheckRollup`);
225
+ const prNumber = safeGitHubNumber(input.prNumber);
226
+ if (!prNumber)
227
+ return { success: false, error: 'prNumber is required and must be a positive integer for review.' };
228
+ if (gh) {
229
+ const raw = runSafe('gh', ['pr', 'view', String(prNumber), '--json', 'number,title,state,body,additions,deletions,changedFiles,reviews,mergeable,statusCheckRollup']);
203
230
  if (raw) {
204
231
  try {
205
232
  return { success: true, _real: true, action: 'review', pullRequest: JSON.parse(raw) };
@@ -207,12 +234,14 @@ export const githubTools = [
207
234
  catch { /* fall through */ }
208
235
  }
209
236
  }
210
- return { success: false, error: prNumber ? 'gh CLI not available or PR not found. Install gh: https://cli.github.com' : 'prNumber is required for review.' };
237
+ return { success: false, error: 'gh CLI not available or PR not found. Install gh: https://cli.github.com' };
211
238
  }
212
239
  if (action === 'merge') {
213
- const prNumber = input.prNumber;
214
- if (gh && prNumber) {
215
- const result = run(`gh pr merge ${prNumber} --merge`);
240
+ const prNumber = safeGitHubNumber(input.prNumber);
241
+ if (!prNumber)
242
+ return { success: false, error: 'prNumber is required and must be a positive integer for merge.' };
243
+ if (gh) {
244
+ const result = runSafe('gh', ['pr', 'merge', String(prNumber), '--merge']);
216
245
  if (result !== null) {
217
246
  return { success: true, _real: true, action: 'merged', prNumber, mergedAt: new Date().toISOString() };
218
247
  }
@@ -226,9 +255,11 @@ export const githubTools = [
226
255
  return { success: true, source: 'local-store', action: 'merged', prNumber, mergedAt: new Date().toISOString() };
227
256
  }
228
257
  if (action === 'close') {
229
- const prNumber = input.prNumber;
230
- if (gh && prNumber) {
231
- const result = run(`gh pr close ${prNumber}`);
258
+ const prNumber = safeGitHubNumber(input.prNumber);
259
+ if (!prNumber)
260
+ return { success: false, error: 'prNumber is required and must be a positive integer for close.' };
261
+ if (gh) {
262
+ const result = runSafe('gh', ['pr', 'close', String(prNumber)]);
232
263
  if (result !== null) {
233
264
  return { success: true, _real: true, action: 'closed', prNumber, closedAt: new Date().toISOString() };
234
265
  }
@@ -279,9 +310,20 @@ export const githubTools = [
279
310
  return { success: true, source: 'local-store', issues, total: issues.length, open: issues.filter(i => i.status === 'open').length };
280
311
  }
281
312
  if (action === 'create') {
282
- const title = input.title || 'New Issue';
283
- const body = input.body || '';
284
- const labels = input.labels || [];
313
+ // Cap issue fields: stored in local JSON store and passed as CLI args
314
+ // to gh (runSafe no injection risk).
315
+ const MAX_ISSUE_TITLE_LEN = 256;
316
+ const MAX_ISSUE_BODY_LEN = 64 * 1024;
317
+ const MAX_ISSUE_LABELS = 20;
318
+ const MAX_ISSUE_LABEL_LEN = 128;
319
+ const rawIssueTitle = input.title || 'New Issue';
320
+ const title = rawIssueTitle.length > MAX_ISSUE_TITLE_LEN ? rawIssueTitle.slice(0, MAX_ISSUE_TITLE_LEN) : rawIssueTitle;
321
+ const rawIssueBody = input.body || '';
322
+ const body = rawIssueBody.length > MAX_ISSUE_BODY_LEN ? rawIssueBody.slice(0, MAX_ISSUE_BODY_LEN) : rawIssueBody;
323
+ const rawLabels = input.labels || [];
324
+ const labels = Array.isArray(rawLabels)
325
+ ? rawLabels.slice(0, MAX_ISSUE_LABELS).map(l => typeof l === 'string' && l.length > MAX_ISSUE_LABEL_LEN ? l.slice(0, MAX_ISSUE_LABEL_LEN) : l)
326
+ : [];
285
327
  if (gh) {
286
328
  const issueArgs = ['issue', 'create', '--title', title, '--body', body];
287
329
  if (labels.length > 0)
@@ -301,8 +343,12 @@ export const githubTools = [
301
343
  const issueNumber = input.issueNumber;
302
344
  if (gh && issueNumber) {
303
345
  const editArgs = ['issue', 'edit', String(issueNumber)];
304
- if (input.title)
305
- editArgs.push('--title', input.title);
346
+ // Cap title and labels to prevent inflating args and local store
347
+ const MAX_UPDATE_TITLE_LEN = 256;
348
+ if (input.title) {
349
+ const t = input.title;
350
+ editArgs.push('--title', t.length > MAX_UPDATE_TITLE_LEN ? t.slice(0, MAX_UPDATE_TITLE_LEN) : t);
351
+ }
306
352
  if (input.labels)
307
353
  editArgs.push('--add-label', input.labels.join(','));
308
354
  if (editArgs.length > 3) {
@@ -313,8 +359,10 @@ export const githubTools = [
313
359
  }
314
360
  const issueKey = Object.keys(store.issues).find(k => k.includes(String(issueNumber)));
315
361
  if (issueKey && store.issues[issueKey]) {
316
- if (input.title)
317
- store.issues[issueKey].title = input.title;
362
+ if (input.title) {
363
+ const t = input.title;
364
+ store.issues[issueKey].title = t.length > 256 ? t.slice(0, 256) : t;
365
+ }
318
366
  if (input.labels)
319
367
  store.issues[issueKey].labels = input.labels;
320
368
  saveGitHubStore(store);
@@ -322,9 +370,11 @@ export const githubTools = [
322
370
  return { success: true, source: 'local-store', action: 'updated', issueNumber };
323
371
  }
324
372
  if (action === 'close') {
325
- const issueNumber = input.issueNumber;
326
- if (gh && issueNumber) {
327
- const result = run(`gh issue close ${issueNumber}`);
373
+ const issueNumber = safeGitHubNumber(input.issueNumber);
374
+ if (!issueNumber)
375
+ return { success: false, error: 'issueNumber is required and must be a positive integer for close.' };
376
+ if (gh) {
377
+ const result = runSafe('gh', ['issue', 'close', String(issueNumber)]);
328
378
  if (result !== null)
329
379
  return { success: true, _real: true, action: 'closed', issueNumber, closedAt: new Date().toISOString() };
330
380
  }
@@ -7,7 +7,7 @@
7
7
  * @module @monomind/cli/mcp-tools/guidance
8
8
  */
9
9
  import { getProjectCwd } from './types.js';
10
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
10
+ import { existsSync, readFileSync, statSync, readdirSync } from 'node:fs';
11
11
  import { join, dirname } from 'node:path';
12
12
  import { fileURLToPath } from 'node:url';
13
13
  const __filename = fileURLToPath(import.meta.url);
@@ -298,6 +298,8 @@ function discoverAgents() {
298
298
  walk(full, depth + 1);
299
299
  }
300
300
  else if (entry.isFile() && entry.name.endsWith('.md') && entry.name !== 'MIGRATION_SUMMARY.md') {
301
+ if (statSync(full).size > 512 * 1024)
302
+ continue; // skip files > 512 KB
301
303
  const content = readFileSync(full, 'utf-8');
302
304
  const nameMatch = content.match(/^name:\s*(.+)$/m);
303
305
  if (nameMatch)
@@ -350,13 +352,18 @@ const guidanceCapabilities = {
350
352
  },
351
353
  },
352
354
  handler: async (params) => {
353
- const area = params.area;
355
+ // Cap area before any use — reflected verbatim in the error JSON if the
356
+ // key is unknown, which would allow a caller to embed an arbitrarily long
357
+ // string in the MCP response body.
358
+ const MAX_AREA_LEN = 128;
359
+ const rawArea = params.area;
360
+ const area = typeof rawArea === 'string' && rawArea.length <= MAX_AREA_LEN ? rawArea : undefined;
354
361
  const format = params.format || 'summary';
355
362
  if (area) {
356
363
  const cap = CAPABILITY_CATALOG[area];
357
364
  if (!cap) {
358
365
  const available = Object.keys(CAPABILITY_CATALOG).join(', ');
359
- return { content: [{ type: 'text', text: JSON.stringify({ error: `Unknown area: ${area}`, available }, null, 2) }], isError: true };
366
+ return { content: [{ type: 'text', text: JSON.stringify({ error: 'Unknown capability area', available }, null, 2) }], isError: true };
360
367
  }
361
368
  return { content: [{ type: 'text', text: JSON.stringify(cap, null, 2) }] };
362
369
  }
@@ -389,7 +396,14 @@ const guidanceRecommend = {
389
396
  required: ['task'],
390
397
  },
391
398
  handler: async (params) => {
392
- const task = params.task;
399
+ // Cap task: iterated through 14 regex patterns via route.pattern.test(task).
400
+ // Each .test() call is O(n) on the input string; without a cap an attacker
401
+ // can make every routing call O(14n) on an arbitrary-length string.
402
+ const MAX_GUIDANCE_TASK_LEN = 16 * 1024;
403
+ const rawTask = params.task;
404
+ const task = typeof rawTask === 'string' && rawTask.length > MAX_GUIDANCE_TASK_LEN
405
+ ? rawTask.slice(0, MAX_GUIDANCE_TASK_LEN)
406
+ : rawTask;
393
407
  const matches = [];
394
408
  for (const route of TASK_ROUTES) {
395
409
  if (route.pattern.test(task)) {
@@ -495,14 +509,18 @@ const guidanceWorkflow = {
495
509
  required: ['type'],
496
510
  },
497
511
  handler: async (params) => {
498
- const type = params.type;
499
- const template = WORKFLOW_TEMPLATES[type];
512
+ // Cap type before any use — reflected in the error JSON when the key is
513
+ // unknown, allowing an attacker to embed an arbitrarily long string.
514
+ const MAX_TYPE_LEN = 128;
515
+ const rawType = params.type;
516
+ const type = typeof rawType === 'string' && rawType.length <= MAX_TYPE_LEN ? rawType : '';
517
+ const template = type ? WORKFLOW_TEMPLATES[type] : undefined;
500
518
  if (!template) {
501
519
  return {
502
520
  content: [{
503
521
  type: 'text',
504
522
  text: JSON.stringify({
505
- error: `Unknown workflow: ${type}`,
523
+ error: 'Unknown workflow type',
506
524
  available: Object.keys(WORKFLOW_TEMPLATES),
507
525
  }, null, 2),
508
526
  }],
@@ -541,7 +559,11 @@ const guidanceQuickRef = {
541
559
  required: ['domain'],
542
560
  },
543
561
  handler: async (params) => {
544
- const domain = params.domain;
562
+ // Cap domain before any use — reflected in the error JSON when the key is
563
+ // unknown, allowing an attacker to embed an arbitrarily long string.
564
+ const MAX_DOMAIN_LEN = 128;
565
+ const rawDomain = params.domain;
566
+ const domain = typeof rawDomain === 'string' && rawDomain.length <= MAX_DOMAIN_LEN ? rawDomain : '';
545
567
  const refs = {
546
568
  'getting-started': {
547
569
  title: 'Getting Started',
@@ -601,9 +623,9 @@ const guidanceQuickRef = {
601
623
  ],
602
624
  },
603
625
  };
604
- const ref = refs[domain];
626
+ const ref = domain ? refs[domain] : undefined;
605
627
  if (!ref) {
606
- return { content: [{ type: 'text', text: JSON.stringify({ error: `Unknown domain: ${domain}`, available: Object.keys(refs) }, null, 2) }], isError: true };
628
+ return { content: [{ type: 'text', text: JSON.stringify({ error: 'Unknown quick-ref domain', available: Object.keys(refs) }, null, 2) }], isError: true };
607
629
  }
608
630
  return { content: [{ type: 'text', text: JSON.stringify(ref, null, 2) }] };
609
631
  },