monomind 1.14.7 → 1.15.1

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 (314) hide show
  1. package/.claude/agents/reengineer-squad/boss.md +113 -0
  2. package/.claude/agents/reengineer-squad/critic-architect.md +132 -0
  3. package/.claude/agents/reengineer-squad/git-manager.md +145 -0
  4. package/.claude/agents/reengineer-squad/idea-generator.md +95 -0
  5. package/.claude/agents/reengineer-squad/implementer.md +112 -0
  6. package/.claude/agents/reengineer-squad/integration-planner.md +112 -0
  7. package/.claude/agents/reengineer-squad/source-analyst.md +103 -0
  8. package/.claude/agents/reengineer-squad/target-analyst.md +118 -0
  9. package/.claude/agents/reengineer-squad/tester.md +105 -0
  10. package/.claude/commands/mastermind/master.md +35 -14
  11. package/.claude/helpers/handlers/capture-handler.cjs +155 -18
  12. package/.claude/helpers/monolean-activate.cjs +20 -0
  13. package/.claude/helpers/monolean-config.cjs +76 -0
  14. package/.claude/helpers/monolean-instructions.cjs +109 -0
  15. package/.claude/helpers/monolean-propagate.cjs +9 -0
  16. package/.claude/helpers/monolean-tracker.cjs +18 -0
  17. package/.claude/helpers/skill-registry.json +2 -2
  18. package/.claude/settings.json +34 -2
  19. package/.claude/skills/agent-browser-testing/SKILL.md +301 -18
  20. package/.claude/skills/mastermind/runorg.md +69 -23
  21. package/.claude/skills/monodesign/SKILL.md +32 -1
  22. package/.claude/skills/monodesign/adapt.md +53 -0
  23. package/.claude/skills/monodesign/agents/monodesign-asset-producer.md +100 -0
  24. package/.claude/skills/monodesign/animate.md +65 -0
  25. package/.claude/skills/monodesign/audit.md +89 -0
  26. package/.claude/skills/monodesign/bolder.md +50 -0
  27. package/.claude/skills/monodesign/clarify.md +64 -0
  28. package/.claude/skills/monodesign/colorize.md +68 -0
  29. package/.claude/skills/monodesign/craft.md +51 -0
  30. package/.claude/skills/monodesign/critique.md +66 -0
  31. package/.claude/skills/monodesign/delight.md +47 -0
  32. package/.claude/skills/monodesign/distill.md +56 -0
  33. package/.claude/skills/monodesign/document.md +80 -0
  34. package/.claude/skills/monodesign/extract.md +74 -0
  35. package/.claude/skills/monodesign/harden.md +65 -0
  36. package/.claude/skills/monodesign/live.md +59 -0
  37. package/.claude/skills/monodesign/onboard.md +50 -0
  38. package/.claude/skills/monodesign/optimize.md +64 -0
  39. package/.claude/skills/monodesign/overdrive.md +56 -0
  40. package/.claude/skills/monodesign/polish.md +68 -0
  41. package/.claude/skills/monodesign/quieter.md +57 -0
  42. package/.claude/skills/monodesign/reference/antipatterns-catalog.md +248 -76
  43. package/.claude/skills/monodesign/reference/codex.md +107 -0
  44. package/.claude/skills/monodesign/reference/craft.md +3 -0
  45. package/.claude/skills/monodesign/reference/hooks.md +99 -0
  46. package/.claude/skills/monodesign/reference/image-prompts.md +12 -0
  47. package/.claude/skills/monodesign/shape.md +71 -0
  48. package/.claude/skills/monodesign/teach.md +69 -0
  49. package/.claude/skills/monodesign/typeset.md +59 -0
  50. package/.claude/skills/monolean/SKILL.md +118 -0
  51. package/.claude/skills/monolean-audit/SKILL.md +41 -0
  52. package/.claude/skills/monolean-debt/SKILL.md +46 -0
  53. package/.claude/skills/monolean-help/SKILL.md +60 -0
  54. package/.claude/skills/monolean-review/SKILL.md +57 -0
  55. package/package.json +8 -3
  56. package/packages/@monomind/cli/bin/cli.js +3 -1
  57. package/packages/@monomind/cli/dist/dashboard/server.js +137 -0
  58. package/packages/@monomind/cli/dist/src/__tests__/browse-adapters.test.d.ts +2 -0
  59. package/packages/@monomind/cli/dist/src/__tests__/browse-adapters.test.js +51 -0
  60. package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.d.ts +2 -0
  61. package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +68 -0
  62. package/packages/@monomind/cli/dist/src/__tests__/browse-builtin-handlers.test.d.ts +2 -0
  63. package/packages/@monomind/cli/dist/src/__tests__/browse-builtin-handlers.test.js +139 -0
  64. package/packages/@monomind/cli/dist/src/__tests__/browse-cdp.test.d.ts +2 -0
  65. package/packages/@monomind/cli/dist/src/__tests__/browse-cdp.test.js +169 -0
  66. package/packages/@monomind/cli/dist/src/__tests__/browse-dashboard.test.d.ts +2 -0
  67. package/packages/@monomind/cli/dist/src/__tests__/browse-dashboard.test.js +179 -0
  68. package/packages/@monomind/cli/dist/src/__tests__/browse-engine.test.d.ts +2 -0
  69. package/packages/@monomind/cli/dist/src/__tests__/browse-engine.test.js +122 -0
  70. package/packages/@monomind/cli/dist/src/__tests__/browse-expression.test.d.ts +2 -0
  71. package/packages/@monomind/cli/dist/src/__tests__/browse-expression.test.js +54 -0
  72. package/packages/@monomind/cli/dist/src/__tests__/browse-store.test.d.ts +2 -0
  73. package/packages/@monomind/cli/dist/src/__tests__/browse-store.test.js +99 -0
  74. package/packages/@monomind/cli/dist/src/__tests__/browse-workflow-types.test.d.ts +2 -0
  75. package/packages/@monomind/cli/dist/src/__tests__/browse-workflow-types.test.js +33 -0
  76. package/packages/@monomind/cli/dist/src/browser/action-builder/analyzer.d.ts +11 -0
  77. package/packages/@monomind/cli/dist/src/browser/action-builder/analyzer.js +71 -0
  78. package/packages/@monomind/cli/dist/src/browser/action-builder/types.d.ts +47 -0
  79. package/packages/@monomind/cli/dist/src/browser/action-builder/types.js +2 -0
  80. package/packages/@monomind/cli/dist/src/browser/adapters/gemini.d.ts +3 -0
  81. package/packages/@monomind/cli/dist/src/browser/adapters/gemini.js +16 -0
  82. package/packages/@monomind/cli/dist/src/browser/adapters/google.d.ts +3 -0
  83. package/packages/@monomind/cli/dist/src/browser/adapters/google.js +17 -0
  84. package/packages/@monomind/cli/dist/src/browser/adapters/index.d.ts +19 -0
  85. package/packages/@monomind/cli/dist/src/browser/adapters/index.js +23 -0
  86. package/packages/@monomind/cli/dist/src/browser/adapters/instagram.d.ts +3 -0
  87. package/packages/@monomind/cli/dist/src/browser/adapters/instagram.js +17 -0
  88. package/packages/@monomind/cli/dist/src/browser/adapters/linkedin.d.ts +3 -0
  89. package/packages/@monomind/cli/dist/src/browser/adapters/linkedin.js +19 -0
  90. package/packages/@monomind/cli/dist/src/browser/adapters/microsoft.d.ts +3 -0
  91. package/packages/@monomind/cli/dist/src/browser/adapters/microsoft.js +16 -0
  92. package/packages/@monomind/cli/dist/src/browser/adapters/x.d.ts +3 -0
  93. package/packages/@monomind/cli/dist/src/browser/adapters/x.js +19 -0
  94. package/packages/@monomind/cli/dist/src/browser/dashboard/api-types.d.ts +50 -0
  95. package/packages/@monomind/cli/dist/src/browser/dashboard/api-types.js +14 -0
  96. package/packages/@monomind/cli/dist/src/browser/dashboard/server.d.ts +9 -0
  97. package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +62 -0
  98. package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +1811 -0
  99. package/packages/@monomind/cli/dist/src/browser/workflow/builtin-handlers.d.ts +3 -0
  100. package/packages/@monomind/cli/dist/src/browser/workflow/builtin-handlers.js +343 -0
  101. package/packages/@monomind/cli/dist/src/browser/workflow/engine.d.ts +15 -0
  102. package/packages/@monomind/cli/dist/src/browser/workflow/engine.js +127 -0
  103. package/packages/@monomind/cli/dist/src/browser/workflow/expression.d.ts +4 -0
  104. package/packages/@monomind/cli/dist/src/browser/workflow/expression.js +64 -0
  105. package/packages/@monomind/cli/dist/src/browser/workflow/store.d.ts +24 -0
  106. package/packages/@monomind/cli/dist/src/browser/workflow/store.js +145 -0
  107. package/packages/@monomind/cli/dist/src/browser/workflow/types.d.ts +48 -0
  108. package/packages/@monomind/cli/dist/src/browser/workflow/types.js +2 -0
  109. package/packages/@monomind/cli/dist/src/commands/browse-action.d.ts +4 -0
  110. package/packages/@monomind/cli/dist/src/commands/browse-action.js +151 -0
  111. package/packages/@monomind/cli/dist/src/commands/browse-platform.d.ts +4 -0
  112. package/packages/@monomind/cli/dist/src/commands/browse-platform.js +117 -0
  113. package/packages/@monomind/cli/dist/src/commands/browse-workflow.d.ts +4 -0
  114. package/packages/@monomind/cli/dist/src/commands/browse-workflow.js +153 -0
  115. package/packages/@monomind/cli/dist/src/commands/browse.d.ts +10 -6
  116. package/packages/@monomind/cli/dist/src/commands/browse.js +11 -2154
  117. package/packages/@monomind/cli/dist/src/commands/design-detect.d.ts +21 -0
  118. package/packages/@monomind/cli/dist/src/commands/design-detect.js +127 -0
  119. package/packages/@monomind/cli/dist/src/commands/design-palette.d.ts +22 -0
  120. package/packages/@monomind/cli/dist/src/commands/design-palette.js +539 -0
  121. package/packages/@monomind/cli/dist/src/commands/hooks-core-commands.d.ts +10 -0
  122. package/packages/@monomind/cli/dist/src/commands/hooks-core-commands.js +377 -0
  123. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +12 -0
  124. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1217 -0
  125. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-utils.d.ts +42 -0
  126. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-utils.js +220 -0
  127. package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.d.ts +14 -0
  128. package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.js +579 -0
  129. package/packages/@monomind/cli/dist/src/commands/hooks-formatting.d.ts +13 -0
  130. package/packages/@monomind/cli/dist/src/commands/hooks-formatting.js +42 -0
  131. package/packages/@monomind/cli/dist/src/commands/hooks-routing-commands.d.ts +15 -0
  132. package/packages/@monomind/cli/dist/src/commands/hooks-routing-commands.js +723 -0
  133. package/packages/@monomind/cli/dist/src/commands/hooks-workers.d.ts +9 -0
  134. package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +782 -0
  135. package/packages/@monomind/cli/dist/src/commands/hooks.d.ts +8 -0
  136. package/packages/@monomind/cli/dist/src/commands/hooks.js +179 -4103
  137. package/packages/@monomind/cli/dist/src/commands/index.d.ts +1 -0
  138. package/packages/@monomind/cli/dist/src/commands/index.js +6 -0
  139. package/packages/@monomind/cli/dist/src/commands/org.js +14 -15
  140. package/packages/@monomind/cli/dist/src/commands/tokens.js +77 -1
  141. package/packages/@monomind/cli/dist/src/graph/enrich.mjs +362 -0
  142. package/packages/@monomind/cli/dist/src/init/executor.js +18 -8
  143. package/packages/@monomind/cli/dist/src/init/settings-generator.js +39 -5
  144. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +25 -5
  145. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.d.ts +3 -5
  146. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +619 -326
  147. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-embedding.d.ts +161 -0
  148. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-embedding.js +506 -0
  149. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.d.ts +26 -0
  150. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +1328 -0
  151. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.d.ts +27 -0
  152. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +1591 -0
  153. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.d.ts +3 -38
  154. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +5 -3393
  155. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +24 -14
  156. package/packages/@monomind/cli/dist/src/mcp-tools/workflow-tools.js +54 -1
  157. package/packages/@monomind/cli/dist/src/memory/embedding-operations.d.ts +58 -0
  158. package/packages/@monomind/cli/dist/src/memory/embedding-operations.js +299 -0
  159. package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.js +37 -3
  160. package/packages/@monomind/cli/dist/src/memory/hnsw-operations.d.ts +130 -0
  161. package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +400 -0
  162. package/packages/@monomind/cli/dist/src/memory/intelligence.js +42 -23
  163. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +52 -8
  164. package/packages/@monomind/cli/dist/src/memory/memory-crud.d.ts +67 -0
  165. package/packages/@monomind/cli/dist/src/memory/memory-crud.js +415 -0
  166. package/packages/@monomind/cli/dist/src/memory/memory-initializer.d.ts +9 -322
  167. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +17 -1794
  168. package/packages/@monomind/cli/dist/src/memory/memory-migrations.d.ts +30 -0
  169. package/packages/@monomind/cli/dist/src/memory/memory-migrations.js +134 -0
  170. package/packages/@monomind/cli/dist/src/memory/memory-read.d.ts +78 -0
  171. package/packages/@monomind/cli/dist/src/memory/memory-read.js +331 -0
  172. package/packages/@monomind/cli/dist/src/memory/memory-schema.d.ts +13 -0
  173. package/packages/@monomind/cli/dist/src/memory/memory-schema.js +167 -0
  174. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.js +37 -4
  175. package/packages/@monomind/cli/dist/src/monovector/route-outcomes.js +16 -6
  176. package/packages/@monomind/cli/dist/src/pricing/model-pricing.d.ts +41 -0
  177. package/packages/@monomind/cli/dist/src/pricing/model-pricing.js +61 -0
  178. package/packages/@monomind/cli/dist/src/ui/.monomind/capture/active-run.json +1 -0
  179. package/packages/@monomind/cli/dist/src/ui/collector.mjs +799 -0
  180. package/packages/@monomind/cli/dist/src/ui/dashboard.html +13986 -0
  181. package/packages/@monomind/cli/dist/src/ui/data/agent-avatars.html +763 -0
  182. package/packages/@monomind/cli/dist/src/ui/data/agent-avatars.json +966 -0
  183. package/packages/@monomind/cli/dist/src/ui/data/avatars/account-strategist.svg +58 -0
  184. package/packages/@monomind/cli/dist/src/ui/data/avatars/accounts-payable.svg +54 -0
  185. package/packages/@monomind/cli/dist/src/ui/data/avatars/adaptive-coordinator.svg +55 -0
  186. package/packages/@monomind/cli/dist/src/ui/data/avatars/adaptive-coordinator2.svg +54 -0
  187. package/packages/@monomind/cli/dist/src/ui/data/avatars/ai-citation.svg +57 -0
  188. package/packages/@monomind/cli/dist/src/ui/data/avatars/ai-engineer.svg +61 -0
  189. package/packages/@monomind/cli/dist/src/ui/data/avatars/analytics-reporter.svg +53 -0
  190. package/packages/@monomind/cli/dist/src/ui/data/avatars/api-tester.svg +53 -0
  191. package/packages/@monomind/cli/dist/src/ui/data/avatars/architecture.svg +54 -0
  192. package/packages/@monomind/cli/dist/src/ui/data/avatars/automation-governance.svg +55 -0
  193. package/packages/@monomind/cli/dist/src/ui/data/avatars/backend-dev.svg +53 -0
  194. package/packages/@monomind/cli/dist/src/ui/data/avatars/benchmarker.svg +54 -0
  195. package/packages/@monomind/cli/dist/src/ui/data/avatars/blockchain-auditor.svg +53 -0
  196. package/packages/@monomind/cli/dist/src/ui/data/avatars/byzantine-coord.svg +57 -0
  197. package/packages/@monomind/cli/dist/src/ui/data/avatars/case-analyst.svg +57 -0
  198. package/packages/@monomind/cli/dist/src/ui/data/avatars/cicd-engineer.svg +55 -0
  199. package/packages/@monomind/cli/dist/src/ui/data/avatars/cloud-architect.svg +54 -0
  200. package/packages/@monomind/cli/dist/src/ui/data/avatars/code-review-swarm.svg +57 -0
  201. package/packages/@monomind/cli/dist/src/ui/data/avatars/coder-v119.svg +57 -0
  202. package/packages/@monomind/cli/dist/src/ui/data/avatars/coder.svg +58 -0
  203. package/packages/@monomind/cli/dist/src/ui/data/avatars/collective-coord.svg +54 -0
  204. package/packages/@monomind/cli/dist/src/ui/data/avatars/compliance-auditor.svg +58 -0
  205. package/packages/@monomind/cli/dist/src/ui/data/avatars/consensus-coordinator.svg +54 -0
  206. package/packages/@monomind/cli/dist/src/ui/data/avatars/content-creator.svg +54 -0
  207. package/packages/@monomind/cli/dist/src/ui/data/avatars/crdt-synchronizer.svg +53 -0
  208. package/packages/@monomind/cli/dist/src/ui/data/avatars/cro-specialist.svg +58 -0
  209. package/packages/@monomind/cli/dist/src/ui/data/avatars/data-consolidator.svg +54 -0
  210. package/packages/@monomind/cli/dist/src/ui/data/avatars/data-engineer.svg +53 -0
  211. package/packages/@monomind/cli/dist/src/ui/data/avatars/database-optimizer.svg +61 -0
  212. package/packages/@monomind/cli/dist/src/ui/data/avatars/deal-strategist.svg +54 -0
  213. package/packages/@monomind/cli/dist/src/ui/data/avatars/defender.svg +53 -0
  214. package/packages/@monomind/cli/dist/src/ui/data/avatars/devops-automator.svg +56 -0
  215. package/packages/@monomind/cli/dist/src/ui/data/avatars/discovery-coach.svg +54 -0
  216. package/packages/@monomind/cli/dist/src/ui/data/avatars/email-marketing.svg +57 -0
  217. package/packages/@monomind/cli/dist/src/ui/data/avatars/embedded-firmware.svg +61 -0
  218. package/packages/@monomind/cli/dist/src/ui/data/avatars/evidence-collector.svg +57 -0
  219. package/packages/@monomind/cli/dist/src/ui/data/avatars/experiment-tracker.svg +53 -0
  220. package/packages/@monomind/cli/dist/src/ui/data/avatars/feedback-synthesizer.svg +54 -0
  221. package/packages/@monomind/cli/dist/src/ui/data/avatars/finance-tracker.svg +54 -0
  222. package/packages/@monomind/cli/dist/src/ui/data/avatars/frontend-developer.svg +54 -0
  223. package/packages/@monomind/cli/dist/src/ui/data/avatars/game-audio-engineer.svg +59 -0
  224. package/packages/@monomind/cli/dist/src/ui/data/avatars/game-designer.svg +54 -0
  225. package/packages/@monomind/cli/dist/src/ui/data/avatars/gossip-coordinator.svg +54 -0
  226. package/packages/@monomind/cli/dist/src/ui/data/avatars/hierarchical-coord.svg +54 -0
  227. package/packages/@monomind/cli/dist/src/ui/data/avatars/incident-commander.svg +57 -0
  228. package/packages/@monomind/cli/dist/src/ui/data/avatars/infrastructure.svg +54 -0
  229. package/packages/@monomind/cli/dist/src/ui/data/avatars/input-validator.svg +53 -0
  230. package/packages/@monomind/cli/dist/src/ui/data/avatars/ios-developer.svg +54 -0
  231. package/packages/@monomind/cli/dist/src/ui/data/avatars/issue-tracker.svg +53 -0
  232. package/packages/@monomind/cli/dist/src/ui/data/avatars/judge.svg +55 -0
  233. package/packages/@monomind/cli/dist/src/ui/data/avatars/launch-strategist.svg +54 -0
  234. package/packages/@monomind/cli/dist/src/ui/data/avatars/legal-compliance.svg +53 -0
  235. package/packages/@monomind/cli/dist/src/ui/data/avatars/level-designer.svg +53 -0
  236. package/packages/@monomind/cli/dist/src/ui/data/avatars/load-balancer.svg +57 -0
  237. package/packages/@monomind/cli/dist/src/ui/data/avatars/mcp-builder.svg +53 -0
  238. package/packages/@monomind/cli/dist/src/ui/data/avatars/memory-coordinator.svg +55 -0
  239. package/packages/@monomind/cli/dist/src/ui/data/avatars/mesh-coordinator.svg +55 -0
  240. package/packages/@monomind/cli/dist/src/ui/data/avatars/ml-developer.svg +58 -0
  241. package/packages/@monomind/cli/dist/src/ui/data/avatars/mobile-app-builder.svg +53 -0
  242. package/packages/@monomind/cli/dist/src/ui/data/avatars/mobile-dev.svg +54 -0
  243. package/packages/@monomind/cli/dist/src/ui/data/avatars/model-qa.svg +58 -0
  244. package/packages/@monomind/cli/dist/src/ui/data/avatars/narrative-designer.svg +58 -0
  245. package/packages/@monomind/cli/dist/src/ui/data/avatars/outbound-strategist.svg +55 -0
  246. package/packages/@monomind/cli/dist/src/ui/data/avatars/path-validator.svg +54 -0
  247. package/packages/@monomind/cli/dist/src/ui/data/avatars/payment-agent.svg +53 -0
  248. package/packages/@monomind/cli/dist/src/ui/data/avatars/perf-analyzer.svg +58 -0
  249. package/packages/@monomind/cli/dist/src/ui/data/avatars/pipeline-analyst.svg +54 -0
  250. package/packages/@monomind/cli/dist/src/ui/data/avatars/planner.svg +55 -0
  251. package/packages/@monomind/cli/dist/src/ui/data/avatars/pr-manager.svg +54 -0
  252. package/packages/@monomind/cli/dist/src/ui/data/avatars/pricing-strategist.svg +54 -0
  253. package/packages/@monomind/cli/dist/src/ui/data/avatars/product-manager.svg +54 -0
  254. package/packages/@monomind/cli/dist/src/ui/data/avatars/production-validator.svg +54 -0
  255. package/packages/@monomind/cli/dist/src/ui/data/avatars/project-shepherd.svg +54 -0
  256. package/packages/@monomind/cli/dist/src/ui/data/avatars/proposal-strategist.svg +54 -0
  257. package/packages/@monomind/cli/dist/src/ui/data/avatars/prosecutor.svg +57 -0
  258. package/packages/@monomind/cli/dist/src/ui/data/avatars/pseudocode.svg +53 -0
  259. package/packages/@monomind/cli/dist/src/ui/data/avatars/queen-coordinator.svg +55 -0
  260. package/packages/@monomind/cli/dist/src/ui/data/avatars/quorum-manager.svg +53 -0
  261. package/packages/@monomind/cli/dist/src/ui/data/avatars/raft-manager.svg +53 -0
  262. package/packages/@monomind/cli/dist/src/ui/data/avatars/reality-checker.svg +58 -0
  263. package/packages/@monomind/cli/dist/src/ui/data/avatars/recruitment.svg +58 -0
  264. package/packages/@monomind/cli/dist/src/ui/data/avatars/refinement.svg +53 -0
  265. package/packages/@monomind/cli/dist/src/ui/data/avatars/release-manager.svg +54 -0
  266. package/packages/@monomind/cli/dist/src/ui/data/avatars/repo-architect.svg +54 -0
  267. package/packages/@monomind/cli/dist/src/ui/data/avatars/researcher.svg +58 -0
  268. package/packages/@monomind/cli/dist/src/ui/data/avatars/resource-allocator.svg +53 -0
  269. package/packages/@monomind/cli/dist/src/ui/data/avatars/reviewer.svg +53 -0
  270. package/packages/@monomind/cli/dist/src/ui/data/avatars/safe-executor.svg +53 -0
  271. package/packages/@monomind/cli/dist/src/ui/data/avatars/sales-coach.svg +53 -0
  272. package/packages/@monomind/cli/dist/src/ui/data/avatars/sales-engineer.svg +58 -0
  273. package/packages/@monomind/cli/dist/src/ui/data/avatars/scout-explorer.svg +58 -0
  274. package/packages/@monomind/cli/dist/src/ui/data/avatars/security-architect.svg +54 -0
  275. package/packages/@monomind/cli/dist/src/ui/data/avatars/security-auditor.svg +55 -0
  276. package/packages/@monomind/cli/dist/src/ui/data/avatars/senior-developer.svg +58 -0
  277. package/packages/@monomind/cli/dist/src/ui/data/avatars/senior-pm.svg +58 -0
  278. package/packages/@monomind/cli/dist/src/ui/data/avatars/seo-specialist.svg +57 -0
  279. package/packages/@monomind/cli/dist/src/ui/data/avatars/social-media.svg +54 -0
  280. package/packages/@monomind/cli/dist/src/ui/data/avatars/solidity-engineer.svg +58 -0
  281. package/packages/@monomind/cli/dist/src/ui/data/avatars/sparc-coder.svg +58 -0
  282. package/packages/@monomind/cli/dist/src/ui/data/avatars/sparc-coord.svg +56 -0
  283. package/packages/@monomind/cli/dist/src/ui/data/avatars/specification.svg +57 -0
  284. package/packages/@monomind/cli/dist/src/ui/data/avatars/sprint-prioritizer.svg +53 -0
  285. package/packages/@monomind/cli/dist/src/ui/data/avatars/sre.svg +54 -0
  286. package/packages/@monomind/cli/dist/src/ui/data/avatars/studio-operations.svg +53 -0
  287. package/packages/@monomind/cli/dist/src/ui/data/avatars/studio-producer.svg +55 -0
  288. package/packages/@monomind/cli/dist/src/ui/data/avatars/support-responder.svg +56 -0
  289. package/packages/@monomind/cli/dist/src/ui/data/avatars/system-architect.svg +54 -0
  290. package/packages/@monomind/cli/dist/src/ui/data/avatars/task-orchestrator.svg +56 -0
  291. package/packages/@monomind/cli/dist/src/ui/data/avatars/technical-artist.svg +53 -0
  292. package/packages/@monomind/cli/dist/src/ui/data/avatars/technical-writer.svg +59 -0
  293. package/packages/@monomind/cli/dist/src/ui/data/avatars/tester.svg +53 -0
  294. package/packages/@monomind/cli/dist/src/ui/data/avatars/threat-detection.svg +61 -0
  295. package/packages/@monomind/cli/dist/src/ui/data/avatars/trend-researcher.svg +54 -0
  296. package/packages/@monomind/cli/dist/src/ui/data/avatars/trial-director.svg +55 -0
  297. package/packages/@monomind/cli/dist/src/ui/data/avatars/unity-architect.svg +54 -0
  298. package/packages/@monomind/cli/dist/src/ui/data/avatars/visionos-engineer.svg +57 -0
  299. package/packages/@monomind/cli/dist/src/ui/data/avatars/worker-specialist.svg +55 -0
  300. package/packages/@monomind/cli/dist/src/ui/data/avatars/workflow-architect.svg +57 -0
  301. package/packages/@monomind/cli/dist/src/ui/data/avatars/workflow-automation.svg +54 -0
  302. package/packages/@monomind/cli/dist/src/ui/data/avatars/zk-steward.svg +54 -0
  303. package/packages/@monomind/cli/dist/src/ui/data/known-projects.json +1 -0
  304. package/packages/@monomind/cli/dist/src/ui/data/mastermind-sessions.json +1 -0
  305. package/packages/@monomind/cli/dist/src/ui/data/sessions/_index.json +1 -0
  306. package/packages/@monomind/cli/dist/src/ui/orgs.html +2215 -0
  307. package/packages/@monomind/cli/dist/src/ui/server.mjs +6206 -0
  308. package/packages/@monomind/cli/dist/src/ui/sse-manager.mjs +119 -0
  309. package/packages/@monomind/cli/dist/src/update/checker.js +1 -1
  310. package/packages/@monomind/cli/dist/workflow/builtin-handlers.js +321 -0
  311. package/packages/@monomind/cli/dist/workflow/engine.js +253 -0
  312. package/packages/@monomind/cli/dist/workflow/expression.js +98 -0
  313. package/packages/@monomind/cli/dist/workflow/types.js +2 -0
  314. package/packages/@monomind/cli/package.json +8 -6
@@ -0,0 +1,799 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+
9
+ function readJSON(filePath) {
10
+ try {
11
+ const raw = fs.readFileSync(filePath, 'utf8');
12
+ return JSON.parse(raw);
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+
18
+ function readJSONL(filePath, last) {
19
+ try {
20
+ const raw = fs.readFileSync(filePath, 'utf8');
21
+ const lines = raw.split('\n').filter(Boolean);
22
+ const slice = last != null ? lines.slice(-last) : lines;
23
+ return slice.map(line => {
24
+ try {
25
+ return JSON.parse(line);
26
+ } catch {
27
+ return null;
28
+ }
29
+ }).filter(Boolean);
30
+ } catch {
31
+ return [];
32
+ }
33
+ }
34
+
35
+ function countJSONLLines(filePath) {
36
+ try {
37
+ const raw = fs.readFileSync(filePath, 'utf8');
38
+ return raw.split('\n').filter(Boolean).length;
39
+ } catch {
40
+ return 0;
41
+ }
42
+ }
43
+
44
+ function fileExists(filePath) {
45
+ try {
46
+ fs.accessSync(filePath);
47
+ return true;
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ function fileStat(filePath) {
54
+ try {
55
+ return fs.statSync(filePath);
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+
61
+ function listDir(dirPath) {
62
+ try {
63
+ return fs.readdirSync(dirPath);
64
+ } catch {
65
+ return [];
66
+ }
67
+ }
68
+
69
+ // ---------------------------------------------------------------------------
70
+ // Section collectors
71
+ // ---------------------------------------------------------------------------
72
+
73
+ function collectProject(projectDir) {
74
+ let name = path.basename(projectDir);
75
+ const pkgPath = path.join(projectDir, 'package.json');
76
+ const pkg = readJSON(pkgPath);
77
+ if (pkg && pkg.name) {
78
+ name = pkg.name;
79
+ }
80
+ return { dir: projectDir, name };
81
+ }
82
+
83
+ function getClaudeProjectSessionsDir(projectDir) {
84
+ // Claude Code stores sessions in ~/.claude/projects/<slug>/ not in the project itself
85
+ const homeDir = os.homedir();
86
+ const slug = projectDir.replace(/\//g, '-');
87
+ const globalSessions = path.join(homeDir, '.claude', 'projects', slug);
88
+ if (fs.existsSync(globalSessions)) return globalSessions;
89
+ // Fallback to local .claude/sessions
90
+ return path.join(projectDir, '.claude', 'sessions');
91
+ }
92
+
93
+ function collectSessions(projectDir) {
94
+ const sessionsDir = getClaudeProjectSessionsDir(projectDir);
95
+ const entries = listDir(sessionsDir);
96
+ const list = entries
97
+ .filter(f => f.endsWith('.json') || f.endsWith('.jsonl'))
98
+ .map(f => {
99
+ const filePath = path.join(sessionsDir, f);
100
+ const stat = fileStat(filePath);
101
+ const id = path.basename(f, path.extname(f));
102
+ return {
103
+ id,
104
+ file: filePath,
105
+ mtime: stat ? stat.mtimeMs : null,
106
+ size: stat ? stat.size : null
107
+ };
108
+ })
109
+ .sort((a, b) => (b.mtime || 0) - (a.mtime || 0));
110
+
111
+ const memFiles = collectMemoryFiles(projectDir);
112
+
113
+ return {
114
+ list,
115
+ count: list.length,
116
+ palace: {
117
+ count: memFiles.length
118
+ }
119
+ };
120
+ }
121
+
122
+ const _appendedSwarmIds = new Set();
123
+
124
+ function collectSwarm(projectDir) {
125
+ const base = path.join(projectDir, '.monomind');
126
+ const state = readJSON(path.join(base, 'swarm', 'swarm-state.json')) || {};
127
+ const dotSwarmState = readJSON(path.join(projectDir, '.swarm', 'state.json')) || {};
128
+ const merged = { ...dotSwarmState, ...state };
129
+
130
+ const terminalStatuses = ['stopped', 'terminated', 'completed', 'error'];
131
+ const swarmId = merged.swarmId || merged.id;
132
+ if (swarmId && terminalStatuses.includes(merged.status) && !_appendedSwarmIds.has(swarmId)) {
133
+ _appendedSwarmIds.add(swarmId);
134
+ const agents = (merged.agents || merged.agentPlan || []).map(a => ({
135
+ id: a.id || a.type || a.role,
136
+ type: a.type || a.role || '?',
137
+ role: a.role || 'worker',
138
+ tasksCompleted: a.tasksCompleted || a.count || 0,
139
+ tasksFailed: a.tasksFailed || 0,
140
+ messageCount: a.messageCount || 0,
141
+ utilization: a.utilization || 0,
142
+ }));
143
+ const entry = {
144
+ swarmId,
145
+ topology: merged.topology || '—',
146
+ consensus: merged.consensus || '—',
147
+ strategy: merged.strategy || '—',
148
+ status: merged.status,
149
+ agents,
150
+ messages: merged.messages || [],
151
+ errors: merged.errors || [],
152
+ findings: merged.findings || [],
153
+ taskCount: merged.taskCount || 0,
154
+ completedTasks: merged.completedTasks || 0,
155
+ failedTasks: merged.failedTasks || 0,
156
+ startedAt: merged.startedAt || merged.createdAt || new Date().toISOString(),
157
+ endedAt: merged.stoppedAt || merged.endedAt || new Date().toISOString(),
158
+ durationMs: 0,
159
+ };
160
+ if (entry.startedAt && entry.endedAt) {
161
+ entry.durationMs = new Date(entry.endedAt).getTime() - new Date(entry.startedAt).getTime();
162
+ }
163
+ try { appendSwarmHistory(projectDir, entry); } catch {}
164
+ }
165
+
166
+ return {
167
+ state: merged,
168
+ activity: readJSON(path.join(base, 'metrics', 'swarm-activity.json')) || {},
169
+ suggestion: {},
170
+ config: readJSON(path.join(base, 'swarm-config.json')) || {},
171
+ };
172
+ }
173
+
174
+ function collectSwarmHistory(projectDir) {
175
+ const historyPath = path.join(projectDir, '.monomind', 'swarm', 'history.jsonl');
176
+ const byId = new Map();
177
+
178
+ // 1. Persisted history (if any swarm ever appended on terminal status)
179
+ for (const e of readJSONL(historyPath)) {
180
+ const id = e && (e.swarmId || e.id);
181
+ if (id) byId.set(id, e);
182
+ }
183
+
184
+ // 2. Derive from the live swarm-state.json. The writer stores a NESTED
185
+ // { swarms: { <id>: {...} } } map, but collectSwarm() only appends to
186
+ // history.jsonl when a FLAT top-level swarmId/status is present — which
187
+ // this format never has. So without this fallback the tab is empty even
188
+ // though swarms exist. Derive entries directly from the map here.
189
+ try {
190
+ const state = readJSON(path.join(projectDir, '.monomind', 'swarm', 'swarm-state.json')) || {};
191
+ const swarmsMap = state.swarms || (state.swarmId ? { [state.swarmId]: state } : {});
192
+ for (const [key, s] of Object.entries(swarmsMap)) {
193
+ if (!s || typeof s !== 'object') continue;
194
+ const sid = s.swarmId || s.id || key;
195
+ if (byId.has(sid)) continue; // a real history entry wins over derived
196
+ const cfg = s.config || {};
197
+ const agents = Array.isArray(s.agents) ? s.agents : [];
198
+ byId.set(sid, {
199
+ swarmId: sid,
200
+ topology: s.topology || cfg.topology || '—',
201
+ consensus: s.consensus || cfg.consensusMechanism || '—',
202
+ strategy: s.strategy || cfg.strategy || '—',
203
+ status: s.status || 'unknown',
204
+ agentCount: agents.length || s.maxAgents || cfg.maxAgents || 0,
205
+ agents,
206
+ taskCount: Array.isArray(s.tasks) ? s.tasks.length : (s.taskCount || 0),
207
+ startedAt: s.createdAt || s.startedAt || null,
208
+ endedAt: s.updatedAt || s.endedAt || null,
209
+ derived: true,
210
+ });
211
+ }
212
+ } catch {}
213
+
214
+ // newest-first
215
+ return Array.from(byId.values()).sort((a, b) =>
216
+ new Date(b.startedAt || 0).getTime() - new Date(a.startedAt || 0).getTime());
217
+ }
218
+
219
+ function appendSwarmHistory(projectDir, entry) {
220
+ const dir = path.join(projectDir, '.monomind', 'swarm');
221
+ if (!fs.existsSync(dir)) {
222
+ fs.mkdirSync(dir, { recursive: true });
223
+ }
224
+ const historyPath = path.join(dir, 'history.jsonl');
225
+ fs.appendFileSync(historyPath, JSON.stringify(entry) + '\n');
226
+ }
227
+
228
+ function collectSwarmEvents(projectDir, opts = {}) {
229
+ const eventsPath = path.join(projectDir, '.monomind', 'swarm', 'events.jsonl');
230
+ const events = readJSONL(eventsPath, opts.last || null);
231
+ if (opts.swarmId) return events.filter(e => e.swarmId === opts.swarmId);
232
+ if (opts.agentId) return events.filter(e => e.agentId === opts.agentId);
233
+ return events;
234
+ }
235
+
236
+ function getSwarmDataSize(projectDir) {
237
+ const dir = path.join(projectDir, '.monomind', 'swarm');
238
+ let totalBytes = 0;
239
+ let fileCount = 0;
240
+ const files = ['history.jsonl', 'events.jsonl'];
241
+ for (const f of files) {
242
+ const stat = fileStat(path.join(dir, f));
243
+ if (stat) { totalBytes += stat.size; fileCount++; }
244
+ }
245
+ return { totalBytes, fileCount, humanSize: totalBytes < 1024 ? totalBytes + ' B' : totalBytes < 1048576 ? (totalBytes / 1024).toFixed(1) + ' KB' : (totalBytes / 1048576).toFixed(1) + ' MB' };
246
+ }
247
+
248
+ function cleanSwarmData(projectDir) {
249
+ const dir = path.join(projectDir, '.monomind', 'swarm');
250
+ const files = ['history.jsonl', 'events.jsonl'];
251
+ let removed = 0;
252
+ for (const f of files) {
253
+ const fp = path.join(dir, f);
254
+ try { fs.unlinkSync(fp); removed++; } catch {}
255
+ }
256
+ _appendedSwarmIds.clear();
257
+ return { removed, files };
258
+ }
259
+
260
+ function collectAgents(projectDir) {
261
+ const base = path.join(projectDir, '.monomind');
262
+ const regsDir = path.join(base, 'agents', 'registrations');
263
+ const regFiles = listDir(regsDir).filter(f => f.endsWith('.json'));
264
+ const registrations = regFiles.map(f => {
265
+ return readJSON(path.join(regsDir, f));
266
+ }).filter(Boolean);
267
+
268
+ const registry = readJSON(path.join(base, 'registry.json')) || {};
269
+
270
+ return {
271
+ registrations,
272
+ registry,
273
+ count: registrations.length
274
+ };
275
+ }
276
+
277
+ // Single source-of-truth for all model pricing (canonical list from src/pricing/model-pricing.ts).
278
+ // server.mjs imports _tokPrice and _tokCost from here instead of duplicating this table.
279
+ const _TOK_PRICES = {
280
+ // Opus
281
+ 'claude-opus-4-8': { in: 5e-6, out: 25e-6, cw: 6.25e-6, cr: 0.5e-6 },
282
+ 'claude-opus-4-6': { in: 5e-6, out: 25e-6, cw: 6.25e-6, cr: 0.5e-6 },
283
+ 'claude-opus-4-5': { in: 5e-6, out: 25e-6, cw: 6.25e-6, cr: 0.5e-6 },
284
+ 'claude-opus-4': { in: 15e-6, out: 75e-6, cw: 18.75e-6, cr: 1.5e-6 },
285
+ // Sonnet
286
+ 'claude-sonnet-4-6': { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 },
287
+ 'claude-sonnet-4-5': { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 },
288
+ 'claude-sonnet-4': { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 },
289
+ 'claude-3-7-sonnet': { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 },
290
+ 'claude-3-5-sonnet': { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 },
291
+ // Haiku
292
+ 'claude-haiku-4-5': { in: 1e-6, out: 5e-6, cw: 1.25e-6, cr: 0.1e-6 },
293
+ 'claude-haiku-4': { in: 0.8e-6, out: 4e-6, cw: 1e-6, cr: 0.08e-6 },
294
+ 'claude-3-5-haiku': { in: 0.8e-6, out: 4e-6, cw: 1e-6, cr: 0.08e-6 },
295
+ // OpenAI
296
+ 'gpt-4o': { in: 2.5e-6, out: 10e-6, cw: 2.5e-6, cr: 1.25e-6 },
297
+ 'gpt-4o-mini': { in: 0.15e-6, out: 0.6e-6, cw: 0.15e-6, cr: 0.075e-6 },
298
+ // Google
299
+ 'gemini-2.5-pro': { in: 1.25e-6, out: 10e-6, cw: 1.25e-6, cr: 0.315e-6 },
300
+ };
301
+ function _tokPrice(model) {
302
+ const _ALIAS = { 'haiku': 'claude-haiku-4-5', 'opus': 'claude-opus-4-6', 'sonnet': 'claude-sonnet-4-6' };
303
+ let k = (model || '').replace(/@.*$/, '').replace(/-\d{8}$/, '');
304
+ k = _ALIAS[k] || k;
305
+ if (_TOK_PRICES[k]) return _TOK_PRICES[k];
306
+ for (const p of Object.keys(_TOK_PRICES)) { if (k.startsWith(p) || k.includes(p)) return _TOK_PRICES[p]; }
307
+ return { in: 3e-6, out: 15e-6, cw: 3.75e-6, cr: 0.3e-6 }; // sonnet default
308
+ }
309
+ function _tokCost(model, usage) {
310
+ const p = _tokPrice(model);
311
+ const webSearch = ((usage.server_tool_use || {}).web_search_requests || 0) * 0.01;
312
+ return (usage.input_tokens || 0) * p.in
313
+ + (usage.output_tokens || 0) * p.out
314
+ + (usage.cache_creation_input_tokens || 0) * p.cw
315
+ + (usage.cache_read_input_tokens || 0) * p.cr
316
+ + webSearch;
317
+ }
318
+
319
+ function collectTokens(projectDir, days = 14) {
320
+ const base = path.join(projectDir, '.monomind', 'metrics');
321
+ const summary = readJSON(path.join(base, 'token-summary.json')) || {};
322
+
323
+ // Scan session JSONLs to build daily chart data and per-session rows
324
+ const sessionsDir = getClaudeProjectSessionsDir(projectDir);
325
+ const jsonlFiles = listDir(sessionsDir).filter(f => f.endsWith('.jsonl'));
326
+
327
+ const dailyMap = {}; // date-string → { cost, calls, tokensIn, tokensOut }
328
+ const rows = []; // per-session summary
329
+ let totalTokensIn = 0, totalTokensOut = 0;
330
+
331
+ // Cutoff: look back `days` days
332
+ const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
333
+ // Month cutoff: first day of the current UTC month — needed to compute monthCost accurately
334
+ // even when the month started more than `days` days ago.
335
+ const now = new Date();
336
+ const monthStartMs = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1);
337
+ // Effective scan floor is the earlier of the two cutoffs (broader window covers both needs).
338
+ const scanCutoff = Math.min(cutoff, monthStartMs);
339
+ const scanCutoffDate = new Date(scanCutoff).toISOString().slice(0, 10);
340
+ const monthPrefix = new Date().toISOString().slice(0, 7); // "YYYY-MM"
341
+
342
+ for (const fname of jsonlFiles) {
343
+ const fpath = path.join(sessionsDir, fname);
344
+ let stat;
345
+ try { stat = fs.statSync(fpath); } catch { continue; }
346
+ // Skip very old sessions for performance (mtime heuristic).
347
+ // Use scanCutoff (which may reach back to month start) minus a 7-day buffer.
348
+ if (stat.mtimeMs < scanCutoff - 7 * 24 * 60 * 60 * 1000) continue;
349
+
350
+ let content;
351
+ try { content = fs.readFileSync(fpath, 'utf8'); } catch { continue; }
352
+
353
+ const lines = content.split('\n');
354
+ let sessTokensIn = 0, sessTokensOut = 0, sessCost = 0, sessCalls = 0;
355
+ let sessLastPrompt = '';
356
+
357
+ for (const line of lines) {
358
+ if (!line.trim()) continue;
359
+ let entry;
360
+ try { entry = JSON.parse(line); } catch { continue; }
361
+
362
+ // Capture last user prompt for session label
363
+ if (entry.type === 'user') {
364
+ const txt = Array.isArray(entry.message?.content)
365
+ ? (entry.message.content.find(b => b.type === 'text')?.text || '').slice(0, 60)
366
+ : String(entry.message?.content || '').slice(0, 60);
367
+ if (txt.trim()) sessLastPrompt = txt.trim();
368
+ }
369
+
370
+ if (entry.type === 'assistant' && entry.message?.usage) {
371
+ const usage = entry.message.usage;
372
+ const model = entry.message.model || '';
373
+ const cost = _tokCost(model, usage);
374
+ const tokIn = (usage.input_tokens || 0) + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
375
+ const tokOut = usage.output_tokens || 0;
376
+ const ts = entry.timestamp || '';
377
+ const day = ts.slice(0, 10); // "YYYY-MM-DD"
378
+
379
+ if (day && day >= scanCutoffDate) {
380
+ if (!dailyMap[day]) dailyMap[day] = { cost: 0, calls: 0, tokensIn: 0, tokensOut: 0 };
381
+ dailyMap[day].cost += cost;
382
+ dailyMap[day].calls++;
383
+ dailyMap[day].tokensIn += tokIn;
384
+ dailyMap[day].tokensOut += tokOut;
385
+ }
386
+
387
+ sessTokensIn += tokIn;
388
+ sessTokensOut += tokOut;
389
+ sessCost += cost;
390
+ sessCalls++;
391
+ totalTokensIn += tokIn;
392
+ totalTokensOut += tokOut;
393
+ }
394
+ }
395
+
396
+ if (sessCalls > 0) {
397
+ rows.push({
398
+ id: fname.replace('.jsonl', ''),
399
+ session: sessLastPrompt || fname.replace('.jsonl', '').slice(0, 20),
400
+ calls: sessCalls,
401
+ tokens: sessTokensIn + sessTokensOut,
402
+ cost: sessCost,
403
+ });
404
+ }
405
+ }
406
+
407
+ // Build sorted daily array
408
+ const daily = Object.keys(dailyMap).sort().slice(-days).map(d => ({
409
+ date: d,
410
+ label: d.slice(5), // "MM-DD"
411
+ cost: dailyMap[d].cost,
412
+ calls: dailyMap[d].calls,
413
+ tokensIn: dailyMap[d].tokensIn,
414
+ tokensOut: dailyMap[d].tokensOut,
415
+ }));
416
+
417
+ // Sort rows by cost descending
418
+ rows.sort((a, b) => b.cost - a.cost);
419
+
420
+ const totalTokens = totalTokensIn + totalTokensOut;
421
+ if (totalTokens > 0) summary.totalTokens = totalTokens;
422
+
423
+ // Overwrite stale cached todayCost/todayCalls with fresh JSONL-derived values.
424
+ // daily uses UTC date keys (entry.timestamp.slice(0,10)), so match that here.
425
+ const todayKey = new Date().toISOString().slice(0, 10);
426
+ const todayEntry = dailyMap[todayKey];
427
+ summary.todayCost = todayEntry ? todayEntry.cost : 0;
428
+ summary.todayCalls = todayEntry ? todayEntry.calls : 0;
429
+
430
+ // Overwrite stale monthCost/monthCalls from fresh JSONL dailyMap entries.
431
+ // dailyMap now covers back to the start of the current month (scanCutoff), so
432
+ // summing entries whose key starts with the current "YYYY-MM" prefix gives the
433
+ // true month-to-date spend — no stale token-summary.json cache involved.
434
+ let monthCostAcc = 0, monthCallsAcc = 0;
435
+ for (const [d, v] of Object.entries(dailyMap)) {
436
+ if (d.startsWith(monthPrefix)) { monthCostAcc += v.cost; monthCallsAcc += v.calls; }
437
+ }
438
+ summary.monthCost = monthCostAcc;
439
+ summary.monthCalls = monthCallsAcc;
440
+
441
+ return { summary, daily, rows };
442
+ }
443
+
444
+ function collectHooks(projectDir) {
445
+ const base = path.join(projectDir, '.monomind');
446
+ const lastRoute = readJSON(path.join(base, 'last-route.json')) || {};
447
+ const feedback = readJSONL(path.join(base, 'routing-feedback.jsonl'), 10);
448
+
449
+ const workerDispatchDir = path.join(base, 'worker-dispatch');
450
+ const workerDispatch = listDir(workerDispatchDir).filter(f => f.startsWith('pending-') && f.endsWith('.json'));
451
+
452
+ return { lastRoute, feedback, workerDispatch };
453
+ }
454
+
455
+ function collectKnowledge(projectDir) {
456
+ const base = path.join(projectDir, '.monomind');
457
+ const chunksPath = path.join(base, 'knowledge', 'chunks.jsonl');
458
+ const skillsPath = path.join(base, 'skills.jsonl');
459
+
460
+ // Read chunks.jsonl once; derive count and recent slice together
461
+ let chunks = 0;
462
+ let recent = [];
463
+ try {
464
+ const raw = fs.readFileSync(chunksPath, 'utf8');
465
+ const lines = raw.split('\n').filter(Boolean);
466
+ chunks = lines.length;
467
+ recent = lines.slice(-5).map(line => { try { return JSON.parse(line); } catch { return null; } }).filter(Boolean);
468
+ } catch {}
469
+ const skills = countJSONLLines(skillsPath);
470
+
471
+ return { chunks, skills, recent };
472
+ }
473
+
474
+ function collectMetrics(projectDir) {
475
+ const base = path.join(projectDir, '.monomind');
476
+ const swarmActivity = readJSON(path.join(base, 'metrics', 'swarm-activity.json')) || {};
477
+ const tokenSummary = readJSON(path.join(base, 'metrics', 'token-summary.json')) || {};
478
+
479
+ // Derive routing stats from feedback log (cap at 1000 to avoid reading unbounded file)
480
+ const feedbackAll = readJSONL(path.join(base, 'routing-feedback.jsonl'), 1000);
481
+ const routingTotal = feedbackAll.length;
482
+ let routingConfSum = 0, routingConfCount = 0;
483
+ const agentCounts = {};
484
+ for (const fb of feedbackAll) {
485
+ if (fb.confidence != null) { routingConfSum += fb.confidence; routingConfCount++; }
486
+ const a = fb.suggestedAgent || fb.agent;
487
+ if (a) agentCounts[a] = (agentCounts[a] || 0) + 1;
488
+ }
489
+ const avgConf = routingConfCount > 0 ? Math.round((routingConfSum / routingConfCount) * 100) : null;
490
+ const topAgent = Object.entries(agentCounts).sort((a, b) => b[1] - a[1])[0];
491
+
492
+ return {
493
+ routing: {
494
+ total: routingTotal,
495
+ avgConfidence: avgConf,
496
+ topAgent: topAgent ? topAgent[0] : null,
497
+ topAgentCount: topAgent ? topAgent[1] : null,
498
+ },
499
+ swarm: {
500
+ active: swarmActivity.swarm && swarmActivity.swarm.active,
501
+ agentCount: swarmActivity.swarm && swarmActivity.swarm.agent_count,
502
+ lastActive: swarmActivity.timestamp || null,
503
+ },
504
+ tokens: {
505
+ todayCost: tokenSummary.todayCost,
506
+ todayCalls: tokenSummary.todayCalls,
507
+ monthCost: tokenSummary.monthCost,
508
+ monthCalls: tokenSummary.monthCalls,
509
+ },
510
+ security: readJSON(path.join(base, 'security', 'audit-status.json')) || {}
511
+ };
512
+ }
513
+
514
+ function collectTriggers(projectDir) {
515
+ return readJSON(path.join(projectDir, '.monomind', 'trigger-index.json')) || {};
516
+ }
517
+
518
+ function collectMemoryFiles(projectDir) {
519
+ const homeDir = os.homedir();
520
+ const slug = path.resolve(projectDir).replace(/\//g, '-');
521
+ const memDir = path.join(homeDir, '.claude', 'projects', slug, 'memory');
522
+ let files = [];
523
+ try { files = fs.readdirSync(memDir).filter(f => f.endsWith('.md') && f !== 'MEMORY.md'); } catch {}
524
+ return files.map(fname => {
525
+ const fp = path.join(memDir, fname);
526
+ let raw = ''; try { raw = fs.readFileSync(fp, 'utf8').replace(/\r\n/g, '\n'); } catch {}
527
+ let name = fname.replace('.md', ''), description = '', type = 'project';
528
+ const fm = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
529
+ if (fm) {
530
+ for (const line of fm[1].split('\n')) {
531
+ const m2 = line.match(/^(\w+):\s*(.+)$/);
532
+ if (m2) {
533
+ if (m2[1] === 'name') name = m2[2].trim();
534
+ if (m2[1] === 'description') description = m2[2].trim();
535
+ if (m2[1] === 'type') type = m2[2].trim();
536
+ }
537
+ }
538
+ }
539
+ let stat = null; try { stat = fs.statSync(fp); } catch {}
540
+ return { filename: fname, name, description, type, mtime: stat ? stat.mtimeMs : null };
541
+ }).sort((a, b) => (b.mtime || 0) - (a.mtime || 0));
542
+ }
543
+
544
+ // Probe candidate paths in priority order, return first existing file's stat
545
+ function probeFile(...candidates) {
546
+ for (const p of candidates) {
547
+ const s = fileStat(p);
548
+ if (s && s.size > 0) return { path: p, size: s.size };
549
+ }
550
+ return null;
551
+ }
552
+
553
+ function collectMemory(projectDir) {
554
+ const d = path.resolve(projectDir);
555
+ const monomindDir = path.join(d, '.monomind');
556
+
557
+ // AgentDB — check all known locations across different init styles
558
+ const dbCandidates = [
559
+ path.join(d, 'data', 'memory.db'), // custom --path ./data/memory.db
560
+ path.join(d, '.swarm', 'memory.db'), // default init path
561
+ path.join(monomindDir, 'memory.db'), // legacy .monomind path
562
+ path.join(d, '.claude', 'memory.db'), // .claude dir (some setups)
563
+ ];
564
+ const dbHit = probeFile(...dbCandidates);
565
+ const dbSize = dbHit ? dbHit.size : 0;
566
+ const dbPath = dbHit ? dbHit.path : null;
567
+
568
+ // HNSW — lives alongside the DB or at the .swarm default
569
+ const hnswCandidates = dbPath ? [
570
+ path.join(path.dirname(dbPath), 'memory.graph'), // alongside DB (hybrid backend)
571
+ path.join(path.dirname(dbPath), 'hnsw.index'), // default init name
572
+ ] : [
573
+ path.join(d, 'data', 'memory.graph'),
574
+ path.join(d, '.swarm', 'hnsw.index'),
575
+ ];
576
+ const hnswHit = probeFile(...hnswCandidates);
577
+ const hnsw = !!hnswHit;
578
+
579
+ // MonoVector DB
580
+ const monovectorHit = probeFile(
581
+ path.join(monomindDir, 'data', 'monovector.db'),
582
+ path.join(d, 'data', 'monovector.db'),
583
+ );
584
+ const monovectorSize = monovectorHit ? monovectorHit.size : 0;
585
+ const monovectorExists = !!monovectorHit;
586
+
587
+ let monovectorPatterns = 0;
588
+ const ranked = readJSON(path.join(monomindDir, 'data', 'ranked-context.json'));
589
+ if (ranked && ranked.entries) monovectorPatterns = ranked.entries.length;
590
+
591
+ const files = collectMemoryFiles(projectDir);
592
+
593
+ return { dbSize, dbPath, hnsw, monovectorSize, monovectorExists, monovectorPatterns, files, count: files.length };
594
+ }
595
+
596
+ function collectSystem() {
597
+ return {
598
+ nodeVersion: process.version,
599
+ uptime: process.uptime(),
600
+ platform: process.platform,
601
+ memoryMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024)
602
+ };
603
+ }
604
+
605
+ // ---------------------------------------------------------------------------
606
+ // Global: all projects on this machine (~/.claude/projects/)
607
+ // ---------------------------------------------------------------------------
608
+
609
+ function slugToPath(slug) {
610
+ return resolveSlugPath(slug);
611
+ }
612
+
613
+ // Reconstruct the real filesystem path from a Claude project slug.
614
+ // Slugs encode the path with every '/' replaced by '-', which is lossy when
615
+ // directory names contain literal hyphens (e.g. /Desktop/agent-f/accounting).
616
+ // Strategy: naive replace first; if not found, greedy DFS through the filesystem
617
+ // trying longest-possible segment (with embedded hyphens) at each level.
618
+ function resolveSlugPath(slug) {
619
+ const naive = '/' + slug.replace(/^-/, '').replace(/-/g, '/');
620
+ try { if (fs.existsSync(naive)) return naive; } catch {}
621
+
622
+ const tokens = slug.replace(/^-/, '').split('-').filter(Boolean);
623
+
624
+ function walk(idx, dir) {
625
+ if (idx === tokens.length) return dir;
626
+ // Try longest span first (greedy) so "agent-f" is preferred over "agent"+"f"
627
+ for (let end = tokens.length; end > idx; end--) {
628
+ const segment = tokens.slice(idx, end).join('-');
629
+ const candidate = path.join(dir, segment);
630
+ try {
631
+ if (fs.statSync(candidate).isDirectory()) {
632
+ const result = walk(end, candidate);
633
+ if (result !== null) return result;
634
+ }
635
+ } catch {}
636
+ }
637
+ return null;
638
+ }
639
+
640
+ return walk(0, '/') || naive;
641
+ }
642
+
643
+ let _apCache = null;
644
+ let _apCacheTs = 0;
645
+ const AP_TTL = 5_000;
646
+
647
+ export function collectAllProjects() {
648
+ const now = Date.now();
649
+ if (_apCache !== null && now - _apCacheTs < AP_TTL) return _apCache;
650
+ const homeDir = os.homedir();
651
+ const projectsRoot = path.join(homeDir, '.claude', 'projects');
652
+ const result = [];
653
+
654
+ let slugs = [];
655
+ try { slugs = fs.readdirSync(projectsRoot); } catch { return result; }
656
+
657
+ for (const slug of slugs) {
658
+ const projectClaudeDir = path.join(projectsRoot, slug);
659
+ let stat;
660
+ try { stat = fs.statSync(projectClaudeDir); } catch { continue; }
661
+ if (!stat.isDirectory()) continue;
662
+
663
+ // Find session files (.jsonl) and subdirs (session folders)
664
+ let entries = [];
665
+ try { entries = fs.readdirSync(projectClaudeDir); } catch { continue; }
666
+
667
+ const sessionFiles = entries.filter(e => e.endsWith('.jsonl'));
668
+ const sessions = sessionFiles.map(f => {
669
+ const fp = path.join(projectClaudeDir, f);
670
+ let fstat = null;
671
+ try { fstat = fs.statSync(fp); } catch {}
672
+ // Peek at first line for model/type info
673
+ let firstTurn = null;
674
+ try {
675
+ const buf = Buffer.alloc(512);
676
+ const fd = fs.openSync(fp, 'r');
677
+ try {
678
+ fs.readSync(fd, buf, 0, 512, 0);
679
+ } finally {
680
+ fs.closeSync(fd);
681
+ }
682
+ const line = buf.toString('utf8').split('\n')[0];
683
+ firstTurn = JSON.parse(line);
684
+ } catch {}
685
+ return {
686
+ id: path.basename(f, '.jsonl'),
687
+ file: fp,
688
+ mtime: fstat ? fstat.mtimeMs : null,
689
+ size: fstat ? fstat.size : null,
690
+ lines: null, // skip line count for perf
691
+ model: firstTurn && firstTurn.model ? firstTurn.model : null,
692
+ };
693
+ }).sort((a, b) => (b.mtime || 0) - (a.mtime || 0));
694
+
695
+ // Resolve the actual filesystem path (handles hyphens in directory names)
696
+ const diskPath = resolveSlugPath(slug);
697
+ const parts = diskPath.split('/').filter(Boolean);
698
+ const name = parts[parts.length - 1] || slug;
699
+ const exists = fs.existsSync(diskPath);
700
+
701
+ // Last activity = most recent session mtime
702
+ const lastActivity = sessions.length ? sessions[0].mtime : null;
703
+
704
+ // Count auto-memory files from ~/.claude/projects/<slug>/memory/
705
+ let memoryCount = 0;
706
+ try {
707
+ const memDir = path.join(os.homedir(), '.claude', 'projects', slug, 'memory');
708
+ if (fs.existsSync(memDir)) {
709
+ memoryCount = fs.readdirSync(memDir).filter(f => f.endsWith('.md') && f !== 'MEMORY.md').length;
710
+ }
711
+ } catch {}
712
+
713
+ result.push({
714
+ slug,
715
+ name,
716
+ path: diskPath,
717
+ exists,
718
+ sessionCount: sessions.length,
719
+ sessions: sessions.slice(0, 5), // top 5 most recent
720
+ lastActivity,
721
+ memoryCount,
722
+ totalSize: sessions.reduce((sum, s) => sum + (s.size || 0), 0),
723
+ });
724
+ }
725
+
726
+ // Sort by most recently active
727
+ result.sort((a, b) => (b.lastActivity || 0) - (a.lastActivity || 0));
728
+ _apCache = result;
729
+ _apCacheTs = Date.now();
730
+ return result;
731
+ }
732
+
733
+ // ---------------------------------------------------------------------------
734
+ // Public API
735
+ // ---------------------------------------------------------------------------
736
+
737
+ export function collectAll(projectDir) {
738
+ const resolvedDir = path.resolve(projectDir);
739
+
740
+ return {
741
+ timestamp: Date.now(),
742
+ project: collectProject(resolvedDir),
743
+ sessions: collectSessions(resolvedDir),
744
+ swarm: collectSwarm(resolvedDir),
745
+ agents: collectAgents(resolvedDir),
746
+ tokens: collectTokens(resolvedDir),
747
+ hooks: collectHooks(resolvedDir),
748
+ knowledge: collectKnowledge(resolvedDir),
749
+ metrics: collectMetrics(resolvedDir),
750
+ triggers: collectTriggers(resolvedDir),
751
+ memory: collectMemory(resolvedDir),
752
+ system: collectSystem(),
753
+ allProjects: collectAllProjects(),
754
+ };
755
+ }
756
+
757
+ export { collectProject, collectSessions, collectSwarm, collectSwarmHistory, appendSwarmHistory, collectSwarmEvents, getSwarmDataSize, cleanSwarmData, collectAgents, collectTokens, collectHooks, collectKnowledge, collectMetrics, collectMemory, collectMemoryFiles, collectSystem, _tokPrice, _tokCost };
758
+
759
+ export function getWatchPaths(projectDir) {
760
+ const resolvedDir = path.resolve(projectDir);
761
+ const m = path.join(resolvedDir, '.monomind');
762
+ const c = path.join(resolvedDir, '.claude');
763
+
764
+ return [
765
+ // Swarm
766
+ path.join(m, 'swarm', 'swarm-state.json'),
767
+ path.join(m, 'swarm', 'history.jsonl'),
768
+ path.join(m, 'swarm-config.json'),
769
+ // Metrics
770
+ path.join(m, 'metrics', 'swarm-activity.json'),
771
+ path.join(m, 'metrics', 'token-summary.json'),
772
+ path.join(m, 'metrics', 'token-sessions.json'),
773
+ path.join(m, 'metrics', 'ddd-progress.json'),
774
+ path.join(m, 'metrics', 'learning.json'),
775
+ // Agents
776
+ path.join(m, 'registry.json'),
777
+ path.join(m, 'agents', 'registrations'),
778
+ // Hooks / routing
779
+ path.join(m, 'last-route.json'),
780
+ path.join(m, 'routing-feedback.jsonl'),
781
+ path.join(m, 'worker-dispatch'),
782
+ // Knowledge
783
+ path.join(m, 'knowledge', 'chunks.jsonl'),
784
+ path.join(m, 'skills.jsonl'),
785
+ // Security
786
+ path.join(m, 'security', 'audit-status.json'),
787
+ // Triggers & memory — watch all candidate locations
788
+ path.join(m, 'trigger-index.json'),
789
+ path.join(resolvedDir, 'data', 'memory.db'),
790
+ path.join(resolvedDir, 'data', 'memory.graph'),
791
+ path.join(resolvedDir, '.swarm', 'memory.db'),
792
+ path.join(resolvedDir, '.swarm', 'hnsw.index'),
793
+ path.join(m, 'memory.db'),
794
+ path.join(m, 'data', 'monovector.db'),
795
+ path.join(m, 'data', 'ranked-context.json'),
796
+ // Sessions
797
+ path.join(c, 'sessions')
798
+ ];
799
+ }