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
@@ -3,6 +3,34 @@
3
3
  * Provides diff analysis and classification via MCP protocol
4
4
  */
5
5
  import { analyzeDiff, assessFileRisk, assessOverallRisk, classifyDiff, suggestReviewers, getGitDiffNumstat, } from '../monovector/diff-classifier.js';
6
+ // ===== Shared validation helpers =====
7
+ const MAX_REF_LEN = 256; // git ref: branch/commit/tag names are bounded
8
+ const MAX_PATH_LEN = 4096; // OS path limit
9
+ const MAX_LIMIT = 100;
10
+ const VALID_FILE_STATUS = new Set(['added', 'modified', 'deleted', 'renamed']);
11
+ // Strip filesystem paths from error messages to avoid leaking internal layout
12
+ function sanitizeError(error) {
13
+ if (error instanceof Error) {
14
+ return error.message
15
+ .replace(/\/[^\s:]+(\/|(?=\s|:|$))/g, '<path>/')
16
+ .substring(0, 500);
17
+ }
18
+ return 'Internal error';
19
+ }
20
+ // Validate a git ref: non-empty string, bounded length, no shell metacharacters.
21
+ // execFileSync already prevents shell injection but we still cap the length and
22
+ // reject control chars / obvious injection patterns so error messages don't echo
23
+ // attacker-supplied content back.
24
+ const REF_SAFE_RE = /^[a-zA-Z0-9_./:@^~\-\.{}\[\]]+$/;
25
+ function validateRef(value) {
26
+ if (typeof value !== 'string' || value.length === 0)
27
+ return 'HEAD';
28
+ if (value.length > MAX_REF_LEN)
29
+ return null;
30
+ if (!REF_SAFE_RE.test(value))
31
+ return null;
32
+ return value;
33
+ }
6
34
  /**
7
35
  * Diff Analysis Tool
8
36
  * Analyzes git diffs for change risk assessment and classification
@@ -38,7 +66,9 @@ export const analyzeDiffTool = {
38
66
  },
39
67
  },
40
68
  handler: async (params) => {
41
- const ref = params.ref || 'HEAD';
69
+ const ref = validateRef(params.ref);
70
+ if (ref === null)
71
+ return { error: true, message: 'Invalid ref: must be a safe git ref (max 256 chars, alphanumeric/._/:@^~-)' };
42
72
  const includeFileRisks = params.includeFileRisks === true;
43
73
  const includeReviewers = params.includeReviewers !== false;
44
74
  const useMonoVector = params.useMonoVector !== false;
@@ -67,7 +97,7 @@ export const analyzeDiffTool = {
67
97
  catch (error) {
68
98
  return {
69
99
  error: true,
70
- message: error instanceof Error ? error.message : String(error),
100
+ message: sanitizeError(error),
71
101
  ref,
72
102
  };
73
103
  }
@@ -93,7 +123,9 @@ export const diffRiskTool = {
93
123
  },
94
124
  },
95
125
  handler: async (params) => {
96
- const ref = params.ref || 'HEAD';
126
+ const ref = validateRef(params.ref);
127
+ if (ref === null)
128
+ return { error: true, message: 'Invalid ref: must be a safe git ref (max 256 chars, alphanumeric/._/:@^~-)' };
97
129
  try {
98
130
  const files = getGitDiffNumstat(ref);
99
131
  const fileRisks = files.map(assessFileRisk);
@@ -107,7 +139,7 @@ export const diffRiskTool = {
107
139
  catch (error) {
108
140
  return {
109
141
  error: true,
110
- message: error instanceof Error ? error.message : String(error),
142
+ message: sanitizeError(error),
111
143
  ref,
112
144
  };
113
145
  }
@@ -133,7 +165,9 @@ export const diffClassifyTool = {
133
165
  },
134
166
  },
135
167
  handler: async (params) => {
136
- const ref = params.ref || 'HEAD';
168
+ const ref = validateRef(params.ref);
169
+ if (ref === null)
170
+ return { error: true, message: 'Invalid ref: must be a safe git ref (max 256 chars, alphanumeric/._/:@^~-)' };
137
171
  try {
138
172
  const files = getGitDiffNumstat(ref);
139
173
  const classification = classifyDiff(files);
@@ -146,7 +180,7 @@ export const diffClassifyTool = {
146
180
  catch (error) {
147
181
  return {
148
182
  error: true,
149
- message: error instanceof Error ? error.message : String(error),
183
+ message: sanitizeError(error),
150
184
  ref,
151
185
  };
152
186
  }
@@ -177,8 +211,13 @@ export const diffReviewersTool = {
177
211
  },
178
212
  },
179
213
  handler: async (params) => {
180
- const ref = params.ref || 'HEAD';
181
- const limit = params.limit || 5;
214
+ const ref = validateRef(params.ref);
215
+ if (ref === null)
216
+ return { error: true, message: 'Invalid ref: must be a safe git ref (max 256 chars, alphanumeric/._/:@^~-)' };
217
+ const rawLimit = params.limit;
218
+ const limit = (typeof rawLimit === 'number' && Number.isFinite(rawLimit) && rawLimit > 0)
219
+ ? Math.min(Math.floor(rawLimit), MAX_LIMIT)
220
+ : 5;
182
221
  try {
183
222
  const files = getGitDiffNumstat(ref);
184
223
  const fileRisks = files.map(assessFileRisk);
@@ -192,7 +231,7 @@ export const diffReviewersTool = {
192
231
  catch (error) {
193
232
  return {
194
233
  error: true,
195
- message: error instanceof Error ? error.message : String(error),
234
+ message: sanitizeError(error),
196
235
  ref,
197
236
  };
198
237
  }
@@ -234,11 +273,33 @@ export const fileRiskTool = {
234
273
  },
235
274
  handler: async (params) => {
236
275
  try {
276
+ const rawPath = params.path;
277
+ if (typeof rawPath !== 'string' || rawPath.length === 0) {
278
+ return { error: true, message: 'path is required (non-empty string)' };
279
+ }
280
+ if (rawPath.length > MAX_PATH_LEN) {
281
+ return { error: true, message: `path too long (max ${MAX_PATH_LEN} chars)` };
282
+ }
283
+ // Only use the path for regex matching (assessFileRisk); still reject
284
+ // control characters to prevent log injection.
285
+ if (/[\x00-\x1F]/.test(rawPath)) {
286
+ return { error: true, message: 'path must not contain control characters' };
287
+ }
288
+ const rawStatus = params.status;
289
+ const status = (typeof rawStatus === 'string' && VALID_FILE_STATUS.has(rawStatus))
290
+ ? rawStatus
291
+ : 'modified';
292
+ const rawAdd = params.additions;
293
+ const additions = (typeof rawAdd === 'number' && Number.isFinite(rawAdd) && rawAdd >= 0)
294
+ ? Math.min(Math.floor(rawAdd), 1_000_000) : 0;
295
+ const rawDel = params.deletions;
296
+ const deletions = (typeof rawDel === 'number' && Number.isFinite(rawDel) && rawDel >= 0)
297
+ ? Math.min(Math.floor(rawDel), 1_000_000) : 0;
237
298
  const file = {
238
- path: params.path,
239
- status: params.status || 'modified',
240
- additions: params.additions || 0,
241
- deletions: params.deletions || 0,
299
+ path: rawPath,
300
+ status,
301
+ additions,
302
+ deletions,
242
303
  hunks: 1,
243
304
  binary: false,
244
305
  };
@@ -253,8 +314,8 @@ export const fileRiskTool = {
253
314
  catch (error) {
254
315
  return {
255
316
  error: true,
256
- message: error instanceof Error ? error.message : String(error),
257
- path: params.path,
317
+ message: sanitizeError(error),
318
+ path: typeof params.path === 'string' ? params.path.substring(0, 200) : '',
258
319
  };
259
320
  }
260
321
  },
@@ -279,7 +340,9 @@ export const diffStatsTool = {
279
340
  },
280
341
  },
281
342
  handler: async (params) => {
282
- const ref = params.ref || 'HEAD';
343
+ const ref = validateRef(params.ref);
344
+ if (ref === null)
345
+ return { error: true, message: 'Invalid ref: must be a safe git ref (max 256 chars, alphanumeric/._/:@^~-)' };
283
346
  try {
284
347
  const files = getGitDiffNumstat(ref);
285
348
  const totalAdditions = files.reduce((sum, f) => sum + f.additions, 0);
@@ -307,7 +370,7 @@ export const diffStatsTool = {
307
370
  catch (error) {
308
371
  return {
309
372
  error: true,
310
- message: error instanceof Error ? error.message : String(error),
373
+ message: sanitizeError(error),
311
374
  ref,
312
375
  };
313
376
  }
@@ -299,17 +299,36 @@ export const browserTools = [
299
299
  },
300
300
  },
301
301
  handler: async (input) => {
302
- const { session, interactive, compact, depth, selector } = input;
302
+ const raw = input;
303
+ let safeSession;
304
+ try {
305
+ safeSession = validateSessionId(raw.session);
306
+ }
307
+ catch (e) {
308
+ return {
309
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
310
+ isError: true,
311
+ };
312
+ }
303
313
  const args = ['snapshot'];
304
- if (interactive)
314
+ if (raw.interactive)
305
315
  args.push('-i');
306
- if (compact)
316
+ if (raw.compact)
307
317
  args.push('-c');
308
- if (depth)
309
- args.push('-d', String(depth));
310
- if (selector)
311
- args.push('-s', selector);
312
- return execBrowserCommand(args, session);
318
+ if (raw.depth)
319
+ args.push('-d', String(raw.depth));
320
+ if (raw.selector !== undefined) {
321
+ try {
322
+ args.push('-s', rejectFlagLike(raw.selector, 'selector'));
323
+ }
324
+ catch (e) {
325
+ return {
326
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
327
+ isError: true,
328
+ };
329
+ }
330
+ }
331
+ return execBrowserCommand(args, safeSession);
313
332
  },
314
333
  },
315
334
  {
@@ -489,7 +508,15 @@ export const browserTools = [
489
508
  },
490
509
  handler: async (input) => {
491
510
  const { target, session } = input;
492
- return execBrowserCommand(['check', target], session);
511
+ try {
512
+ return execBrowserCommand(['check', rejectFlagLike(target, 'target')], session);
513
+ }
514
+ catch (e) {
515
+ return {
516
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
517
+ isError: true,
518
+ };
519
+ }
493
520
  },
494
521
  },
495
522
  {
@@ -507,7 +534,15 @@ export const browserTools = [
507
534
  },
508
535
  handler: async (input) => {
509
536
  const { target, session } = input;
510
- return execBrowserCommand(['uncheck', target], session);
537
+ try {
538
+ return execBrowserCommand(['uncheck', rejectFlagLike(target, 'target')], session);
539
+ }
540
+ catch (e) {
541
+ return {
542
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
543
+ isError: true,
544
+ };
545
+ }
511
546
  },
512
547
  },
513
548
  {
@@ -550,7 +585,15 @@ export const browserTools = [
550
585
  },
551
586
  handler: async (input) => {
552
587
  const { target, session } = input;
553
- return execBrowserCommand(['get', 'text', target], session);
588
+ try {
589
+ return execBrowserCommand(['get', 'text', rejectFlagLike(target, 'target')], session);
590
+ }
591
+ catch (e) {
592
+ return {
593
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
594
+ isError: true,
595
+ };
596
+ }
554
597
  },
555
598
  },
556
599
  {
@@ -568,7 +611,15 @@ export const browserTools = [
568
611
  },
569
612
  handler: async (input) => {
570
613
  const { target, session } = input;
571
- return execBrowserCommand(['get', 'value', target], session);
614
+ try {
615
+ return execBrowserCommand(['get', 'value', rejectFlagLike(target, 'target')], session);
616
+ }
617
+ catch (e) {
618
+ return {
619
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
620
+ isError: true,
621
+ };
622
+ }
572
623
  },
573
624
  },
574
625
  {
@@ -622,17 +673,28 @@ export const browserTools = [
622
673
  },
623
674
  },
624
675
  handler: async (input) => {
625
- const { selector, text, url, timeout, session } = input;
676
+ const raw = input;
626
677
  const args = ['wait'];
627
- if (selector)
628
- args.push(selector);
629
- if (text)
630
- args.push('--text', text);
631
- if (url)
632
- args.push('--url', url);
633
- if (timeout)
634
- args.push(String(timeout));
635
- return execBrowserCommand(args, session);
678
+ try {
679
+ if (raw.selector !== undefined)
680
+ args.push(rejectFlagLike(raw.selector, 'selector'));
681
+ if (raw.text !== undefined)
682
+ args.push('--text', rejectFlagLike(raw.text, 'text'));
683
+ if (raw.url !== undefined)
684
+ args.push('--url', validateUrl(raw.url));
685
+ }
686
+ catch (e) {
687
+ return {
688
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }) }],
689
+ isError: true,
690
+ };
691
+ }
692
+ // Cap timeout to prevent event-loop blocking via a huge value
693
+ if (raw.timeout !== undefined && typeof raw.timeout === 'number') {
694
+ const clampedTimeout = Math.min(Math.max(Math.floor(raw.timeout), 0), 60_000);
695
+ args.push(String(clampedTimeout));
696
+ }
697
+ return execBrowserCommand(args, raw.session);
636
698
  },
637
699
  },
638
700
  // ==========================================================================
@@ -7,7 +7,7 @@
7
7
  * @module @monomind/cli/mcp-tools/claims
8
8
  */
9
9
  // File-based persistence
10
- import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'fs';
10
+ import { existsSync, readFileSync, statSync, writeFileSync, renameSync, mkdirSync } from 'fs';
11
11
  import { join, resolve } from 'path';
12
12
  const CLAIMS_DIR = '.monomind/claims';
13
13
  const CLAIMS_FILE = 'claims.json';
@@ -20,10 +20,11 @@ function ensureClaimsDir() {
20
20
  mkdirSync(dir, { recursive: true });
21
21
  }
22
22
  }
23
+ const MAX_CLAIMS_STORE_BYTES = 10 * 1024 * 1024; // 10 MB
23
24
  function loadClaims() {
24
25
  try {
25
26
  const path = getClaimsPath();
26
- if (existsSync(path)) {
27
+ if (existsSync(path) && statSync(path).size <= MAX_CLAIMS_STORE_BYTES) {
27
28
  return JSON.parse(readFileSync(path, 'utf-8'));
28
29
  }
29
30
  }
@@ -80,7 +81,11 @@ export const claimsTools = [
80
81
  handler: async (input) => {
81
82
  const issueId = input.issueId;
82
83
  const claimantStr = input.claimant;
83
- const context = input.context;
84
+ // Cap context: stored verbatim in the claim JSON record on disk.
85
+ const MAX_CLAIM_CONTEXT_LEN = 4 * 1024;
86
+ const rawContext = input.context;
87
+ const context = typeof rawContext === 'string' && rawContext.length > MAX_CLAIM_CONTEXT_LEN
88
+ ? rawContext.slice(0, MAX_CLAIM_CONTEXT_LEN) : rawContext;
84
89
  const RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
85
90
  if (!issueId || issueId.length > 256 || RESERVED_KEYS.has(issueId)) {
86
91
  return { success: false, error: 'Invalid issueId' };
@@ -211,7 +216,13 @@ export const claimsTools = [
211
216
  const issueId = input.issueId;
212
217
  const fromStr = input.from;
213
218
  const toStr = input.to;
214
- const reason = input.reason;
219
+ // Cap handoff reason: stored as claim.handoffReason in the claims JSON store on disk.
220
+ // Without a cap, an arbitrarily long reason inflates every write of the store file.
221
+ const MAX_HANDOFF_REASON_LEN = 1024;
222
+ const rawHandoffReason = input.reason;
223
+ const reason = typeof rawHandoffReason === 'string' && rawHandoffReason.length > MAX_HANDOFF_REASON_LEN
224
+ ? rawHandoffReason.slice(0, MAX_HANDOFF_REASON_LEN)
225
+ : rawHandoffReason;
215
226
  const progress = input.progress || 0;
216
227
  const RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
217
228
  if (!issueId || typeof issueId !== 'string' || issueId.length > 256 || RESERVED_KEYS.has(issueId)) {
@@ -337,7 +348,11 @@ export const claimsTools = [
337
348
  const issueId = input.issueId;
338
349
  const status = input.status;
339
350
  const claimantStr = input.claimant;
340
- const note = input.note;
351
+ // Cap note: stored as claim.blockReason in the claims JSON store on disk.
352
+ const MAX_CLAIM_NOTE_LEN = 4 * 1024;
353
+ const rawNote = input.note;
354
+ const note = typeof rawNote === 'string' && rawNote.length > MAX_CLAIM_NOTE_LEN
355
+ ? rawNote.slice(0, MAX_CLAIM_NOTE_LEN) : rawNote;
341
356
  const progress = input.progress;
342
357
  const RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
343
358
  if (!issueId || typeof issueId !== 'string' || issueId.length > 256 || RESERVED_KEYS.has(issueId)) {
@@ -450,9 +465,22 @@ export const claimsTools = [
450
465
  },
451
466
  handler: async (input) => {
452
467
  const issueId = input.issueId;
453
- const reason = input.reason;
468
+ // Runtime-validate StealReason: JSON schema declares an enum, but callers
469
+ // that bypass schema validation (raw MCP calls) can pass arbitrary strings,
470
+ // which would be persisted verbatim in store.stealable[issueId].reason.
471
+ const VALID_STEAL_REASONS = new Set(['overloaded', 'stale', 'blocked-timeout', 'voluntary']);
472
+ const rawStealReason = input.reason;
473
+ if (!rawStealReason || !VALID_STEAL_REASONS.has(rawStealReason)) {
474
+ return { success: false, error: `Invalid reason "${rawStealReason}". Must be one of: overloaded, stale, blocked-timeout, voluntary` };
475
+ }
476
+ const reason = rawStealReason;
454
477
  const preferredTypes = input.preferredTypes;
455
- const context = input.context;
478
+ // Cap context: stored verbatim in the stealable record on disk.
479
+ const MAX_STEAL_CONTEXT_LEN = 4 * 1024;
480
+ const rawStealContext = input.context;
481
+ const context = typeof rawStealContext === 'string' && rawStealContext.length > MAX_STEAL_CONTEXT_LEN
482
+ ? rawStealContext.slice(0, MAX_STEAL_CONTEXT_LEN)
483
+ : rawStealContext;
456
484
  const RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
457
485
  if (!issueId || typeof issueId !== 'string' || issueId.length > 256 || RESERVED_KEYS.has(issueId)) {
458
486
  return { success: false, error: 'Invalid issueId' };
@@ -136,11 +136,27 @@ export const configTools = [
136
136
  },
137
137
  handler: async (input) => {
138
138
  const store = loadConfigStore();
139
- const key = input.key;
140
- const scope = input.scope || 'default';
139
+ // Cap key and scope to prevent DoS via O(n) key.split('.') and to block
140
+ // prototype-pollution when key/scope are used as object property names.
141
+ const MAX_CONFIG_KEY_LEN = 512;
142
+ const MAX_CONFIG_SCOPE_LEN = 128;
143
+ const rawKey = input.key;
144
+ const key = typeof rawKey === 'string' && rawKey.length > MAX_CONFIG_KEY_LEN
145
+ ? rawKey.slice(0, MAX_CONFIG_KEY_LEN) : rawKey;
146
+ const rawScope = input.scope || 'default';
147
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
148
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
149
+ if (DANGEROUS_KEYS.has(scope)) {
150
+ return { key, value: undefined, scope, exists: false, source: 'none' };
151
+ }
152
+ for (const seg of key.split('.')) {
153
+ if (DANGEROUS_KEYS.has(seg)) {
154
+ return { key, value: undefined, scope, exists: false, source: 'none' };
155
+ }
156
+ }
141
157
  let value;
142
158
  // Check scope first, then default values
143
- if (scope !== 'default' && store.scopes[scope]) {
159
+ if (scope !== 'default' && Object.hasOwn(store.scopes, scope)) {
144
160
  value = store.scopes[scope][key];
145
161
  }
146
162
  if (value === undefined) {
@@ -173,9 +189,18 @@ export const configTools = [
173
189
  },
174
190
  handler: async (input) => {
175
191
  const store = loadConfigStore();
176
- const key = input.key;
192
+ // Cap key and scope: both become JSON object keys in the on-disk config
193
+ // store (store.values[key] and store.scopes[scope][key]). key is also
194
+ // split on '.' — O(n) — before the dangerous-key check.
195
+ const MAX_CONFIG_KEY_LEN = 512;
196
+ const MAX_CONFIG_SCOPE_LEN = 128;
197
+ const rawKey = input.key;
198
+ const key = typeof rawKey === 'string' && rawKey.length > MAX_CONFIG_KEY_LEN
199
+ ? rawKey.slice(0, MAX_CONFIG_KEY_LEN) : rawKey;
177
200
  const value = input.value;
178
- const scope = input.scope || 'default';
201
+ const rawScope = input.scope || 'default';
202
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
203
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
179
204
  for (const seg of key.split('.')) {
180
205
  if (DANGEROUS_KEYS.has(seg)) {
181
206
  return { success: false, error: `Forbidden key segment: "${seg}"` };
@@ -219,9 +244,18 @@ export const configTools = [
219
244
  },
220
245
  handler: async (input) => {
221
246
  const store = loadConfigStore();
222
- const scope = input.scope || 'default';
223
- const prefix = input.prefix;
247
+ const MAX_CONFIG_SCOPE_LEN = 128;
248
+ const MAX_PREFIX_LEN = 256;
249
+ const rawScope = input.scope || 'default';
250
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
251
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
252
+ const rawPrefix = input.prefix;
253
+ const prefix = typeof rawPrefix === 'string' && rawPrefix.length > MAX_PREFIX_LEN
254
+ ? rawPrefix.slice(0, MAX_PREFIX_LEN) : rawPrefix;
224
255
  const includeDefaults = input.includeDefaults !== false;
256
+ if (DANGEROUS_KEYS.has(scope)) {
257
+ return { configs: [], total: 0, scope, updatedAt: store.updatedAt };
258
+ }
225
259
  // Merge stored values with defaults
226
260
  let configs = {};
227
261
  if (includeDefaults) {
@@ -230,7 +264,7 @@ export const configTools = [
230
264
  // Add stored values
231
265
  Object.assign(configs, store.values);
232
266
  // Add scope-specific values
233
- if (scope !== 'default' && store.scopes[scope]) {
267
+ if (scope !== 'default' && Object.hasOwn(store.scopes, scope)) {
234
268
  Object.assign(configs, store.scopes[scope]);
235
269
  }
236
270
  // Filter by prefix
@@ -265,18 +299,35 @@ export const configTools = [
265
299
  },
266
300
  handler: async (input) => {
267
301
  const store = loadConfigStore();
268
- const scope = input.scope || 'default';
269
- const key = input.key;
302
+ // Cap scope and key to prevent DoS and prototype pollution.
303
+ const MAX_CONFIG_KEY_LEN = 512;
304
+ const MAX_CONFIG_SCOPE_LEN = 128;
305
+ const rawScope = input.scope || 'default';
306
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
307
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
308
+ const rawKey = input.key;
309
+ const key = typeof rawKey === 'string' && rawKey.length > MAX_CONFIG_KEY_LEN
310
+ ? rawKey.slice(0, MAX_CONFIG_KEY_LEN) : rawKey;
311
+ if (DANGEROUS_KEYS.has(scope)) {
312
+ return { success: false, error: `Forbidden scope: "${scope}"` };
313
+ }
314
+ if (key) {
315
+ for (const seg of key.split('.')) {
316
+ if (DANGEROUS_KEYS.has(seg)) {
317
+ return { success: false, error: `Forbidden key segment: "${seg}"` };
318
+ }
319
+ }
320
+ }
270
321
  let resetKeys = [];
271
322
  if (key) {
272
323
  // Reset specific key
273
324
  if (scope === 'default') {
274
- if (key in store.values) {
325
+ if (Object.hasOwn(store.values, key)) {
275
326
  delete store.values[key];
276
327
  resetKeys.push(key);
277
328
  }
278
329
  }
279
- else if (store.scopes[scope] && key in store.scopes[scope]) {
330
+ else if (Object.hasOwn(store.scopes, scope) && Object.hasOwn(store.scopes[scope], key)) {
280
331
  delete store.scopes[scope][key];
281
332
  resetKeys.push(key);
282
333
  }
@@ -287,7 +338,7 @@ export const configTools = [
287
338
  resetKeys = Object.keys(store.values);
288
339
  store.values = { ...DEFAULT_CONFIG };
289
340
  }
290
- else if (store.scopes[scope]) {
341
+ else if (Object.hasOwn(store.scopes, scope)) {
291
342
  resetKeys = Object.keys(store.scopes[scope]);
292
343
  delete store.scopes[scope];
293
344
  }
@@ -315,14 +366,21 @@ export const configTools = [
315
366
  },
316
367
  handler: async (input) => {
317
368
  const store = loadConfigStore();
318
- const scope = input.scope || 'default';
369
+ // Cap scope to prevent DoS and prototype pollution.
370
+ const MAX_CONFIG_SCOPE_LEN = 128;
371
+ const rawScope = input.scope || 'default';
372
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
373
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
319
374
  const includeDefaults = input.includeDefaults !== false;
375
+ if (DANGEROUS_KEYS.has(scope)) {
376
+ return { config: {}, scope, version: store.version, exportedAt: new Date().toISOString(), count: 0 };
377
+ }
320
378
  let exportData = {};
321
379
  if (includeDefaults) {
322
380
  exportData = { ...DEFAULT_CONFIG };
323
381
  }
324
382
  Object.assign(exportData, store.values);
325
- if (scope !== 'default' && store.scopes[scope]) {
383
+ if (scope !== 'default' && Object.hasOwn(store.scopes, scope)) {
326
384
  Object.assign(exportData, store.scopes[scope]);
327
385
  }
328
386
  return {
@@ -350,8 +408,15 @@ export const configTools = [
350
408
  handler: async (input) => {
351
409
  const store = loadConfigStore();
352
410
  const config = filterDangerousKeys(input.config);
353
- const scope = input.scope || 'default';
411
+ // Cap scope to prevent DoS and prototype pollution.
412
+ const MAX_CONFIG_SCOPE_LEN = 128;
413
+ const rawScope = input.scope || 'default';
414
+ const scope = typeof rawScope === 'string' && rawScope.length > MAX_CONFIG_SCOPE_LEN
415
+ ? rawScope.slice(0, MAX_CONFIG_SCOPE_LEN) : rawScope;
354
416
  const merge = input.merge !== false;
417
+ if (DANGEROUS_KEYS.has(scope)) {
418
+ return { success: false, error: `Forbidden scope: "${scope}"` };
419
+ }
355
420
  const importedKeys = Object.keys(config);
356
421
  if (scope === 'default') {
357
422
  if (merge) {
@@ -362,7 +427,7 @@ export const configTools = [
362
427
  }
363
428
  }
364
429
  else {
365
- if (!store.scopes[scope] || !merge) {
430
+ if (!Object.hasOwn(store.scopes, scope) || !merge) {
366
431
  store.scopes[scope] = {};
367
432
  }
368
433
  Object.assign(store.scopes[scope], config);