@monoes/monomindcli 2.9.22 → 2.9.23

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 (486) hide show
  1. package/.claude/agents/consensus/quorum-manager.md +35 -54
  2. package/.claude/agents/core/coordinator.md +14 -18
  3. package/.claude/agents/core/researcher.md +1 -1
  4. package/.claude/agents/github/issue-tracker.md +3 -3
  5. package/.claude/agents/github/{code-review-swarm.md → monoswarm-code-review.md} +1 -1
  6. package/.claude/agents/github/{swarm-issue.md → monoswarm-issue.md} +1 -1
  7. package/.claude/agents/github/{multi-repo-swarm.md → monoswarm-multi-repo.md} +1 -1
  8. package/.claude/agents/github/{swarm-pr.md → monoswarm-pr.md} +1 -1
  9. package/.claude/agents/github/pr-manager.md +1 -1
  10. package/.claude/agents/github/release-manager.md +1 -1
  11. package/.claude/agents/github/repo-architect.md +1 -1
  12. package/.claude/agents/github/sync-coordinator.md +4 -4
  13. package/.claude/agents/{hive-mind → monoswarm}/collective-intelligence-coordinator.md +9 -16
  14. package/.claude/agents/{swarm → monoswarm}/mesh-coordinator.md +19 -24
  15. package/.claude/agents/{hive-mind/swarm-memory-manager.md → monoswarm/monoswarm-memory-manager.md} +1 -1
  16. package/.claude/agents/templates/{coordinator-swarm-init.md → coordinator-monoswarm-init.md} +1 -1
  17. package/.claude/agents/testing/{tdd-london-swarm.md → tdd-london-monoswarm.md} +2 -2
  18. package/.claude/commands/agents/agent-coordination.md +3 -3
  19. package/.claude/commands/agents/agent-types.md +1 -1
  20. package/.claude/commands/automation/self-healing.md +1 -1
  21. package/.claude/commands/automation/smart-spawn.md +1 -1
  22. package/.claude/commands/coordination/README.md +1 -1
  23. package/.claude/commands/coordination/{swarm-init.md → monoswarm-init.md} +2 -2
  24. package/.claude/commands/coordination/task-orchestrate.md +4 -4
  25. package/.claude/commands/github/README.md +1 -1
  26. package/.claude/commands/github/issue-tracker.md +2 -2
  27. package/.claude/commands/github/pr-manager.md +1 -1
  28. package/.claude/commands/github/release-manager.md +1 -1
  29. package/.claude/commands/github/repo-architect.md +1 -1
  30. package/.claude/commands/github/sync-coordinator.md +2 -2
  31. package/.claude/commands/hooks/README.md +1 -2
  32. package/.claude/commands/hooks/overview.md +1 -2
  33. package/.claude/commands/hooks/setup.md +0 -3
  34. package/.claude/commands/mastermind/createtask.md +2 -2
  35. package/.claude/commands/mastermind/do.md +3 -3
  36. package/.claude/commands/mastermind/help.md +2 -2
  37. package/.claude/commands/mastermind/ideate.md +1 -1
  38. package/.claude/commands/mastermind/improve.md +1 -1
  39. package/.claude/commands/mastermind/memory.md +2 -2
  40. package/.claude/commands/mastermind/{swarm.md → monoswarm.md} +13 -26
  41. package/.claude/commands/mastermind/topology.md +1 -1
  42. package/.claude/commands/memory/README.md +2 -2
  43. package/.claude/commands/memory/memory-search.md +1 -1
  44. package/.claude/commands/monoswarm/README.md +59 -0
  45. package/.claude/commands/monoswarm/consensus.md +61 -0
  46. package/.claude/commands/monoswarm/init.md +68 -0
  47. package/.claude/commands/monoswarm/memory.md +55 -0
  48. package/.claude/commands/monoswarm/monoswarm.md +139 -0
  49. package/.claude/commands/{swarm → monoswarm}/research.md +2 -2
  50. package/.claude/commands/monoswarm/spawn.md +49 -0
  51. package/.claude/commands/monoswarm/status.md +48 -0
  52. package/.claude/commands/monoswarm/stop.md +46 -0
  53. package/.claude/commands/optimization/auto-topology.md +9 -9
  54. package/.claude/commands/stream-chain/run.md +1 -1
  55. package/.claude/commands/workflows/development.md +1 -1
  56. package/.claude/commands/workflows/research.md +2 -2
  57. package/.claude/helpers/audit-log-writer.cjs +72 -0
  58. package/.claude/helpers/control-start.cjs +84 -26
  59. package/.claude/helpers/handlers/agent-start-handler.cjs +5 -5
  60. package/.claude/helpers/handlers/gates-handler.cjs +31 -10
  61. package/.claude/helpers/handlers/session-restore-handler.cjs +1 -1
  62. package/.claude/helpers/handlers/task-handler.cjs +4 -4
  63. package/.claude/helpers/skill-registry.json +4718 -3669
  64. package/.claude/helpers/statusline.cjs +21 -21
  65. package/.claude/helpers/token-tracker.cjs +0 -6
  66. package/.claude/settings.json +2 -3
  67. package/.claude/skills/hooks-automation/SKILL.md +5 -5
  68. package/.claude/skills/mastermind-protocol/SKILL.md +3 -3
  69. package/.claude/skills/memory-toolkit/SKILL.md +2 -2
  70. package/.claude/skills/{swarm-orchestration → monoswarm}/SKILL.md +106 -42
  71. package/.claude/skills/specialagent/SKILL.md +1 -1
  72. package/README.md +31 -12
  73. package/dist/src/autopilot-state.d.ts +0 -16
  74. package/dist/src/autopilot-state.d.ts.map +1 -1
  75. package/dist/src/autopilot-state.js +0 -15
  76. package/dist/src/autopilot-state.js.map +1 -1
  77. package/dist/src/browser/dashboard/server.js +3 -3
  78. package/dist/src/browser/dashboard/server.js.map +1 -1
  79. package/dist/src/browser/dashboard/ui.html +2 -2
  80. package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
  81. package/dist/src/capabilities/cap-documents.js +49 -38
  82. package/dist/src/capabilities/cap-documents.js.map +1 -1
  83. package/dist/src/commands/agent-lifecycle.d.ts.map +1 -1
  84. package/dist/src/commands/agent-lifecycle.js +4 -9
  85. package/dist/src/commands/agent-lifecycle.js.map +1 -1
  86. package/dist/src/commands/agent-ops.d.ts.map +1 -1
  87. package/dist/src/commands/agent-ops.js +37 -24
  88. package/dist/src/commands/agent-ops.js.map +1 -1
  89. package/dist/src/commands/analyze-ast.d.ts +1 -1
  90. package/dist/src/commands/analyze-ast.d.ts.map +1 -1
  91. package/dist/src/commands/analyze-ast.js +8 -27
  92. package/dist/src/commands/analyze-ast.js.map +1 -1
  93. package/dist/src/commands/analyze-imports.d.ts.map +1 -1
  94. package/dist/src/commands/analyze-imports.js +18 -17
  95. package/dist/src/commands/analyze-imports.js.map +1 -1
  96. package/dist/src/commands/analyze-symbols.d.ts.map +1 -1
  97. package/dist/src/commands/analyze-symbols.js +10 -24
  98. package/dist/src/commands/analyze-symbols.js.map +1 -1
  99. package/dist/src/commands/analyze.d.ts +19 -6
  100. package/dist/src/commands/analyze.d.ts.map +1 -1
  101. package/dist/src/commands/analyze.js +61 -15
  102. package/dist/src/commands/analyze.js.map +1 -1
  103. package/dist/src/commands/autopilot.d.ts.map +1 -1
  104. package/dist/src/commands/autopilot.js +4 -89
  105. package/dist/src/commands/autopilot.js.map +1 -1
  106. package/dist/src/commands/browse.d.ts +1 -1
  107. package/dist/src/commands/cleanup.d.ts.map +1 -1
  108. package/dist/src/commands/cleanup.js +4 -2
  109. package/dist/src/commands/cleanup.js.map +1 -1
  110. package/dist/src/commands/completions.d.ts.map +1 -1
  111. package/dist/src/commands/completions.js +0 -1
  112. package/dist/src/commands/completions.js.map +1 -1
  113. package/dist/src/commands/config.js +7 -7
  114. package/dist/src/commands/config.js.map +1 -1
  115. package/dist/src/commands/doctor-project-checks.d.ts +7 -0
  116. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  117. package/dist/src/commands/doctor-project-checks.js +37 -5
  118. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  119. package/dist/src/commands/doctor.d.ts.map +1 -1
  120. package/dist/src/commands/doctor.js +9 -3
  121. package/dist/src/commands/doctor.js.map +1 -1
  122. package/dist/src/commands/hooks-routing-commands.d.ts +1 -2
  123. package/dist/src/commands/hooks-routing-commands.d.ts.map +1 -1
  124. package/dist/src/commands/hooks-routing-commands.js +1 -101
  125. package/dist/src/commands/hooks-routing-commands.js.map +1 -1
  126. package/dist/src/commands/hooks-workers.d.ts.map +1 -1
  127. package/dist/src/commands/hooks-workers.js +19 -71
  128. package/dist/src/commands/hooks-workers.js.map +1 -1
  129. package/dist/src/commands/hooks.d.ts +1 -1
  130. package/dist/src/commands/hooks.d.ts.map +1 -1
  131. package/dist/src/commands/hooks.js +4 -7
  132. package/dist/src/commands/hooks.js.map +1 -1
  133. package/dist/src/commands/index.d.ts +1 -1
  134. package/dist/src/commands/index.d.ts.map +1 -1
  135. package/dist/src/commands/index.js +2 -2
  136. package/dist/src/commands/index.js.map +1 -1
  137. package/dist/src/commands/init-subcommands.d.ts.map +1 -1
  138. package/dist/src/commands/init-subcommands.js +4 -0
  139. package/dist/src/commands/init-subcommands.js.map +1 -1
  140. package/dist/src/commands/init-wizard.d.ts.map +1 -1
  141. package/dist/src/commands/init-wizard.js +0 -8
  142. package/dist/src/commands/init-wizard.js.map +1 -1
  143. package/dist/src/commands/init.d.ts.map +1 -1
  144. package/dist/src/commands/init.js +53 -23
  145. package/dist/src/commands/init.js.map +1 -1
  146. package/dist/src/commands/mcp.d.ts +1 -0
  147. package/dist/src/commands/mcp.d.ts.map +1 -1
  148. package/dist/src/commands/mcp.js +111 -60
  149. package/dist/src/commands/mcp.js.map +1 -1
  150. package/dist/src/commands/memory-crud.d.ts.map +1 -1
  151. package/dist/src/commands/memory-crud.js +33 -20
  152. package/dist/src/commands/memory-crud.js.map +1 -1
  153. package/dist/src/commands/monoswarm.d.ts +8 -0
  154. package/dist/src/commands/monoswarm.d.ts.map +1 -0
  155. package/dist/src/commands/{swarm.js → monoswarm.js} +83 -297
  156. package/dist/src/commands/monoswarm.js.map +1 -0
  157. package/dist/src/commands/neural-core.d.ts.map +1 -1
  158. package/dist/src/commands/neural-core.js +9 -1
  159. package/dist/src/commands/neural-core.js.map +1 -1
  160. package/dist/src/commands/neural-optimize.d.ts.map +1 -1
  161. package/dist/src/commands/neural-optimize.js +30 -110
  162. package/dist/src/commands/neural-optimize.js.map +1 -1
  163. package/dist/src/commands/neural-registry.d.ts +1 -2
  164. package/dist/src/commands/neural-registry.d.ts.map +1 -1
  165. package/dist/src/commands/neural-registry.js +21 -168
  166. package/dist/src/commands/neural-registry.js.map +1 -1
  167. package/dist/src/commands/org-observe.d.ts +13 -3
  168. package/dist/src/commands/org-observe.d.ts.map +1 -1
  169. package/dist/src/commands/org-observe.js +134 -45
  170. package/dist/src/commands/org-observe.js.map +1 -1
  171. package/dist/src/commands/org.d.ts +14 -0
  172. package/dist/src/commands/org.d.ts.map +1 -1
  173. package/dist/src/commands/org.js +98 -20
  174. package/dist/src/commands/org.js.map +1 -1
  175. package/dist/src/commands/performance.d.ts.map +1 -1
  176. package/dist/src/commands/performance.js +38 -31
  177. package/dist/src/commands/performance.js.map +1 -1
  178. package/dist/src/commands/security-misc.d.ts.map +1 -1
  179. package/dist/src/commands/security-misc.js +220 -90
  180. package/dist/src/commands/security-misc.js.map +1 -1
  181. package/dist/src/commands/security-scan.d.ts +13 -0
  182. package/dist/src/commands/security-scan.d.ts.map +1 -1
  183. package/dist/src/commands/security-scan.js +96 -27
  184. package/dist/src/commands/security-scan.js.map +1 -1
  185. package/dist/src/commands/security.js +1 -1
  186. package/dist/src/commands/security.js.map +1 -1
  187. package/dist/src/commands/start.d.ts.map +1 -1
  188. package/dist/src/commands/start.js +17 -96
  189. package/dist/src/commands/start.js.map +1 -1
  190. package/dist/src/commands/status.d.ts.map +1 -1
  191. package/dist/src/commands/status.js +72 -64
  192. package/dist/src/commands/status.js.map +1 -1
  193. package/dist/src/commands/tokens.d.ts.map +1 -1
  194. package/dist/src/commands/tokens.js +4 -5
  195. package/dist/src/commands/tokens.js.map +1 -1
  196. package/dist/src/consensus/audit-writer.d.ts +2 -2
  197. package/dist/src/consensus/audit-writer.d.ts.map +1 -1
  198. package/dist/src/consensus/audit-writer.js +1 -1
  199. package/dist/src/index.d.ts +2 -2
  200. package/dist/src/index.d.ts.map +1 -1
  201. package/dist/src/index.js +12 -10
  202. package/dist/src/index.js.map +1 -1
  203. package/dist/src/init/claudemd-generator.d.ts.map +1 -1
  204. package/dist/src/init/claudemd-generator.js +32 -31
  205. package/dist/src/init/claudemd-generator.js.map +1 -1
  206. package/dist/src/init/codex-generator.d.ts +10 -0
  207. package/dist/src/init/codex-generator.d.ts.map +1 -0
  208. package/dist/src/init/codex-generator.js +67 -0
  209. package/dist/src/init/codex-generator.js.map +1 -0
  210. package/dist/src/init/copy-assets.d.ts.map +1 -1
  211. package/dist/src/init/copy-assets.js +4 -8
  212. package/dist/src/init/copy-assets.js.map +1 -1
  213. package/dist/src/init/executor.d.ts.map +1 -1
  214. package/dist/src/init/executor.js +9 -2
  215. package/dist/src/init/executor.js.map +1 -1
  216. package/dist/src/init/helpers-generator.js +1 -1
  217. package/dist/src/init/index.d.ts +1 -0
  218. package/dist/src/init/index.d.ts.map +1 -1
  219. package/dist/src/init/index.js +1 -0
  220. package/dist/src/init/index.js.map +1 -1
  221. package/dist/src/init/opencode-generator.js +2 -2
  222. package/dist/src/init/opencode-generator.js.map +1 -1
  223. package/dist/src/init/settings-generator.d.ts.map +1 -1
  224. package/dist/src/init/settings-generator.js +1 -2
  225. package/dist/src/init/settings-generator.js.map +1 -1
  226. package/dist/src/init/shared.d.ts.map +1 -1
  227. package/dist/src/init/shared.js +3 -7
  228. package/dist/src/init/shared.js.map +1 -1
  229. package/dist/src/init/statusline-generator.js +19 -19
  230. package/dist/src/init/types.d.ts +9 -10
  231. package/dist/src/init/types.d.ts.map +1 -1
  232. package/dist/src/init/types.js +8 -6
  233. package/dist/src/init/types.js.map +1 -1
  234. package/dist/src/init/upgrade.js +5 -5
  235. package/dist/src/init/upgrade.js.map +1 -1
  236. package/dist/src/init/write-capabilities.d.ts.map +1 -1
  237. package/dist/src/init/write-capabilities.js +36 -49
  238. package/dist/src/init/write-capabilities.js.map +1 -1
  239. package/dist/src/init/write-claude.js +1 -1
  240. package/dist/src/init/write-claude.js.map +1 -1
  241. package/dist/src/init/write-codex.d.ts +4 -0
  242. package/dist/src/init/write-codex.d.ts.map +1 -0
  243. package/dist/src/init/write-codex.js +57 -0
  244. package/dist/src/init/write-codex.js.map +1 -0
  245. package/dist/src/init/write-runtime-config.d.ts.map +1 -1
  246. package/dist/src/init/write-runtime-config.js +4 -5
  247. package/dist/src/init/write-runtime-config.js.map +1 -1
  248. package/dist/src/knowledge/eval/golden-set.js +15 -15
  249. package/dist/src/knowledge/eval/golden-set.js.map +1 -1
  250. package/dist/src/mcp-client.d.ts.map +1 -1
  251. package/dist/src/mcp-client.js +1 -2
  252. package/dist/src/mcp-client.js.map +1 -1
  253. package/dist/src/mcp-server.js +1 -1
  254. package/dist/src/mcp-server.js.map +1 -1
  255. package/dist/src/mcp-tools/agent-tools.d.ts +1 -1
  256. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  257. package/dist/src/mcp-tools/agent-tools.js +3 -3
  258. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  259. package/dist/src/mcp-tools/autopilot-tools.d.ts +1 -1
  260. package/dist/src/mcp-tools/autopilot-tools.d.ts.map +1 -1
  261. package/dist/src/mcp-tools/autopilot-tools.js +4 -62
  262. package/dist/src/mcp-tools/autopilot-tools.js.map +1 -1
  263. package/dist/src/mcp-tools/guidance-tools.d.ts.map +1 -1
  264. package/dist/src/mcp-tools/guidance-tools.js +21 -31
  265. package/dist/src/mcp-tools/guidance-tools.js.map +1 -1
  266. package/dist/src/mcp-tools/hooks-intelligence.d.ts +0 -1
  267. package/dist/src/mcp-tools/hooks-intelligence.d.ts.map +1 -1
  268. package/dist/src/mcp-tools/hooks-intelligence.js +56 -103
  269. package/dist/src/mcp-tools/hooks-intelligence.js.map +1 -1
  270. package/dist/src/mcp-tools/hooks-routing.d.ts +1 -2
  271. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  272. package/dist/src/mcp-tools/hooks-routing.js +78 -152
  273. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  274. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  275. package/dist/src/mcp-tools/hooks-tools.js +2 -4
  276. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  277. package/dist/src/mcp-tools/index.d.ts +1 -2
  278. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  279. package/dist/src/mcp-tools/index.js +1 -2
  280. package/dist/src/mcp-tools/index.js.map +1 -1
  281. package/dist/src/mcp-tools/memory-tools.js +10 -10
  282. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  283. package/dist/src/mcp-tools/monograph/query-tools.js +9 -9
  284. package/dist/src/mcp-tools/monograph/query-tools.js.map +1 -1
  285. package/dist/src/mcp-tools/monoswarm-tools.d.ts +17 -0
  286. package/dist/src/mcp-tools/monoswarm-tools.d.ts.map +1 -0
  287. package/dist/src/mcp-tools/monoswarm-tools.js +1153 -0
  288. package/dist/src/mcp-tools/monoswarm-tools.js.map +1 -0
  289. package/dist/src/mcp-tools/performance-tools.d.ts.map +1 -1
  290. package/dist/src/mcp-tools/performance-tools.js +32 -25
  291. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  292. package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
  293. package/dist/src/mcp-tools/system-tools.js +30 -13
  294. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  295. package/dist/src/mcp-tools/transfer-tools.d.ts +8 -12
  296. package/dist/src/mcp-tools/transfer-tools.d.ts.map +1 -1
  297. package/dist/src/mcp-tools/transfer-tools.js +9 -13
  298. package/dist/src/mcp-tools/transfer-tools.js.map +1 -1
  299. package/dist/src/memory/embedding-operations.d.ts.map +1 -1
  300. package/dist/src/memory/embedding-operations.js +0 -37
  301. package/dist/src/memory/embedding-operations.js.map +1 -1
  302. package/dist/src/memory/hnsw-operations.d.ts +14 -74
  303. package/dist/src/memory/hnsw-operations.d.ts.map +1 -1
  304. package/dist/src/memory/hnsw-operations.js +22 -262
  305. package/dist/src/memory/hnsw-operations.js.map +1 -1
  306. package/dist/src/memory/intelligence.d.ts +2 -2
  307. package/dist/src/memory/intelligence.d.ts.map +1 -1
  308. package/dist/src/memory/intelligence.js +8 -7
  309. package/dist/src/memory/intelligence.js.map +1 -1
  310. package/dist/src/memory/memory-bridge.d.ts +24 -24
  311. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  312. package/dist/src/memory/memory-bridge.js +33 -34
  313. package/dist/src/memory/memory-bridge.js.map +1 -1
  314. package/dist/src/memory/memory-crud.d.ts.map +1 -1
  315. package/dist/src/memory/memory-crud.js +0 -20
  316. package/dist/src/memory/memory-crud.js.map +1 -1
  317. package/dist/src/memory/memory-initializer.d.ts +2 -3
  318. package/dist/src/memory/memory-initializer.d.ts.map +1 -1
  319. package/dist/src/memory/memory-initializer.js +2 -3
  320. package/dist/src/memory/memory-initializer.js.map +1 -1
  321. package/dist/src/memory/memory-read.d.ts.map +1 -1
  322. package/dist/src/memory/memory-read.js +5 -14
  323. package/dist/src/memory/memory-read.js.map +1 -1
  324. package/dist/src/memory/sona-optimizer.d.ts +1 -1
  325. package/dist/src/memory/sona-optimizer.js +1 -1
  326. package/dist/src/monovector/model-outcomes.d.ts +25 -0
  327. package/dist/src/monovector/model-outcomes.d.ts.map +1 -0
  328. package/dist/src/monovector/model-outcomes.js +113 -0
  329. package/dist/src/monovector/model-outcomes.js.map +1 -0
  330. package/dist/src/orgrt/agent-runner.d.ts +8 -2
  331. package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
  332. package/dist/src/orgrt/agent-runner.js.map +1 -1
  333. package/dist/src/orgrt/antigravity-runner.d.ts +25 -2
  334. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  335. package/dist/src/orgrt/antigravity-runner.js +265 -124
  336. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  337. package/dist/src/orgrt/approvals.d.ts.map +1 -1
  338. package/dist/src/orgrt/approvals.js +8 -0
  339. package/dist/src/orgrt/approvals.js.map +1 -1
  340. package/dist/src/orgrt/checkpoint-ops.d.ts +10 -16
  341. package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -1
  342. package/dist/src/orgrt/checkpoint-ops.js +12 -18
  343. package/dist/src/orgrt/checkpoint-ops.js.map +1 -1
  344. package/dist/src/orgrt/checkpoint.d.ts +12 -1
  345. package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
  346. package/dist/src/orgrt/checkpoint.js +19 -3
  347. package/dist/src/orgrt/checkpoint.js.map +1 -1
  348. package/dist/src/orgrt/codex-runner.d.ts +26 -2
  349. package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
  350. package/dist/src/orgrt/codex-runner.js +359 -128
  351. package/dist/src/orgrt/codex-runner.js.map +1 -1
  352. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
  353. package/dist/src/orgrt/copilot-runner.js +12 -2
  354. package/dist/src/orgrt/copilot-runner.js.map +1 -1
  355. package/dist/src/orgrt/cross-org.d.ts.map +1 -1
  356. package/dist/src/orgrt/cross-org.js +11 -0
  357. package/dist/src/orgrt/cross-org.js.map +1 -1
  358. package/dist/src/orgrt/crush-runner.d.ts +4 -1
  359. package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
  360. package/dist/src/orgrt/crush-runner.js +42 -30
  361. package/dist/src/orgrt/crush-runner.js.map +1 -1
  362. package/dist/src/orgrt/daemon.d.ts +38 -25
  363. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  364. package/dist/src/orgrt/daemon.js +150 -28
  365. package/dist/src/orgrt/daemon.js.map +1 -1
  366. package/dist/src/orgrt/decisions.d.ts +1 -0
  367. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  368. package/dist/src/orgrt/decisions.js +20 -0
  369. package/dist/src/orgrt/decisions.js.map +1 -1
  370. package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
  371. package/dist/src/orgrt/grok-runner.js +39 -14
  372. package/dist/src/orgrt/grok-runner.js.map +1 -1
  373. package/dist/src/orgrt/kimicode-runner.d.ts +53 -7
  374. package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
  375. package/dist/src/orgrt/kimicode-runner.js +246 -144
  376. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  377. package/dist/src/orgrt/mailbox.d.ts +26 -1
  378. package/dist/src/orgrt/mailbox.d.ts.map +1 -1
  379. package/dist/src/orgrt/mailbox.js +74 -2
  380. package/dist/src/orgrt/mailbox.js.map +1 -1
  381. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
  382. package/dist/src/orgrt/pi-rpc-runner.js +76 -91
  383. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
  384. package/dist/src/orgrt/policy.d.ts +11 -0
  385. package/dist/src/orgrt/policy.d.ts.map +1 -1
  386. package/dist/src/orgrt/policy.js +25 -2
  387. package/dist/src/orgrt/policy.js.map +1 -1
  388. package/dist/src/orgrt/provider.d.ts +29 -1
  389. package/dist/src/orgrt/provider.d.ts.map +1 -1
  390. package/dist/src/orgrt/provider.js +62 -2
  391. package/dist/src/orgrt/provider.js.map +1 -1
  392. package/dist/src/orgrt/qwen-rpc-runner.d.ts +56 -0
  393. package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -0
  394. package/dist/src/orgrt/qwen-rpc-runner.js +346 -0
  395. package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -0
  396. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
  397. package/dist/src/orgrt/qwen-runner.js +11 -8
  398. package/dist/src/orgrt/qwen-runner.js.map +1 -1
  399. package/dist/src/orgrt/scheduler-integration.d.ts.map +1 -1
  400. package/dist/src/orgrt/scheduler-integration.js +7 -0
  401. package/dist/src/orgrt/scheduler-integration.js.map +1 -1
  402. package/dist/src/orgrt/session.d.ts +29 -1
  403. package/dist/src/orgrt/session.d.ts.map +1 -1
  404. package/dist/src/orgrt/session.js +87 -18
  405. package/dist/src/orgrt/session.js.map +1 -1
  406. package/dist/src/orgrt/task-dag.d.ts +29 -1
  407. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  408. package/dist/src/orgrt/task-dag.js +54 -0
  409. package/dist/src/orgrt/task-dag.js.map +1 -1
  410. package/dist/src/orgrt/test-loop.d.ts.map +1 -1
  411. package/dist/src/orgrt/test-loop.js +86 -9
  412. package/dist/src/orgrt/test-loop.js.map +1 -1
  413. package/dist/src/orgrt/tool-fence.d.ts.map +1 -1
  414. package/dist/src/orgrt/tool-fence.js +15 -0
  415. package/dist/src/orgrt/tool-fence.js.map +1 -1
  416. package/dist/src/orgrt/types.d.ts +32 -1
  417. package/dist/src/orgrt/types.d.ts.map +1 -1
  418. package/dist/src/orgrt/types.js +47 -4
  419. package/dist/src/orgrt/types.js.map +1 -1
  420. package/dist/src/pricing/model-pricing.d.ts.map +1 -1
  421. package/dist/src/pricing/model-pricing.js +0 -4
  422. package/dist/src/pricing/model-pricing.js.map +1 -1
  423. package/dist/src/security/audit-log.d.ts +47 -0
  424. package/dist/src/security/audit-log.d.ts.map +1 -0
  425. package/dist/src/security/audit-log.js +84 -0
  426. package/dist/src/security/audit-log.js.map +1 -0
  427. package/dist/src/services/config-file-manager.d.ts +2 -2
  428. package/dist/src/services/config-file-manager.d.ts.map +1 -1
  429. package/dist/src/services/config-file-manager.js +6 -7
  430. package/dist/src/services/config-file-manager.js.map +1 -1
  431. package/dist/src/suggest.d.ts.map +1 -1
  432. package/dist/src/suggest.js +4 -5
  433. package/dist/src/suggest.js.map +1 -1
  434. package/dist/src/transfer/anonymization/index.d.ts +1 -1
  435. package/dist/src/transfer/anonymization/index.js +1 -1
  436. package/dist/src/types.d.ts +3 -3
  437. package/dist/src/types.d.ts.map +1 -1
  438. package/dist/src/ui/collector.mjs +9 -13
  439. package/dist/src/ui/dashboard.html +30 -10
  440. package/dist/src/ui/data/agent-avatars.html +0 -12
  441. package/dist/src/ui/data/agent-avatars.json +10 -26
  442. package/dist/src/ui/routes-org.mjs +59 -16
  443. package/dist/src/ui/server.mjs +50 -23
  444. package/dist/src/utils/json-file.d.ts +12 -0
  445. package/dist/src/utils/json-file.d.ts.map +1 -1
  446. package/dist/src/utils/json-file.js +11 -0
  447. package/dist/src/utils/json-file.js.map +1 -1
  448. package/dist/tsconfig.tsbuildinfo +1 -1
  449. package/package.json +4 -4
  450. package/.claude/agents/consensus/crdt-synchronizer.md +0 -977
  451. package/.claude/commands/hive-mind/README.md +0 -42
  452. package/.claude/commands/hive-mind/hive-mind-consensus.md +0 -72
  453. package/.claude/commands/hive-mind/hive-mind-init.md +0 -68
  454. package/.claude/commands/hive-mind/hive-mind-memory.md +0 -73
  455. package/.claude/commands/hive-mind/hive-mind-spawn.md +0 -82
  456. package/.claude/commands/hive-mind/hive-mind-status.md +0 -56
  457. package/.claude/commands/hive-mind/hive-mind-stop.md +0 -55
  458. package/.claude/commands/hive-mind/hive-mind.md +0 -87
  459. package/.claude/commands/swarm/README.md +0 -40
  460. package/.claude/commands/swarm/swarm.md +0 -79
  461. package/.claude/skills/hive-mind-advanced/SKILL.md +0 -347
  462. package/.claude/skills/swarm-advanced/SKILL.md +0 -936
  463. package/dist/src/commands/swarm.d.ts +0 -8
  464. package/dist/src/commands/swarm.d.ts.map +0 -1
  465. package/dist/src/commands/swarm.js.map +0 -1
  466. package/dist/src/mcp-tools/hive-mind-tools.d.ts +0 -17
  467. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +0 -1
  468. package/dist/src/mcp-tools/hive-mind-tools.js +0 -1239
  469. package/dist/src/mcp-tools/hive-mind-tools.js.map +0 -1
  470. package/dist/src/mcp-tools/swarm-tools.d.ts +0 -9
  471. package/dist/src/mcp-tools/swarm-tools.d.ts.map +0 -1
  472. package/dist/src/mcp-tools/swarm-tools.js +0 -411
  473. package/dist/src/mcp-tools/swarm-tools.js.map +0 -1
  474. package/dist/src/ui/data/avatars/crdt-synchronizer.svg +0 -53
  475. package/dist/src/ui/data/avatars/gossip-coordinator.svg +0 -54
  476. package/scripts/deploy-ipfs-node.sh +0 -153
  477. package/scripts/setup-ipfs-registry.md +0 -365
  478. /package/.claude/agents/{hive-mind → monoswarm}/scout-explorer.md +0 -0
  479. /package/.claude/agents/{hive-mind → monoswarm}/worker-specialist.md +0 -0
  480. /package/.claude/commands/{swarm → monoswarm}/analysis.md +0 -0
  481. /package/.claude/commands/{swarm → monoswarm}/development.md +0 -0
  482. /package/.claude/commands/{swarm → monoswarm}/examples.md +0 -0
  483. /package/.claude/commands/{swarm → monoswarm}/maintenance.md +0 -0
  484. /package/.claude/commands/{swarm → monoswarm}/optimization.md +0 -0
  485. /package/.claude/commands/{swarm → monoswarm}/testing.md +0 -0
  486. /package/dist/src/ui/data/avatars/{code-review-swarm.svg → monoswarm-code-review.svg} +0 -0
@@ -0,0 +1,1153 @@
1
+ /**
2
+ * Monoswarm MCP Tools for CLI
3
+ *
4
+ * Merged replacement for the former swarm-tools.ts + hive-mind-tools.ts.
5
+ * Every tool here does one of two things: read/write a single JSON state
6
+ * file (`.monomind/monoswarm/state.json`), or tally votes already recorded
7
+ * in that file against a threshold. Nothing here starts a process, thread,
8
+ * or network connection — real concurrent work happens only when the caller
9
+ * separately dispatches subagents with Claude Code's Task tool.
10
+ *
11
+ * This is a clean break, not a migration: the old `.monomind/swarm/` and
12
+ * `.monomind/hive-mind/` state files are abandoned in place (a later cleanup
13
+ * phase purges them) rather than imported here.
14
+ */
15
+ import { existsSync, readFileSync, statSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
16
+ import { randomBytes } from 'node:crypto';
17
+ import { join } from 'node:path';
18
+ import { getProjectCwd, getMonomindDataRoot } from './types.js';
19
+ import { agentTools, loadAgentStore, loadAgentStoreOrNull } from './agent-tools.js';
20
+ // ---------------------------------------------------------------------------
21
+ // State persistence — single file under the git-safe data root.
22
+ // ---------------------------------------------------------------------------
23
+ const MONOSWARM_DIR = 'monoswarm';
24
+ const MONOSWARM_STATE_FILE = 'state.json';
25
+ function getMonoswarmDir() {
26
+ return join(getMonomindDataRoot(), MONOSWARM_DIR);
27
+ }
28
+ function getMonoswarmStatePath() {
29
+ return join(getMonoswarmDir(), MONOSWARM_STATE_FILE);
30
+ }
31
+ function ensureMonoswarmDir() {
32
+ const dir = getMonoswarmDir();
33
+ if (!existsSync(dir)) {
34
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
35
+ }
36
+ }
37
+ const MAX_MONOSWARM_STATE_BYTES = 10 * 1024 * 1024; // 10 MB
38
+ function defaultState() {
39
+ const now = new Date().toISOString();
40
+ return {
41
+ monoswarmId: '',
42
+ initialized: false,
43
+ topology: 'mesh',
44
+ maxAgents: 8,
45
+ status: 'initializing',
46
+ agents: [],
47
+ tasks: [],
48
+ config: {},
49
+ votes: { pending: [], history: [] },
50
+ sharedMemory: {},
51
+ notices: [],
52
+ createdAt: now,
53
+ updatedAt: now,
54
+ };
55
+ }
56
+ function loadMonoswarmState() {
57
+ try {
58
+ const path = getMonoswarmStatePath();
59
+ if (existsSync(path)) {
60
+ if (statSync(path).size > MAX_MONOSWARM_STATE_BYTES)
61
+ return defaultState();
62
+ return JSON.parse(readFileSync(path, 'utf-8'));
63
+ }
64
+ }
65
+ catch (e) {
66
+ if (process.env.DEBUG || process.env.MONOMIND_DEBUG)
67
+ console.error('[monoswarm-tools] failed to parse state.json — resetting to default state:', e);
68
+ }
69
+ return defaultState();
70
+ }
71
+ function saveMonoswarmState(state) {
72
+ ensureMonoswarmDir();
73
+ state.updatedAt = new Date().toISOString();
74
+ const dest = getMonoswarmStatePath();
75
+ const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
76
+ writeFileSync(tmp, JSON.stringify(state, null, 2), 'utf-8');
77
+ renameSync(tmp, dest);
78
+ }
79
+ const AUDIT_KEY_FILE = 'audit-key';
80
+ /**
81
+ * Resolve the HMAC signing key used for vote/audit records. Falls back to a
82
+ * per-project key generated once and persisted alongside the monoswarm
83
+ * state (kept out of state.json and never returned by any tool).
84
+ * MONOMIND_SESSION_SECRET still takes precedence for callers that want to
85
+ * manage/rotate the key themselves.
86
+ */
87
+ function getOrCreateAuditKey() {
88
+ const envKey = process.env.MONOMIND_SESSION_SECRET;
89
+ if (envKey)
90
+ return envKey;
91
+ const path = join(getMonoswarmDir(), AUDIT_KEY_FILE);
92
+ try {
93
+ if (existsSync(path)) {
94
+ const existing = readFileSync(path, 'utf-8').trim();
95
+ if (existing)
96
+ return existing;
97
+ }
98
+ }
99
+ catch { /* fall through to regeneration */ }
100
+ try {
101
+ ensureMonoswarmDir();
102
+ const key = randomBytes(32).toString('hex');
103
+ const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
104
+ writeFileSync(tmp, key, 'utf-8');
105
+ renameSync(tmp, path);
106
+ return key;
107
+ }
108
+ catch {
109
+ // Filesystem unavailable — fall back to an ephemeral in-process key.
110
+ return randomBytes(32).toString('hex');
111
+ }
112
+ }
113
+ function saveAgentStore(store) {
114
+ const storeDir = join(getMonomindDataRoot(), 'agents');
115
+ if (!existsSync(storeDir)) {
116
+ mkdirSync(storeDir, { recursive: true });
117
+ }
118
+ const dest = join(storeDir, 'store.json');
119
+ const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
120
+ writeFileSync(tmp, JSON.stringify(store, null, 2), 'utf-8');
121
+ renameSync(tmp, dest);
122
+ }
123
+ const RESERVED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
124
+ const VALID_TOPOLOGIES = new Set([
125
+ 'hierarchical', 'mesh', 'hierarchical-mesh', 'ring', 'star', 'hybrid', 'adaptive',
126
+ ]);
127
+ // ---------------------------------------------------------------------------
128
+ // Vote-threshold math
129
+ // ---------------------------------------------------------------------------
130
+ /** Calculate required votes for a given strategy and total voter count. */
131
+ function calculateRequiredVotes(strategy, totalVoters, minVotes) {
132
+ if (totalVoters <= 0)
133
+ return 1;
134
+ switch (strategy) {
135
+ case 'supermajority':
136
+ return Math.floor((totalVoters * 2) / 3) + 1;
137
+ case 'unanimous':
138
+ return totalVoters;
139
+ case 'threshold':
140
+ return Math.min(Math.max(1, minVotes ?? Math.floor(totalVoters / 2) + 1), totalVoters);
141
+ case 'majority':
142
+ default:
143
+ return Math.floor(totalVoters / 2) + 1;
144
+ }
145
+ }
146
+ /**
147
+ * Detect a voter who cast conflicting votes across proposals of the same
148
+ * type — a double-vote check, not real Byzantine fault detection.
149
+ */
150
+ function detectDuplicateVotes(pending, currentProposal, voterId, newVote) {
151
+ for (const p of pending) {
152
+ if (p.proposalId === currentProposal.proposalId)
153
+ continue;
154
+ if (p.type !== currentProposal.type)
155
+ continue;
156
+ if (voterId in p.votes && p.votes[voterId] !== newVote) {
157
+ return true; // Conflicting vote detected
158
+ }
159
+ }
160
+ return false;
161
+ }
162
+ /**
163
+ * Try to resolve a proposal based on its strategy. Returns 'approved',
164
+ * 'rejected', or null if still pending.
165
+ */
166
+ function tryResolveProposal(proposal, totalVoters) {
167
+ const votesFor = Object.values(proposal.votes).filter(v => v).length;
168
+ const votesAgainst = Object.values(proposal.votes).filter(v => !v).length;
169
+ const required = calculateRequiredVotes(proposal.strategy, totalVoters, proposal.minVotes);
170
+ if (votesFor >= required)
171
+ return 'approved';
172
+ if (votesAgainst >= required)
173
+ return 'rejected';
174
+ if (proposal.strategy === 'unanimous' && votesAgainst > 0) {
175
+ return 'rejected';
176
+ }
177
+ const totalVotes = Object.keys(proposal.votes).length;
178
+ const remaining = totalVoters - totalVotes;
179
+ if (votesFor + remaining < required && votesAgainst + remaining < required) {
180
+ return 'rejected'; // Deadlock: neither side can win
181
+ }
182
+ return null;
183
+ }
184
+ // ---------------------------------------------------------------------------
185
+ // Tools
186
+ // ---------------------------------------------------------------------------
187
+ export const monoswarmTools = [
188
+ {
189
+ name: 'monoswarm_init',
190
+ description: 'Record a coordination topology, agent roster, and vote strategy in a JSON state file. Starts no process — agents are dispatched separately via Claude Code\'s Task tool.',
191
+ category: 'monoswarm',
192
+ inputSchema: {
193
+ type: 'object',
194
+ properties: {
195
+ topology: { type: 'string', description: 'Topology label (hierarchical, mesh, hierarchical-mesh, ring, star, hybrid, adaptive)' },
196
+ maxAgents: { type: 'number', description: 'Maximum number of agents (1-50)' },
197
+ strategy: { type: 'string', description: 'Agent role strategy (specialized, balanced, adaptive)' },
198
+ coordinatorId: { type: 'string', description: 'Initial coordinator agent ID (formerly "queen")' },
199
+ voteStrategy: { type: 'string', enum: ['majority', 'supermajority', 'unanimous', 'threshold'], description: 'Default vote strategy for monoswarm_vote. Default: majority.' },
200
+ },
201
+ },
202
+ handler: async (input) => {
203
+ const topology = input.topology || 'hierarchical-mesh';
204
+ const maxAgents = Math.min(Math.max(input.maxAgents || 8, 1), 50);
205
+ const MAX_FIELD_LEN = 256;
206
+ const rawStrategy = input.strategy || 'specialized';
207
+ const strategy = typeof rawStrategy === 'string' && rawStrategy.length > MAX_FIELD_LEN
208
+ ? rawStrategy.slice(0, MAX_FIELD_LEN) : rawStrategy;
209
+ if (!VALID_TOPOLOGIES.has(topology)) {
210
+ return {
211
+ success: false,
212
+ error: `Invalid topology: ${topology}. Valid: ${[...VALID_TOPOLOGIES].join(', ')}`,
213
+ };
214
+ }
215
+ const VALID_VOTE_STRATEGIES = ['majority', 'supermajority', 'unanimous', 'threshold'];
216
+ const rawVoteStrategy = input.voteStrategy || 'majority';
217
+ const voteStrategy = VALID_VOTE_STRATEGIES.includes(rawVoteStrategy)
218
+ ? rawVoteStrategy
219
+ : 'majority';
220
+ const rawCoordinatorId = input.coordinatorId || undefined;
221
+ const coordinatorId = typeof rawCoordinatorId === 'string' && rawCoordinatorId.length > MAX_FIELD_LEN
222
+ ? rawCoordinatorId.slice(0, MAX_FIELD_LEN) : rawCoordinatorId;
223
+ const monoswarmId = `monoswarm-${Date.now()}-${randomBytes(6).toString('hex')}`;
224
+ const now = new Date().toISOString();
225
+ const state = {
226
+ monoswarmId,
227
+ initialized: true,
228
+ topology,
229
+ maxAgents,
230
+ status: 'running',
231
+ agents: [],
232
+ coordinator: coordinatorId ? { agentId: coordinatorId, electedAt: now, term: 1 } : undefined,
233
+ tasks: [],
234
+ config: { topology, maxAgents, strategy },
235
+ voteStrategy,
236
+ votes: { pending: [], history: [] },
237
+ sharedMemory: {},
238
+ notices: [],
239
+ createdAt: now,
240
+ updatedAt: now,
241
+ };
242
+ saveMonoswarmState(state);
243
+ return {
244
+ success: true,
245
+ monoswarmId,
246
+ topology,
247
+ strategy,
248
+ maxAgents,
249
+ voteStrategy,
250
+ coordinatorId,
251
+ initializedAt: now,
252
+ config: state.config,
253
+ persisted: true,
254
+ };
255
+ },
256
+ },
257
+ {
258
+ name: 'monoswarm_status',
259
+ description: 'Read the merged coordination + vote state from the JSON state file — agent roster, topology, pending/resolved votes, shared memory key count.',
260
+ category: 'monoswarm',
261
+ inputSchema: {
262
+ type: 'object',
263
+ properties: {
264
+ verbose: { type: 'boolean', description: 'Include worker details, vote history, and shared memory contents' },
265
+ },
266
+ },
267
+ handler: async (input) => {
268
+ const state = loadMonoswarmState();
269
+ if (!state.initialized) {
270
+ return {
271
+ status: 'not_initialized',
272
+ message: 'No monoswarm state recorded. Use monoswarm_init to create one.',
273
+ };
274
+ }
275
+ const agentStore = loadAgentStore();
276
+ const uptime = state.createdAt ? Date.now() - new Date(state.createdAt).getTime() : 0;
277
+ let stateBytes = 0;
278
+ try {
279
+ const path = getMonoswarmStatePath();
280
+ if (existsSync(path))
281
+ stateBytes = statSync(path).size;
282
+ }
283
+ catch { /* best-effort */ }
284
+ const summary = {
285
+ monoswarmId: state.monoswarmId,
286
+ status: state.status,
287
+ topology: state.topology,
288
+ maxAgents: state.maxAgents,
289
+ agentCount: state.agents.length,
290
+ taskCount: state.tasks.length,
291
+ voteStrategy: state.voteStrategy ?? 'majority',
292
+ coordinator: state.coordinator ? {
293
+ agentId: state.coordinator.agentId,
294
+ electedAt: state.coordinator.electedAt,
295
+ term: state.coordinator.term,
296
+ } : undefined,
297
+ agents: state.agents.map(id => {
298
+ const agent = agentStore.agents[id];
299
+ return {
300
+ id,
301
+ type: agent?.agentType || 'worker',
302
+ status: agent?.status || 'unknown',
303
+ tasksCompleted: agent?.taskCount || 0,
304
+ };
305
+ }),
306
+ pendingVotes: state.votes.pending.length,
307
+ voteHistoryCount: state.votes.history.length,
308
+ sharedMemoryKeys: Object.keys(state.sharedMemory).length,
309
+ stateSize: `${Math.round(stateBytes / 1024)} KB`,
310
+ config: state.config,
311
+ uptime,
312
+ createdAt: state.createdAt,
313
+ updatedAt: state.updatedAt,
314
+ };
315
+ if (input.verbose) {
316
+ return {
317
+ ...summary,
318
+ voteHistory: state.votes.history.slice(-10),
319
+ sharedMemory: state.sharedMemory,
320
+ notices: state.notices.slice(-10),
321
+ };
322
+ }
323
+ return summary;
324
+ },
325
+ },
326
+ {
327
+ name: 'monoswarm_scale',
328
+ description: 'Adjust the number of agent records in the roster to a target count by writing/removing bookkeeping entries in the state file. No process is started or stopped.',
329
+ category: 'monoswarm',
330
+ inputSchema: {
331
+ type: 'object',
332
+ properties: {
333
+ targetAgents: { type: 'number', description: 'Target number of agents' },
334
+ agentType: { type: 'string', description: 'Agent type for newly spawned agent records (default: worker)' },
335
+ },
336
+ required: ['targetAgents'],
337
+ },
338
+ handler: async (input) => {
339
+ const targetAgents = input.targetAgents;
340
+ const agentType = input.agentType || 'worker';
341
+ if (!Number.isFinite(targetAgents) || targetAgents < 0 || !Number.isInteger(targetAgents)) {
342
+ return { success: false, error: 'targetAgents must be a non-negative integer' };
343
+ }
344
+ const state = loadMonoswarmState();
345
+ if (!state.initialized) {
346
+ return { success: false, error: 'Monoswarm not initialized. Use monoswarm_init first.' };
347
+ }
348
+ const currentCount = state.agents.length;
349
+ const delta = targetAgents - currentCount;
350
+ const spawnTool = agentTools.find(t => t.name === 'agent_spawn');
351
+ const terminateTool = agentTools.find(t => t.name === 'agent_terminate');
352
+ const spawned = [];
353
+ const terminated = [];
354
+ if (delta > 0) {
355
+ for (let i = 0; i < delta; i++) {
356
+ const result = await spawnTool.handler({ agentType });
357
+ if (result.success && result.agentId) {
358
+ state.agents.push(result.agentId);
359
+ spawned.push(result.agentId);
360
+ }
361
+ }
362
+ }
363
+ else if (delta < 0) {
364
+ const toRemove = state.agents.slice(0, -delta);
365
+ for (const agentId of toRemove) {
366
+ const result = await terminateTool.handler({ agentId });
367
+ if (result.success) {
368
+ terminated.push(agentId);
369
+ }
370
+ }
371
+ state.agents = state.agents.filter(id => !terminated.includes(id));
372
+ }
373
+ state.maxAgents = Math.max(state.maxAgents, state.agents.length);
374
+ saveMonoswarmState(state);
375
+ const targetReached = state.agents.length === targetAgents;
376
+ return {
377
+ success: targetReached,
378
+ error: targetReached
379
+ ? undefined
380
+ : `Reached ${state.agents.length}/${targetAgents} agents — some spawn/terminate operations failed`,
381
+ monoswarmId: state.monoswarmId,
382
+ previousCount: currentCount,
383
+ currentCount: state.agents.length,
384
+ targetAgents,
385
+ spawned,
386
+ terminated,
387
+ };
388
+ },
389
+ },
390
+ {
391
+ name: 'monoswarm_health',
392
+ description: 'Inspect the state file and agent roster and report a derived healthy/degraded status — no live process is polled.',
393
+ category: 'monoswarm',
394
+ inputSchema: {
395
+ type: 'object',
396
+ properties: {},
397
+ },
398
+ handler: async () => {
399
+ const state = loadMonoswarmState();
400
+ if (!state.initialized) {
401
+ return {
402
+ status: 'not_initialized',
403
+ healthy: false,
404
+ checks: [
405
+ { name: 'monoswarm_exists', status: 'fail', message: 'No monoswarm state recorded' },
406
+ ],
407
+ checkedAt: new Date().toISOString(),
408
+ };
409
+ }
410
+ const isRunning = state.status === 'running';
411
+ const stateFileExists = existsSync(getMonoswarmStatePath());
412
+ const checks = [
413
+ { name: 'monoswarm_exists', status: 'ok', message: `Monoswarm ${state.monoswarmId} recorded` },
414
+ {
415
+ name: 'coordinator',
416
+ status: isRunning ? 'ok' : 'warn',
417
+ message: isRunning ? 'Status: running' : `Status: ${state.status}`,
418
+ },
419
+ {
420
+ name: 'agents',
421
+ status: state.agents.length > 0 ? 'ok' : 'info',
422
+ message: `${state.agents.length} agents registered (max: ${state.maxAgents})`,
423
+ },
424
+ {
425
+ name: 'persistence',
426
+ status: stateFileExists ? 'ok' : 'warn',
427
+ message: stateFileExists ? 'State file persisted' : 'State file missing',
428
+ },
429
+ {
430
+ name: 'topology',
431
+ status: 'ok',
432
+ message: `Topology: ${state.topology}`,
433
+ },
434
+ ];
435
+ const healthy = isRunning && stateFileExists;
436
+ return {
437
+ status: healthy ? 'healthy' : 'degraded',
438
+ healthy,
439
+ monoswarmId: state.monoswarmId,
440
+ topology: state.topology,
441
+ agentCount: state.agents.length,
442
+ checks,
443
+ checkedAt: new Date().toISOString(),
444
+ };
445
+ },
446
+ },
447
+ {
448
+ name: 'monoswarm_shutdown',
449
+ description: 'Mark the state file terminated and remove roster agents from the agent store. No process is stopped because none was started.',
450
+ category: 'monoswarm',
451
+ inputSchema: {
452
+ type: 'object',
453
+ properties: {
454
+ graceful: { type: 'boolean', description: 'Refuse to shut down while votes are pending unless force is set (default: true)' },
455
+ force: { type: 'boolean', description: 'Force immediate shutdown even with pending votes' },
456
+ },
457
+ },
458
+ handler: async (input) => {
459
+ const state = loadMonoswarmState();
460
+ if (!state.initialized) {
461
+ return { success: false, error: 'Monoswarm not initialized or already shut down' };
462
+ }
463
+ if (state.status === 'terminated') {
464
+ return { success: false, monoswarmId: state.monoswarmId, error: 'Monoswarm already terminated' };
465
+ }
466
+ const graceful = input.graceful !== false;
467
+ const force = input.force === true;
468
+ const pendingVotes = state.votes.pending.length;
469
+ if (graceful && pendingVotes > 0 && !force) {
470
+ return {
471
+ success: false,
472
+ error: `Cannot gracefully shut down with ${pendingVotes} pending vote(s). Use force: true to override.`,
473
+ pendingVotes,
474
+ agentCount: state.agents.length,
475
+ };
476
+ }
477
+ // Clear roster agents from the agent store. Must use the null-aware
478
+ // loader here (this handler mutates and saves) — loadAgentStore() on a
479
+ // corrupt/oversized store.json returns the empty default, and saving
480
+ // that back would wipe every real agent, not just this roster.
481
+ const agentStore = loadAgentStoreOrNull();
482
+ if (!agentStore) {
483
+ return { success: false, error: 'Agent store is unreadable/corrupt — refusing to shut down to avoid overwriting real agent data.', pendingVotes, agentCount: state.agents.length };
484
+ }
485
+ for (const agentId of state.agents) {
486
+ if (agentStore.agents[agentId])
487
+ delete agentStore.agents[agentId];
488
+ }
489
+ saveAgentStore(agentStore);
490
+ const shutdownTime = new Date().toISOString();
491
+ const agentsTerminated = state.agents.length;
492
+ const previousCoordinator = state.coordinator?.agentId;
493
+ state.status = 'terminated';
494
+ state.initialized = false;
495
+ state.coordinator = undefined;
496
+ state.agents = [];
497
+ state.votes.pending = [];
498
+ state.sharedMemory = {};
499
+ saveMonoswarmState(state);
500
+ return {
501
+ success: true,
502
+ monoswarmId: state.monoswarmId,
503
+ terminated: true,
504
+ graceful,
505
+ agentsTerminated,
506
+ previousCoordinator,
507
+ votesCleared: pendingVotes,
508
+ terminatedAt: shutdownTime,
509
+ };
510
+ },
511
+ },
512
+ {
513
+ name: 'monoswarm_agent_add',
514
+ description: 'Add an agent record (id, role) to the roster in the state file, and write a matching record into the agent store. Starts nothing.',
515
+ category: 'monoswarm',
516
+ inputSchema: {
517
+ type: 'object',
518
+ properties: {
519
+ count: { type: 'number', description: 'Number of agent records to add (default: 1)', default: 1 },
520
+ role: { type: 'string', enum: ['worker', 'specialist', 'scout'], description: 'Agent role', default: 'worker' },
521
+ agentType: { type: 'string', description: 'Agent type for added agents', default: 'worker' },
522
+ prefix: { type: 'string', description: 'Prefix for agent IDs', default: 'monoswarm-agent' },
523
+ },
524
+ },
525
+ handler: async (input) => {
526
+ const state = loadMonoswarmState();
527
+ if (!state.initialized) {
528
+ return { success: false, error: 'Monoswarm not initialized. Run monoswarm_init first.' };
529
+ }
530
+ const count = Math.min(Math.max(1, input.count || 1), 20);
531
+ const MAX_ROLE_LEN = 256;
532
+ const MAX_PREFIX_LEN = 128;
533
+ const rawRole = input.role || 'worker';
534
+ const role = typeof rawRole === 'string' && rawRole.length > MAX_ROLE_LEN
535
+ ? rawRole.slice(0, MAX_ROLE_LEN) : rawRole;
536
+ const rawAgentType = input.agentType || 'worker';
537
+ const agentType = typeof rawAgentType === 'string' && rawAgentType.length > MAX_ROLE_LEN
538
+ ? rawAgentType.slice(0, MAX_ROLE_LEN) : rawAgentType;
539
+ const rawPrefix = input.prefix || 'monoswarm-agent';
540
+ const prefix = typeof rawPrefix === 'string' && rawPrefix.length > MAX_PREFIX_LEN
541
+ ? rawPrefix.slice(0, MAX_PREFIX_LEN) : rawPrefix;
542
+ const agentStore = loadAgentStoreOrNull();
543
+ if (!agentStore) {
544
+ return { success: false, error: 'Agent store is unreadable/corrupt — refusing to add agents to avoid overwriting real agent data.' };
545
+ }
546
+ const added = [];
547
+ for (let i = 0; i < count; i++) {
548
+ const agentId = `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
549
+ if (RESERVED_KEYS.has(agentId))
550
+ continue;
551
+ agentStore.agents[agentId] = {
552
+ agentId,
553
+ agentType,
554
+ status: 'idle',
555
+ health: 1.0,
556
+ taskCount: 0,
557
+ config: { role },
558
+ createdAt: new Date().toISOString(),
559
+ domain: 'monoswarm',
560
+ };
561
+ const MAX_AGENTS = 100;
562
+ if (!state.agents.includes(agentId)) {
563
+ if (state.agents.length >= MAX_AGENTS) {
564
+ return { success: false, error: `Monoswarm has reached max agent capacity (${MAX_AGENTS})` };
565
+ }
566
+ state.agents.push(agentId);
567
+ }
568
+ added.push({ agentId, role, joinedAt: new Date().toISOString() });
569
+ }
570
+ saveAgentStore(agentStore);
571
+ saveMonoswarmState(state);
572
+ return {
573
+ success: true,
574
+ added: count,
575
+ agents: added,
576
+ totalAgents: state.agents.length,
577
+ message: `Added ${count} agent record(s) to the roster`,
578
+ };
579
+ },
580
+ },
581
+ {
582
+ name: 'monoswarm_join',
583
+ description: 'Append an agent id to the roster array in the state file. No membership handshake occurs — this is a list append.',
584
+ category: 'monoswarm',
585
+ inputSchema: {
586
+ type: 'object',
587
+ properties: {
588
+ agentId: { type: 'string', description: 'Agent ID to add to the roster' },
589
+ role: { type: 'string', enum: ['worker', 'specialist', 'scout'], description: 'Agent role' },
590
+ },
591
+ required: ['agentId'],
592
+ },
593
+ handler: async (input) => {
594
+ const state = loadMonoswarmState();
595
+ const agentId = input.agentId;
596
+ if (typeof agentId !== 'string' || agentId.length === 0 || agentId.length > 128 ||
597
+ RESERVED_KEYS.has(agentId) || !/^[a-zA-Z0-9_-]+$/.test(agentId)) {
598
+ return { success: false, error: 'Invalid agentId' };
599
+ }
600
+ if (!state.initialized) {
601
+ return { success: false, error: 'Monoswarm not initialized' };
602
+ }
603
+ const MAX_AGENTS = 100;
604
+ if (!state.agents.includes(agentId)) {
605
+ if (state.agents.length >= MAX_AGENTS) {
606
+ return { success: false, error: `Monoswarm has reached max agent capacity (${MAX_AGENTS})` };
607
+ }
608
+ state.agents.push(agentId);
609
+ saveMonoswarmState(state);
610
+ }
611
+ return {
612
+ success: true,
613
+ agentId,
614
+ role: input.role || 'worker',
615
+ totalAgents: state.agents.length,
616
+ joinedAt: new Date().toISOString(),
617
+ };
618
+ },
619
+ },
620
+ {
621
+ name: 'monoswarm_leave',
622
+ description: 'Remove an agent id from the roster array in the state file.',
623
+ category: 'monoswarm',
624
+ inputSchema: {
625
+ type: 'object',
626
+ properties: {
627
+ agentId: { type: 'string', description: 'Agent ID to remove' },
628
+ },
629
+ required: ['agentId'],
630
+ },
631
+ handler: async (input) => {
632
+ const state = loadMonoswarmState();
633
+ const agentId = input.agentId;
634
+ if (typeof agentId !== 'string' || agentId.length === 0 || agentId.length > 128 ||
635
+ RESERVED_KEYS.has(agentId) || !/^[a-zA-Z0-9_-]+$/.test(agentId)) {
636
+ return { success: false, error: 'Invalid agentId' };
637
+ }
638
+ const index = state.agents.indexOf(agentId);
639
+ if (index > -1) {
640
+ state.agents.splice(index, 1);
641
+ saveMonoswarmState(state);
642
+ return {
643
+ success: true,
644
+ agentId,
645
+ leftAt: new Date().toISOString(),
646
+ remainingAgents: state.agents.length,
647
+ };
648
+ }
649
+ return { success: false, agentId, error: 'Agent not in roster' };
650
+ },
651
+ },
652
+ {
653
+ name: 'monoswarm_vote',
654
+ description: 'Create or vote on a proposal; passes when the vote count meets the chosen strategy\'s threshold (majority / supermajority / unanimous / a custom threshold) — single in-process tally, not a distributed consensus protocol.',
655
+ category: 'monoswarm',
656
+ inputSchema: {
657
+ type: 'object',
658
+ properties: {
659
+ action: { type: 'string', enum: ['propose', 'vote', 'status', 'list'], description: 'Vote action' },
660
+ proposalId: { type: 'string', description: 'Proposal ID (for vote/status)' },
661
+ type: { type: 'string', description: 'Proposal type (for propose)' },
662
+ value: { description: 'Proposal value (for propose)' },
663
+ vote: { type: 'boolean', description: 'Vote (true=for, false=against)' },
664
+ voterId: { type: 'string', description: 'Voter agent ID' },
665
+ strategy: { type: 'string', enum: ['majority', 'supermajority', 'unanimous', 'threshold'], description: 'Vote strategy (default: the strategy chosen at monoswarm_init, else majority)' },
666
+ minVotes: { type: 'number', description: 'Explicit vote count required (for threshold strategy)' },
667
+ minDivergenceRounds: { type: 'number', description: 'Anti-groupthink delay: minimum rounds with divergent votes required before resolution. Default: 0 (disabled).' },
668
+ },
669
+ required: ['action'],
670
+ },
671
+ handler: async (input) => {
672
+ const state = loadMonoswarmState();
673
+ const action = input.action;
674
+ const rawStrategy = input.strategy || state.voteStrategy || 'majority';
675
+ const VALID_STRATEGIES = ['majority', 'supermajority', 'unanimous', 'threshold'];
676
+ if (!VALID_STRATEGIES.includes(rawStrategy)) {
677
+ return {
678
+ action,
679
+ error: `Unknown strategy "${rawStrategy}". Available strategies: ${VALID_STRATEGIES.join(', ')}.`,
680
+ availableStrategies: VALID_STRATEGIES,
681
+ };
682
+ }
683
+ const strategy = rawStrategy;
684
+ const totalVoters = state.agents.length;
685
+ if (action === 'propose') {
686
+ const proposalId = `proposal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
687
+ const minVotes = strategy === 'threshold' ? input.minVotes : undefined;
688
+ const required = calculateRequiredVotes(strategy, totalVoters, minVotes);
689
+ const minDivergenceRounds = typeof input.minDivergenceRounds === 'number'
690
+ ? Math.max(0, input.minDivergenceRounds)
691
+ : 0;
692
+ const MAX_TYPE_LEN = 128;
693
+ const MAX_VOTER_ID_LEN = 256;
694
+ const MAX_VALUE_BYTES = 64 * 1024;
695
+ const rawType = input.type || 'general';
696
+ const proposalType = typeof rawType === 'string' && rawType.length > MAX_TYPE_LEN
697
+ ? rawType.slice(0, MAX_TYPE_LEN) : rawType;
698
+ const rawVoterId = input.voterId || 'system';
699
+ const proposedBy = typeof rawVoterId === 'string' && rawVoterId.length > MAX_VOTER_ID_LEN
700
+ ? rawVoterId.slice(0, MAX_VOTER_ID_LEN) : rawVoterId;
701
+ const rawValue = input.value;
702
+ const cappedValue = typeof rawValue === 'string' && rawValue.length > MAX_VALUE_BYTES
703
+ ? rawValue.slice(0, MAX_VALUE_BYTES) : rawValue;
704
+ const proposal = {
705
+ proposalId,
706
+ type: proposalType,
707
+ value: cappedValue,
708
+ proposedBy,
709
+ proposedAt: new Date().toISOString(),
710
+ votes: {},
711
+ status: 'pending',
712
+ strategy,
713
+ minVotes: strategy === 'threshold' ? required : undefined,
714
+ duplicateVoters: undefined,
715
+ minDivergenceRounds: minDivergenceRounds > 0 ? minDivergenceRounds : undefined,
716
+ divergenceRoundsSeen: 0,
717
+ };
718
+ state.votes.pending.push(proposal);
719
+ saveMonoswarmState(state);
720
+ return {
721
+ action,
722
+ proposalId,
723
+ type: proposal.type,
724
+ strategy,
725
+ status: 'pending',
726
+ required,
727
+ totalVoters,
728
+ minVotes: proposal.minVotes,
729
+ minDivergenceRounds: proposal.minDivergenceRounds,
730
+ };
731
+ }
732
+ if (action === 'vote') {
733
+ const proposal = state.votes.pending.find(p => p.proposalId === input.proposalId);
734
+ if (!proposal) {
735
+ return { action, error: 'Proposal not found or already resolved' };
736
+ }
737
+ const voterId = input.voterId;
738
+ if (!voterId) {
739
+ return { action, error: 'voterId is required for voting' };
740
+ }
741
+ if (totalVoters === 0) {
742
+ return { action, error: 'No agents in roster — cannot vote' };
743
+ }
744
+ if (!state.agents.includes(voterId)) {
745
+ return { action, error: `Voter ${voterId} is not a member of this roster` };
746
+ }
747
+ const voteValue = input.vote;
748
+ const proposalStrategy = proposal.strategy || 'majority';
749
+ const required = calculateRequiredVotes(proposalStrategy, totalVoters, proposal.minVotes);
750
+ if (voterId in proposal.votes) {
751
+ const previousVote = proposal.votes[voterId];
752
+ if (previousVote === voteValue) {
753
+ return {
754
+ action,
755
+ error: `Voter ${voterId} has already cast the same vote on this proposal`,
756
+ proposalId: proposal.proposalId,
757
+ existingVote: previousVote,
758
+ };
759
+ }
760
+ // Conflicting vote from the same voter — flag it and drop the vote.
761
+ if (!proposal.duplicateVoters)
762
+ proposal.duplicateVoters = [];
763
+ if (!proposal.duplicateVoters.includes(voterId)) {
764
+ proposal.duplicateVoters.push(voterId);
765
+ }
766
+ delete proposal.votes[voterId];
767
+ saveMonoswarmState(state);
768
+ return {
769
+ action,
770
+ proposalId: proposal.proposalId,
771
+ voterId,
772
+ duplicateVoteDetected: true,
773
+ message: `Voter ${voterId} attempted a conflicting vote. Previous vote invalidated.`,
774
+ duplicateVoters: proposal.duplicateVoters,
775
+ status: proposal.status,
776
+ };
777
+ }
778
+ // Cross-proposal duplicate-vote check (same voter, same proposal type, conflicting votes).
779
+ const isDuplicate = detectDuplicateVotes(state.votes.pending, proposal, voterId, voteValue);
780
+ if (isDuplicate) {
781
+ if (!proposal.duplicateVoters)
782
+ proposal.duplicateVoters = [];
783
+ if (!proposal.duplicateVoters.includes(voterId)) {
784
+ proposal.duplicateVoters.push(voterId);
785
+ }
786
+ saveMonoswarmState(state);
787
+ return {
788
+ action,
789
+ proposalId: proposal.proposalId,
790
+ voterId,
791
+ duplicateVoteDetected: true,
792
+ message: `Voter ${voterId} cast conflicting votes across proposals of the same type. Vote rejected.`,
793
+ duplicateVoters: proposal.duplicateVoters,
794
+ status: proposal.status,
795
+ };
796
+ }
797
+ proposal.votes[voterId] = voteValue;
798
+ const votesFor = Object.values(proposal.votes).filter(v => v).length;
799
+ const votesAgainst = Object.values(proposal.votes).filter(v => !v).length;
800
+ const allVotes = Object.values(proposal.votes);
801
+ const isUnanimous = allVotes.every(v => v) || allVotes.every(v => !v);
802
+ if (!isUnanimous && allVotes.length >= 2) {
803
+ proposal.divergenceRoundsSeen = (proposal.divergenceRoundsSeen ?? 0) + 1;
804
+ }
805
+ const totalVotesCast = Object.keys(proposal.votes).length;
806
+ const electorateExhausted = totalVoters > 0 && totalVotesCast >= totalVoters;
807
+ const divergenceGateOpen = !proposal.minDivergenceRounds
808
+ || (proposal.divergenceRoundsSeen ?? 0) >= proposal.minDivergenceRounds
809
+ || electorateExhausted;
810
+ const resolution = divergenceGateOpen ? tryResolveProposal(proposal, totalVoters) : null;
811
+ let resolved = false;
812
+ if (resolution !== null) {
813
+ resolved = true;
814
+ proposal.status = resolution;
815
+ state.votes.history.push({
816
+ proposalId: proposal.proposalId,
817
+ type: proposal.type,
818
+ result: resolution,
819
+ votes: { for: votesFor, against: votesAgainst },
820
+ decidedAt: new Date().toISOString(),
821
+ strategy: proposalStrategy,
822
+ duplicateVotersDetected: proposal.duplicateVoters?.length ? proposal.duplicateVoters : undefined,
823
+ });
824
+ if (state.votes.history.length > 1000) {
825
+ state.votes.history = state.votes.history.slice(-1000);
826
+ }
827
+ state.votes.pending = state.votes.pending.filter(p => p.proposalId !== proposal.proposalId);
828
+ }
829
+ saveMonoswarmState(state);
830
+ if (resolved) {
831
+ try {
832
+ const bridge = await import('../memory/memory-bridge.js');
833
+ await bridge.bridgeStoreEntry({
834
+ key: `monoswarm-vote-${proposal.proposalId}`,
835
+ value: JSON.stringify({
836
+ proposalId: proposal.proposalId,
837
+ type: proposal.type,
838
+ strategy: proposalStrategy,
839
+ status: proposal.status,
840
+ votes: proposal.votes,
841
+ resolvedAt: new Date().toISOString(),
842
+ }),
843
+ namespace: 'monoswarm-votes',
844
+ tags: [proposal.type, proposalStrategy, proposal.status],
845
+ });
846
+ }
847
+ catch { /* SQLite memory backend not available — JSON store is primary */ }
848
+ const hk = getOrCreateAuditKey();
849
+ try {
850
+ const { AuditWriter } = await import('../consensus/audit-writer.js');
851
+ const auditDir = join(getProjectCwd(), '.monomind', 'consensus');
852
+ const writer = new AuditWriter(auditDir);
853
+ const now = new Date().toISOString();
854
+ const voteEntries = Object.entries(proposal.votes).map(([agentId, vote]) => ({
855
+ agentId,
856
+ agentSlug: agentId,
857
+ vote,
858
+ votedAt: now,
859
+ }));
860
+ writer.record({
861
+ decisionId: proposal.proposalId,
862
+ swarmId: state.monoswarmId,
863
+ protocol: proposalStrategy,
864
+ topic: proposal.type,
865
+ decision: resolution,
866
+ votes: voteEntries,
867
+ quorumRequired: required,
868
+ quorumThreshold: required / Math.max(totalVoters, 1),
869
+ round: (proposal.divergenceRoundsSeen ?? 0) + 1,
870
+ startedAt: proposal.proposedAt,
871
+ completedAt: now,
872
+ sessionSecret: hk,
873
+ });
874
+ }
875
+ catch (e) {
876
+ if (process.env.MONOMIND_LOG_LEVEL === 'debug') {
877
+ process.stderr.write(`[monoswarm-vote] Audit write failed: ${e.message}\n`);
878
+ }
879
+ }
880
+ }
881
+ return {
882
+ action,
883
+ proposalId: proposal.proposalId,
884
+ voterId,
885
+ vote: voteValue,
886
+ strategy: proposalStrategy,
887
+ votesFor,
888
+ votesAgainst,
889
+ required,
890
+ totalVoters,
891
+ resolved,
892
+ result: resolved ? resolution : undefined,
893
+ status: proposal.status,
894
+ duplicateVoters: proposal.duplicateVoters?.length ? proposal.duplicateVoters : undefined,
895
+ divergenceGateOpen,
896
+ divergenceRoundsSeen: proposal.divergenceRoundsSeen ?? 0,
897
+ minDivergenceRounds: proposal.minDivergenceRounds,
898
+ divergenceHint: !divergenceGateOpen
899
+ ? `Anti-groupthink delay: ${proposal.divergenceRoundsSeen ?? 0}/${proposal.minDivergenceRounds} divergent rounds seen. Resolution deferred.`
900
+ : undefined,
901
+ };
902
+ }
903
+ if (action === 'status') {
904
+ const proposal = state.votes.pending.find(p => p.proposalId === input.proposalId);
905
+ if (!proposal) {
906
+ const historical = state.votes.history.find(h => h.proposalId === input.proposalId);
907
+ if (historical) {
908
+ return { action, ...historical, historical: true, resolved: true };
909
+ }
910
+ return { action, error: 'Proposal not found' };
911
+ }
912
+ const votesFor = Object.values(proposal.votes).filter(v => v).length;
913
+ const votesAgainst = Object.values(proposal.votes).filter(v => !v).length;
914
+ const proposalStrategy = proposal.strategy || 'majority';
915
+ const required = calculateRequiredVotes(proposalStrategy, totalVoters, proposal.minVotes);
916
+ return {
917
+ action,
918
+ proposalId: proposal.proposalId,
919
+ type: proposal.type,
920
+ strategy: proposalStrategy,
921
+ status: proposal.status,
922
+ votesFor,
923
+ votesAgainst,
924
+ totalVotes: Object.keys(proposal.votes).length,
925
+ required,
926
+ totalVoters,
927
+ resolved: false,
928
+ minVotes: proposal.minVotes,
929
+ duplicateVoters: proposal.duplicateVoters?.length ? proposal.duplicateVoters : undefined,
930
+ };
931
+ }
932
+ if (action === 'list') {
933
+ return {
934
+ action,
935
+ pending: state.votes.pending.map(p => ({
936
+ proposalId: p.proposalId,
937
+ type: p.type,
938
+ strategy: p.strategy || 'majority',
939
+ proposedAt: p.proposedAt,
940
+ totalVotes: Object.keys(p.votes).length,
941
+ required: calculateRequiredVotes(p.strategy || 'majority', totalVoters, p.minVotes),
942
+ status: p.status,
943
+ })),
944
+ recentHistory: state.votes.history.slice(-5),
945
+ };
946
+ }
947
+ return { action, error: 'Unknown action' };
948
+ },
949
+ },
950
+ {
951
+ name: 'monoswarm_notice',
952
+ description: 'Append a message to a shared array in the state file — a noticeboard, not message delivery; nothing subscribes to it.',
953
+ category: 'monoswarm',
954
+ inputSchema: {
955
+ type: 'object',
956
+ properties: {
957
+ message: { type: 'string', description: 'Notice text' },
958
+ priority: { type: 'string', enum: ['low', 'normal', 'high', 'critical'], description: 'Notice priority' },
959
+ fromId: { type: 'string', description: 'Sender agent ID' },
960
+ },
961
+ required: ['message'],
962
+ },
963
+ handler: async (input) => {
964
+ const state = loadMonoswarmState();
965
+ if (!state.initialized) {
966
+ return { success: false, error: 'Monoswarm not initialized' };
967
+ }
968
+ const MAX_MSG_LEN = 1024 * 1024; // 1 MB
969
+ const MAX_FROM_ID_LEN = 256;
970
+ const MAX_PRIORITY_LEN = 16;
971
+ const rawMessage = input.message;
972
+ const message = typeof rawMessage === 'string' && rawMessage.length > MAX_MSG_LEN
973
+ ? rawMessage.slice(0, MAX_MSG_LEN) : rawMessage;
974
+ const rawFromId = input.fromId || 'system';
975
+ const fromId = typeof rawFromId === 'string' && rawFromId.length > MAX_FROM_ID_LEN
976
+ ? rawFromId.slice(0, MAX_FROM_ID_LEN) : rawFromId;
977
+ const rawPriority = input.priority || 'normal';
978
+ const priority = typeof rawPriority === 'string' && rawPriority.length > MAX_PRIORITY_LEN
979
+ ? rawPriority.slice(0, MAX_PRIORITY_LEN) : rawPriority;
980
+ const noticeId = `notice-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
981
+ state.notices.push({ noticeId, message, priority, fromId, timestamp: new Date().toISOString() });
982
+ state.notices = state.notices.slice(-100); // Keep only the last 100 notices
983
+ saveMonoswarmState(state);
984
+ return {
985
+ success: true,
986
+ noticeId,
987
+ recipients: state.agents.length,
988
+ priority,
989
+ postedAt: new Date().toISOString(),
990
+ };
991
+ },
992
+ },
993
+ {
994
+ name: 'monoswarm_memory',
995
+ description: 'Plain key/value bookkeeping in the state file — not a distributed or replicated store.',
996
+ category: 'monoswarm',
997
+ inputSchema: {
998
+ type: 'object',
999
+ properties: {
1000
+ action: { type: 'string', enum: ['get', 'set', 'delete', 'list'], description: 'Memory action' },
1001
+ key: { type: 'string', description: 'Memory key' },
1002
+ value: { description: 'Value to store (for set)' },
1003
+ },
1004
+ required: ['action'],
1005
+ },
1006
+ handler: async (input) => {
1007
+ const state = loadMonoswarmState();
1008
+ const action = input.action;
1009
+ const key = input.key;
1010
+ const MAX_KEY_LEN = 256;
1011
+ const MAX_VALUE_BYTES = 1024 * 1024; // 1 MB
1012
+ const MAX_KEYS = 1000;
1013
+ if (action === 'get') {
1014
+ if (!key)
1015
+ return { action, error: 'Key required' };
1016
+ if (typeof key !== 'string' || key.length > MAX_KEY_LEN || RESERVED_KEYS.has(key)) {
1017
+ return { action, error: 'Invalid key' };
1018
+ }
1019
+ return {
1020
+ action,
1021
+ key,
1022
+ value: Object.hasOwn(state.sharedMemory, key) ? state.sharedMemory[key] : undefined,
1023
+ exists: Object.hasOwn(state.sharedMemory, key),
1024
+ };
1025
+ }
1026
+ if (action === 'set') {
1027
+ if (!key)
1028
+ return { action, error: 'Key required' };
1029
+ if (typeof key !== 'string' || key.length > MAX_KEY_LEN || RESERVED_KEYS.has(key)) {
1030
+ return { action, error: 'Invalid key' };
1031
+ }
1032
+ const rawValue = input.value;
1033
+ const cappedValue = typeof rawValue === 'string' && rawValue.length > MAX_VALUE_BYTES
1034
+ ? rawValue.slice(0, MAX_VALUE_BYTES) : rawValue;
1035
+ const keyCount = Object.keys(state.sharedMemory).length;
1036
+ if (!Object.hasOwn(state.sharedMemory, key) && keyCount >= MAX_KEYS) {
1037
+ return { action, error: `Shared memory full (max ${MAX_KEYS} keys)` };
1038
+ }
1039
+ state.sharedMemory[key] = cappedValue;
1040
+ saveMonoswarmState(state);
1041
+ try {
1042
+ const bridge = await import('../memory/memory-bridge.js');
1043
+ await bridge.bridgeStoreEntry({
1044
+ key: `monoswarm-memory-${key}`,
1045
+ value: JSON.stringify(input.value),
1046
+ namespace: 'monoswarm-memory',
1047
+ });
1048
+ }
1049
+ catch { /* SQLite memory backend not available */ }
1050
+ return { action, key, success: true, updatedAt: new Date().toISOString() };
1051
+ }
1052
+ if (action === 'delete') {
1053
+ if (!key)
1054
+ return { action, error: 'Key required' };
1055
+ if (typeof key !== 'string' || key.length > MAX_KEY_LEN || RESERVED_KEYS.has(key)) {
1056
+ return { action, error: 'Invalid key' };
1057
+ }
1058
+ const existed = Object.hasOwn(state.sharedMemory, key);
1059
+ delete state.sharedMemory[key];
1060
+ saveMonoswarmState(state);
1061
+ return { action, key, deleted: existed };
1062
+ }
1063
+ if (action === 'list') {
1064
+ return {
1065
+ action,
1066
+ keys: Object.keys(state.sharedMemory),
1067
+ count: Object.keys(state.sharedMemory).length,
1068
+ };
1069
+ }
1070
+ return { action, error: 'Unknown action' };
1071
+ },
1072
+ },
1073
+ {
1074
+ name: 'monoswarm_audit_list',
1075
+ description: 'List tamper-evident vote audit records (HMAC-signed JSONL trail) — local file, not a distributed ledger.',
1076
+ category: 'monoswarm',
1077
+ inputSchema: {
1078
+ type: 'object',
1079
+ properties: {
1080
+ swarmId: { type: 'string', description: 'Filter by monoswarm ID (optional)' },
1081
+ limit: { type: 'number', description: 'Max records to return (default: 50, max: 500)' },
1082
+ },
1083
+ },
1084
+ handler: async (input) => {
1085
+ try {
1086
+ const { AuditWriter } = await import('../consensus/audit-writer.js');
1087
+ const auditDir = join(getProjectCwd(), '.monomind', 'consensus');
1088
+ const writer = new AuditWriter(auditDir);
1089
+ const limit = Math.min(Math.max(1, input.limit || 50), 500);
1090
+ const swarmId = input.swarmId;
1091
+ const records = writer.listDecisions(swarmId, limit);
1092
+ return {
1093
+ success: true,
1094
+ count: records.length,
1095
+ records: records.map(r => ({
1096
+ decisionId: r.decisionId,
1097
+ swarmId: r.swarmId,
1098
+ protocol: r.protocol,
1099
+ topic: r.topic,
1100
+ decision: r.decision,
1101
+ voteCount: r.votes.length,
1102
+ quorumAchieved: r.quorumAchieved,
1103
+ round: r.round,
1104
+ durationMs: r.durationMs,
1105
+ completedAt: r.completedAt,
1106
+ signed: !!r.recordSignature,
1107
+ })),
1108
+ };
1109
+ }
1110
+ catch (e) {
1111
+ return { success: false, error: `Audit trail unavailable: ${e.message}` };
1112
+ }
1113
+ },
1114
+ },
1115
+ {
1116
+ name: 'monoswarm_audit_verify',
1117
+ description: 'Verify tamper-evidence of a vote decision (checks HMAC signatures on all votes and the record itself) — a local file check, not a distributed ledger.',
1118
+ category: 'monoswarm',
1119
+ inputSchema: {
1120
+ type: 'object',
1121
+ properties: {
1122
+ decisionId: { type: 'string', description: 'Decision/proposal ID to verify' },
1123
+ },
1124
+ required: ['decisionId'],
1125
+ },
1126
+ handler: async (input) => {
1127
+ const hk = getOrCreateAuditKey();
1128
+ const decisionId = input.decisionId;
1129
+ if (typeof decisionId !== 'string' || decisionId.length === 0 || decisionId.length > 256) {
1130
+ return { success: false, error: 'Invalid decisionId' };
1131
+ }
1132
+ try {
1133
+ const { AuditWriter } = await import('../consensus/audit-writer.js');
1134
+ const auditDir = join(getProjectCwd(), '.monomind', 'consensus');
1135
+ const writer = new AuditWriter(auditDir);
1136
+ const result = writer.verifyDecision(decisionId, hk);
1137
+ return {
1138
+ success: true,
1139
+ decisionId,
1140
+ valid: result.valid,
1141
+ invalidVotes: result.invalidVotes,
1142
+ message: result.valid
1143
+ ? 'All vote signatures and record signature verified — no tampering detected.'
1144
+ : `Verification failed: ${result.invalidVotes.length} invalid vote(s) or record signature mismatch.`,
1145
+ };
1146
+ }
1147
+ catch (e) {
1148
+ return { success: false, error: `Audit verification failed: ${e.message}` };
1149
+ }
1150
+ },
1151
+ },
1152
+ ];
1153
+ //# sourceMappingURL=monoswarm-tools.js.map