monomind 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/.claude/agents/design/design-monodesign.md +121 -0
  2. package/.claude/agents/github/issue-tracker.md +12 -12
  3. package/.claude/agents/github/pr-manager.md +10 -10
  4. package/.claude/agents/github/release-manager.md +49 -105
  5. package/.claude/agents/github/repo-architect.md +73 -92
  6. package/.claude/agents/github/sync-coordinator.md +55 -123
  7. package/.claude/agents/marketing/marketing-competitive-content.md +155 -0
  8. package/.claude/agents/marketing/marketing-content-creator.md +13 -0
  9. package/.claude/agents/marketing/marketing-cro-specialist.md +147 -0
  10. package/.claude/agents/marketing/marketing-email-specialist.md +90 -0
  11. package/.claude/agents/marketing/marketing-launch-strategist.md +129 -0
  12. package/.claude/agents/marketing/marketing-pricing-strategist.md +127 -0
  13. package/.claude/agents/specialists/integration-architect.md +94 -0
  14. package/.claude/commands/agents/README.md +4 -0
  15. package/.claude/commands/agents/agent-capabilities.md +6 -2
  16. package/.claude/commands/agents/agent-coordination.md +4 -0
  17. package/.claude/commands/agents/agent-spawning.md +4 -0
  18. package/.claude/commands/agents/agent-types.md +6 -2
  19. package/.claude/commands/analysis/README.md +14 -5
  20. package/.claude/commands/analysis/bottleneck-detect.md +30 -123
  21. package/.claude/commands/analysis/performance-bottlenecks.md +14 -14
  22. package/.claude/commands/analysis/performance-report.md +38 -11
  23. package/.claude/commands/analysis/token-efficiency.md +13 -16
  24. package/.claude/commands/analysis/token-usage.md +34 -12
  25. package/.claude/commands/automation/README.md +15 -5
  26. package/.claude/commands/automation/auto-agent.md +49 -85
  27. package/.claude/commands/automation/self-healing.md +20 -18
  28. package/.claude/commands/automation/session-memory.md +28 -29
  29. package/.claude/commands/automation/smart-agents.md +17 -9
  30. package/.claude/commands/automation/smart-spawn.md +52 -11
  31. package/.claude/commands/automation/workflow-select.md +46 -11
  32. package/.claude/commands/browse.md +5 -0
  33. package/.claude/commands/coordination/README.md +9 -5
  34. package/.claude/commands/coordination/agent-spawn.md +53 -9
  35. package/.claude/commands/coordination/swarm-init.md +39 -42
  36. package/.claude/commands/coordination/task-orchestrate.md +65 -11
  37. package/.claude/commands/github/README.md +21 -8
  38. package/.claude/commands/github/github-modes.md +9 -5
  39. package/.claude/commands/github/issue-tracker.md +34 -33
  40. package/.claude/commands/github/pr-manager.md +20 -17
  41. package/.claude/commands/github/release-manager.md +37 -49
  42. package/.claude/commands/github/repo-architect.md +39 -41
  43. package/.claude/commands/github/sync-coordinator.md +45 -49
  44. package/.claude/commands/hive-mind/README.md +42 -17
  45. package/.claude/commands/hive-mind/hive-mind-consensus.md +68 -4
  46. package/.claude/commands/hive-mind/hive-mind-init.md +55 -5
  47. package/.claude/commands/hive-mind/hive-mind-memory.md +69 -4
  48. package/.claude/commands/hive-mind/hive-mind-spawn.md +71 -10
  49. package/.claude/commands/hive-mind/hive-mind-status.md +52 -4
  50. package/.claude/commands/hive-mind/hive-mind-stop.md +51 -4
  51. package/.claude/commands/hive-mind/hive-mind.md +74 -14
  52. package/.claude/commands/hooks/README.md +62 -7
  53. package/.claude/commands/hooks/overview.md +94 -35
  54. package/.claude/commands/hooks/post-edit.md +48 -87
  55. package/.claude/commands/hooks/post-task.md +37 -87
  56. package/.claude/commands/hooks/pre-edit.md +52 -84
  57. package/.claude/commands/hooks/pre-task.md +46 -81
  58. package/.claude/commands/hooks/session-end.md +49 -85
  59. package/.claude/commands/hooks/setup.md +87 -58
  60. package/.claude/commands/mastermind/_repeat.md +308 -0
  61. package/.claude/commands/mastermind/architect.md +49 -0
  62. package/.claude/commands/mastermind/brain.md +98 -0
  63. package/.claude/commands/mastermind/build.md +22 -0
  64. package/.claude/commands/mastermind/content.md +22 -0
  65. package/.claude/commands/mastermind/createorg.md +94 -0
  66. package/.claude/commands/mastermind/finance.md +22 -0
  67. package/.claude/commands/mastermind/idea.md +22 -0
  68. package/.claude/commands/mastermind/marketing.md +22 -0
  69. package/.claude/commands/mastermind/master.md +379 -0
  70. package/.claude/commands/mastermind/ops.md +22 -0
  71. package/.claude/commands/mastermind/release.md +22 -0
  72. package/.claude/commands/mastermind/research.md +22 -0
  73. package/.claude/commands/mastermind/review.md +22 -0
  74. package/.claude/commands/mastermind/runorg.md +106 -0
  75. package/.claude/commands/mastermind/sales.md +22 -0
  76. package/.claude/commands/mastermind/techport.md +17 -0
  77. package/.claude/commands/memory/README.md +75 -5
  78. package/.claude/commands/memory/memory-search.md +63 -11
  79. package/.claude/commands/monitoring/README.md +64 -4
  80. package/.claude/commands/monitoring/agent-metrics.md +50 -10
  81. package/.claude/commands/monitoring/agents.md +59 -32
  82. package/.claude/commands/monitoring/status.md +96 -34
  83. package/.claude/commands/monograph/README.md +102 -0
  84. package/.claude/commands/monograph/monograph-build.md +79 -0
  85. package/.claude/commands/monograph/monograph-search.md +96 -0
  86. package/.claude/commands/monograph/monograph-stats.md +53 -0
  87. package/.claude/commands/monograph/monograph-watch.md +63 -0
  88. package/.claude/commands/monograph/monograph-wiki.md +91 -0
  89. package/.claude/commands/monomind/createtask.md +277 -0
  90. package/.claude/commands/{monomind-do.md → monomind/do.md} +21 -8
  91. package/.claude/commands/monomind/help.md +118 -0
  92. package/.claude/commands/{monomind-idea.md → monomind/idea.md} +22 -28
  93. package/.claude/commands/{monomind-improve.md → monomind/improve.md} +21 -27
  94. package/.claude/commands/monomind/memory.md +230 -0
  95. package/.claude/commands/monomind/repeat.md +201 -0
  96. package/.claude/commands/monomind/review.md +313 -0
  97. package/.claude/commands/monomind/specialagents.md +125 -0
  98. package/.claude/commands/monomind/swarm.md +161 -0
  99. package/.claude/commands/monomind/understand.md +148 -0
  100. package/.claude/commands/optimization/README.md +69 -5
  101. package/.claude/commands/optimization/auto-topology.md +66 -43
  102. package/.claude/commands/optimization/parallel-execution.md +65 -39
  103. package/.claude/commands/optimization/performance-optimize.md +79 -0
  104. package/.claude/commands/pair/README.md +48 -230
  105. package/.claude/commands/pair/examples.md +85 -441
  106. package/.claude/commands/pair/modes.md +77 -303
  107. package/.claude/commands/pair/session.md +76 -359
  108. package/.claude/commands/sparc/analyzer.md +9 -26
  109. package/.claude/commands/sparc/architect.md +8 -25
  110. package/.claude/commands/sparc/ask.md +27 -68
  111. package/.claude/commands/sparc/batch-executor.md +8 -25
  112. package/.claude/commands/sparc/code.md +12 -53
  113. package/.claude/commands/sparc/coder.md +8 -25
  114. package/.claude/commands/sparc/debug.md +12 -53
  115. package/.claude/commands/sparc/debugger.md +8 -25
  116. package/.claude/commands/sparc/designer.md +8 -25
  117. package/.claude/commands/sparc/devops.md +16 -57
  118. package/.claude/commands/sparc/docs-writer.md +12 -53
  119. package/.claude/commands/sparc/documenter.md +8 -25
  120. package/.claude/commands/sparc/innovator.md +8 -25
  121. package/.claude/commands/sparc/integration.md +12 -53
  122. package/.claude/commands/sparc/mcp.md +12 -53
  123. package/.claude/commands/sparc/memory-manager.md +28 -25
  124. package/.claude/commands/sparc/optimizer.md +8 -25
  125. package/.claude/commands/sparc/orchestrator.md +35 -97
  126. package/.claude/commands/sparc/post-deployment-monitoring-mode.md +13 -54
  127. package/.claude/commands/sparc/refinement-optimization-mode.md +13 -54
  128. package/.claude/commands/sparc/researcher.md +8 -25
  129. package/.claude/commands/sparc/reviewer.md +8 -25
  130. package/.claude/commands/sparc/security-review.md +13 -54
  131. package/.claude/commands/sparc/sparc-modes.md +97 -151
  132. package/.claude/commands/sparc/sparc.md +16 -56
  133. package/.claude/commands/sparc/spec-pseudocode.md +13 -54
  134. package/.claude/commands/sparc/supabase-admin.md +19 -66
  135. package/.claude/commands/sparc/swarm-coordinator.md +21 -25
  136. package/.claude/commands/sparc/tdd.md +8 -25
  137. package/.claude/commands/sparc/tester.md +8 -25
  138. package/.claude/commands/sparc/tutorial.md +12 -53
  139. package/.claude/commands/sparc/workflow-manager.md +8 -25
  140. package/.claude/commands/sparc.md +76 -130
  141. package/.claude/commands/stream-chain/pipeline.md +72 -77
  142. package/.claude/commands/stream-chain/run.md +133 -47
  143. package/.claude/commands/swarm/README.md +37 -12
  144. package/.claude/commands/swarm/analysis.md +47 -69
  145. package/.claude/commands/swarm/development.md +45 -69
  146. package/.claude/commands/swarm/examples.md +77 -142
  147. package/.claude/commands/swarm/maintenance.md +47 -74
  148. package/.claude/commands/swarm/optimization.md +54 -87
  149. package/.claude/commands/swarm/research.md +47 -107
  150. package/.claude/commands/swarm/swarm-analysis.md +58 -4
  151. package/.claude/commands/swarm/swarm-background.md +61 -4
  152. package/.claude/commands/swarm/swarm-modes.md +63 -4
  153. package/.claude/commands/swarm/swarm-monitor.md +50 -4
  154. package/.claude/commands/swarm/swarm-status.md +40 -4
  155. package/.claude/commands/swarm/swarm-strategies.md +73 -5
  156. package/.claude/commands/swarm/swarm.md +70 -18
  157. package/.claude/commands/swarm/testing.md +51 -102
  158. package/.claude/commands/tokens.md +6 -1
  159. package/.claude/commands/training/README.md +36 -6
  160. package/.claude/commands/training/model-update.md +68 -15
  161. package/.claude/commands/training/neural-patterns.md +54 -55
  162. package/.claude/commands/training/neural-train.md +70 -16
  163. package/.claude/commands/training/pattern-learn.md +60 -16
  164. package/.claude/commands/training/specialization.md +78 -49
  165. package/.claude/commands/truth/start.md +87 -109
  166. package/.claude/commands/ts.md +7 -2
  167. package/.claude/commands/verify/check.md +90 -34
  168. package/.claude/commands/verify/start.md +71 -94
  169. package/.claude/commands/workflows/README.md +62 -6
  170. package/.claude/commands/workflows/development.md +69 -61
  171. package/.claude/commands/workflows/research.md +73 -47
  172. package/.claude/commands/workflows/workflow-create.md +75 -16
  173. package/.claude/commands/workflows/workflow-execute.md +94 -16
  174. package/.claude/commands/workflows/workflow-export.md +81 -16
  175. package/.claude/helpers/control-start.cjs +91 -0
  176. package/.claude/helpers/extras-registry.json +4104 -1991
  177. package/.claude/helpers/graphify-freshen.cjs +44 -13
  178. package/.claude/helpers/hook-handler.cjs +256 -1
  179. package/.claude/helpers/learning-service.mjs +0 -0
  180. package/.claude/helpers/loop-tracker.cjs +107 -0
  181. package/.claude/helpers/metrics-db.mjs +0 -0
  182. package/.claude/helpers/router.cjs +48 -68
  183. package/.claude/helpers/skill-registry.json +89 -104
  184. package/.claude/helpers/statusline.cjs +33 -2
  185. package/.claude/helpers/swarm-hooks.sh +0 -0
  186. package/.claude/scheduled_tasks.lock +1 -0
  187. package/.claude/settings.json +15 -0
  188. package/.claude/skills/.monomind/data/ranked-context.json +5 -0
  189. package/.claude/skills/.monomind/sessions/current.json +13 -0
  190. package/.claude/skills/.monomind/sessions/session-1777829336455.json +15 -0
  191. package/.claude/skills/.monomind/sessions/session-1777831614725.json +15 -0
  192. package/.claude/skills/.monomind/sessions/session-1777832095857.json +15 -0
  193. package/.claude/skills/.monomind/sessions/session-1777839814183.json +15 -0
  194. package/.claude/skills/.monomind/sessions/session-1777841847131.json +15 -0
  195. package/.claude/skills/.monomind/sessions/session-1777843309463.json +15 -0
  196. package/.claude/skills/.monomind/sessions/session-1777880867159.json +15 -0
  197. package/.claude/skills/.monomind/sessions/session-1777881884593.json +15 -0
  198. package/.claude/skills/.monomind/sessions/session-1777884090471.json +15 -0
  199. package/.claude/skills/.monomind/sessions/session-1777884808221.json +15 -0
  200. package/.claude/skills/.monomind/sessions/session-1777885672155.json +15 -0
  201. package/.claude/skills/.monomind/sessions/session-1777886852818.json +15 -0
  202. package/.claude/skills/.monomind/sessions/session-1777896532690.json +15 -0
  203. package/.claude/skills/agentdb-advanced/SKILL.md +11 -12
  204. package/.claude/skills/agentdb-learning/SKILL.md +20 -21
  205. package/.claude/skills/agentdb-memory-patterns/SKILL.md +28 -30
  206. package/.claude/skills/agentdb-optimization/SKILL.md +11 -12
  207. package/.claude/skills/agentdb-vector-search/SKILL.md +37 -41
  208. package/.claude/skills/{v3-integration-deep → agentic-integration}/SKILL.md +20 -13
  209. package/.claude/skills/agentic-jujutsu/SKILL.md +22 -22
  210. package/.claude/skills/{v3-cli-modernization → cli-modernization}/SKILL.md +17 -8
  211. package/.claude/skills/{v3-core-implementation → core-implementation}/SKILL.md +33 -8
  212. package/.claude/skills/{v3-ddd-architecture → ddd-architecture}/SKILL.md +18 -25
  213. package/.claude/skills/github-code-review/SKILL.md +82 -83
  214. package/.claude/skills/github-multi-repo/SKILL.md +42 -46
  215. package/.claude/skills/github-project-management/SKILL.md +83 -88
  216. package/.claude/skills/github-release-management/SKILL.md +12 -18
  217. package/.claude/skills/github-workflow-automation/SKILL.md +70 -74
  218. package/.claude/skills/hooks-automation/SKILL.md +9 -13
  219. package/.claude/skills/mastermind/_intake.md +83 -0
  220. package/.claude/skills/mastermind/_protocol.md +275 -0
  221. package/.claude/skills/mastermind/architect.md +847 -0
  222. package/.claude/skills/mastermind/build.md +158 -0
  223. package/.claude/skills/mastermind/content.md +185 -0
  224. package/.claude/skills/mastermind/createorg.md +318 -0
  225. package/.claude/skills/mastermind/finance.md +154 -0
  226. package/.claude/skills/mastermind/idea.md +158 -0
  227. package/.claude/skills/mastermind/marketing.md +216 -0
  228. package/.claude/skills/mastermind/monotask.md +350 -0
  229. package/.claude/skills/mastermind/ops.md +156 -0
  230. package/.claude/skills/mastermind/references/copywriting-frameworks.md +181 -0
  231. package/.claude/skills/mastermind/references/persuasion-psychology.md +158 -0
  232. package/.claude/skills/mastermind/release.md +156 -0
  233. package/.claude/skills/mastermind/research.md +156 -0
  234. package/.claude/skills/mastermind/review.md +157 -0
  235. package/.claude/skills/mastermind/runorg.md +308 -0
  236. package/.claude/skills/mastermind/sales.md +158 -0
  237. package/.claude/skills/mastermind/techport.md +743 -0
  238. package/.claude/skills/{v3-mcp-optimization → mcp-optimization}/SKILL.md +35 -14
  239. package/.claude/skills/{v3-memory-unification → memory-unification}/SKILL.md +20 -4
  240. package/.claude/skills/monodesign/SKILL.md +302 -0
  241. package/.claude/skills/monodesign/reference/adapt.md +190 -0
  242. package/.claude/skills/monodesign/reference/animate.md +175 -0
  243. package/.claude/skills/monodesign/reference/antipatterns-catalog.md +187 -0
  244. package/.claude/skills/monodesign/reference/audit.md +133 -0
  245. package/.claude/skills/monodesign/reference/bolder.md +113 -0
  246. package/.claude/skills/monodesign/reference/brand-workflow.md +180 -0
  247. package/.claude/skills/monodesign/reference/brand.md +114 -0
  248. package/.claude/skills/monodesign/reference/clarify.md +174 -0
  249. package/.claude/skills/monodesign/reference/cognitive-load.md +106 -0
  250. package/.claude/skills/monodesign/reference/color-and-contrast.md +105 -0
  251. package/.claude/skills/monodesign/reference/colorize.md +154 -0
  252. package/.claude/skills/monodesign/reference/component-specs.md +260 -0
  253. package/.claude/skills/monodesign/reference/component-states.md +274 -0
  254. package/.claude/skills/monodesign/reference/component-system.md +358 -0
  255. package/.claude/skills/monodesign/reference/copy-formulas.md +160 -0
  256. package/.claude/skills/monodesign/reference/craft.md +193 -0
  257. package/.claude/skills/monodesign/reference/critique.md +213 -0
  258. package/.claude/skills/monodesign/reference/delight.md +302 -0
  259. package/.claude/skills/monodesign/reference/design-principles.md +246 -0
  260. package/.claude/skills/monodesign/reference/distill.md +111 -0
  261. package/.claude/skills/monodesign/reference/document.md +427 -0
  262. package/.claude/skills/monodesign/reference/extract.md +69 -0
  263. package/.claude/skills/monodesign/reference/harden.md +347 -0
  264. package/.claude/skills/monodesign/reference/heuristics-scoring.md +234 -0
  265. package/.claude/skills/monodesign/reference/image-prompts.md +118 -0
  266. package/.claude/skills/monodesign/reference/interaction-design.md +195 -0
  267. package/.claude/skills/monodesign/reference/layout.md +141 -0
  268. package/.claude/skills/monodesign/reference/live.md +622 -0
  269. package/.claude/skills/monodesign/reference/motion-design.md +109 -0
  270. package/.claude/skills/monodesign/reference/onboard.md +234 -0
  271. package/.claude/skills/monodesign/reference/optimize.md +258 -0
  272. package/.claude/skills/monodesign/reference/overdrive.md +130 -0
  273. package/.claude/skills/monodesign/reference/personas.md +179 -0
  274. package/.claude/skills/monodesign/reference/polish.md +233 -0
  275. package/.claude/skills/monodesign/reference/pre-delivery-checklist.md +108 -0
  276. package/.claude/skills/monodesign/reference/product.md +62 -0
  277. package/.claude/skills/monodesign/reference/quieter.md +99 -0
  278. package/.claude/skills/monodesign/reference/responsive-design.md +114 -0
  279. package/.claude/skills/monodesign/reference/shape.md +151 -0
  280. package/.claude/skills/monodesign/reference/spatial-design.md +100 -0
  281. package/.claude/skills/monodesign/reference/teach.md +156 -0
  282. package/.claude/skills/monodesign/reference/token-architecture.md +222 -0
  283. package/.claude/skills/monodesign/reference/typeset.md +124 -0
  284. package/.claude/skills/monodesign/reference/typography.md +159 -0
  285. package/.claude/skills/monodesign/reference/ux-research.md +143 -0
  286. package/.claude/skills/monodesign/reference/ux-rules.md +211 -0
  287. package/.claude/skills/monodesign/reference/ux-writing.md +107 -0
  288. package/.claude/skills/monomotion/SKILL.md +145 -0
  289. package/.claude/skills/monomotion/rules/api-control.md +139 -0
  290. package/.claude/skills/monomotion/rules/effects.md +109 -0
  291. package/.claude/skills/monomotion/rules/integration.md +140 -0
  292. package/.claude/skills/monomotion/rules/scroll.md +131 -0
  293. package/.claude/skills/monomotion/rules/sequencing.md +105 -0
  294. package/.claude/skills/monomotion/rules/svg.md +101 -0
  295. package/.claude/skills/monomotion/rules/text.md +119 -0
  296. package/.claude/skills/pair-programming/SKILL.md +1 -1
  297. package/.claude/skills/performance-analysis/SKILL.md +3 -3
  298. package/.claude/skills/{v3-performance-optimization → performance-optimization}/SKILL.md +16 -8
  299. package/.claude/skills/reasoningbank-agentdb/SKILL.md +17 -19
  300. package/.claude/skills/reasoningbank-intelligence/SKILL.md +4 -6
  301. package/.claude/skills/{v3-security-overhaul → security-hardening}/SKILL.md +13 -3
  302. package/.claude/skills/skill-builder/SKILL.md +19 -19
  303. package/.claude/skills/sparc-methodology/SKILL.md +55 -211
  304. package/.claude/skills/stop-slop/SKILL.md +67 -0
  305. package/.claude/skills/stop-slop/references/examples.md +61 -0
  306. package/.claude/skills/stop-slop/references/phrases.md +130 -0
  307. package/.claude/skills/stop-slop/references/structures.md +136 -0
  308. package/.claude/skills/swarm-advanced/SKILL.md +13 -43
  309. package/.claude/skills/{v3-swarm-coordination → swarm-coordination}/SKILL.md +39 -21
  310. package/.claude/skills/swarm-orchestration/SKILL.md +12 -12
  311. package/.claude/skills/verification-quality/SKILL.md +5 -5
  312. package/.claude/statusline-command.sh +0 -0
  313. package/.claude/statusline.sh +0 -0
  314. package/.claude-plugin/scripts/install.sh +0 -0
  315. package/.claude-plugin/scripts/uninstall.sh +0 -0
  316. package/.claude-plugin/scripts/verify.sh +0 -0
  317. package/README.md +5 -5
  318. package/package.json +17 -17
  319. package/packages/@monomind/cli/README.md +441 -0
  320. package/packages/@monomind/cli/bin/cli.js +78 -13
  321. package/packages/@monomind/cli/bin/mcp-server.js +0 -0
  322. package/packages/@monomind/cli/dist/src/agents/halt-signal.js +33 -7
  323. package/packages/@monomind/cli/dist/src/agents/managed-agent.js +5 -2
  324. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +3 -2
  325. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +1 -1
  326. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +5 -2
  327. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +26 -4
  328. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +17 -9
  329. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +5 -3
  330. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +58 -10
  331. package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +0 -1
  332. package/packages/@monomind/cli/dist/src/agents/version-store.js +44 -21
  333. package/packages/@monomind/cli/dist/src/autopilot-state.js +79 -28
  334. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +7 -2
  335. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +20 -8
  336. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.d.ts +2 -1
  337. package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +25 -2
  338. package/packages/@monomind/cli/dist/src/commands/agent.js +6 -4
  339. package/packages/@monomind/cli/dist/src/commands/appliance-advanced.js +23 -0
  340. package/packages/@monomind/cli/dist/src/commands/autopilot.js +3 -3
  341. package/packages/@monomind/cli/dist/src/commands/benchmark.js +119 -8
  342. package/packages/@monomind/cli/dist/src/commands/claims.js +22 -14
  343. package/packages/@monomind/cli/dist/src/commands/config.js +32 -0
  344. package/packages/@monomind/cli/dist/src/commands/daemon.js +13 -11
  345. package/packages/@monomind/cli/dist/src/commands/deployment.js +21 -2
  346. package/packages/@monomind/cli/dist/src/commands/doctor.js +5 -4
  347. package/packages/@monomind/cli/dist/src/commands/embeddings.js +124 -48
  348. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +15 -14
  349. package/packages/@monomind/cli/dist/src/commands/hooks.js +45 -41
  350. package/packages/@monomind/cli/dist/src/commands/index.d.ts +2 -0
  351. package/packages/@monomind/cli/dist/src/commands/index.js +20 -7
  352. package/packages/@monomind/cli/dist/src/commands/init.js +53 -19
  353. package/packages/@monomind/cli/dist/src/commands/mcp.js +31 -44
  354. package/packages/@monomind/cli/dist/src/commands/memory.js +47 -15
  355. package/packages/@monomind/cli/dist/src/commands/migrate.js +156 -108
  356. package/packages/@monomind/cli/dist/src/commands/monograph.d.ts +8 -0
  357. package/packages/@monomind/cli/dist/src/commands/monograph.js +526 -0
  358. package/packages/@monomind/cli/dist/src/commands/neural.js +96 -56
  359. package/packages/@monomind/cli/dist/src/commands/performance.js +30 -8
  360. package/packages/@monomind/cli/dist/src/commands/plugins.js +13 -37
  361. package/packages/@monomind/cli/dist/src/commands/process.js +25 -2
  362. package/packages/@monomind/cli/dist/src/commands/providers.js +37 -5
  363. package/packages/@monomind/cli/dist/src/commands/replay.js +4 -4
  364. package/packages/@monomind/cli/dist/src/commands/route.js +37 -5
  365. package/packages/@monomind/cli/dist/src/commands/ruvector/import.js +12 -2
  366. package/packages/@monomind/cli/dist/src/commands/ruvector/init.js +15 -0
  367. package/packages/@monomind/cli/dist/src/commands/ruvector/status.js +16 -3
  368. package/packages/@monomind/cli/dist/src/commands/security.js +342 -193
  369. package/packages/@monomind/cli/dist/src/commands/session.js +51 -8
  370. package/packages/@monomind/cli/dist/src/commands/start.js +18 -4
  371. package/packages/@monomind/cli/dist/src/commands/swarm.js +47 -36
  372. package/packages/@monomind/cli/dist/src/commands/tokens.js +11 -11
  373. package/packages/@monomind/cli/dist/src/commands/transfer-store.js +1 -1
  374. package/packages/@monomind/cli/dist/src/commands/workflow.js +31 -4
  375. package/packages/@monomind/cli/dist/src/config-adapter.d.ts +2 -1
  376. package/packages/@monomind/cli/dist/src/consensus/audit-writer.js +46 -13
  377. package/packages/@monomind/cli/dist/src/consensus/vote-signer.d.ts +0 -3
  378. package/packages/@monomind/cli/dist/src/consensus/vote-signer.js +9 -1
  379. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +4 -2
  380. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +25 -8
  381. package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.d.ts +10 -3
  382. package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.js +50 -16
  383. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +27 -5
  384. package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +2 -2
  385. package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +26 -16
  386. package/packages/@monomind/cli/dist/src/eval/trace-collector.js +23 -3
  387. package/packages/@monomind/cli/dist/src/index.js +12 -10
  388. package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +8 -8
  389. package/packages/@monomind/cli/dist/src/init/executor.js +153 -70
  390. package/packages/@monomind/cli/dist/src/init/helpers-generator.js +35 -22
  391. package/packages/@monomind/cli/dist/src/init/mcp-generator.js +3 -3
  392. package/packages/@monomind/cli/dist/src/init/settings-generator.js +10 -3
  393. package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +18 -3
  394. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -1
  395. package/packages/@monomind/cli/dist/src/init/types.d.ts +35 -11
  396. package/packages/@monomind/cli/dist/src/init/types.js +5 -9
  397. package/packages/@monomind/cli/dist/src/interactive/interrupt.js +8 -3
  398. package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +38 -4
  399. package/packages/@monomind/cli/dist/src/mcp-client.js +10 -4
  400. package/packages/@monomind/cli/dist/src/mcp-server.d.ts +9 -2
  401. package/packages/@monomind/cli/dist/src/mcp-server.js +182 -35
  402. package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +66 -34
  403. package/packages/@monomind/cli/dist/src/mcp-tools/agentdb-tools.js +34 -7
  404. package/packages/@monomind/cli/dist/src/mcp-tools/analyze-tools.js +25 -16
  405. package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.js +4 -6
  406. package/packages/@monomind/cli/dist/src/mcp-tools/autopilot-tools.js +12 -2
  407. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +199 -20
  408. package/packages/@monomind/cli/dist/src/mcp-tools/claims-tools.js +68 -18
  409. package/packages/@monomind/cli/dist/src/mcp-tools/config-tools.js +33 -5
  410. package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.js +59 -4
  411. package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.js +46 -10
  412. package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +46 -5
  413. package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +29 -16
  414. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +38 -10
  415. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +96 -33
  416. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +70 -37
  417. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +29 -13
  418. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +5867 -56
  419. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +121 -37
  420. package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +21 -8
  421. package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +10 -8
  422. package/packages/@monomind/cli/dist/src/mcp-tools/request-tracker.js +4 -1
  423. package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.js +19 -8
  424. package/packages/@monomind/cli/dist/src/mcp-tools/session-tools.js +57 -17
  425. package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +35 -17
  426. package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +4 -3
  427. package/packages/@monomind/cli/dist/src/mcp-tools/task-tools.js +53 -13
  428. package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.js +63 -14
  429. package/packages/@monomind/cli/dist/src/mcp-tools/transfer-tools.js +21 -16
  430. package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +92 -23
  431. package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +41 -10
  432. package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +2 -2
  433. package/packages/@monomind/cli/dist/src/memory/intelligence.js +39 -13
  434. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -0
  435. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +149 -56
  436. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +107 -45
  437. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +8 -1
  438. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +25 -8
  439. package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +40 -0
  440. package/packages/@monomind/cli/dist/src/observability/replay-reader.js +138 -0
  441. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +35 -5
  442. package/packages/@monomind/cli/dist/src/parser.d.ts +8 -0
  443. package/packages/@monomind/cli/dist/src/parser.js +48 -14
  444. package/packages/@monomind/cli/dist/src/plugins/manager.js +112 -19
  445. package/packages/@monomind/cli/dist/src/plugins/store/discovery.d.ts +1 -1
  446. package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +80 -62
  447. package/packages/@monomind/cli/dist/src/production/circuit-breaker.js +8 -1
  448. package/packages/@monomind/cli/dist/src/production/error-handler.d.ts +4 -2
  449. package/packages/@monomind/cli/dist/src/production/error-handler.js +27 -5
  450. package/packages/@monomind/cli/dist/src/production/monitoring.js +8 -4
  451. package/packages/@monomind/cli/dist/src/production/rate-limiter.js +30 -22
  452. package/packages/@monomind/cli/dist/src/ruvector/agent-wasm.js +2 -2
  453. package/packages/@monomind/cli/dist/src/ruvector/coverage-router.js +19 -9
  454. package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.d.ts +1 -0
  455. package/packages/@monomind/cli/dist/src/ruvector/diff-classifier.js +26 -6
  456. package/packages/@monomind/cli/dist/src/ruvector/enhanced-model-router.js +24 -2
  457. package/packages/@monomind/cli/dist/src/ruvector/index.d.ts +1 -2
  458. package/packages/@monomind/cli/dist/src/ruvector/index.js +2 -2
  459. package/packages/@monomind/cli/dist/src/ruvector/model-router.d.ts +4 -2
  460. package/packages/@monomind/cli/dist/src/ruvector/model-router.js +30 -6
  461. package/packages/@monomind/cli/dist/src/ruvector/moe-router.d.ts +7 -0
  462. package/packages/@monomind/cli/dist/src/ruvector/moe-router.js +35 -12
  463. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.d.ts +7 -1
  464. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.js +40 -9
  465. package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +3 -1
  466. package/packages/@monomind/cli/dist/src/services/claim-service.js +33 -2
  467. package/packages/@monomind/cli/dist/src/services/config-file-manager.d.ts +16 -2
  468. package/packages/@monomind/cli/dist/src/services/config-file-manager.js +105 -17
  469. package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +51 -11
  470. package/packages/@monomind/cli/dist/src/services/headless-worker-executor.d.ts +7 -0
  471. package/packages/@monomind/cli/dist/src/services/headless-worker-executor.js +188 -45
  472. package/packages/@monomind/cli/dist/src/services/registry-api.js +62 -9
  473. package/packages/@monomind/cli/dist/src/services/ruvector-training.js +8 -0
  474. package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +4 -1
  475. package/packages/@monomind/cli/dist/src/services/worker-daemon.js +112 -28
  476. package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +9 -2
  477. package/packages/@monomind/cli/dist/src/services/worker-queue.js +86 -5
  478. package/packages/@monomind/cli/dist/src/suggest.js +9 -0
  479. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +5 -3
  480. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +17 -5
  481. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +3 -0
  482. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +30 -6
  483. package/packages/@monomind/cli/dist/src/transfer/anonymization/index.js +5 -3
  484. package/packages/@monomind/cli/dist/src/transfer/export.js +5 -3
  485. package/packages/@monomind/cli/dist/src/transfer/ipfs/client.js +84 -7
  486. package/packages/@monomind/cli/dist/src/transfer/ipfs/upload.js +13 -4
  487. package/packages/@monomind/cli/dist/src/transfer/storage/gcs.js +19 -10
  488. package/packages/@monomind/cli/dist/src/transfer/store/discovery.d.ts +9 -2
  489. package/packages/@monomind/cli/dist/src/transfer/store/discovery.js +68 -13
  490. package/packages/@monomind/cli/dist/src/transfer/store/download.d.ts +15 -6
  491. package/packages/@monomind/cli/dist/src/transfer/store/download.js +113 -24
  492. package/packages/@monomind/cli/dist/src/transfer/store/publish.d.ts +1 -1
  493. package/packages/@monomind/cli/dist/src/transfer/store/publish.js +13 -14
  494. package/packages/@monomind/cli/dist/src/transfer/store/registry.d.ts +3 -3
  495. package/packages/@monomind/cli/dist/src/transfer/store/registry.js +32 -16
  496. package/packages/@monomind/cli/dist/src/update/checker.js +17 -4
  497. package/packages/@monomind/cli/dist/src/update/executor.js +25 -20
  498. package/packages/@monomind/cli/dist/src/update/rate-limiter.d.ts +11 -0
  499. package/packages/@monomind/cli/dist/src/update/rate-limiter.js +23 -3
  500. package/packages/@monomind/cli/dist/src/utils/parse-jsonl.d.ts +6 -0
  501. package/packages/@monomind/cli/dist/src/utils/parse-jsonl.js +22 -0
  502. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +37 -3
  503. package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +27 -11
  504. package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +51 -13
  505. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +3 -0
  506. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +6 -2
  507. package/packages/@monomind/cli/dist/src/workflow/template-engine.js +7 -0
  508. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +95 -14
  509. package/packages/@monomind/cli/package.json +5 -3
  510. package/packages/@monomind/guidance/README.md +1192 -0
  511. package/packages/@monomind/shared/README.md +322 -0
  512. package/packages/@monomind/shared/dist/types/consensus-audit.d.ts +3 -1
  513. package/packages/README.md +513 -0
  514. package/.claude/agents/design/design-brand-guardian.md +0 -323
  515. package/.claude/agents/design/design-image-prompt-engineer.md +0 -237
  516. package/.claude/agents/design/design-inclusive-visuals-specialist.md +0 -72
  517. package/.claude/agents/design/design-ui-designer.md +0 -384
  518. package/.claude/agents/design/design-ux-architect.md +0 -470
  519. package/.claude/agents/design/design-ux-researcher.md +0 -330
  520. package/.claude/agents/design/design-visual-storyteller.md +0 -150
  521. package/.claude/agents/design/design-whimsy-injector.md +0 -439
  522. package/.claude/agents/v3/integration-architect.md +0 -338
  523. package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +0 -54
  524. package/.claude/commands/coordination/init.md +0 -44
  525. package/.claude/commands/coordination/orchestrate.md +0 -43
  526. package/.claude/commands/coordination/spawn.md +0 -45
  527. package/.claude/commands/github/code-review-swarm.md +0 -550
  528. package/.claude/commands/github/code-review.md +0 -25
  529. package/.claude/commands/github/github-swarm.md +0 -121
  530. package/.claude/commands/github/issue-triage.md +0 -25
  531. package/.claude/commands/github/multi-repo-swarm.md +0 -519
  532. package/.claude/commands/github/pr-enhance.md +0 -26
  533. package/.claude/commands/github/project-board-sync.md +0 -471
  534. package/.claude/commands/github/release-swarm.md +0 -590
  535. package/.claude/commands/github/repo-analyze.md +0 -25
  536. package/.claude/commands/github/swarm-issue.md +0 -482
  537. package/.claude/commands/github/swarm-pr.md +0 -310
  538. package/.claude/commands/github/workflow-automation.md +0 -468
  539. package/.claude/commands/hive-mind/hive-mind-metrics.md +0 -8
  540. package/.claude/commands/hive-mind/hive-mind-resume.md +0 -8
  541. package/.claude/commands/hive-mind/hive-mind-sessions.md +0 -8
  542. package/.claude/commands/hive-mind/hive-mind-wizard.md +0 -8
  543. package/.claude/commands/list-agents.md +0 -17
  544. package/.claude/commands/memory/memory-persist.md +0 -25
  545. package/.claude/commands/memory/memory-usage.md +0 -25
  546. package/.claude/commands/memory/neural.md +0 -47
  547. package/.claude/commands/metrics.md +0 -11
  548. package/.claude/commands/monitoring/real-time-view.md +0 -25
  549. package/.claude/commands/monitoring/swarm-monitor.md +0 -25
  550. package/.claude/commands/monomind-createtask.md +0 -302
  551. package/.claude/commands/monomind-help.md +0 -103
  552. package/.claude/commands/monomind-memory.md +0 -107
  553. package/.claude/commands/monomind-repeat.md +0 -149
  554. package/.claude/commands/monomind-swarm.md +0 -205
  555. package/.claude/commands/optimization/cache-manage.md +0 -25
  556. package/.claude/commands/optimization/topology-optimize.md +0 -25
  557. package/.claude/commands/pair/commands.md +0 -546
  558. package/.claude/commands/pair/config.md +0 -510
  559. package/.claude/commands/pair/start.md +0 -209
  560. package/.claude/commands/use-agent.md +0 -67
  561. package/.claude/skills/monomind-createtask/SKILL.md +0 -269
  562. package/.claude/skills/monomind-task-engine/SKILL.md +0 -358
  563. /package/.claude/agents/{v3 → specialists}/memory-specialist.md +0 -0
  564. /package/.claude/agents/{v3 → specialists}/performance-engineer.md +0 -0
  565. /package/.claude/agents/{v3 → specialists}/queen-coordinator.md +0 -0
  566. /package/.claude/agents/{v3 → specialists}/security-architect.md +0 -0
@@ -30,7 +30,7 @@ const trainCommand = {
30
30
  { command: 'monomind neural train -p security --wasm --contrastive', description: 'Security patterns with contrastive learning' },
31
31
  ],
32
32
  action: async (ctx) => {
33
- const patternType = (ctx.flags.pattern || ctx.flags.patternType || ctx.flags['pattern-type']) || 'coordination';
33
+ const patternType = ctx.flags['pattern-type'] || 'coordination';
34
34
  const epochs = parseInt(ctx.flags.epochs || '50', 10);
35
35
  const learningRate = parseFloat(ctx.flags['learning-rate'] || '0.01');
36
36
  const batchSize = parseInt(ctx.flags['batch-size'] || '32', 10);
@@ -97,9 +97,29 @@ const trainCommand = {
97
97
  let trainingData = [];
98
98
  if (dataFile) {
99
99
  const fs = await import('fs');
100
+ const p = await import('path');
100
101
  if (fs.existsSync(dataFile)) {
102
+ // Path containment check
103
+ const resolvedData = p.resolve(dataFile);
104
+ const cwd = process.cwd();
105
+ if (!resolvedData.startsWith(cwd + p.sep) && resolvedData !== cwd) {
106
+ spinner.fail(`--data path escapes project directory: ${dataFile}`);
107
+ return { success: false, exitCode: 1 };
108
+ }
109
+ // File size guard
110
+ const MAX_TRAINING_BYTES = 50 * 1024 * 1024;
111
+ const statResult = fs.statSync(dataFile);
112
+ if (statResult.size > MAX_TRAINING_BYTES) {
113
+ spinner.fail(`Training data file too large: ${statResult.size} bytes (max ${MAX_TRAINING_BYTES})`);
114
+ return { success: false, exitCode: 1 };
115
+ }
101
116
  const raw = fs.readFileSync(dataFile, 'utf8');
102
- trainingData = JSON.parse(raw);
117
+ const parsedData = JSON.parse(raw);
118
+ if (parsedData && typeof parsedData === 'object' && ('__proto__' in parsedData || 'constructor' in parsedData)) {
119
+ spinner.fail('Prototype pollution attempt detected in training data');
120
+ return { success: false, exitCode: 1 };
121
+ }
122
+ trainingData = parsedData;
103
123
  }
104
124
  else {
105
125
  spinner.fail(`Training data file not found: ${dataFile}`);
@@ -532,6 +552,10 @@ const patternsCommand = {
532
552
  output.writeln(output.success(`✓ Loaded from: ${persistence.patternsFile}`));
533
553
  }
534
554
  }
555
+ else if (action === 'analyze' && !query) {
556
+ output.printError('--query is required when --action analyze is used.');
557
+ return { success: false, exitCode: 1 };
558
+ }
535
559
  else if (action === 'analyze' && query) {
536
560
  // Analyze patterns related to query
537
561
  const related = await findSimilarPatterns(query, { k: limit });
@@ -689,46 +713,9 @@ const optimizeCommand = {
689
713
  }
690
714
  catch { /* ignore */ }
691
715
  if (method === 'quantize') {
692
- // Perform real Int8 quantization on pattern embeddings
693
- spinner.setText('Quantizing pattern embeddings to Int8...');
694
- let quantizedCount = 0;
695
- let memoryReduction = 0;
696
- for (const pattern of patterns) {
697
- if (pattern.embedding && pattern.embedding.length > 0) {
698
- // Float32 (4 bytes) -> Int8 (1 byte) = 4x reduction
699
- const beforeBytes = pattern.embedding.length * 4;
700
- const afterBytes = pattern.embedding.length; // Int8
701
- memoryReduction += beforeBytes - afterBytes;
702
- quantizedCount++;
703
- }
704
- }
705
- // Save optimized patterns
706
- await flushPatterns();
707
- // Get after size
708
- let afterSize = beforeSize;
709
- try {
710
- const patternFile = path.join(patternDir, 'patterns.json');
711
- if (fs.existsSync(patternFile)) {
712
- afterSize = fs.statSync(patternFile).size;
713
- }
714
- }
715
- catch { /* ignore */ }
716
- spinner.succeed(`Quantized ${quantizedCount} patterns`);
717
- output.writeln();
718
- output.printTable({
719
- columns: [
720
- { key: 'metric', header: 'Metric', width: 25 },
721
- { key: 'before', header: 'Before', width: 18 },
722
- { key: 'after', header: 'After', width: 18 },
723
- ],
724
- data: [
725
- { metric: 'Pattern Count', before: String(patterns.length), after: String(patterns.length) },
726
- { metric: 'Storage Size', before: `${(beforeSize / 1024).toFixed(1)} KB`, after: `${(afterSize / 1024).toFixed(1)} KB` },
727
- { metric: 'Embedding Memory', before: `${((memoryReduction * 4) / 1024).toFixed(1)} KB`, after: `${(memoryReduction / 1024).toFixed(1)} KB` },
728
- { metric: 'Memory Reduction', before: '-', after: `~${(3.92).toFixed(2)}x (Int8)` },
729
- { metric: 'Precision', before: 'Float32', after: 'Int8 (±0.5%)' },
730
- ],
731
- });
716
+ spinner.fail('Quantization not implemented');
717
+ output.printWarning('Quantization is not yet implemented. Patterns were not modified.');
718
+ return { success: false, message: 'Quantization not implemented', exitCode: 1 };
732
719
  }
733
720
  else if (method === 'analyze') {
734
721
  spinner.succeed('Analysis complete');
@@ -855,10 +842,22 @@ const exportCommand = {
855
842
  },
856
843
  };
857
844
  // Load patterns from local storage
858
- const memoryDir = path.join(process.cwd(), '.monomind', 'memory');
845
+ const memoryDir = path.join(process.cwd(), '.monomind', 'neural');
859
846
  const patternsFile = path.join(memoryDir, 'patterns.json');
860
847
  if (fs.existsSync(patternsFile)) {
861
- const patterns = JSON.parse(fs.readFileSync(patternsFile, 'utf8'));
848
+ const MAX_PATTERNS_BYTES = 100 * 1024 * 1024;
849
+ const patStat = fs.statSync(patternsFile);
850
+ if (patStat.size > MAX_PATTERNS_BYTES) {
851
+ spinner.fail(`patterns.json too large to export safely (${patStat.size} bytes)`);
852
+ return { success: false, exitCode: 1 };
853
+ }
854
+ const patternsRaw = fs.readFileSync(patternsFile, 'utf8');
855
+ const patternsJson = JSON.parse(patternsRaw);
856
+ if (patternsJson && typeof patternsJson === 'object' && ('__proto__' in patternsJson || 'constructor' in patternsJson)) {
857
+ spinner.fail('Prototype pollution attempt detected in patterns.json');
858
+ return { success: false, exitCode: 1 };
859
+ }
860
+ const patterns = patternsJson;
862
861
  for (const pattern of patterns) {
863
862
  // Security: Strip potential PII
864
863
  if (stripPii) {
@@ -921,7 +920,7 @@ const exportCommand = {
921
920
  /sk-ant-[a-zA-Z0-9-]+/, // Anthropic keys
922
921
  /sk-[a-zA-Z0-9]{48}/, // OpenAI keys
923
922
  /AIza[a-zA-Z0-9-_]{35}/, // Google keys
924
- /pinata_[a-zA-Z0-9]+/, // Pinata JWT
923
+ /pinata_[a-zA-Z0-9]{20,}/, // Pinata JWT (min 20 chars to avoid false positives on short names)
925
924
  /-----BEGIN.*KEY-----/, // PEM keys
926
925
  ];
927
926
  for (const pattern of secretPatterns) {
@@ -932,7 +931,15 @@ const exportCommand = {
932
931
  }
933
932
  // Output handling
934
933
  if (outputFile) {
935
- fs.writeFileSync(outputFile, JSON.stringify(exportPackage, null, 2));
934
+ const resolvedOut = path.resolve(outputFile);
935
+ const cwd = process.cwd();
936
+ if (!resolvedOut.startsWith(cwd + path.sep) && resolvedOut !== cwd) {
937
+ spinner.fail(`--output path escapes project directory: ${outputFile}`);
938
+ return { success: false, exitCode: 1 };
939
+ }
940
+ const tmpOutput = outputFile + '.tmp';
941
+ fs.writeFileSync(tmpOutput, JSON.stringify(exportPackage, null, 2));
942
+ fs.renameSync(tmpOutput, outputFile);
936
943
  spinner.succeed(`Exported to: ${outputFile}`);
937
944
  }
938
945
  if (pinToIpfs) {
@@ -962,7 +969,7 @@ const exportCommand = {
962
969
  const result = await response.json();
963
970
  spinner.succeed('Successfully exported to IPFS');
964
971
  output.writeln();
965
- output.table({
972
+ output.printTable({
966
973
  columns: [
967
974
  { key: 'property', header: 'Property', width: 20 },
968
975
  { key: 'value', header: 'Value', width: 50 },
@@ -1033,7 +1040,11 @@ const listCommand = {
1033
1040
  headers: { 'Accept': 'application/json' },
1034
1041
  });
1035
1042
  if (response.ok) {
1036
- registry = await response.json();
1043
+ const MAX_REGISTRY_BYTES = 50 * 1024 * 1024;
1044
+ const buf = await response.arrayBuffer();
1045
+ if (buf.byteLength > MAX_REGISTRY_BYTES)
1046
+ throw new Error(`Registry response too large: ${buf.byteLength} bytes`);
1047
+ registry = JSON.parse(new TextDecoder().decode(buf));
1037
1048
  break;
1038
1049
  }
1039
1050
  }
@@ -1160,7 +1171,11 @@ const importCommand = {
1160
1171
  headers: { 'Accept': 'application/json' },
1161
1172
  });
1162
1173
  if (response.ok) {
1163
- importData = await response.json();
1174
+ const MAX_IMPORT_BYTES = 50 * 1024 * 1024;
1175
+ const importBuf = await response.arrayBuffer();
1176
+ if (importBuf.byteLength > MAX_IMPORT_BYTES)
1177
+ throw new Error(`Import response too large: ${importBuf.byteLength} bytes`);
1178
+ importData = JSON.parse(new TextDecoder().decode(importBuf));
1164
1179
  break;
1165
1180
  }
1166
1181
  }
@@ -1178,14 +1193,31 @@ const importCommand = {
1178
1193
  spinner.fail(`File not found: ${file}`);
1179
1194
  return { success: false, exitCode: 1 };
1180
1195
  }
1196
+ // Cap import file size to prevent OOM on attacker-controlled content.
1197
+ const stat = fs.statSync(file);
1198
+ const MAX_IMPORT_BYTES = 50 * 1024 * 1024; // 50 MB
1199
+ if (stat.size > MAX_IMPORT_BYTES) {
1200
+ spinner.fail(`Import file too large: ${stat.size} bytes (max ${MAX_IMPORT_BYTES})`);
1201
+ return { success: false, exitCode: 1 };
1202
+ }
1181
1203
  importData = JSON.parse(fs.readFileSync(file, 'utf8'));
1182
1204
  }
1183
1205
  if (!importData) {
1184
1206
  spinner.fail('No import data available');
1185
1207
  return { success: false, exitCode: 1 };
1186
1208
  }
1187
- // Verify signature if present and requested
1188
- if (verifySignature && importData.signature && importData.publicKey) {
1209
+ // SECURITY: Verify signature when --verify is set (default true).
1210
+ // Previously two bypasses existed:
1211
+ // (a) catch-fall-through made any malformed signature/key skip verification
1212
+ // and proceed to import — fail-OPEN.
1213
+ // (b) the entire block was guarded on `signature && publicKey`, so an
1214
+ // attacker who simply omitted those fields skipped verification
1215
+ // regardless of --verify. Both now fail-CLOSED.
1216
+ if (verifySignature) {
1217
+ if (!importData.signature || !importData.publicKey) {
1218
+ spinner.fail('SECURITY: --verify requested but payload is unsigned. Aborting (use --no-verify to override).');
1219
+ return { success: false, exitCode: 1 };
1220
+ }
1189
1221
  spinner.setText('Verifying Ed25519 signature...');
1190
1222
  try {
1191
1223
  const { webcrypto } = crypto;
@@ -1202,7 +1234,11 @@ const importCommand = {
1202
1234
  output.writeln(output.success('Signature verified'));
1203
1235
  }
1204
1236
  catch (err) {
1205
- output.writeln(output.warning(`Signature verification skipped: ${err instanceof Error ? err.message : String(err)}`));
1237
+ // FAIL-CLOSED: any error during verification (malformed key, wrong
1238
+ // algorithm, runtime not supporting Ed25519, etc.) must reject the
1239
+ // import, NOT fall through with a warning.
1240
+ spinner.fail(`SECURITY: Signature verification error: ${err instanceof Error ? err.message : String(err)}. Aborting.`);
1241
+ return { success: false, exitCode: 1 };
1206
1242
  }
1207
1243
  }
1208
1244
  // Extract patterns - handle both single model and model registry formats
@@ -1247,8 +1283,8 @@ const importCommand = {
1247
1283
  if (validPatterns.length < patterns.length) {
1248
1284
  output.writeln(output.warning(`Filtered ${patterns.length - validPatterns.length} suspicious patterns`));
1249
1285
  }
1250
- // Save to local memory
1251
- const memoryDir = path.join(process.cwd(), '.monomind', 'memory');
1286
+ // Save to neural store (same location intelligence.ts writes to)
1287
+ const memoryDir = path.join(process.cwd(), '.monomind', 'neural');
1252
1288
  if (!fs.existsSync(memoryDir)) {
1253
1289
  fs.mkdirSync(memoryDir, { recursive: true });
1254
1290
  }
@@ -1261,10 +1297,14 @@ const importCommand = {
1261
1297
  const existingIds = new Set(existingPatterns.map(p => p.id));
1262
1298
  const newPatterns = validPatterns.filter(p => !existingIds.has(p.id));
1263
1299
  const finalPatterns = merge ? [...existingPatterns, ...newPatterns] : validPatterns;
1264
- fs.writeFileSync(patternsFile, JSON.stringify(finalPatterns, null, 2));
1300
+ // Unique tmp filename so concurrent invocations don't clobber each other's
1301
+ // .tmp files mid-write (which would produce a corrupt patterns.json on rename).
1302
+ const tmpPatterns = `${patternsFile}.${process.pid}.${Date.now()}.tmp`;
1303
+ fs.writeFileSync(tmpPatterns, JSON.stringify(finalPatterns, null, 2), { flag: 'wx' });
1304
+ fs.renameSync(tmpPatterns, patternsFile);
1265
1305
  spinner.succeed('Import complete');
1266
1306
  output.writeln();
1267
- output.table({
1307
+ output.printTable({
1268
1308
  columns: [
1269
1309
  { key: 'metric', header: 'Metric', width: 25 },
1270
1310
  { key: 'value', header: 'Value', width: 20 },
@@ -21,8 +21,12 @@ const benchmarkCommand = {
21
21
  ],
22
22
  action: async (ctx) => {
23
23
  const suite = ctx.flags.suite || 'all';
24
- const iterations = parseInt(ctx.flags.iterations || '100', 10);
25
- const warmup = parseInt(ctx.flags.warmup || '10', 10);
24
+ const MAX_ITERATIONS = 10_000;
25
+ const MAX_WARMUP = 500;
26
+ const iterationsRaw = parseInt(ctx.flags.iterations || '100', 10);
27
+ const warmupRaw = parseInt(ctx.flags.warmup || '10', 10);
28
+ const iterations = Number.isFinite(iterationsRaw) ? Math.min(Math.max(1, iterationsRaw), MAX_ITERATIONS) : 100;
29
+ const warmup = Number.isFinite(warmupRaw) ? Math.min(Math.max(0, warmupRaw), MAX_WARMUP) : 10;
26
30
  const outputFormat = ctx.flags.output || 'text';
27
31
  output.writeln();
28
32
  output.writeln(output.bold('Performance Benchmark (Real Measurements)'));
@@ -55,12 +59,14 @@ const benchmarkCommand = {
55
59
  embedTimes.push(performance.now() - start);
56
60
  }
57
61
  const mean = embedTimes.reduce((a, b) => a + b, 0) / embedTimes.length;
62
+ const embedTargetMet = mean < 10;
58
63
  results.push({
59
64
  operation: 'Embedding Gen',
60
65
  mean: `${mean.toFixed(2)}ms`,
61
66
  p95: `${percentile(embedTimes, 95).toFixed(2)}ms`,
62
67
  p99: `${percentile(embedTimes, 99).toFixed(2)}ms`,
63
- improvement: mean < 10 ? output.success('Target met') : output.warning('Below target'),
68
+ improvement: embedTargetMet ? output.success('Target met') : output.warning('Below target'),
69
+ targetMet: embedTargetMet,
64
70
  });
65
71
  }
66
72
  // 2. Flash Attention-style Batch Operations
@@ -84,12 +90,14 @@ const benchmarkCommand = {
84
90
  // Compare to baseline (single-vector comparison takes ~0.5μs, so 100 vectors baseline ~0.05ms)
85
91
  const baselineMs = 0.05;
86
92
  const speedup = baselineMs / mean;
93
+ const flashTargetMet = speedup > 1;
87
94
  results.push({
88
95
  operation: 'Flash Attention',
89
96
  mean: `${mean.toFixed(3)}ms`,
90
97
  p95: `${percentile(flashTimes, 95).toFixed(3)}ms`,
91
98
  p99: `${percentile(flashTimes, 99).toFixed(3)}ms`,
92
- improvement: speedup > 1 ? output.success(`${speedup.toFixed(2)}x`) : output.dim(`${speedup.toFixed(2)}x`),
99
+ improvement: flashTargetMet ? output.success(`${speedup.toFixed(2)}x`) : output.dim(`${speedup.toFixed(2)}x`),
100
+ targetMet: flashTargetMet,
93
101
  });
94
102
  }
95
103
  // 3. HNSW Search Benchmark
@@ -121,12 +129,14 @@ const benchmarkCommand = {
121
129
  // HNSW should be O(log n) ~150x faster
122
130
  const baselineBruteForce = hnswStatus.entryCount * 0.0005;
123
131
  const speedup = baselineBruteForce / (mean / 1000);
132
+ const hnswTargetMet = speedup > 10;
124
133
  results.push({
125
134
  operation: `HNSW Search (n=${hnswStatus.entryCount})`,
126
135
  mean: `${mean.toFixed(2)}ms`,
127
136
  p95: `${percentile(searchTimes, 95).toFixed(2)}ms`,
128
137
  p99: `${percentile(searchTimes, 99).toFixed(2)}ms`,
129
- improvement: speedup > 10 ? output.success(`~${Math.round(speedup)}x`) : output.dim(`${speedup.toFixed(1)}x`),
138
+ improvement: hnswTargetMet ? output.success(`~${Math.round(speedup)}x`) : output.dim(`${speedup.toFixed(1)}x`),
139
+ targetMet: hnswTargetMet,
130
140
  });
131
141
  }
132
142
  else {
@@ -136,6 +146,7 @@ const benchmarkCommand = {
136
146
  p95: 'N/A',
137
147
  p99: 'N/A',
138
148
  improvement: output.warning('No index'),
149
+ targetMet: false,
139
150
  });
140
151
  }
141
152
  }
@@ -150,6 +161,7 @@ const benchmarkCommand = {
150
161
  p95: `${(sonaResult.maxMs * 1000).toFixed(2)}μs`,
151
162
  p99: `${(sonaResult.maxMs * 1000).toFixed(2)}μs`,
152
163
  improvement: sonaResult.targetMet ? output.success('<0.05ms ✓') : output.warning('Above target'),
164
+ targetMet: sonaResult.targetMet,
153
165
  });
154
166
  }
155
167
  // 5. Memory Store/Retrieve
@@ -168,12 +180,14 @@ const benchmarkCommand = {
168
180
  storeTimes.push(performance.now() - start);
169
181
  }
170
182
  const mean = storeTimes.reduce((a, b) => a + b, 0) / storeTimes.length;
183
+ const storeTargetMet = mean < 50;
171
184
  results.push({
172
185
  operation: 'Memory Store+Embed',
173
186
  mean: `${mean.toFixed(1)}ms`,
174
187
  p95: `${percentile(storeTimes, 95).toFixed(1)}ms`,
175
188
  p99: `${percentile(storeTimes, 99).toFixed(1)}ms`,
176
- improvement: mean < 50 ? output.success('Target met') : output.warning('Slow'),
189
+ improvement: storeTargetMet ? output.success('Target met') : output.warning('Slow'),
190
+ targetMet: storeTargetMet,
177
191
  });
178
192
  }
179
193
  const totalTime = ((Date.now() - startTotal) / 1000).toFixed(2);
@@ -195,7 +209,7 @@ const benchmarkCommand = {
195
209
  data: results,
196
210
  });
197
211
  output.writeln();
198
- const allTargetsMet = results.every(r => !r.improvement.includes('warning') && !r.improvement.includes('Slow'));
212
+ const allTargetsMet = results.every(r => r.targetMet);
199
213
  output.printBox([
200
214
  `Suite: ${suite}`,
201
215
  `Iterations: ${iterations}`,
@@ -233,7 +247,7 @@ const profileCommand = {
233
247
  const startMem = process.memoryUsage();
234
248
  const startTime = process.hrtime.bigint();
235
249
  // Sample for a brief period
236
- await new Promise(r => setTimeout(r, Math.min(duration * 100, 2000)));
250
+ await new Promise(r => setTimeout(r, Math.min(duration * 1000, 30_000)));
237
251
  const endCpu = process.cpuUsage(startCpu);
238
252
  const endMem = process.memoryUsage();
239
253
  const endTime = process.hrtime.bigint();
@@ -273,6 +287,10 @@ const profileCommand = {
273
287
  });
274
288
  output.writeln();
275
289
  output.writeln(output.dim(`Profile duration: ${elapsedMs.toFixed(0)}ms`));
290
+ const outputFile = ctx.flags.output;
291
+ if (outputFile) {
292
+ output.printWarning(`--output flag is not yet implemented. Profile data was not saved to ${outputFile}.`);
293
+ }
276
294
  return { success: true };
277
295
  },
278
296
  };
@@ -474,6 +492,9 @@ const optimizeCommand = {
474
492
  ],
475
493
  action: async (ctx) => {
476
494
  const target = ctx.flags.target || 'all';
495
+ if (ctx.flags.apply) {
496
+ output.printWarning('Optimization application is not yet implemented. Showing recommendations only.');
497
+ }
477
498
  output.writeln();
478
499
  output.writeln(output.bold('Performance Optimization'));
479
500
  output.writeln(output.dim('─'.repeat(50)));
@@ -515,6 +536,7 @@ const bottleneckCommand = {
515
536
  { command: 'monomind performance bottleneck -d full', description: 'Full analysis' },
516
537
  ],
517
538
  action: async (ctx) => {
539
+ output.printWarning('Bottleneck analysis is using static sample data. Dynamic analysis coming soon.');
518
540
  output.writeln();
519
541
  output.writeln(output.bold('Bottleneck Analysis'));
520
542
  output.writeln(output.dim('─'.repeat(50)));
@@ -388,7 +388,7 @@ const infoCommand = {
388
388
  { name: 'registry', short: 'r', type: 'string', description: 'Registry to use' },
389
389
  ],
390
390
  examples: [
391
- { command: 'monomind plugins info -n @monoes/neural', description: 'Show plugin info' },
391
+ { command: 'monomind plugins info -n @monomind/neural', description: 'Show plugin info' },
392
392
  ],
393
393
  action: async (ctx) => {
394
394
  const name = ctx.flags.name;
@@ -549,33 +549,9 @@ const createCommand = {
549
549
  output.writeln();
550
550
  output.writeln(output.bold('Creating Plugin'));
551
551
  output.writeln(output.dim('─'.repeat(40)));
552
- const spinner = output.createSpinner({ text: 'Scaffolding project...', spinner: 'dots' });
553
- spinner.start();
554
- const files = ['package.json', 'src/index.ts', 'src/hooks.ts', 'README.md', 'tsconfig.json'];
555
- for (const file of files) {
556
- spinner.setText(`Creating ${file}...`);
557
- await new Promise(r => setTimeout(r, 150));
558
- }
559
- spinner.succeed('Plugin scaffolded');
560
- output.writeln();
561
- output.printBox([
562
- `Plugin: ${name}`,
563
- `Template: ${template}`,
564
- `Location: ./${name}/`,
565
- ``,
566
- `Files created:`,
567
- ` - package.json`,
568
- ` - src/index.ts`,
569
- ` - src/hooks.ts`,
570
- ` - README.md`,
571
- ` - tsconfig.json`,
572
- ``,
573
- `Next steps:`,
574
- ` cd ${name}`,
575
- ` npm install`,
576
- ` npm run build`,
577
- ].join('\n'), 'Success');
578
- return { success: true };
552
+ output.printWarning('Plugin scaffolding is not yet implemented.');
553
+ output.writeln(output.dim('Use --name to specify your plugin name. File generation coming soon.'));
554
+ return { success: false, message: 'Not yet implemented', exitCode: 1 };
579
555
  },
580
556
  };
581
557
  // Upgrade subcommand
@@ -587,8 +563,8 @@ const upgradeCommand = {
587
563
  { name: 'version', short: 'v', type: 'string', description: 'Target version (default: latest)' },
588
564
  ],
589
565
  examples: [
590
- { command: 'monomind plugins upgrade -n @monoes/neural', description: 'Upgrade to latest' },
591
- { command: 'monomind plugins upgrade -n @monoes/neural -v 3.1.0', description: 'Upgrade to specific version' },
566
+ { command: 'monomind plugins upgrade -n @monomind/neural', description: 'Upgrade to latest' },
567
+ { command: 'monomind plugins upgrade -n @monomind/neural -v 3.1.0', description: 'Upgrade to specific version' },
592
568
  ],
593
569
  action: async (ctx) => {
594
570
  const name = ctx.flags.name;
@@ -729,7 +705,7 @@ const rateCommand = {
729
705
  { name: 'rating', short: 'r', type: 'number', description: 'Rating (1-5)', required: true },
730
706
  ],
731
707
  examples: [
732
- { command: 'monomind plugins rate -n @monoes/embeddings -r 5', description: 'Rate 5 stars' },
708
+ { command: 'monomind plugins rate -n @monomind/embeddings -r 5', description: 'Rate 5 stars' },
733
709
  { command: 'monomind plugins rate -n my-plugin -r 4', description: 'Rate 4 stars' },
734
710
  ],
735
711
  action: async (ctx) => {
@@ -803,12 +779,12 @@ export const pluginsCommand = {
803
779
  output.writeln();
804
780
  output.writeln(output.bold('Official Plugins:'));
805
781
  output.printList([
806
- '@monoes/neural - Neural patterns and inference (WASM SIMD)',
807
- '@monoes/security - Security scanning and CVE detection',
808
- '@monoes/embeddings - Vector embeddings with hyperbolic support',
809
- '@monoes/claims - Claims-based authorization',
810
- '@monoes/performance - Performance profiling and benchmarks',
811
- '@monoes/plugin-gastown-bridge - Gas Town orchestrator integration (WASM-accelerated)',
782
+ '@monomind/neural - Neural patterns and inference (WASM SIMD)',
783
+ '@monomind/security - Security scanning and CVE detection',
784
+ '@monomind/embeddings - Vector embeddings with hyperbolic support',
785
+ '@monomind/claims - Claims-based authorization',
786
+ '@monomind/performance - Performance profiling and benchmarks',
787
+ '@monomind/plugin-gastown-bridge - Gas Town orchestrator integration (WASM-accelerated)',
812
788
  ]);
813
789
  output.writeln();
814
790
  output.writeln(output.dim('Run "monomind plugins list --official" to see all official plugins'));
@@ -6,12 +6,35 @@ import { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from '
6
6
  import { dirname, resolve } from 'path';
7
7
  // Helper functions for PID file management
8
8
  function writePidFile(pidFile, pid, port) {
9
- const dir = dirname(resolve(pidFile));
9
+ const resolved = resolve(pidFile);
10
+ const dir = dirname(resolved);
10
11
  if (!existsSync(dir)) {
11
12
  mkdirSync(dir, { recursive: true });
12
13
  }
13
14
  const data = JSON.stringify({ pid, port, startedAt: new Date().toISOString() });
14
- writeFileSync(resolve(pidFile), data, 'utf-8');
15
+ // wx flag = O_CREAT | O_EXCL — refuses to follow a pre-staged symlink that
16
+ // could redirect this write to ~/.ssh/authorized_keys or similar.
17
+ // mode 0o600 — pid file shouldn't be world-readable.
18
+ try {
19
+ writeFileSync(resolved, data, { encoding: 'utf-8', flag: 'wx', mode: 0o600 });
20
+ }
21
+ catch (e) {
22
+ if (e.code === 'EEXIST') {
23
+ // Stale PID file — caller is expected to have already verified the
24
+ // referenced process is dead. Unlink and retry once.
25
+ try {
26
+ const fs = require('fs');
27
+ fs.unlinkSync(resolved);
28
+ writeFileSync(resolved, data, { encoding: 'utf-8', flag: 'wx', mode: 0o600 });
29
+ }
30
+ catch (retryErr) {
31
+ throw retryErr;
32
+ }
33
+ }
34
+ else {
35
+ throw e;
36
+ }
37
+ }
15
38
  }
16
39
  function readPidFile(pidFile) {
17
40
  try {
@@ -78,7 +78,10 @@ const configureCommand = {
78
78
  entry = { name: provider, enabled: true };
79
79
  providers.push(entry);
80
80
  }
81
- // Apply supplied settings
81
+ // Warn when key is supplied via CLI flag (visible in process table and shell history)
82
+ if (apiKey !== undefined) {
83
+ output.writeln(output.warning(' Warning: passing API keys via --key exposes them in process listings and shell history. Prefer setting the environment variable instead.'));
84
+ }
82
85
  if (apiKey !== undefined)
83
86
  entry.apiKey = apiKey;
84
87
  if (model !== undefined)
@@ -170,17 +173,46 @@ const testCommand = {
170
173
  test: async () => {
171
174
  const entry = configuredProviders.find((p) => typeof p.name === 'string' && p.name.toLowerCase() === 'ollama');
172
175
  const baseUrl = entry?.baseUrl || 'http://localhost:11434';
176
+ let parsedBaseUrl;
177
+ try {
178
+ parsedBaseUrl = new URL(baseUrl);
179
+ }
180
+ catch {
181
+ return { pass: false, reason: 'Invalid URL in Ollama config' };
182
+ }
183
+ if (!['http:', 'https:'].includes(parsedBaseUrl.protocol)) {
184
+ return { pass: false, reason: 'Only http/https URLs are permitted for Ollama endpoint' };
185
+ }
186
+ // SSRF defense: block cloud-metadata + RFC1918 private ranges by default.
187
+ // Ollama is conventionally local, so allow loopback by default but
188
+ // refuse metadata IPs and link-local. Set MONOMIND_OLLAMA_ALLOW_REMOTE=1
189
+ // to opt into hitting non-loopback hosts (useful for dev clusters).
190
+ const host = parsedBaseUrl.hostname;
191
+ const isLoopback = host === 'localhost' || host === '127.0.0.1' || host === '::1' ||
192
+ host === '0.0.0.0' || /^127\./.test(host);
193
+ const isMetadata = host === '169.254.169.254' || /^169\.254\./.test(host) ||
194
+ /^fe80:/i.test(host);
195
+ const isPrivateV4 = /^10\./.test(host) ||
196
+ /^192\.168\./.test(host) ||
197
+ /^172\.(1[6-9]|2\d|3[01])\./.test(host);
198
+ if (isMetadata) {
199
+ return { pass: false, reason: `Refusing to fetch metadata IP ${host}` };
200
+ }
201
+ const allowRemote = process.env.MONOMIND_OLLAMA_ALLOW_REMOTE === '1';
202
+ if (!isLoopback && (isPrivateV4 || !allowRemote)) {
203
+ return { pass: false, reason: `Refusing non-loopback Ollama host ${host}. Set MONOMIND_OLLAMA_ALLOW_REMOTE=1 to override.` };
204
+ }
173
205
  try {
174
206
  const controller = new AbortController();
175
207
  const timeout = setTimeout(() => controller.abort(), 3000);
176
- const res = await fetch(baseUrl, { signal: controller.signal });
208
+ const res = await fetch(parsedBaseUrl.href, { signal: controller.signal });
177
209
  clearTimeout(timeout);
178
210
  if (res.ok)
179
- return { pass: true, reason: `Reachable at ${baseUrl}` };
180
- return { pass: false, reason: `HTTP ${res.status} from ${baseUrl}` };
211
+ return { pass: true, reason: `Reachable at ${parsedBaseUrl.href}` };
212
+ return { pass: false, reason: `HTTP ${res.status} from ${parsedBaseUrl.href}` };
181
213
  }
182
214
  catch {
183
- return { pass: false, reason: `Unreachable at ${baseUrl}` };
215
+ return { pass: false, reason: `Unreachable at ${parsedBaseUrl.href}` };
184
216
  }
185
217
  },
186
218
  },
@@ -20,11 +20,11 @@ const showSubcommand = {
20
20
  const reader = new ReplayReader();
21
21
  const data = await reader.show(sessionId);
22
22
  const asJson = ctx.flags['json'];
23
- output.log(asJson ? JSON.stringify(data, null, 2) : `Replay for session ${sessionId}`);
23
+ output.writeln(asJson ? JSON.stringify(data, null, 2) : `Replay for session ${sessionId}`);
24
24
  return { success: true, data };
25
25
  }
26
26
  catch {
27
- output.log(`No replay data for session ${sessionId}`);
27
+ output.writeln(`No replay data for session ${sessionId}`);
28
28
  return { success: true, message: 'No replay data' };
29
29
  }
30
30
  },
@@ -42,11 +42,11 @@ const listSubcommand = {
42
42
  const reader = new ReplayReader();
43
43
  const data = await reader.list(ctx.flags['limit']);
44
44
  const asJson = ctx.flags['json'];
45
- output.log(asJson ? JSON.stringify(data, null, 2) : 'Available replays listed');
45
+ output.writeln(asJson ? JSON.stringify(data, null, 2) : 'Available replays listed');
46
46
  return { success: true, data };
47
47
  }
48
48
  catch {
49
- output.log('No replay sessions available');
49
+ output.writeln('No replay sessions available');
50
50
  return { success: true, message: 'No sessions' };
51
51
  }
52
52
  },