@claude-flow/cli 3.10.46 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/.claude/agents/analysis/analyze-code-quality.md +178 -178
  2. package/.claude/agents/analysis/code-analyzer.md +209 -209
  3. package/.claude/agents/analysis/code-review/analyze-code-quality.md +178 -178
  4. package/.claude/agents/architecture/arch-system-design.md +156 -156
  5. package/.claude/agents/architecture/system-design/arch-system-design.md +154 -154
  6. package/.claude/agents/browser/browser-agent.yaml +182 -182
  7. package/.claude/agents/consensus/byzantine-coordinator.md +62 -62
  8. package/.claude/agents/consensus/crdt-synchronizer.md +996 -996
  9. package/.claude/agents/consensus/gossip-coordinator.md +62 -62
  10. package/.claude/agents/consensus/performance-benchmarker.md +850 -850
  11. package/.claude/agents/consensus/quorum-manager.md +822 -822
  12. package/.claude/agents/consensus/raft-manager.md +62 -62
  13. package/.claude/agents/consensus/security-manager.md +621 -621
  14. package/.claude/agents/core/planner.md +374 -374
  15. package/.claude/agents/custom/test-long-runner.md +44 -44
  16. package/.claude/agents/data/data-ml-model.md +444 -444
  17. package/.claude/agents/data/ml/data-ml-model.md +192 -192
  18. package/.claude/agents/development/backend/dev-backend-api.md +141 -141
  19. package/.claude/agents/development/dev-backend-api.md +344 -344
  20. package/.claude/agents/devops/ci-cd/ops-cicd-github.md +163 -163
  21. package/.claude/agents/devops/ops-cicd-github.md +164 -164
  22. package/.claude/agents/documentation/api-docs/docs-api-openapi.md +173 -173
  23. package/.claude/agents/documentation/docs-api-openapi.md +354 -354
  24. package/.claude/agents/flow-nexus/app-store.md +87 -87
  25. package/.claude/agents/flow-nexus/authentication.md +68 -68
  26. package/.claude/agents/flow-nexus/challenges.md +80 -80
  27. package/.claude/agents/flow-nexus/neural-network.md +87 -87
  28. package/.claude/agents/flow-nexus/payments.md +82 -82
  29. package/.claude/agents/flow-nexus/sandbox.md +75 -75
  30. package/.claude/agents/flow-nexus/swarm.md +75 -75
  31. package/.claude/agents/flow-nexus/user-tools.md +95 -95
  32. package/.claude/agents/flow-nexus/workflow.md +83 -83
  33. package/.claude/agents/github/code-review-swarm.md +377 -377
  34. package/.claude/agents/github/github-modes.md +172 -172
  35. package/.claude/agents/github/issue-tracker.md +575 -575
  36. package/.claude/agents/github/multi-repo-swarm.md +552 -552
  37. package/.claude/agents/github/pr-manager.md +437 -437
  38. package/.claude/agents/github/project-board-sync.md +508 -508
  39. package/.claude/agents/github/release-manager.md +604 -604
  40. package/.claude/agents/github/release-swarm.md +582 -582
  41. package/.claude/agents/github/repo-architect.md +397 -397
  42. package/.claude/agents/github/swarm-issue.md +572 -572
  43. package/.claude/agents/github/swarm-pr.md +427 -427
  44. package/.claude/agents/github/sync-coordinator.md +451 -451
  45. package/.claude/agents/github/workflow-automation.md +902 -902
  46. package/.claude/agents/goal/agent.md +815 -815
  47. package/.claude/agents/optimization/benchmark-suite.md +664 -664
  48. package/.claude/agents/optimization/load-balancer.md +430 -430
  49. package/.claude/agents/optimization/performance-monitor.md +671 -671
  50. package/.claude/agents/optimization/resource-allocator.md +673 -673
  51. package/.claude/agents/optimization/topology-optimizer.md +807 -807
  52. package/.claude/agents/payments/agentic-payments.md +126 -126
  53. package/.claude/agents/sona/sona-learning-optimizer.md +74 -74
  54. package/.claude/agents/sparc/architecture.md +698 -698
  55. package/.claude/agents/sparc/pseudocode.md +519 -519
  56. package/.claude/agents/sparc/refinement.md +801 -801
  57. package/.claude/agents/sparc/specification.md +477 -477
  58. package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +224 -224
  59. package/.claude/agents/specialized/spec-mobile-react-native.md +226 -226
  60. package/.claude/agents/sublinear/consensus-coordinator.md +337 -337
  61. package/.claude/agents/sublinear/matrix-optimizer.md +184 -184
  62. package/.claude/agents/sublinear/pagerank-analyzer.md +298 -298
  63. package/.claude/agents/sublinear/performance-optimizer.md +367 -367
  64. package/.claude/agents/sublinear/trading-predictor.md +245 -245
  65. package/.claude/agents/swarm/adaptive-coordinator.md +1126 -1126
  66. package/.claude/agents/swarm/hierarchical-coordinator.md +709 -709
  67. package/.claude/agents/swarm/mesh-coordinator.md +962 -962
  68. package/.claude/agents/templates/automation-smart-agent.md +204 -204
  69. package/.claude/agents/templates/base-template-generator.md +289 -289
  70. package/.claude/agents/templates/coordinator-swarm-init.md +89 -89
  71. package/.claude/agents/templates/github-pr-manager.md +176 -176
  72. package/.claude/agents/templates/implementer-sparc-coder.md +258 -258
  73. package/.claude/agents/templates/memory-coordinator.md +186 -186
  74. package/.claude/agents/templates/orchestrator-task.md +138 -138
  75. package/.claude/agents/templates/performance-analyzer.md +198 -198
  76. package/.claude/agents/templates/sparc-coordinator.md +513 -513
  77. package/.claude/agents/testing/production-validator.md +394 -394
  78. package/.claude/agents/testing/tdd-london-swarm.md +243 -243
  79. package/.claude/agents/v3/aidefence-guardian.md +282 -282
  80. package/.claude/agents/v3/claims-authorizer.md +208 -208
  81. package/.claude/agents/v3/collective-intelligence-coordinator.md +993 -993
  82. package/.claude/agents/v3/ddd-domain-expert.md +220 -220
  83. package/.claude/agents/v3/injection-analyst.md +236 -236
  84. package/.claude/agents/v3/performance-engineer.md +1233 -1233
  85. package/.claude/agents/v3/pii-detector.md +151 -151
  86. package/.claude/agents/v3/reasoningbank-learner.md +213 -213
  87. package/.claude/agents/v3/security-architect-aidefence.md +410 -410
  88. package/.claude/agents/v3/security-architect.md +867 -867
  89. package/.claude/agents/v3/swarm-memory-manager.md +157 -157
  90. package/.claude/agents/v3/v3-integration-architect.md +205 -205
  91. package/.claude/commands/agents/README.md +50 -50
  92. package/.claude/commands/agents/agent-capabilities.md +140 -140
  93. package/.claude/commands/agents/agent-coordination.md +28 -28
  94. package/.claude/commands/agents/agent-spawning.md +28 -28
  95. package/.claude/commands/agents/agent-types.md +216 -216
  96. package/.claude/commands/agents/health.md +139 -139
  97. package/.claude/commands/agents/list.md +100 -100
  98. package/.claude/commands/agents/logs.md +130 -130
  99. package/.claude/commands/agents/metrics.md +122 -122
  100. package/.claude/commands/agents/pool.md +127 -127
  101. package/.claude/commands/agents/spawn.md +140 -140
  102. package/.claude/commands/agents/status.md +115 -115
  103. package/.claude/commands/agents/stop.md +102 -102
  104. package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +53 -53
  105. package/.claude/commands/analysis/README.md +9 -9
  106. package/.claude/commands/analysis/bottleneck-detect.md +162 -162
  107. package/.claude/commands/analysis/performance-bottlenecks.md +58 -58
  108. package/.claude/commands/analysis/performance-report.md +25 -25
  109. package/.claude/commands/analysis/token-efficiency.md +44 -44
  110. package/.claude/commands/analysis/token-usage.md +25 -25
  111. package/.claude/commands/automation/README.md +9 -9
  112. package/.claude/commands/automation/auto-agent.md +122 -122
  113. package/.claude/commands/automation/self-healing.md +105 -105
  114. package/.claude/commands/automation/session-memory.md +89 -89
  115. package/.claude/commands/automation/smart-agents.md +72 -72
  116. package/.claude/commands/automation/smart-spawn.md +25 -25
  117. package/.claude/commands/automation/workflow-select.md +25 -25
  118. package/.claude/commands/claude-flow-help.md +103 -103
  119. package/.claude/commands/claude-flow-memory.md +107 -107
  120. package/.claude/commands/claude-flow-swarm.md +205 -205
  121. package/.claude/commands/coordination/README.md +9 -9
  122. package/.claude/commands/coordination/agent-spawn.md +25 -25
  123. package/.claude/commands/coordination/init.md +44 -44
  124. package/.claude/commands/coordination/orchestrate.md +43 -43
  125. package/.claude/commands/coordination/spawn.md +45 -45
  126. package/.claude/commands/coordination/swarm-init.md +85 -85
  127. package/.claude/commands/coordination/task-orchestrate.md +25 -25
  128. package/.claude/commands/github/README.md +11 -11
  129. package/.claude/commands/github/code-review-swarm.md +513 -513
  130. package/.claude/commands/github/code-review.md +25 -25
  131. package/.claude/commands/github/github-modes.md +146 -146
  132. package/.claude/commands/github/github-swarm.md +121 -121
  133. package/.claude/commands/github/issue-tracker.md +291 -291
  134. package/.claude/commands/github/issue-triage.md +25 -25
  135. package/.claude/commands/github/multi-repo-swarm.md +518 -518
  136. package/.claude/commands/github/pr-enhance.md +26 -26
  137. package/.claude/commands/github/pr-manager.md +169 -169
  138. package/.claude/commands/github/project-board-sync.md +470 -470
  139. package/.claude/commands/github/release-manager.md +339 -339
  140. package/.claude/commands/github/release-swarm.md +543 -543
  141. package/.claude/commands/github/repo-analyze.md +25 -25
  142. package/.claude/commands/github/repo-architect.md +366 -366
  143. package/.claude/commands/github/swarm-issue.md +484 -484
  144. package/.claude/commands/github/swarm-pr.md +287 -287
  145. package/.claude/commands/github/sync-coordinator.md +302 -302
  146. package/.claude/commands/github/workflow-automation.md +441 -441
  147. package/.claude/commands/hive-mind/README.md +17 -17
  148. package/.claude/commands/hive-mind/hive-mind-consensus.md +8 -8
  149. package/.claude/commands/hive-mind/hive-mind-init.md +18 -18
  150. package/.claude/commands/hive-mind/hive-mind-memory.md +8 -8
  151. package/.claude/commands/hive-mind/hive-mind-metrics.md +8 -8
  152. package/.claude/commands/hive-mind/hive-mind-resume.md +8 -8
  153. package/.claude/commands/hive-mind/hive-mind-sessions.md +8 -8
  154. package/.claude/commands/hive-mind/hive-mind-spawn.md +21 -21
  155. package/.claude/commands/hive-mind/hive-mind-status.md +8 -8
  156. package/.claude/commands/hive-mind/hive-mind-stop.md +8 -8
  157. package/.claude/commands/hive-mind/hive-mind-wizard.md +8 -8
  158. package/.claude/commands/hive-mind/hive-mind.md +27 -27
  159. package/.claude/commands/hooks/README.md +11 -11
  160. package/.claude/commands/hooks/overview.md +57 -57
  161. package/.claude/commands/hooks/post-edit.md +117 -117
  162. package/.claude/commands/hooks/post-task.md +112 -112
  163. package/.claude/commands/hooks/pre-edit.md +113 -113
  164. package/.claude/commands/hooks/pre-task.md +111 -111
  165. package/.claude/commands/hooks/session-end.md +118 -118
  166. package/.claude/commands/hooks/setup.md +102 -102
  167. package/.claude/commands/memory/README.md +9 -9
  168. package/.claude/commands/memory/memory-persist.md +25 -25
  169. package/.claude/commands/memory/memory-search.md +25 -25
  170. package/.claude/commands/memory/memory-usage.md +25 -25
  171. package/.claude/commands/memory/neural.md +47 -47
  172. package/.claude/commands/monitoring/README.md +9 -9
  173. package/.claude/commands/monitoring/agent-metrics.md +25 -25
  174. package/.claude/commands/monitoring/agents.md +44 -44
  175. package/.claude/commands/monitoring/real-time-view.md +25 -25
  176. package/.claude/commands/monitoring/status.md +46 -46
  177. package/.claude/commands/monitoring/swarm-monitor.md +25 -25
  178. package/.claude/commands/optimization/README.md +9 -9
  179. package/.claude/commands/optimization/auto-topology.md +61 -61
  180. package/.claude/commands/optimization/cache-manage.md +25 -25
  181. package/.claude/commands/optimization/parallel-execute.md +25 -25
  182. package/.claude/commands/optimization/parallel-execution.md +49 -49
  183. package/.claude/commands/optimization/topology-optimize.md +25 -25
  184. package/.claude/commands/pair/README.md +260 -260
  185. package/.claude/commands/pair/commands.md +545 -545
  186. package/.claude/commands/pair/config.md +509 -509
  187. package/.claude/commands/pair/examples.md +511 -511
  188. package/.claude/commands/pair/modes.md +347 -347
  189. package/.claude/commands/pair/session.md +406 -406
  190. package/.claude/commands/pair/start.md +208 -208
  191. package/.claude/commands/sparc/analyzer.md +51 -51
  192. package/.claude/commands/sparc/architect.md +53 -53
  193. package/.claude/commands/sparc/ask.md +97 -97
  194. package/.claude/commands/sparc/batch-executor.md +54 -54
  195. package/.claude/commands/sparc/code.md +89 -89
  196. package/.claude/commands/sparc/coder.md +54 -54
  197. package/.claude/commands/sparc/debug.md +83 -83
  198. package/.claude/commands/sparc/debugger.md +54 -54
  199. package/.claude/commands/sparc/designer.md +53 -53
  200. package/.claude/commands/sparc/devops.md +109 -109
  201. package/.claude/commands/sparc/docs-writer.md +80 -80
  202. package/.claude/commands/sparc/documenter.md +54 -54
  203. package/.claude/commands/sparc/innovator.md +54 -54
  204. package/.claude/commands/sparc/integration.md +83 -83
  205. package/.claude/commands/sparc/mcp.md +117 -117
  206. package/.claude/commands/sparc/memory-manager.md +54 -54
  207. package/.claude/commands/sparc/optimizer.md +54 -54
  208. package/.claude/commands/sparc/orchestrator.md +131 -131
  209. package/.claude/commands/sparc/post-deployment-monitoring-mode.md +83 -83
  210. package/.claude/commands/sparc/refinement-optimization-mode.md +83 -83
  211. package/.claude/commands/sparc/researcher.md +54 -54
  212. package/.claude/commands/sparc/reviewer.md +54 -54
  213. package/.claude/commands/sparc/security-review.md +80 -80
  214. package/.claude/commands/sparc/sparc-modes.md +174 -174
  215. package/.claude/commands/sparc/sparc.md +111 -111
  216. package/.claude/commands/sparc/spec-pseudocode.md +80 -80
  217. package/.claude/commands/sparc/supabase-admin.md +348 -348
  218. package/.claude/commands/sparc/swarm-coordinator.md +54 -54
  219. package/.claude/commands/sparc/tdd.md +54 -54
  220. package/.claude/commands/sparc/tester.md +54 -54
  221. package/.claude/commands/sparc/tutorial.md +79 -79
  222. package/.claude/commands/sparc/workflow-manager.md +54 -54
  223. package/.claude/commands/sparc.md +166 -166
  224. package/.claude/commands/stream-chain/pipeline.md +120 -120
  225. package/.claude/commands/stream-chain/run.md +69 -69
  226. package/.claude/commands/swarm/README.md +15 -15
  227. package/.claude/commands/swarm/analysis.md +95 -95
  228. package/.claude/commands/swarm/development.md +96 -96
  229. package/.claude/commands/swarm/examples.md +168 -168
  230. package/.claude/commands/swarm/maintenance.md +102 -102
  231. package/.claude/commands/swarm/optimization.md +117 -117
  232. package/.claude/commands/swarm/research.md +136 -136
  233. package/.claude/commands/swarm/swarm-analysis.md +8 -8
  234. package/.claude/commands/swarm/swarm-background.md +8 -8
  235. package/.claude/commands/swarm/swarm-init.md +19 -19
  236. package/.claude/commands/swarm/swarm-modes.md +8 -8
  237. package/.claude/commands/swarm/swarm-monitor.md +8 -8
  238. package/.claude/commands/swarm/swarm-spawn.md +19 -19
  239. package/.claude/commands/swarm/swarm-status.md +8 -8
  240. package/.claude/commands/swarm/swarm-strategies.md +8 -8
  241. package/.claude/commands/swarm/swarm.md +87 -87
  242. package/.claude/commands/swarm/testing.md +131 -131
  243. package/.claude/commands/training/README.md +9 -9
  244. package/.claude/commands/training/model-update.md +25 -25
  245. package/.claude/commands/training/neural-patterns.md +107 -107
  246. package/.claude/commands/training/neural-train.md +75 -75
  247. package/.claude/commands/training/pattern-learn.md +25 -25
  248. package/.claude/commands/training/specialization.md +62 -62
  249. package/.claude/commands/truth/start.md +142 -142
  250. package/.claude/commands/verify/check.md +49 -49
  251. package/.claude/commands/verify/start.md +127 -127
  252. package/.claude/commands/workflows/README.md +9 -9
  253. package/.claude/commands/workflows/development.md +77 -77
  254. package/.claude/commands/workflows/research.md +62 -62
  255. package/.claude/commands/workflows/workflow-create.md +25 -25
  256. package/.claude/commands/workflows/workflow-execute.md +25 -25
  257. package/.claude/commands/workflows/workflow-export.md +25 -25
  258. package/.claude/helpers/README.md +96 -96
  259. package/.claude/helpers/adr-compliance.sh +186 -186
  260. package/.claude/helpers/auto-commit.sh +178 -178
  261. package/.claude/helpers/auto-memory-hook.mjs +368 -368
  262. package/.claude/helpers/checkpoint-manager.sh +251 -251
  263. package/.claude/helpers/daemon-manager.sh +252 -252
  264. package/.claude/helpers/ddd-tracker.sh +144 -144
  265. package/.claude/helpers/github-safe.js +156 -156
  266. package/.claude/helpers/github-setup.sh +45 -45
  267. package/.claude/helpers/guidance-hook.sh +13 -13
  268. package/.claude/helpers/guidance-hooks.sh +102 -102
  269. package/.claude/helpers/health-monitor.sh +108 -108
  270. package/.claude/helpers/hook-handler.cjs +286 -286
  271. package/.claude/helpers/intelligence.cjs +1031 -1031
  272. package/.claude/helpers/learning-hooks.sh +329 -329
  273. package/.claude/helpers/learning-optimizer.sh +127 -127
  274. package/.claude/helpers/learning-service.mjs +1144 -1144
  275. package/.claude/helpers/memory.js +83 -83
  276. package/.claude/helpers/metrics-db.mjs +488 -488
  277. package/.claude/helpers/pattern-consolidator.sh +86 -86
  278. package/.claude/helpers/perf-worker.sh +160 -160
  279. package/.claude/helpers/post-commit +16 -16
  280. package/.claude/helpers/pre-commit +26 -26
  281. package/.claude/helpers/quick-start.sh +19 -19
  282. package/.claude/helpers/router.js +105 -105
  283. package/.claude/helpers/security-scanner.sh +127 -127
  284. package/.claude/helpers/session.js +157 -157
  285. package/.claude/helpers/setup-mcp.sh +18 -18
  286. package/.claude/helpers/standard-checkpoint-hooks.sh +189 -189
  287. package/.claude/helpers/statusline-hook.sh +21 -21
  288. package/.claude/helpers/statusline.cjs +604 -604
  289. package/.claude/helpers/statusline.js +352 -352
  290. package/.claude/helpers/swarm-comms.sh +353 -353
  291. package/.claude/helpers/swarm-hooks.sh +761 -761
  292. package/.claude/helpers/swarm-monitor.sh +210 -210
  293. package/.claude/helpers/sync-v3-metrics.sh +245 -245
  294. package/.claude/helpers/update-v3-progress.sh +165 -165
  295. package/.claude/helpers/v3-quick-status.sh +57 -57
  296. package/.claude/helpers/v3.sh +110 -110
  297. package/.claude/helpers/validate-v3-config.sh +215 -215
  298. package/.claude/helpers/worker-manager.sh +170 -170
  299. package/.claude/settings.json +182 -182
  300. package/.claude/skills/agentdb-advanced/SKILL.md +550 -550
  301. package/.claude/skills/agentdb-learning/SKILL.md +545 -545
  302. package/.claude/skills/agentdb-memory-patterns/SKILL.md +339 -339
  303. package/.claude/skills/agentdb-optimization/SKILL.md +509 -509
  304. package/.claude/skills/agentdb-vector-search/SKILL.md +339 -339
  305. package/.claude/skills/browser/SKILL.md +204 -204
  306. package/.claude/skills/dual-mode/README.md +71 -71
  307. package/.claude/skills/dual-mode/dual-collect.md +103 -103
  308. package/.claude/skills/dual-mode/dual-coordinate.md +85 -85
  309. package/.claude/skills/dual-mode/dual-spawn.md +81 -81
  310. package/.claude/skills/flow-nexus-neural/SKILL.md +727 -727
  311. package/.claude/skills/flow-nexus-platform/SKILL.md +1154 -1154
  312. package/.claude/skills/flow-nexus-swarm/SKILL.md +604 -604
  313. package/.claude/skills/github-code-review/SKILL.md +1125 -1125
  314. package/.claude/skills/github-multi-repo/SKILL.md +862 -862
  315. package/.claude/skills/github-project-management/SKILL.md +1262 -1262
  316. package/.claude/skills/github-release-management/SKILL.md +1064 -1064
  317. package/.claude/skills/github-workflow-automation/SKILL.md +1047 -1047
  318. package/.claude/skills/hooks-automation/SKILL.md +1201 -1201
  319. package/.claude/skills/pair-programming/SKILL.md +1202 -1202
  320. package/.claude/skills/reasoningbank-agentdb/SKILL.md +446 -446
  321. package/.claude/skills/reasoningbank-intelligence/SKILL.md +201 -201
  322. package/.claude/skills/skill-builder/SKILL.md +910 -910
  323. package/.claude/skills/sparc-methodology/SKILL.md +1106 -1106
  324. package/.claude/skills/stream-chain/SKILL.md +560 -560
  325. package/.claude/skills/swarm-advanced/SKILL.md +970 -970
  326. package/.claude/skills/swarm-orchestration/SKILL.md +179 -179
  327. package/.claude/skills/v3-cli-modernization/SKILL.md +871 -871
  328. package/.claude/skills/v3-core-implementation/SKILL.md +796 -796
  329. package/.claude/skills/v3-ddd-architecture/SKILL.md +441 -441
  330. package/.claude/skills/v3-integration-deep/SKILL.md +240 -240
  331. package/.claude/skills/v3-mcp-optimization/SKILL.md +776 -776
  332. package/.claude/skills/v3-memory-unification/SKILL.md +173 -173
  333. package/.claude/skills/v3-performance-optimization/SKILL.md +389 -389
  334. package/.claude/skills/v3-security-overhaul/SKILL.md +81 -81
  335. package/.claude/skills/v3-swarm-coordination/SKILL.md +339 -339
  336. package/.claude/skills/verification-quality/SKILL.md +691 -691
  337. package/README.md +412 -412
  338. package/bin/cli.js +314 -314
  339. package/bin/mcp-server.js +224 -224
  340. package/bin/preinstall.cjs +2 -2
  341. package/dist/src/benchmarks/capability-tasks.d.ts +126 -0
  342. package/dist/src/benchmarks/capability-tasks.d.ts.map +1 -0
  343. package/dist/src/benchmarks/capability-tasks.js +147 -0
  344. package/dist/src/benchmarks/capability-tasks.js.map +1 -0
  345. package/dist/src/benchmarks/gaia-agent-contrastive.d.ts +53 -0
  346. package/dist/src/benchmarks/gaia-agent-contrastive.d.ts.map +1 -0
  347. package/dist/src/benchmarks/gaia-agent-contrastive.js +177 -0
  348. package/dist/src/benchmarks/gaia-agent-contrastive.js.map +1 -0
  349. package/dist/src/benchmarks/gaia-agent-gemini.d.ts +51 -0
  350. package/dist/src/benchmarks/gaia-agent-gemini.d.ts.map +1 -0
  351. package/dist/src/benchmarks/gaia-agent-gemini.js +352 -0
  352. package/dist/src/benchmarks/gaia-agent-gemini.js.map +1 -0
  353. package/dist/src/benchmarks/gaia-claude-p.d.ts +105 -0
  354. package/dist/src/benchmarks/gaia-claude-p.d.ts.map +1 -0
  355. package/dist/src/benchmarks/gaia-claude-p.js +269 -0
  356. package/dist/src/benchmarks/gaia-claude-p.js.map +1 -0
  357. package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts +20 -0
  358. package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts.map +1 -0
  359. package/dist/src/benchmarks/gaia-claude-p.smoke.js +168 -0
  360. package/dist/src/benchmarks/gaia-claude-p.smoke.js.map +1 -0
  361. package/dist/src/benchmarks/gaia-codeagent-runner.py +556 -0
  362. package/dist/src/benchmarks/gaia-codeagent.d.ts +129 -0
  363. package/dist/src/benchmarks/gaia-codeagent.d.ts.map +1 -0
  364. package/dist/src/benchmarks/gaia-codeagent.js +590 -0
  365. package/dist/src/benchmarks/gaia-codeagent.js.map +1 -0
  366. package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts +33 -0
  367. package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts.map +1 -0
  368. package/dist/src/benchmarks/gaia-codeagent.smoke.js +241 -0
  369. package/dist/src/benchmarks/gaia-codeagent.smoke.js.map +1 -0
  370. package/dist/src/benchmarks/gaia-critic.js +24 -24
  371. package/dist/src/benchmarks/gaia-dag-pilot.d.ts +22 -0
  372. package/dist/src/benchmarks/gaia-dag-pilot.d.ts.map +1 -0
  373. package/dist/src/benchmarks/gaia-dag-pilot.js +158 -0
  374. package/dist/src/benchmarks/gaia-dag-pilot.js.map +1 -0
  375. package/dist/src/benchmarks/gaia-dag.d.ts +110 -0
  376. package/dist/src/benchmarks/gaia-dag.d.ts.map +1 -0
  377. package/dist/src/benchmarks/gaia-dag.js +658 -0
  378. package/dist/src/benchmarks/gaia-dag.js.map +1 -0
  379. package/dist/src/benchmarks/gaia-dag.smoke.d.ts +21 -0
  380. package/dist/src/benchmarks/gaia-dag.smoke.d.ts.map +1 -0
  381. package/dist/src/benchmarks/gaia-dag.smoke.js +290 -0
  382. package/dist/src/benchmarks/gaia-dag.smoke.js.map +1 -0
  383. package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts +17 -0
  384. package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts.map +1 -0
  385. package/dist/src/benchmarks/gaia-ensemble-pilot.js +106 -0
  386. package/dist/src/benchmarks/gaia-ensemble-pilot.js.map +1 -0
  387. package/dist/src/benchmarks/gaia-ensemble.d.ts +103 -0
  388. package/dist/src/benchmarks/gaia-ensemble.d.ts.map +1 -0
  389. package/dist/src/benchmarks/gaia-ensemble.js +462 -0
  390. package/dist/src/benchmarks/gaia-ensemble.js.map +1 -0
  391. package/dist/src/benchmarks/gaia-gemini-pilot.d.ts +17 -0
  392. package/dist/src/benchmarks/gaia-gemini-pilot.d.ts.map +1 -0
  393. package/dist/src/benchmarks/gaia-gemini-pilot.js +168 -0
  394. package/dist/src/benchmarks/gaia-gemini-pilot.js.map +1 -0
  395. package/dist/src/benchmarks/gaia-mode-router.d.ts +67 -0
  396. package/dist/src/benchmarks/gaia-mode-router.d.ts.map +1 -0
  397. package/dist/src/benchmarks/gaia-mode-router.js +126 -0
  398. package/dist/src/benchmarks/gaia-mode-router.js.map +1 -0
  399. package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts +15 -0
  400. package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts.map +1 -0
  401. package/dist/src/benchmarks/gaia-mode-router.smoke.js +131 -0
  402. package/dist/src/benchmarks/gaia-mode-router.smoke.js.map +1 -0
  403. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts +24 -0
  404. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts.map +1 -0
  405. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js +276 -0
  406. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js.map +1 -0
  407. package/dist/src/benchmarks/gaia-tools/image_describe.d.ts +45 -0
  408. package/dist/src/benchmarks/gaia-tools/image_describe.d.ts.map +1 -0
  409. package/dist/src/benchmarks/gaia-tools/image_describe.js +222 -0
  410. package/dist/src/benchmarks/gaia-tools/image_describe.js.map +1 -0
  411. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts +24 -0
  412. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts.map +1 -0
  413. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js +169 -0
  414. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js.map +1 -0
  415. package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts +27 -0
  416. package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts.map +1 -0
  417. package/dist/src/benchmarks/gaia-tools/pdf_read.js +226 -0
  418. package/dist/src/benchmarks/gaia-tools/pdf_read.js.map +1 -0
  419. package/dist/src/benchmarks/gaia-tools/python_exec.d.ts +31 -0
  420. package/dist/src/benchmarks/gaia-tools/python_exec.d.ts.map +1 -0
  421. package/dist/src/benchmarks/gaia-tools/python_exec.js +94 -0
  422. package/dist/src/benchmarks/gaia-tools/python_exec.js.map +1 -0
  423. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts +13 -0
  424. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts.map +1 -0
  425. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js +98 -0
  426. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js.map +1 -0
  427. package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts +52 -0
  428. package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts.map +1 -0
  429. package/dist/src/benchmarks/gaia-tools/visit_webpage.js +304 -0
  430. package/dist/src/benchmarks/gaia-tools/visit_webpage.js.map +1 -0
  431. package/dist/src/benchmarks/gaia-tools/web_browse.d.ts +61 -0
  432. package/dist/src/benchmarks/gaia-tools/web_browse.d.ts.map +1 -0
  433. package/dist/src/benchmarks/gaia-tools/web_browse.js +217 -0
  434. package/dist/src/benchmarks/gaia-tools/web_browse.js.map +1 -0
  435. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts +26 -0
  436. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts.map +1 -0
  437. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js +152 -0
  438. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js.map +1 -0
  439. package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts +24 -0
  440. package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts.map +1 -0
  441. package/dist/src/benchmarks/gaia-tools/web_search.smoke.js +311 -0
  442. package/dist/src/benchmarks/gaia-tools/web_search.smoke.js.map +1 -0
  443. package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts +25 -0
  444. package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts.map +1 -0
  445. package/dist/src/benchmarks/gaia-visit-webpage.smoke.js +304 -0
  446. package/dist/src/benchmarks/gaia-visit-webpage.smoke.js.map +1 -0
  447. package/dist/src/commands/completions.js +409 -409
  448. package/dist/src/commands/daemon.js +44 -44
  449. package/dist/src/commands/embeddings.js +26 -26
  450. package/dist/src/commands/hive-mind.js +97 -97
  451. package/dist/src/commands/hooks.js +9 -9
  452. package/dist/src/commands/neural.d.ts.map +1 -1
  453. package/dist/src/commands/neural.js +2351 -1
  454. package/dist/src/commands/neural.js.map +1 -1
  455. package/dist/src/commands/performance-capability.d.ts +30 -0
  456. package/dist/src/commands/performance-capability.d.ts.map +1 -0
  457. package/dist/src/commands/performance-capability.js +349 -0
  458. package/dist/src/commands/performance-capability.js.map +1 -0
  459. package/dist/src/commands/ruvector/backup.js +23 -23
  460. package/dist/src/commands/ruvector/benchmark.js +31 -31
  461. package/dist/src/commands/ruvector/import.js +14 -14
  462. package/dist/src/commands/ruvector/init.js +115 -115
  463. package/dist/src/commands/ruvector/migrate.js +99 -99
  464. package/dist/src/commands/ruvector/optimize.js +51 -51
  465. package/dist/src/commands/ruvector/setup.js +624 -624
  466. package/dist/src/commands/ruvector/status.js +38 -38
  467. package/dist/src/init/claudemd-generator.js +231 -231
  468. package/dist/src/init/executor.js +453 -453
  469. package/dist/src/init/helpers-generator.js +727 -727
  470. package/dist/src/init/statusline-generator.js +717 -717
  471. package/dist/src/mcp-tools/agent-execute-core.d.ts +23 -1
  472. package/dist/src/mcp-tools/agent-execute-core.d.ts.map +1 -1
  473. package/dist/src/mcp-tools/agent-execute-core.js +136 -9
  474. package/dist/src/mcp-tools/agent-execute-core.js.map +1 -1
  475. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  476. package/dist/src/mcp-tools/agent-tools.js +48 -4
  477. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  478. package/dist/src/mcp-tools/agentdb-tools.js +15 -15
  479. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  480. package/dist/src/mcp-tools/hooks-tools.js +196 -0
  481. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  482. package/dist/src/memory/graph-edge-writer.js +18 -18
  483. package/dist/src/memory/memory-bridge.js +84 -84
  484. package/dist/src/memory/memory-initializer.js +393 -393
  485. package/dist/src/memory/rabitq-index.js +5 -5
  486. package/dist/src/runtime/headless.js +28 -28
  487. package/dist/src/ruvector/enhanced-model-router.d.ts +5 -0
  488. package/dist/src/ruvector/enhanced-model-router.d.ts.map +1 -1
  489. package/dist/src/ruvector/enhanced-model-router.js +18 -1
  490. package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
  491. package/dist/src/ruvector/model-prices.d.ts +50 -0
  492. package/dist/src/ruvector/model-prices.d.ts.map +1 -0
  493. package/dist/src/ruvector/model-prices.js +72 -0
  494. package/dist/src/ruvector/model-prices.js.map +1 -0
  495. package/dist/src/ruvector/model-router.d.ts +147 -8
  496. package/dist/src/ruvector/model-router.d.ts.map +1 -1
  497. package/dist/src/ruvector/model-router.js +418 -18
  498. package/dist/src/ruvector/model-router.js.map +1 -1
  499. package/dist/src/ruvector/neural-router.d.ts +172 -39
  500. package/dist/src/ruvector/neural-router.d.ts.map +1 -1
  501. package/dist/src/ruvector/neural-router.js +780 -91
  502. package/dist/src/ruvector/neural-router.js.map +1 -1
  503. package/dist/src/ruvector/router-calibrator.d.ts +65 -0
  504. package/dist/src/ruvector/router-calibrator.d.ts.map +1 -0
  505. package/dist/src/ruvector/router-calibrator.js +120 -0
  506. package/dist/src/ruvector/router-calibrator.js.map +1 -0
  507. package/dist/src/ruvector/router-trajectory.d.ts +137 -45
  508. package/dist/src/ruvector/router-trajectory.d.ts.map +1 -1
  509. package/dist/src/ruvector/router-trajectory.js +226 -63
  510. package/dist/src/ruvector/router-trajectory.js.map +1 -1
  511. package/dist/src/ruvector/task-embedder.d.ts +56 -0
  512. package/dist/src/ruvector/task-embedder.d.ts.map +1 -0
  513. package/dist/src/ruvector/task-embedder.js +237 -0
  514. package/dist/src/ruvector/task-embedder.js.map +1 -0
  515. package/dist/src/services/headless-worker-executor.js +84 -84
  516. package/dist/src/transfer/deploy-seraphine.js +23 -23
  517. package/dist/tsconfig.tsbuildinfo +1 -1
  518. package/package.json +136 -134
  519. package/scripts/beir-bootstrap-significance.mjs +162 -162
  520. package/scripts/bench-rvagent.mjs +312 -312
  521. package/scripts/benchmark-codemods.mjs +127 -127
  522. package/scripts/benchmark-cross-repo.mjs +206 -206
  523. package/scripts/benchmark-pretrained-retrieval.mjs +305 -305
  524. package/scripts/benchmark-self-learning.mjs +241 -241
  525. package/scripts/benchmark-trajectory-mrr.mjs +191 -191
  526. package/scripts/deploy-ipfs-node.sh +153 -153
  527. package/scripts/grid-search-retrieval.mjs +216 -216
  528. package/scripts/postinstall.cjs +153 -153
  529. package/scripts/pretrain-from-github.mjs +358 -358
  530. package/scripts/publish-registry.ts +345 -345
  531. package/scripts/publish.sh +57 -57
  532. package/scripts/run-beir-bge.mjs +324 -324
  533. package/scripts/run-beir-hybrid.mjs +261 -261
  534. package/scripts/run-beir-lucene-bm25.mjs +154 -154
  535. package/scripts/run-beir-nfcorpus.mjs +231 -231
  536. package/scripts/run-beir-rrf-ablation.mjs +221 -221
  537. package/scripts/setup-ipfs-registry.md +366 -366
  538. package/dist/src/ruvector/flash-attention.d.ts +0 -195
  539. package/dist/src/ruvector/flash-attention.d.ts.map +0 -1
  540. package/dist/src/ruvector/flash-attention.js +0 -643
  541. package/dist/src/ruvector/flash-attention.js.map +0 -1
  542. package/dist/src/ruvector/moe-router.d.ts +0 -206
  543. package/dist/src/ruvector/moe-router.d.ts.map +0 -1
  544. package/dist/src/ruvector/moe-router.js +0 -626
  545. package/dist/src/ruvector/moe-router.js.map +0 -1
  546. package/dist/src/services/event-stream.d.ts +0 -25
  547. package/dist/src/services/event-stream.js +0 -27
  548. package/dist/src/services/loop-worker-runner.d.ts +0 -16
  549. package/dist/src/services/loop-worker-runner.js +0 -34
  550. package/dist/src/services/runtime-capabilities.d.ts +0 -22
  551. package/dist/src/services/runtime-capabilities.js +0 -45
@@ -21,699 +21,699 @@
21
21
  */
22
22
  export function generateStatuslineScript(options) {
23
23
  const maxAgents = options.runtime.maxAgents;
24
- return `#!/usr/bin/env node
25
- /**
26
- * RuFlo V3 Statusline — delegation build (#2195)
27
- *
28
- * Fix for ruvnet/ruflo#2195: the previous version re-implemented all data
29
- * readers locally using fragile file probes that missed AgentDB patterns,
30
- * the v3/docs/adr/ ADR directory, and the real vector count.
31
- *
32
- * This version delegates to 'npx @claude-flow/cli hooks statusline --json'
33
- * as the single source of truth. That command queries AgentDB directly,
34
- * counts ADRs in both directories, and reports the real intelligence pct.
35
- *
36
- * ADR counting falls back to local file reads so the display still works
37
- * without network access (counts both v3/docs/adr/ and v3/implementation/adrs/).
38
- *
39
- * Cache: JSON result is cached in /tmp for 10s so rapid prompt triggers
40
- * (every keystroke in some shells) don't hammer the CLI on every call.
41
- *
42
- * Usage: node statusline.cjs [--json] [--compact] [--dashboard]
43
- */
44
-
45
- /* eslint-disable @typescript-eslint/no-var-requires */
46
- const fs = require('fs');
47
- const path = require('path');
48
- const { execSync } = require('child_process');
49
- const os = require('os');
50
-
51
- // Configuration
52
- const CONFIG = {
53
- maxAgents: ${maxAgents},
54
- // Session-cost display. Claude Code's cost.total_cost_usd is a client-side
55
- // estimate that "may differ from your actual bill" and reads as misleading on
56
- // subscription plans, where token usage is not billed per dollar. These let
57
- // each user pick what the segment means to them without changing the default.
58
- // RUFLO_STATUSLINE_COST_SYMBOL override the leading '$' (e.g. ⚡, €, 🌱);
59
- // set to an empty string for the number alone.
60
- // RUFLO_STATUSLINE_HIDE_COST 1/true/yes/on removes the segment entirely.
61
- costSymbol: process.env.RUFLO_STATUSLINE_COST_SYMBOL ?? '$',
62
- hideCost: /^(1|true|yes|on)$/i.test(process.env.RUFLO_STATUSLINE_HIDE_COST || ''),
63
- };
64
-
65
- const CWD = process.cwd();
66
-
67
- // ─── Delegation cache ───────────────────────────────────────────
68
- // Cache the CLI JSON result for 60s so rapid prompt re-renders
69
- // (Claude Code refreshes the statusline several times a second while
70
- // streaming) don't re-invoke the CLI each time. #2337: bumped 10s→60s
71
- // because 10s was far too short for how often Claude Code re-renders.
72
- const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
73
- const CACHE_TTL_MS = 60000;
74
-
75
- // #2337: resolve an already-installed @claude-flow/cli (or ruflo) bin so we
76
- // can invoke it directly via \`node\`. The previous version called
77
- // \`npx --yes @claude-flow/cli@latest\` on every uncached render, which forces
78
- // a registry resolution + cold-start of the entire CLI per render. With
79
- // multiple concurrent Claude Code sessions this storms the host (reporter
80
- // saw load average 40-65 on a 12-core box).
81
- //
82
- // Returns the absolute path to bin/cli.js or null. Mirrors getPkgVersion()'s
83
- // path probing (project, monorepo, plugin marketplace, global node_modules
84
- // including custom-prefix layouts like ~/.npm-global).
85
- function resolveCliBin() {
86
- try {
87
- const home = os.homedir();
88
- const candidates = [
89
- path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'bin', 'cli.js'),
90
- path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'bin', 'cli.js'),
91
- path.join(CWD, 'node_modules', 'ruflo', 'bin', 'cli.js'),
92
- path.join(CWD, 'v3', '@claude-flow', 'cli', 'bin', 'cli.js'),
93
- ];
94
- try {
95
- const binDir = path.dirname(process.execPath);
96
- const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
97
- for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
98
- if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
99
- }
100
- for (const gm of globalModuleDirs) {
101
- candidates.push(
102
- path.join(gm, 'ruflo', 'bin', 'cli.js'),
103
- path.join(gm, '@claude-flow', 'cli', 'bin', 'cli.js'),
104
- );
105
- }
106
- } catch { /* ignore */ }
107
- for (const p of candidates) {
108
- if (fs.existsSync(p)) return p;
109
- }
110
- } catch { /* ignore */ }
111
- return null;
112
- }
113
-
114
- function readCache() {
115
- try {
116
- if (fs.existsSync(CACHE_FILE)) {
117
- const raw = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
118
- if (raw && raw._ts && (Date.now() - raw._ts) < CACHE_TTL_MS) {
119
- return raw.data;
120
- }
121
- }
122
- } catch { /* ignore */ }
123
- return null;
124
- }
125
-
126
- function writeCache(data) {
127
- try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ _ts: Date.now(), data }), 'utf-8'); } catch { /* ignore */ }
128
- }
129
-
130
- /**
131
- * Single source of truth: delegate to the CLI hooks statusline --json command.
132
- * Falls back to a minimal static object on failure so the statusline still renders.
133
- *
134
- * Fix for ruflo#2195: the previous local readers returned 0 for AgentDB patterns
135
- * (missed the .swarm/memory.db → AgentDB path), computed dddProgress wrong,
136
- * and only counted ADRs in v3/implementation/adrs/ (missed v3/docs/adr/).
137
- */
138
- function getStatuslineData() {
139
- const cached = readCache();
140
- if (cached) return cached;
141
-
142
- try {
143
- // #2337: prefer an already-installed CLI bin via direct \`node\` invocation
144
- // — no npx, no registry round-trip, no @latest re-resolve per render.
145
- // Fall back to \`npx --prefer-offline @claude-flow/cli\` (no @latest) only
146
- // when nothing is installed locally, so a cold environment still works.
147
- const cliBin = resolveCliBin();
148
- const cmd = cliBin
149
- ? '"' + process.execPath + '" "' + cliBin + '" hooks statusline --json 2>/dev/null'
150
- : 'npx --prefer-offline @claude-flow/cli hooks statusline --json 2>/dev/null';
151
- const raw = execSync(
152
- cmd,
153
- { encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
154
- ).trim();
155
- // The CLI may emit preamble lines before the JSON — find the first '{'.
156
- const jsonStart = raw.indexOf('{');
157
- if (jsonStart === -1) throw new Error('no JSON in CLI output');
158
- const data = JSON.parse(raw.slice(jsonStart));
159
- // Overlay every block the CLI JSON omits (adrs/agentdb/tests/hooks/integration)
160
- // with real local reads, so those segments reflect actual state instead of 0.
161
- applyLocalOverlays(data);
162
- writeCache(data);
163
- return data;
164
- } catch { /* CLI unavailable or timed out */ }
165
-
166
- // Fallback: use local file probes only (will be less accurate, but non-zero
167
- // when CLI is available and accurate when it's not).
168
- return buildLocalFallback();
169
- }
170
-
171
- // Count ADRs from BOTH known directories (fix for ruflo#2195: old code missed
172
- // v3/docs/adr/ which holds ADR-088..ADR-137, i.e. 41 of the 128 total ADRs).
173
- function getLocalADRCount() {
174
- const adrDirs = [
175
- path.join(CWD, 'v3', 'implementation', 'adrs'),
176
- path.join(CWD, 'v3', 'docs', 'adr'),
177
- path.join(CWD, 'docs', 'adrs'),
178
- path.join(CWD, '.claude-flow', 'adrs'),
179
- ];
180
- let total = 0;
181
- for (const dir of adrDirs) {
182
- try {
183
- if (fs.existsSync(dir)) {
184
- const files = fs.readdirSync(dir).filter(function(f) {
185
- return f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f));
186
- });
187
- total += files.length;
188
- }
189
- } catch { /* ignore */ }
190
- }
191
- return { count: total, implemented: total, compliance: 0 };
192
- }
193
-
194
- // ─── Local overlays for segments the CLI JSON omits ──────────────
195
- // 'hooks statusline --json' only returns user/v3Progress/security/swarm/system.
196
- // agentdb/tests/hooks/integration are never populated, so without these overlays
197
- // they render as a permanent 0. Each reader is cheap and degrades to zeros.
198
-
199
- // Real AgentDB stats from the local memory DB. Vectors live in .swarm/memory.db
200
- // (sql.js + HNSW); ruvector.db is an opaque redb store counted only toward size.
201
- // One read-only sqlite3 query (mode=ro never takes a write lock the daemon owns).
202
- function getLocalAgentDB() {
203
- const result = { vectorCount: 0, dbSizeKB: 0, hasHnsw: false };
204
- try {
205
- let bytes = 0;
206
- for (const f of ['.swarm/memory.db', 'ruvector.db']) {
207
- try { bytes += fs.statSync(path.join(CWD, f)).size; } catch { /* missing */ }
208
- }
209
- result.dbSizeKB = Math.round(bytes / 1024);
210
-
211
- const memDb = path.join(CWD, '.swarm', 'memory.db');
212
- if (fs.existsSync(memDb)) {
213
- const Q = String.fromCharCode(34);
214
- const sql = Q + 'SELECT (SELECT COUNT(*) FROM memory_entries WHERE embedding IS NOT NULL)||' + "'|'" + '||(SELECT COUNT(*) FROM vector_indexes);' + Q;
215
- const out = safeExec("sqlite3 'file:" + memDb + "?mode=ro' " + sql, 1500);
216
- if (out && out.indexOf('|') !== -1) {
217
- const parts = out.split('|');
218
- result.vectorCount = parseInt(parts[0], 10) || 0;
219
- result.hasHnsw = (parseInt(parts[1], 10) || 0) > 0;
220
- }
221
- }
222
- } catch { /* ignore */ }
223
- return result;
224
- }
225
-
226
- // Count test files via a bounded directory walk (no file reads).
227
- function getLocalTests() {
228
- let testFiles = 0;
229
- function countTests(dir, depth) {
230
- if ((depth || 0) > 4) return;
231
- try {
232
- if (!fs.existsSync(dir)) return;
233
- for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
234
- if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules') {
235
- countTests(path.join(dir, e.name), (depth || 0) + 1);
236
- } else if (e.isFile() && (e.name.includes('.test.') || e.name.includes('.spec.') || e.name.startsWith('test_') || e.name.startsWith('spec_'))) {
237
- testFiles++;
238
- }
239
- }
240
- } catch { /* ignore */ }
241
- }
242
- for (const d of ['tests', 'test', '__tests__', 'src', 'v3']) countTests(path.join(CWD, d));
243
- return { testFiles, testCases: testFiles * 4 };
244
- }
245
-
246
- // Count configured hooks from project .claude/settings.json. Claude Code hooks
247
- // have no enabled/disabled flag, so every configured hook counts as enabled.
248
- function getLocalHooks() {
249
- const result = { enabled: 0, total: 0 };
250
- try {
251
- const settings = readJSON(path.join(CWD, '.claude', 'settings.json'));
252
- const hooks = settings && settings.hooks;
253
- if (hooks && typeof hooks === 'object') {
254
- let n = 0;
255
- for (const ev of Object.keys(hooks)) {
256
- const groups = hooks[ev];
257
- if (Array.isArray(groups)) {
258
- for (const g of groups) {
259
- if (g && Array.isArray(g.hooks)) n += g.hooks.length;
260
- }
261
- }
262
- }
263
- result.total = n;
264
- result.enabled = n;
265
- }
266
- } catch { /* ignore */ }
267
- return result;
268
- }
269
-
270
- // Best-effort integration block: DB presence + locally-configured stdio MCP
271
- // servers (project .mcp.json + global ~/.claude.json). Remote connectors are
272
- // account-managed and not present in local config, so they are not counted.
273
- function getLocalIntegration() {
274
- const integration = { mcpServers: { enabled: 0, total: 0 }, hasDatabase: false };
275
- try {
276
- for (const f of ['.swarm/memory.db', 'ruvector.db']) {
277
- if (fs.existsSync(path.join(CWD, f))) { integration.hasDatabase = true; break; }
278
- }
279
- const names = new Set();
280
- const projMcp = readJSON(path.join(CWD, '.mcp.json'));
281
- if (projMcp && projMcp.mcpServers) for (const k of Object.keys(projMcp.mcpServers)) names.add(k);
282
- const claudeJson = readJSON(path.join(os.homedir(), '.claude.json'));
283
- if (claudeJson) {
284
- if (claudeJson.mcpServers) for (const k of Object.keys(claudeJson.mcpServers)) names.add(k);
285
- const proj = claudeJson.projects && claudeJson.projects[CWD];
286
- if (proj && proj.mcpServers && !Array.isArray(proj.mcpServers)) {
287
- for (const k of Object.keys(proj.mcpServers)) names.add(k);
288
- }
289
- }
290
- integration.mcpServers.total = names.size;
291
- integration.mcpServers.enabled = names.size;
292
- } catch { /* ignore */ }
293
- return integration;
294
- }
295
-
296
- // Overlay every locally-derived block onto the CLI data (mutates in place).
297
- function applyLocalOverlays(data) {
298
- data.adrs = getLocalADRCount();
299
- data.agentdb = getLocalAgentDB();
300
- data.tests = getLocalTests();
301
- data.hooks = getLocalHooks();
302
- data.integration = getLocalIntegration();
303
- return data;
304
- }
305
-
306
- // Minimal local fallback when the CLI is not installed or times out.
307
- // Returns a structure that matches the CLI JSON schema so the renderer works.
308
- function buildLocalFallback() {
309
- const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
310
-
311
- return applyLocalOverlays({
312
- user: { name: 'user', gitBranch: '', modelName: 'Claude Code' },
313
- v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
314
- security: { status: 'NONE', cvesFixed: 0, totalCves: 0 },
315
- swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
316
- system: { memoryMB: memMB, contextPct: 0, intelligencePct: 0, subAgents: 0 },
317
- lastUpdated: new Date().toISOString(),
318
- });
319
- }
320
-
321
- // ANSI colors
322
- const c = {
323
- reset: '\\x1b[0m',
324
- bold: '\\x1b[1m',
325
- dim: '\\x1b[2m',
326
- red: '\\x1b[0;31m',
327
- green: '\\x1b[0;32m',
328
- yellow: '\\x1b[0;33m',
329
- blue: '\\x1b[0;34m',
330
- purple: '\\x1b[0;35m',
331
- cyan: '\\x1b[0;36m',
332
- brightRed: '\\x1b[1;31m',
333
- brightGreen: '\\x1b[1;32m',
334
- brightYellow: '\\x1b[1;33m',
335
- brightBlue: '\\x1b[1;34m',
336
- brightPurple: '\\x1b[1;35m',
337
- brightCyan: '\\x1b[1;36m',
338
- brightWhite: '\\x1b[1;37m',
339
- };
340
-
341
- // Safe execSync with strict timeout (returns empty string on failure)
342
- function safeExec(cmd, timeoutMs) {
343
- try {
344
- return execSync(cmd, {
345
- encoding: 'utf-8',
346
- timeout: timeoutMs || 2000,
347
- stdio: ['pipe', 'pipe', 'pipe'],
348
- }).trim();
349
- } catch {
350
- return '';
351
- }
352
- }
353
-
354
- // Safe JSON file reader (returns null on failure)
355
- function readJSON(filePath) {
356
- try {
357
- if (fs.existsSync(filePath)) {
358
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
359
- }
360
- } catch { /* ignore */ }
361
- return null;
362
- }
363
-
364
- // ─── Git info (pure-Node / single exec — needed for branch display) ──────────
365
-
366
- function getGitInfo() {
367
- const result = {
368
- name: 'user', gitBranch: '', modified: 0, untracked: 0,
369
- staged: 0, ahead: 0, behind: 0,
370
- };
371
-
372
- const script = [
373
- 'git config user.name 2>/dev/null || echo user',
374
- 'echo "---SEP---"',
375
- 'git branch --show-current 2>/dev/null',
376
- 'echo "---SEP---"',
377
- 'git status --porcelain 2>/dev/null',
378
- 'echo "---SEP---"',
379
- 'git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo "0 0"',
380
- ].join('; ');
381
-
382
- const raw = safeExec("sh -c '" + script + "'", 3000);
383
- if (!raw) return result;
384
-
385
- const parts = raw.split('---SEP---').map(function(s) { return s.trim(); });
386
- if (parts.length >= 4) {
387
- result.name = parts[0] || 'user';
388
- result.gitBranch = parts[1] || '';
389
-
390
- if (parts[2]) {
391
- for (const line of parts[2].split('\\n')) {
392
- if (!line || line.length < 2) continue;
393
- const x = line[0], y = line[1];
394
- if (x === '?' && y === '?') { result.untracked++; continue; }
395
- if (x !== ' ' && x !== '?') result.staged++;
396
- if (y !== ' ' && y !== '?') result.modified++;
397
- }
398
- }
399
-
400
- const ab = (parts[3] || '0 0').split(/\\s+/);
401
- result.ahead = parseInt(ab[0]) || 0;
402
- result.behind = parseInt(ab[1]) || 0;
403
- }
404
-
405
- return result;
406
- }
407
-
408
- // Detect model name from Claude config (pure file reads, no exec)
409
- function getModelName() {
410
- try {
411
- const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));
412
- if (claudeConfig && claudeConfig.projects) {
413
- for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
414
- if (CWD === projectPath || CWD.startsWith(projectPath + '/')) {
415
- const usage = projectConfig.lastModelUsage;
416
- if (usage) {
417
- const ids = Object.keys(usage);
418
- if (ids.length > 0) {
419
- let modelId = ids[ids.length - 1];
420
- let latest = 0;
421
- for (const id of ids) {
422
- const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;
423
- if (ts > latest) { latest = ts; modelId = id; }
424
- }
425
- if (modelId.includes('opus')) return 'Opus 4.8';
426
- if (modelId.includes('sonnet')) return 'Sonnet 4.6';
427
- if (modelId.includes('haiku')) return 'Haiku 4.5';
428
- return modelId.split('-').slice(1, 3).join(' ');
429
- }
430
- }
431
- break;
432
- }
433
- }
434
- }
435
- } catch { /* ignore */ }
436
-
437
- // Fallback: settings.json model field
438
- const settings = getSettings();
439
- if (settings && settings.model) {
440
- const m = settings.model;
441
- if (m.includes('opus')) return 'Opus 4.8';
442
- if (m.includes('sonnet')) return 'Sonnet 4.6';
443
- if (m.includes('haiku')) return 'Haiku 4.5';
444
- }
445
- return 'Claude Code';
446
- }
447
-
448
- // ─── Stdin reader (Claude Code pipes session JSON) ──────────────
449
- // Claude Code sends session JSON via stdin. Read synchronously so the
450
- // script works both when invoked by Claude Code (stdin has JSON) and
451
- // when run manually from terminal (stdin is empty/tty).
452
- let _stdinData = null;
453
- function getStdinData() {
454
- if (_stdinData !== undefined && _stdinData !== null) return _stdinData;
455
- try {
456
- if (process.stdin.isTTY) { _stdinData = null; return null; }
457
- const chunks = [];
458
- const buf = Buffer.alloc(4096);
459
- let bytesRead;
460
- try {
461
- while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {
462
- chunks.push(buf.slice(0, bytesRead));
463
- }
464
- } catch { /* EOF or read error */ }
465
- const raw = Buffer.concat(chunks).toString('utf-8').trim();
466
- _stdinData = (raw && raw.startsWith('{')) ? JSON.parse(raw) : null;
467
- } catch {
468
- _stdinData = null;
469
- }
470
- return _stdinData;
471
- }
472
-
473
- function getModelFromStdin() {
474
- const data = getStdinData();
475
- return (data && data.model && data.model.display_name) ? data.model.display_name : null;
476
- }
477
-
478
- function getContextFromStdin() {
479
- const data = getStdinData();
480
- if (data && data.context_window) {
481
- return { usedPct: Math.floor(data.context_window.used_percentage || 0) };
482
- }
483
- return null;
484
- }
485
-
486
- function getCostFromStdin() {
487
- const data = getStdinData();
488
- if (data && data.cost) {
489
- const durationMs = data.cost.total_duration_ms || 0;
490
- const mins = Math.floor(durationMs / 60000);
491
- const secs = Math.floor((durationMs % 60000) / 1000);
492
- return {
493
- costUsd: data.cost.total_cost_usd || 0,
494
- duration: mins > 0 ? mins + 'm' + secs + 's' : secs + 's',
495
- };
496
- }
497
- return null;
498
- }
499
-
500
- // Read package version from the first package.json we find.
501
- function getPkgVersion() {
502
- let ver = '3.6';
503
- try {
504
- const home = os.homedir();
505
- const pkgPaths = [
506
- path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'package.json'),
507
- path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'package.json'),
508
- path.join(CWD, 'node_modules', 'ruflo', 'package.json'),
509
- path.join(CWD, 'v3', '@claude-flow', 'cli', 'package.json'),
510
- ];
511
- // #2221: global installs (npm i -g ruflo) live outside CWD/node_modules, so the
512
- // probes above all miss and the version falls back to the hard-coded default.
513
- // Derive the global node_modules dir from the running node binary (no npm spawn —
514
- // statusline renders often). Covers nvm/mise (bin/../lib/node_modules) and Windows
515
- // (bin/node_modules) layouts.
516
- try {
517
- const binDir = path.dirname(process.execPath);
518
- const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
519
- // #2221 follow-up: a custom npm prefix (e.g. ~/.npm-global) is decoupled from
520
- // the node binary location, so the binDir-derived probes above all miss. Also
521
- // probe the npm prefix from the environment and the common ~/.npm-global default.
522
- for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
523
- if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
524
- }
525
- for (const gm of globalModuleDirs) {
526
- pkgPaths.push(
527
- path.join(gm, 'ruflo', 'package.json'),
528
- path.join(gm, '@claude-flow', 'cli', 'package.json'),
529
- );
530
- }
531
- } catch { /* ignore */ }
532
- for (const p of pkgPaths) {
533
- if (!fs.existsSync(p)) continue;
534
- try {
535
- const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
536
- if (pkg && typeof pkg.version === 'string' && pkg.version.length > 0) { ver = pkg.version; break; }
537
- } catch { /* ignore */ }
538
- }
539
- } catch { /* ignore */ }
540
- return ver;
541
- }
542
-
543
- // ─── Rendering ──────────────────────────────────────────────────
544
-
545
- function progressBar(current, total) {
546
- const width = 5;
547
- const filled = Math.round((current / total) * width);
548
- return '[' + '●'.repeat(filled) + '○'.repeat(width - filled) + ']';
549
- }
550
-
551
- function generateStatusline() {
552
- const d = getStatuslineData();
553
- const git = getGitInfo();
554
- const modelName = getModelFromStdin() || (d.user && d.user.modelName) || 'Claude Code';
555
- const ctxInfo = getContextFromStdin();
556
- const costInfo = getCostFromStdin();
557
- const pkgVersion = getPkgVersion();
558
-
559
- const progress = d.v3Progress || {};
560
- const security = d.security || {};
561
- const swarm = d.swarm || {};
562
- const system = d.system || {};
563
- const adrs = d.adrs || {};
564
- const hooks = d.hooks || {};
565
- const agentdb = d.agentdb || {};
566
- const tests = d.tests || {};
567
-
568
- const domainsCompleted = progress.domainsCompleted || 0;
569
- const totalDomains = progress.totalDomains || 5;
570
- const dddProgress = progress.dddProgress || 0;
571
- const patternsLearned = progress.patternsLearned || 0;
572
- const activeAgents = swarm.activeAgents || 0;
573
- const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
574
- const coordinationActive = swarm.coordinationActive || false;
575
- const intelligencePct = system.intelligencePct || 0;
576
- const memoryMB = system.memoryMB || 0;
577
- const subAgents = system.subAgents || 0;
578
- const cvesFixed = security.cvesFixed || 0;
579
- const totalCves = security.totalCves || 0;
580
- const secStatus = security.status || 'NONE';
581
- const adrCount = adrs.count || 0;
582
- const adrImpl = adrs.implemented || 0;
583
- const hooksEnabled = hooks.enabled || 0;
584
- const hooksTotal = hooks.total || 0;
585
- const vectorCount = agentdb.vectorCount || 0;
586
- const hasHnsw = agentdb.hasHnsw || false;
587
- const dbSizeKB = agentdb.dbSizeKB || 0;
588
- const testFiles = tests.testFiles || 0;
589
- const testCases = tests.testCases || testFiles * 4;
590
-
591
- const lines = [];
592
-
593
- // Header
594
- let header = c.bold + c.brightPurple + '▊ RuFlo V' + pkgVersion + ' ' + c.reset;
595
- header += (coordinationActive ? c.brightCyan : c.dim) + '● ' + c.brightCyan + git.name + c.reset;
596
- if (git.gitBranch) {
597
- header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightBlue + '⏇ ' + git.gitBranch + c.reset;
598
- const changes = git.modified + git.staged + git.untracked;
599
- if (changes > 0) {
600
- let ind = '';
601
- if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;
602
- if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;
603
- if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;
604
- header += ' ' + ind;
605
- }
606
- if (git.ahead > 0) header += ' ' + c.brightGreen + '↑' + git.ahead + c.reset;
607
- if (git.behind > 0) header += ' ' + c.brightRed + '↓' + git.behind + c.reset;
608
- }
609
- header += ' ' + c.dim + '│' + c.reset + ' ' + c.purple + modelName + c.reset;
610
- const duration = costInfo ? costInfo.duration : '';
611
- if (duration) header += ' ' + c.dim + '│' + c.reset + ' ' + c.cyan + '⏱ ' + duration + c.reset;
612
- if (ctxInfo && ctxInfo.usedPct > 0) {
613
- const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
614
- header += ' ' + c.dim + '│' + c.reset + ' ' + ctxColor + '● ' + ctxInfo.usedPct + '% ctx' + c.reset;
615
- }
616
- if (!CONFIG.hideCost && costInfo && costInfo.costUsd > 0) {
617
- header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightYellow + CONFIG.costSymbol + costInfo.costUsd.toFixed(2) + c.reset;
618
- }
619
- lines.push(header);
620
-
621
- // Separator
622
- lines.push(c.dim + '─'.repeat(53) + c.reset);
623
-
624
- // Line 1: DDD Domains
625
- const domainsColor = domainsCompleted >= 3 ? c.brightGreen : domainsCompleted > 0 ? c.yellow : c.red;
626
- let perfIndicator;
627
- if (hasHnsw && vectorCount > 0) {
628
- const speedup = vectorCount > 10000 ? '12500x' : vectorCount > 1000 ? '150x' : '10x';
629
- perfIndicator = c.brightGreen + '⚡ HNSW ' + speedup + c.reset;
630
- } else if (patternsLearned > 0) {
631
- const pk = patternsLearned >= 1000 ? (patternsLearned / 1000).toFixed(1) + 'k' : String(patternsLearned);
632
- perfIndicator = c.brightYellow + '📚 ' + pk + ' patterns' + c.reset;
633
- } else {
634
- perfIndicator = c.dim + '⚡ target: 150x-12500x' + c.reset;
635
- }
636
- lines.push(
637
- c.brightCyan + '🏗️ DDD Domains' + c.reset + ' ' + progressBar(domainsCompleted, totalDomains) + ' ' +
638
- domainsColor + domainsCompleted + c.reset + '/' + c.brightWhite + totalDomains + c.reset + ' ' + perfIndicator
639
- );
640
-
641
- // Line 2: Swarm + Hooks + CVE + Memory + Intelligence
642
- const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset : c.dim + '○' + c.reset;
643
- const agentsColor = activeAgents > 0 ? c.brightGreen : c.red;
644
- const secIcon = secStatus === 'CLEAN' ? '🟢' : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? '🟡' : (secStatus === 'NONE' ? '⚪' : '🔴');
645
- const secColor = secStatus === 'CLEAN' ? c.brightGreen : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? c.brightYellow : (secStatus === 'NONE' ? c.dim : c.brightRed);
646
- const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
647
- const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
648
-
649
- lines.push(
650
- c.brightYellow + '🤖 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + maxAgents + c.reset + '] ' +
651
- c.brightPurple + '👥 ' + subAgents + c.reset + ' ' +
652
- c.brightBlue + '🪝 ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset + ' ' +
653
- secIcon + ' ' + secColor + 'CVE ' + cvesFixed + c.reset + '/' + c.brightWhite + totalCves + c.reset + ' ' +
654
- c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset + ' ' +
655
- intellColor + '🧠 ' + String(intelligencePct).padStart(3) + '%' + c.reset
656
- );
657
-
658
- // Line 3: Architecture
659
- const dddColor = dddProgress >= 50 ? c.brightGreen : dddProgress > 0 ? c.yellow : c.red;
660
- const adrColor = adrCount > 0 ? (adrImpl === adrCount ? c.brightGreen : c.yellow) : c.dim;
661
- const adrDisplay = adrColor + '●' + adrImpl + '/' + adrCount + c.reset;
662
-
663
- lines.push(
664
- c.brightPurple + '🔧 Architecture' + c.reset + ' ' +
665
- c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '│' + c.reset + ' ' +
666
- c.cyan + 'DDD' + c.reset + ' ' + dddColor + '●' + String(dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
667
- c.cyan + 'Security' + c.reset + ' ' + secColor + '●' + secStatus + c.reset
668
- );
669
-
670
- // Line 4: AgentDB, Tests, Integration
671
- const hnswInd = hasHnsw ? c.brightGreen + '⚡' + c.reset : '';
672
- const sizeDisp = dbSizeKB >= 1024 ? (dbSizeKB / 1024).toFixed(1) + 'MB' : dbSizeKB + 'KB';
673
- const vectorColor = vectorCount > 0 ? c.brightGreen : c.dim;
674
- const testColor = testFiles > 0 ? c.brightGreen : c.dim;
675
-
676
- // MCP / DB integration from data
677
- const integration = d.integration || {};
678
- const mcpServers = (integration.mcpServers) || {};
679
- let integStr = '';
680
- if (mcpServers.total > 0) {
681
- const mcpCol = mcpServers.enabled === mcpServers.total ? c.brightGreen : mcpServers.enabled > 0 ? c.brightYellow : c.red;
682
- integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '●' + mcpServers.enabled + '/' + mcpServers.total + c.reset;
683
- }
684
- if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '◆' + c.reset + 'DB';
685
- if (!integStr) integStr = c.dim + '● none' + c.reset;
686
-
687
- lines.push(
688
- c.brightCyan + '📊 AgentDB' + c.reset + ' ' +
689
- c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '●' + vectorCount + hnswInd + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
690
- c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
691
- c.cyan + 'Tests' + c.reset + ' ' + testColor + '●' + testFiles + c.reset + ' ' + c.dim + '(~' + testCases + ' cases)' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
692
- integStr
693
- );
694
-
695
- return lines.join('\\n');
696
- }
697
-
698
- // JSON output — delegates to CLI for accuracy; caller can use --json flag
699
- function generateJSON() {
700
- const d = getStatuslineData();
701
- const git = getGitInfo();
702
- return Object.assign({}, d, {
703
- user: Object.assign({ name: git.name, gitBranch: git.gitBranch }, d.user || {}),
704
- git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
705
- lastUpdated: new Date().toISOString(),
706
- });
707
- }
708
-
709
- // ─── Main ───────────────────────────────────────────────────────
710
- if (process.argv.includes('--json')) {
711
- console.log(JSON.stringify(generateJSON(), null, 2));
712
- } else if (process.argv.includes('--compact')) {
713
- console.log(JSON.stringify(generateJSON()));
714
- } else {
715
- console.log(generateStatusline());
716
- }
24
+ return `#!/usr/bin/env node
25
+ /**
26
+ * RuFlo V3 Statusline — delegation build (#2195)
27
+ *
28
+ * Fix for ruvnet/ruflo#2195: the previous version re-implemented all data
29
+ * readers locally using fragile file probes that missed AgentDB patterns,
30
+ * the v3/docs/adr/ ADR directory, and the real vector count.
31
+ *
32
+ * This version delegates to 'npx @claude-flow/cli hooks statusline --json'
33
+ * as the single source of truth. That command queries AgentDB directly,
34
+ * counts ADRs in both directories, and reports the real intelligence pct.
35
+ *
36
+ * ADR counting falls back to local file reads so the display still works
37
+ * without network access (counts both v3/docs/adr/ and v3/implementation/adrs/).
38
+ *
39
+ * Cache: JSON result is cached in /tmp for 10s so rapid prompt triggers
40
+ * (every keystroke in some shells) don't hammer the CLI on every call.
41
+ *
42
+ * Usage: node statusline.cjs [--json] [--compact] [--dashboard]
43
+ */
44
+
45
+ /* eslint-disable @typescript-eslint/no-var-requires */
46
+ const fs = require('fs');
47
+ const path = require('path');
48
+ const { execSync } = require('child_process');
49
+ const os = require('os');
50
+
51
+ // Configuration
52
+ const CONFIG = {
53
+ maxAgents: ${maxAgents},
54
+ // Session-cost display. Claude Code's cost.total_cost_usd is a client-side
55
+ // estimate that "may differ from your actual bill" and reads as misleading on
56
+ // subscription plans, where token usage is not billed per dollar. These let
57
+ // each user pick what the segment means to them without changing the default.
58
+ // RUFLO_STATUSLINE_COST_SYMBOL override the leading '$' (e.g. ⚡, €, 🌱);
59
+ // set to an empty string for the number alone.
60
+ // RUFLO_STATUSLINE_HIDE_COST 1/true/yes/on removes the segment entirely.
61
+ costSymbol: process.env.RUFLO_STATUSLINE_COST_SYMBOL ?? '$',
62
+ hideCost: /^(1|true|yes|on)$/i.test(process.env.RUFLO_STATUSLINE_HIDE_COST || ''),
63
+ };
64
+
65
+ const CWD = process.cwd();
66
+
67
+ // ─── Delegation cache ───────────────────────────────────────────
68
+ // Cache the CLI JSON result for 60s so rapid prompt re-renders
69
+ // (Claude Code refreshes the statusline several times a second while
70
+ // streaming) don't re-invoke the CLI each time. #2337: bumped 10s→60s
71
+ // because 10s was far too short for how often Claude Code re-renders.
72
+ const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
73
+ const CACHE_TTL_MS = 60000;
74
+
75
+ // #2337: resolve an already-installed @claude-flow/cli (or ruflo) bin so we
76
+ // can invoke it directly via \`node\`. The previous version called
77
+ // \`npx --yes @claude-flow/cli@latest\` on every uncached render, which forces
78
+ // a registry resolution + cold-start of the entire CLI per render. With
79
+ // multiple concurrent Claude Code sessions this storms the host (reporter
80
+ // saw load average 40-65 on a 12-core box).
81
+ //
82
+ // Returns the absolute path to bin/cli.js or null. Mirrors getPkgVersion()'s
83
+ // path probing (project, monorepo, plugin marketplace, global node_modules
84
+ // including custom-prefix layouts like ~/.npm-global).
85
+ function resolveCliBin() {
86
+ try {
87
+ const home = os.homedir();
88
+ const candidates = [
89
+ path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'bin', 'cli.js'),
90
+ path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'bin', 'cli.js'),
91
+ path.join(CWD, 'node_modules', 'ruflo', 'bin', 'cli.js'),
92
+ path.join(CWD, 'v3', '@claude-flow', 'cli', 'bin', 'cli.js'),
93
+ ];
94
+ try {
95
+ const binDir = path.dirname(process.execPath);
96
+ const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
97
+ for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
98
+ if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
99
+ }
100
+ for (const gm of globalModuleDirs) {
101
+ candidates.push(
102
+ path.join(gm, 'ruflo', 'bin', 'cli.js'),
103
+ path.join(gm, '@claude-flow', 'cli', 'bin', 'cli.js'),
104
+ );
105
+ }
106
+ } catch { /* ignore */ }
107
+ for (const p of candidates) {
108
+ if (fs.existsSync(p)) return p;
109
+ }
110
+ } catch { /* ignore */ }
111
+ return null;
112
+ }
113
+
114
+ function readCache() {
115
+ try {
116
+ if (fs.existsSync(CACHE_FILE)) {
117
+ const raw = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
118
+ if (raw && raw._ts && (Date.now() - raw._ts) < CACHE_TTL_MS) {
119
+ return raw.data;
120
+ }
121
+ }
122
+ } catch { /* ignore */ }
123
+ return null;
124
+ }
125
+
126
+ function writeCache(data) {
127
+ try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ _ts: Date.now(), data }), 'utf-8'); } catch { /* ignore */ }
128
+ }
129
+
130
+ /**
131
+ * Single source of truth: delegate to the CLI hooks statusline --json command.
132
+ * Falls back to a minimal static object on failure so the statusline still renders.
133
+ *
134
+ * Fix for ruflo#2195: the previous local readers returned 0 for AgentDB patterns
135
+ * (missed the .swarm/memory.db → AgentDB path), computed dddProgress wrong,
136
+ * and only counted ADRs in v3/implementation/adrs/ (missed v3/docs/adr/).
137
+ */
138
+ function getStatuslineData() {
139
+ const cached = readCache();
140
+ if (cached) return cached;
141
+
142
+ try {
143
+ // #2337: prefer an already-installed CLI bin via direct \`node\` invocation
144
+ // — no npx, no registry round-trip, no @latest re-resolve per render.
145
+ // Fall back to \`npx --prefer-offline @claude-flow/cli\` (no @latest) only
146
+ // when nothing is installed locally, so a cold environment still works.
147
+ const cliBin = resolveCliBin();
148
+ const cmd = cliBin
149
+ ? '"' + process.execPath + '" "' + cliBin + '" hooks statusline --json 2>/dev/null'
150
+ : 'npx --prefer-offline @claude-flow/cli hooks statusline --json 2>/dev/null';
151
+ const raw = execSync(
152
+ cmd,
153
+ { encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
154
+ ).trim();
155
+ // The CLI may emit preamble lines before the JSON — find the first '{'.
156
+ const jsonStart = raw.indexOf('{');
157
+ if (jsonStart === -1) throw new Error('no JSON in CLI output');
158
+ const data = JSON.parse(raw.slice(jsonStart));
159
+ // Overlay every block the CLI JSON omits (adrs/agentdb/tests/hooks/integration)
160
+ // with real local reads, so those segments reflect actual state instead of 0.
161
+ applyLocalOverlays(data);
162
+ writeCache(data);
163
+ return data;
164
+ } catch { /* CLI unavailable or timed out */ }
165
+
166
+ // Fallback: use local file probes only (will be less accurate, but non-zero
167
+ // when CLI is available and accurate when it's not).
168
+ return buildLocalFallback();
169
+ }
170
+
171
+ // Count ADRs from BOTH known directories (fix for ruflo#2195: old code missed
172
+ // v3/docs/adr/ which holds ADR-088..ADR-137, i.e. 41 of the 128 total ADRs).
173
+ function getLocalADRCount() {
174
+ const adrDirs = [
175
+ path.join(CWD, 'v3', 'implementation', 'adrs'),
176
+ path.join(CWD, 'v3', 'docs', 'adr'),
177
+ path.join(CWD, 'docs', 'adrs'),
178
+ path.join(CWD, '.claude-flow', 'adrs'),
179
+ ];
180
+ let total = 0;
181
+ for (const dir of adrDirs) {
182
+ try {
183
+ if (fs.existsSync(dir)) {
184
+ const files = fs.readdirSync(dir).filter(function(f) {
185
+ return f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f));
186
+ });
187
+ total += files.length;
188
+ }
189
+ } catch { /* ignore */ }
190
+ }
191
+ return { count: total, implemented: total, compliance: 0 };
192
+ }
193
+
194
+ // ─── Local overlays for segments the CLI JSON omits ──────────────
195
+ // 'hooks statusline --json' only returns user/v3Progress/security/swarm/system.
196
+ // agentdb/tests/hooks/integration are never populated, so without these overlays
197
+ // they render as a permanent 0. Each reader is cheap and degrades to zeros.
198
+
199
+ // Real AgentDB stats from the local memory DB. Vectors live in .swarm/memory.db
200
+ // (sql.js + HNSW); ruvector.db is an opaque redb store counted only toward size.
201
+ // One read-only sqlite3 query (mode=ro never takes a write lock the daemon owns).
202
+ function getLocalAgentDB() {
203
+ const result = { vectorCount: 0, dbSizeKB: 0, hasHnsw: false };
204
+ try {
205
+ let bytes = 0;
206
+ for (const f of ['.swarm/memory.db', 'ruvector.db']) {
207
+ try { bytes += fs.statSync(path.join(CWD, f)).size; } catch { /* missing */ }
208
+ }
209
+ result.dbSizeKB = Math.round(bytes / 1024);
210
+
211
+ const memDb = path.join(CWD, '.swarm', 'memory.db');
212
+ if (fs.existsSync(memDb)) {
213
+ const Q = String.fromCharCode(34);
214
+ const sql = Q + 'SELECT (SELECT COUNT(*) FROM memory_entries WHERE embedding IS NOT NULL)||' + "'|'" + '||(SELECT COUNT(*) FROM vector_indexes);' + Q;
215
+ const out = safeExec("sqlite3 'file:" + memDb + "?mode=ro' " + sql, 1500);
216
+ if (out && out.indexOf('|') !== -1) {
217
+ const parts = out.split('|');
218
+ result.vectorCount = parseInt(parts[0], 10) || 0;
219
+ result.hasHnsw = (parseInt(parts[1], 10) || 0) > 0;
220
+ }
221
+ }
222
+ } catch { /* ignore */ }
223
+ return result;
224
+ }
225
+
226
+ // Count test files via a bounded directory walk (no file reads).
227
+ function getLocalTests() {
228
+ let testFiles = 0;
229
+ function countTests(dir, depth) {
230
+ if ((depth || 0) > 4) return;
231
+ try {
232
+ if (!fs.existsSync(dir)) return;
233
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
234
+ if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules') {
235
+ countTests(path.join(dir, e.name), (depth || 0) + 1);
236
+ } else if (e.isFile() && (e.name.includes('.test.') || e.name.includes('.spec.') || e.name.startsWith('test_') || e.name.startsWith('spec_'))) {
237
+ testFiles++;
238
+ }
239
+ }
240
+ } catch { /* ignore */ }
241
+ }
242
+ for (const d of ['tests', 'test', '__tests__', 'src', 'v3']) countTests(path.join(CWD, d));
243
+ return { testFiles, testCases: testFiles * 4 };
244
+ }
245
+
246
+ // Count configured hooks from project .claude/settings.json. Claude Code hooks
247
+ // have no enabled/disabled flag, so every configured hook counts as enabled.
248
+ function getLocalHooks() {
249
+ const result = { enabled: 0, total: 0 };
250
+ try {
251
+ const settings = readJSON(path.join(CWD, '.claude', 'settings.json'));
252
+ const hooks = settings && settings.hooks;
253
+ if (hooks && typeof hooks === 'object') {
254
+ let n = 0;
255
+ for (const ev of Object.keys(hooks)) {
256
+ const groups = hooks[ev];
257
+ if (Array.isArray(groups)) {
258
+ for (const g of groups) {
259
+ if (g && Array.isArray(g.hooks)) n += g.hooks.length;
260
+ }
261
+ }
262
+ }
263
+ result.total = n;
264
+ result.enabled = n;
265
+ }
266
+ } catch { /* ignore */ }
267
+ return result;
268
+ }
269
+
270
+ // Best-effort integration block: DB presence + locally-configured stdio MCP
271
+ // servers (project .mcp.json + global ~/.claude.json). Remote connectors are
272
+ // account-managed and not present in local config, so they are not counted.
273
+ function getLocalIntegration() {
274
+ const integration = { mcpServers: { enabled: 0, total: 0 }, hasDatabase: false };
275
+ try {
276
+ for (const f of ['.swarm/memory.db', 'ruvector.db']) {
277
+ if (fs.existsSync(path.join(CWD, f))) { integration.hasDatabase = true; break; }
278
+ }
279
+ const names = new Set();
280
+ const projMcp = readJSON(path.join(CWD, '.mcp.json'));
281
+ if (projMcp && projMcp.mcpServers) for (const k of Object.keys(projMcp.mcpServers)) names.add(k);
282
+ const claudeJson = readJSON(path.join(os.homedir(), '.claude.json'));
283
+ if (claudeJson) {
284
+ if (claudeJson.mcpServers) for (const k of Object.keys(claudeJson.mcpServers)) names.add(k);
285
+ const proj = claudeJson.projects && claudeJson.projects[CWD];
286
+ if (proj && proj.mcpServers && !Array.isArray(proj.mcpServers)) {
287
+ for (const k of Object.keys(proj.mcpServers)) names.add(k);
288
+ }
289
+ }
290
+ integration.mcpServers.total = names.size;
291
+ integration.mcpServers.enabled = names.size;
292
+ } catch { /* ignore */ }
293
+ return integration;
294
+ }
295
+
296
+ // Overlay every locally-derived block onto the CLI data (mutates in place).
297
+ function applyLocalOverlays(data) {
298
+ data.adrs = getLocalADRCount();
299
+ data.agentdb = getLocalAgentDB();
300
+ data.tests = getLocalTests();
301
+ data.hooks = getLocalHooks();
302
+ data.integration = getLocalIntegration();
303
+ return data;
304
+ }
305
+
306
+ // Minimal local fallback when the CLI is not installed or times out.
307
+ // Returns a structure that matches the CLI JSON schema so the renderer works.
308
+ function buildLocalFallback() {
309
+ const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
310
+
311
+ return applyLocalOverlays({
312
+ user: { name: 'user', gitBranch: '', modelName: 'Claude Code' },
313
+ v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
314
+ security: { status: 'NONE', cvesFixed: 0, totalCves: 0 },
315
+ swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
316
+ system: { memoryMB: memMB, contextPct: 0, intelligencePct: 0, subAgents: 0 },
317
+ lastUpdated: new Date().toISOString(),
318
+ });
319
+ }
320
+
321
+ // ANSI colors
322
+ const c = {
323
+ reset: '\\x1b[0m',
324
+ bold: '\\x1b[1m',
325
+ dim: '\\x1b[2m',
326
+ red: '\\x1b[0;31m',
327
+ green: '\\x1b[0;32m',
328
+ yellow: '\\x1b[0;33m',
329
+ blue: '\\x1b[0;34m',
330
+ purple: '\\x1b[0;35m',
331
+ cyan: '\\x1b[0;36m',
332
+ brightRed: '\\x1b[1;31m',
333
+ brightGreen: '\\x1b[1;32m',
334
+ brightYellow: '\\x1b[1;33m',
335
+ brightBlue: '\\x1b[1;34m',
336
+ brightPurple: '\\x1b[1;35m',
337
+ brightCyan: '\\x1b[1;36m',
338
+ brightWhite: '\\x1b[1;37m',
339
+ };
340
+
341
+ // Safe execSync with strict timeout (returns empty string on failure)
342
+ function safeExec(cmd, timeoutMs) {
343
+ try {
344
+ return execSync(cmd, {
345
+ encoding: 'utf-8',
346
+ timeout: timeoutMs || 2000,
347
+ stdio: ['pipe', 'pipe', 'pipe'],
348
+ }).trim();
349
+ } catch {
350
+ return '';
351
+ }
352
+ }
353
+
354
+ // Safe JSON file reader (returns null on failure)
355
+ function readJSON(filePath) {
356
+ try {
357
+ if (fs.existsSync(filePath)) {
358
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
359
+ }
360
+ } catch { /* ignore */ }
361
+ return null;
362
+ }
363
+
364
+ // ─── Git info (pure-Node / single exec — needed for branch display) ──────────
365
+
366
+ function getGitInfo() {
367
+ const result = {
368
+ name: 'user', gitBranch: '', modified: 0, untracked: 0,
369
+ staged: 0, ahead: 0, behind: 0,
370
+ };
371
+
372
+ const script = [
373
+ 'git config user.name 2>/dev/null || echo user',
374
+ 'echo "---SEP---"',
375
+ 'git branch --show-current 2>/dev/null',
376
+ 'echo "---SEP---"',
377
+ 'git status --porcelain 2>/dev/null',
378
+ 'echo "---SEP---"',
379
+ 'git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo "0 0"',
380
+ ].join('; ');
381
+
382
+ const raw = safeExec("sh -c '" + script + "'", 3000);
383
+ if (!raw) return result;
384
+
385
+ const parts = raw.split('---SEP---').map(function(s) { return s.trim(); });
386
+ if (parts.length >= 4) {
387
+ result.name = parts[0] || 'user';
388
+ result.gitBranch = parts[1] || '';
389
+
390
+ if (parts[2]) {
391
+ for (const line of parts[2].split('\\n')) {
392
+ if (!line || line.length < 2) continue;
393
+ const x = line[0], y = line[1];
394
+ if (x === '?' && y === '?') { result.untracked++; continue; }
395
+ if (x !== ' ' && x !== '?') result.staged++;
396
+ if (y !== ' ' && y !== '?') result.modified++;
397
+ }
398
+ }
399
+
400
+ const ab = (parts[3] || '0 0').split(/\\s+/);
401
+ result.ahead = parseInt(ab[0]) || 0;
402
+ result.behind = parseInt(ab[1]) || 0;
403
+ }
404
+
405
+ return result;
406
+ }
407
+
408
+ // Detect model name from Claude config (pure file reads, no exec)
409
+ function getModelName() {
410
+ try {
411
+ const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));
412
+ if (claudeConfig && claudeConfig.projects) {
413
+ for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
414
+ if (CWD === projectPath || CWD.startsWith(projectPath + '/')) {
415
+ const usage = projectConfig.lastModelUsage;
416
+ if (usage) {
417
+ const ids = Object.keys(usage);
418
+ if (ids.length > 0) {
419
+ let modelId = ids[ids.length - 1];
420
+ let latest = 0;
421
+ for (const id of ids) {
422
+ const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;
423
+ if (ts > latest) { latest = ts; modelId = id; }
424
+ }
425
+ if (modelId.includes('opus')) return 'Opus 4.8';
426
+ if (modelId.includes('sonnet')) return 'Sonnet 4.6';
427
+ if (modelId.includes('haiku')) return 'Haiku 4.5';
428
+ return modelId.split('-').slice(1, 3).join(' ');
429
+ }
430
+ }
431
+ break;
432
+ }
433
+ }
434
+ }
435
+ } catch { /* ignore */ }
436
+
437
+ // Fallback: settings.json model field
438
+ const settings = getSettings();
439
+ if (settings && settings.model) {
440
+ const m = settings.model;
441
+ if (m.includes('opus')) return 'Opus 4.8';
442
+ if (m.includes('sonnet')) return 'Sonnet 4.6';
443
+ if (m.includes('haiku')) return 'Haiku 4.5';
444
+ }
445
+ return 'Claude Code';
446
+ }
447
+
448
+ // ─── Stdin reader (Claude Code pipes session JSON) ──────────────
449
+ // Claude Code sends session JSON via stdin. Read synchronously so the
450
+ // script works both when invoked by Claude Code (stdin has JSON) and
451
+ // when run manually from terminal (stdin is empty/tty).
452
+ let _stdinData = null;
453
+ function getStdinData() {
454
+ if (_stdinData !== undefined && _stdinData !== null) return _stdinData;
455
+ try {
456
+ if (process.stdin.isTTY) { _stdinData = null; return null; }
457
+ const chunks = [];
458
+ const buf = Buffer.alloc(4096);
459
+ let bytesRead;
460
+ try {
461
+ while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {
462
+ chunks.push(buf.slice(0, bytesRead));
463
+ }
464
+ } catch { /* EOF or read error */ }
465
+ const raw = Buffer.concat(chunks).toString('utf-8').trim();
466
+ _stdinData = (raw && raw.startsWith('{')) ? JSON.parse(raw) : null;
467
+ } catch {
468
+ _stdinData = null;
469
+ }
470
+ return _stdinData;
471
+ }
472
+
473
+ function getModelFromStdin() {
474
+ const data = getStdinData();
475
+ return (data && data.model && data.model.display_name) ? data.model.display_name : null;
476
+ }
477
+
478
+ function getContextFromStdin() {
479
+ const data = getStdinData();
480
+ if (data && data.context_window) {
481
+ return { usedPct: Math.floor(data.context_window.used_percentage || 0) };
482
+ }
483
+ return null;
484
+ }
485
+
486
+ function getCostFromStdin() {
487
+ const data = getStdinData();
488
+ if (data && data.cost) {
489
+ const durationMs = data.cost.total_duration_ms || 0;
490
+ const mins = Math.floor(durationMs / 60000);
491
+ const secs = Math.floor((durationMs % 60000) / 1000);
492
+ return {
493
+ costUsd: data.cost.total_cost_usd || 0,
494
+ duration: mins > 0 ? mins + 'm' + secs + 's' : secs + 's',
495
+ };
496
+ }
497
+ return null;
498
+ }
499
+
500
+ // Read package version from the first package.json we find.
501
+ function getPkgVersion() {
502
+ let ver = '3.6';
503
+ try {
504
+ const home = os.homedir();
505
+ const pkgPaths = [
506
+ path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'package.json'),
507
+ path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'package.json'),
508
+ path.join(CWD, 'node_modules', 'ruflo', 'package.json'),
509
+ path.join(CWD, 'v3', '@claude-flow', 'cli', 'package.json'),
510
+ ];
511
+ // #2221: global installs (npm i -g ruflo) live outside CWD/node_modules, so the
512
+ // probes above all miss and the version falls back to the hard-coded default.
513
+ // Derive the global node_modules dir from the running node binary (no npm spawn —
514
+ // statusline renders often). Covers nvm/mise (bin/../lib/node_modules) and Windows
515
+ // (bin/node_modules) layouts.
516
+ try {
517
+ const binDir = path.dirname(process.execPath);
518
+ const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
519
+ // #2221 follow-up: a custom npm prefix (e.g. ~/.npm-global) is decoupled from
520
+ // the node binary location, so the binDir-derived probes above all miss. Also
521
+ // probe the npm prefix from the environment and the common ~/.npm-global default.
522
+ for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
523
+ if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
524
+ }
525
+ for (const gm of globalModuleDirs) {
526
+ pkgPaths.push(
527
+ path.join(gm, 'ruflo', 'package.json'),
528
+ path.join(gm, '@claude-flow', 'cli', 'package.json'),
529
+ );
530
+ }
531
+ } catch { /* ignore */ }
532
+ for (const p of pkgPaths) {
533
+ if (!fs.existsSync(p)) continue;
534
+ try {
535
+ const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
536
+ if (pkg && typeof pkg.version === 'string' && pkg.version.length > 0) { ver = pkg.version; break; }
537
+ } catch { /* ignore */ }
538
+ }
539
+ } catch { /* ignore */ }
540
+ return ver;
541
+ }
542
+
543
+ // ─── Rendering ──────────────────────────────────────────────────
544
+
545
+ function progressBar(current, total) {
546
+ const width = 5;
547
+ const filled = Math.round((current / total) * width);
548
+ return '[' + '●'.repeat(filled) + '○'.repeat(width - filled) + ']';
549
+ }
550
+
551
+ function generateStatusline() {
552
+ const d = getStatuslineData();
553
+ const git = getGitInfo();
554
+ const modelName = getModelFromStdin() || (d.user && d.user.modelName) || 'Claude Code';
555
+ const ctxInfo = getContextFromStdin();
556
+ const costInfo = getCostFromStdin();
557
+ const pkgVersion = getPkgVersion();
558
+
559
+ const progress = d.v3Progress || {};
560
+ const security = d.security || {};
561
+ const swarm = d.swarm || {};
562
+ const system = d.system || {};
563
+ const adrs = d.adrs || {};
564
+ const hooks = d.hooks || {};
565
+ const agentdb = d.agentdb || {};
566
+ const tests = d.tests || {};
567
+
568
+ const domainsCompleted = progress.domainsCompleted || 0;
569
+ const totalDomains = progress.totalDomains || 5;
570
+ const dddProgress = progress.dddProgress || 0;
571
+ const patternsLearned = progress.patternsLearned || 0;
572
+ const activeAgents = swarm.activeAgents || 0;
573
+ const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
574
+ const coordinationActive = swarm.coordinationActive || false;
575
+ const intelligencePct = system.intelligencePct || 0;
576
+ const memoryMB = system.memoryMB || 0;
577
+ const subAgents = system.subAgents || 0;
578
+ const cvesFixed = security.cvesFixed || 0;
579
+ const totalCves = security.totalCves || 0;
580
+ const secStatus = security.status || 'NONE';
581
+ const adrCount = adrs.count || 0;
582
+ const adrImpl = adrs.implemented || 0;
583
+ const hooksEnabled = hooks.enabled || 0;
584
+ const hooksTotal = hooks.total || 0;
585
+ const vectorCount = agentdb.vectorCount || 0;
586
+ const hasHnsw = agentdb.hasHnsw || false;
587
+ const dbSizeKB = agentdb.dbSizeKB || 0;
588
+ const testFiles = tests.testFiles || 0;
589
+ const testCases = tests.testCases || testFiles * 4;
590
+
591
+ const lines = [];
592
+
593
+ // Header
594
+ let header = c.bold + c.brightPurple + '▊ RuFlo V' + pkgVersion + ' ' + c.reset;
595
+ header += (coordinationActive ? c.brightCyan : c.dim) + '● ' + c.brightCyan + git.name + c.reset;
596
+ if (git.gitBranch) {
597
+ header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightBlue + '⏇ ' + git.gitBranch + c.reset;
598
+ const changes = git.modified + git.staged + git.untracked;
599
+ if (changes > 0) {
600
+ let ind = '';
601
+ if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;
602
+ if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;
603
+ if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;
604
+ header += ' ' + ind;
605
+ }
606
+ if (git.ahead > 0) header += ' ' + c.brightGreen + '↑' + git.ahead + c.reset;
607
+ if (git.behind > 0) header += ' ' + c.brightRed + '↓' + git.behind + c.reset;
608
+ }
609
+ header += ' ' + c.dim + '│' + c.reset + ' ' + c.purple + modelName + c.reset;
610
+ const duration = costInfo ? costInfo.duration : '';
611
+ if (duration) header += ' ' + c.dim + '│' + c.reset + ' ' + c.cyan + '⏱ ' + duration + c.reset;
612
+ if (ctxInfo && ctxInfo.usedPct > 0) {
613
+ const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
614
+ header += ' ' + c.dim + '│' + c.reset + ' ' + ctxColor + '● ' + ctxInfo.usedPct + '% ctx' + c.reset;
615
+ }
616
+ if (!CONFIG.hideCost && costInfo && costInfo.costUsd > 0) {
617
+ header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightYellow + CONFIG.costSymbol + costInfo.costUsd.toFixed(2) + c.reset;
618
+ }
619
+ lines.push(header);
620
+
621
+ // Separator
622
+ lines.push(c.dim + '─'.repeat(53) + c.reset);
623
+
624
+ // Line 1: DDD Domains
625
+ const domainsColor = domainsCompleted >= 3 ? c.brightGreen : domainsCompleted > 0 ? c.yellow : c.red;
626
+ let perfIndicator;
627
+ if (hasHnsw && vectorCount > 0) {
628
+ const speedup = vectorCount > 10000 ? '12500x' : vectorCount > 1000 ? '150x' : '10x';
629
+ perfIndicator = c.brightGreen + '⚡ HNSW ' + speedup + c.reset;
630
+ } else if (patternsLearned > 0) {
631
+ const pk = patternsLearned >= 1000 ? (patternsLearned / 1000).toFixed(1) + 'k' : String(patternsLearned);
632
+ perfIndicator = c.brightYellow + '📚 ' + pk + ' patterns' + c.reset;
633
+ } else {
634
+ perfIndicator = c.dim + '⚡ target: 150x-12500x' + c.reset;
635
+ }
636
+ lines.push(
637
+ c.brightCyan + '🏗️ DDD Domains' + c.reset + ' ' + progressBar(domainsCompleted, totalDomains) + ' ' +
638
+ domainsColor + domainsCompleted + c.reset + '/' + c.brightWhite + totalDomains + c.reset + ' ' + perfIndicator
639
+ );
640
+
641
+ // Line 2: Swarm + Hooks + CVE + Memory + Intelligence
642
+ const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset : c.dim + '○' + c.reset;
643
+ const agentsColor = activeAgents > 0 ? c.brightGreen : c.red;
644
+ const secIcon = secStatus === 'CLEAN' ? '🟢' : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? '🟡' : (secStatus === 'NONE' ? '⚪' : '🔴');
645
+ const secColor = secStatus === 'CLEAN' ? c.brightGreen : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? c.brightYellow : (secStatus === 'NONE' ? c.dim : c.brightRed);
646
+ const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
647
+ const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
648
+
649
+ lines.push(
650
+ c.brightYellow + '🤖 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + maxAgents + c.reset + '] ' +
651
+ c.brightPurple + '👥 ' + subAgents + c.reset + ' ' +
652
+ c.brightBlue + '🪝 ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset + ' ' +
653
+ secIcon + ' ' + secColor + 'CVE ' + cvesFixed + c.reset + '/' + c.brightWhite + totalCves + c.reset + ' ' +
654
+ c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset + ' ' +
655
+ intellColor + '🧠 ' + String(intelligencePct).padStart(3) + '%' + c.reset
656
+ );
657
+
658
+ // Line 3: Architecture
659
+ const dddColor = dddProgress >= 50 ? c.brightGreen : dddProgress > 0 ? c.yellow : c.red;
660
+ const adrColor = adrCount > 0 ? (adrImpl === adrCount ? c.brightGreen : c.yellow) : c.dim;
661
+ const adrDisplay = adrColor + '●' + adrImpl + '/' + adrCount + c.reset;
662
+
663
+ lines.push(
664
+ c.brightPurple + '🔧 Architecture' + c.reset + ' ' +
665
+ c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '│' + c.reset + ' ' +
666
+ c.cyan + 'DDD' + c.reset + ' ' + dddColor + '●' + String(dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
667
+ c.cyan + 'Security' + c.reset + ' ' + secColor + '●' + secStatus + c.reset
668
+ );
669
+
670
+ // Line 4: AgentDB, Tests, Integration
671
+ const hnswInd = hasHnsw ? c.brightGreen + '⚡' + c.reset : '';
672
+ const sizeDisp = dbSizeKB >= 1024 ? (dbSizeKB / 1024).toFixed(1) + 'MB' : dbSizeKB + 'KB';
673
+ const vectorColor = vectorCount > 0 ? c.brightGreen : c.dim;
674
+ const testColor = testFiles > 0 ? c.brightGreen : c.dim;
675
+
676
+ // MCP / DB integration from data
677
+ const integration = d.integration || {};
678
+ const mcpServers = (integration.mcpServers) || {};
679
+ let integStr = '';
680
+ if (mcpServers.total > 0) {
681
+ const mcpCol = mcpServers.enabled === mcpServers.total ? c.brightGreen : mcpServers.enabled > 0 ? c.brightYellow : c.red;
682
+ integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '●' + mcpServers.enabled + '/' + mcpServers.total + c.reset;
683
+ }
684
+ if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '◆' + c.reset + 'DB';
685
+ if (!integStr) integStr = c.dim + '● none' + c.reset;
686
+
687
+ lines.push(
688
+ c.brightCyan + '📊 AgentDB' + c.reset + ' ' +
689
+ c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '●' + vectorCount + hnswInd + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
690
+ c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
691
+ c.cyan + 'Tests' + c.reset + ' ' + testColor + '●' + testFiles + c.reset + ' ' + c.dim + '(~' + testCases + ' cases)' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
692
+ integStr
693
+ );
694
+
695
+ return lines.join('\\n');
696
+ }
697
+
698
+ // JSON output — delegates to CLI for accuracy; caller can use --json flag
699
+ function generateJSON() {
700
+ const d = getStatuslineData();
701
+ const git = getGitInfo();
702
+ return Object.assign({}, d, {
703
+ user: Object.assign({ name: git.name, gitBranch: git.gitBranch }, d.user || {}),
704
+ git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
705
+ lastUpdated: new Date().toISOString(),
706
+ });
707
+ }
708
+
709
+ // ─── Main ───────────────────────────────────────────────────────
710
+ if (process.argv.includes('--json')) {
711
+ console.log(JSON.stringify(generateJSON(), null, 2));
712
+ } else if (process.argv.includes('--compact')) {
713
+ console.log(JSON.stringify(generateJSON()));
714
+ } else {
715
+ console.log(generateStatusline());
716
+ }
717
717
  `;
718
718
  }
719
719
  /**
@@ -723,30 +723,30 @@ export function generateStatuslineHook(options) {
723
723
  if (!options.statusline.enabled) {
724
724
  return '#!/bin/bash\n# Statusline disabled\n';
725
725
  }
726
- return `#!/bin/bash
727
- # RuFlo V3 Statusline Hook
728
- # Source this in your .bashrc/.zshrc for terminal statusline
729
-
730
- # Function to get statusline
731
- claude_flow_statusline() {
732
- local statusline_script="\${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs"
733
- if [ -f "$statusline_script" ]; then
734
- node "$statusline_script" 2>/dev/null || echo ""
735
- fi
736
- }
737
-
738
- # Bash: Add to PS1
739
- # export PS1='$(claude_flow_statusline) \\n\\$ '
740
-
741
- # Zsh: Add to RPROMPT
742
- # export RPROMPT='$(claude_flow_statusline)'
743
-
744
- # Claude Code: Add to .claude/settings.json
745
- # "statusLine": {
746
- # "type": "command",
747
- # "command": "node .claude/helpers/statusline.cjs 2>/dev/null"
748
- # "when": "test -f .claude/helpers/statusline.cjs"
749
- # }
726
+ return `#!/bin/bash
727
+ # RuFlo V3 Statusline Hook
728
+ # Source this in your .bashrc/.zshrc for terminal statusline
729
+
730
+ # Function to get statusline
731
+ claude_flow_statusline() {
732
+ local statusline_script="\${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs"
733
+ if [ -f "$statusline_script" ]; then
734
+ node "$statusline_script" 2>/dev/null || echo ""
735
+ fi
736
+ }
737
+
738
+ # Bash: Add to PS1
739
+ # export PS1='$(claude_flow_statusline) \\n\\$ '
740
+
741
+ # Zsh: Add to RPROMPT
742
+ # export RPROMPT='$(claude_flow_statusline)'
743
+
744
+ # Claude Code: Add to .claude/settings.json
745
+ # "statusLine": {
746
+ # "type": "command",
747
+ # "command": "node .claude/helpers/statusline.cjs 2>/dev/null"
748
+ # "when": "test -f .claude/helpers/statusline.cjs"
749
+ # }
750
750
  `;
751
751
  }
752
752
  //# sourceMappingURL=statusline-generator.js.map