kynjal-cli 3.1.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/.claude/agents/core/coder.md +1 -1
  2. package/.claude/agents/core/planner.md +2 -2
  3. package/.claude/agents/core/researcher.md +1 -1
  4. package/.claude/agents/core/reviewer.md +1 -1
  5. package/.claude/agents/core/tester.md +1 -1
  6. package/.claude/agents/data/data-ml-model.md +4 -4
  7. package/.claude/agents/development/dev-backend-api.md +4 -4
  8. package/.claude/agents/documentation/docs-api-openapi.md +4 -4
  9. package/.claude/agents/github/code-review-swarm.md +2 -2
  10. package/.claude/agents/github/issue-tracker.md +2 -2
  11. package/.claude/agents/github/pr-manager.md +2 -2
  12. package/.claude/agents/github/release-manager.md +2 -2
  13. package/.claude/agents/github/workflow-automation.md +2 -2
  14. package/.claude/agents/sparc/architecture.md +3 -3
  15. package/.claude/agents/sparc/pseudocode.md +2 -2
  16. package/.claude/agents/sparc/refinement.md +3 -3
  17. package/.claude/agents/sparc/specification.md +2 -2
  18. package/.claude/agents/swarm/adaptive-coordinator.md +1 -1
  19. package/.claude/agents/swarm/hierarchical-coordinator.md +1 -1
  20. package/.claude/agents/swarm/mesh-coordinator.md +1 -1
  21. package/.claude/agents/templates/base-template-generator.md +25 -4
  22. package/.claude/agents/templates/sparc-coordinator.md +3 -3
  23. package/.claude/helpers/auto-commit.sh +1 -1
  24. package/.claude/helpers/auto-memory-hook.mjs +27 -9
  25. package/.claude/helpers/hook-handler.cjs +58 -18
  26. package/.claude/helpers/statusline.cjs +14 -33
  27. package/.claude/helpers/statusline.js +3 -3
  28. package/.claude/settings.json +9 -9
  29. package/.claude/skills/reasoningbank-intelligence/SKILL.md +2 -2
  30. package/.claude/skills/swarm-orchestration/SKILL.md +1 -1
  31. package/README.md +383 -170
  32. package/bin/cli.js +6 -6
  33. package/bin/mcp-server.js +1 -1
  34. package/bin/preinstall.cjs +2 -0
  35. package/dist/src/appliance/gguf-engine.js +664 -0
  36. package/dist/src/appliance/gguf-engine.js.map +1 -0
  37. package/dist/src/appliance/ruvllm-bridge.js +492 -0
  38. package/dist/src/appliance/ruvllm-bridge.js.map +1 -0
  39. package/dist/src/appliance/rvfa-builder.js +383 -0
  40. package/dist/src/appliance/rvfa-builder.js.map +1 -0
  41. package/dist/src/appliance/rvfa-distribution.js +533 -0
  42. package/dist/src/appliance/rvfa-distribution.js.map +1 -0
  43. package/dist/src/appliance/rvfa-format.js +465 -0
  44. package/dist/src/appliance/rvfa-format.js.map +1 -0
  45. package/dist/src/appliance/rvfa-runner.js +373 -0
  46. package/dist/src/appliance/rvfa-runner.js.map +1 -0
  47. package/dist/src/appliance/rvfa-signing.js +469 -0
  48. package/dist/src/appliance/rvfa-signing.js.map +1 -0
  49. package/dist/src/benchmarks/pretrain/index.js +542 -331
  50. package/dist/src/benchmarks/pretrain/index.js.map +1 -1
  51. package/dist/src/commands/agent.d.ts.map +1 -1
  52. package/dist/src/commands/agent.js +725 -502
  53. package/dist/src/commands/agent.js.map +1 -1
  54. package/dist/src/commands/analyze.js +1548 -1218
  55. package/dist/src/commands/analyze.js.map +1 -1
  56. package/dist/src/commands/appliance-advanced.d.ts +9 -0
  57. package/dist/src/commands/appliance-advanced.d.ts.map +1 -0
  58. package/dist/src/commands/appliance-advanced.js +324 -0
  59. package/dist/src/commands/appliance-advanced.js.map +1 -0
  60. package/dist/src/commands/appliance.d.ts +8 -0
  61. package/dist/src/commands/appliance.d.ts.map +1 -0
  62. package/dist/src/commands/appliance.js +581 -0
  63. package/dist/src/commands/appliance.js.map +1 -0
  64. package/dist/src/commands/benchmark.js +523 -372
  65. package/dist/src/commands/benchmark.js.map +1 -1
  66. package/dist/src/commands/claims.js +364 -274
  67. package/dist/src/commands/claims.js.map +1 -1
  68. package/dist/src/commands/cleanup.d.ts +13 -0
  69. package/dist/src/commands/cleanup.d.ts.map +1 -0
  70. package/dist/src/commands/cleanup.js +262 -0
  71. package/dist/src/commands/cleanup.js.map +1 -0
  72. package/dist/src/commands/completions.js +118 -477
  73. package/dist/src/commands/completions.js.map +1 -1
  74. package/dist/src/commands/config.js +303 -237
  75. package/dist/src/commands/config.js.map +1 -1
  76. package/dist/src/commands/daemon.d.ts.map +1 -1
  77. package/dist/src/commands/daemon.js +597 -425
  78. package/dist/src/commands/daemon.js.map +1 -1
  79. package/dist/src/commands/deployment.js +275 -194
  80. package/dist/src/commands/deployment.js.map +1 -1
  81. package/dist/src/commands/doctor.d.ts.map +1 -1
  82. package/dist/src/commands/doctor.js +690 -460
  83. package/dist/src/commands/doctor.js.map +1 -1
  84. package/dist/src/commands/embeddings.js +1543 -1293
  85. package/dist/src/commands/embeddings.js.map +1 -1
  86. package/dist/src/commands/guidance.js +596 -449
  87. package/dist/src/commands/guidance.js.map +1 -1
  88. package/dist/src/commands/hive-mind.js +938 -854
  89. package/dist/src/commands/hive-mind.js.map +1 -1
  90. package/dist/src/commands/hooks.d.ts.map +1 -1
  91. package/dist/src/commands/hooks.js +3677 -2570
  92. package/dist/src/commands/hooks.js.map +1 -1
  93. package/dist/src/commands/index.js +322 -122
  94. package/dist/src/commands/index.js.map +1 -1
  95. package/dist/src/commands/init.d.ts +1 -1
  96. package/dist/src/commands/init.d.ts.map +1 -1
  97. package/dist/src/commands/init.js +943 -787
  98. package/dist/src/commands/init.js.map +1 -1
  99. package/dist/src/commands/issues.js +558 -383
  100. package/dist/src/commands/issues.js.map +1 -1
  101. package/dist/src/commands/mcp.d.ts.map +1 -1
  102. package/dist/src/commands/mcp.js +605 -475
  103. package/dist/src/commands/mcp.js.map +1 -1
  104. package/dist/src/commands/memory.d.ts.map +1 -1
  105. package/dist/src/commands/memory.js +1031 -814
  106. package/dist/src/commands/memory.js.map +1 -1
  107. package/dist/src/commands/migrate.js +347 -282
  108. package/dist/src/commands/migrate.js.map +1 -1
  109. package/dist/src/commands/neural.d.ts.map +1 -1
  110. package/dist/src/commands/neural.js +1563 -1283
  111. package/dist/src/commands/neural.js.map +1 -1
  112. package/dist/src/commands/performance.js +643 -497
  113. package/dist/src/commands/performance.js.map +1 -1
  114. package/dist/src/commands/plugins.js +841 -668
  115. package/dist/src/commands/plugins.js.map +1 -1
  116. package/dist/src/commands/process.js +447 -392
  117. package/dist/src/commands/process.js.map +1 -1
  118. package/dist/src/commands/progress.js +256 -162
  119. package/dist/src/commands/progress.js.map +1 -1
  120. package/dist/src/commands/providers.js +220 -150
  121. package/dist/src/commands/providers.js.map +1 -1
  122. package/dist/src/commands/route.js +665 -520
  123. package/dist/src/commands/route.js.map +1 -1
  124. package/dist/src/commands/ruvector/backup.js +651 -505
  125. package/dist/src/commands/ruvector/backup.js.map +1 -1
  126. package/dist/src/commands/ruvector/benchmark.js +401 -349
  127. package/dist/src/commands/ruvector/benchmark.js.map +1 -1
  128. package/dist/src/commands/ruvector/import.js +267 -225
  129. package/dist/src/commands/ruvector/import.js.map +1 -1
  130. package/dist/src/commands/ruvector/index.js +75 -37
  131. package/dist/src/commands/ruvector/index.js.map +1 -1
  132. package/dist/src/commands/ruvector/init.js +359 -336
  133. package/dist/src/commands/ruvector/init.js.map +1 -1
  134. package/dist/src/commands/ruvector/migrate.js +322 -335
  135. package/dist/src/commands/ruvector/migrate.js.map +1 -1
  136. package/dist/src/commands/ruvector/optimize.js +431 -375
  137. package/dist/src/commands/ruvector/optimize.js.map +1 -1
  138. package/dist/src/commands/ruvector/setup.js +117 -703
  139. package/dist/src/commands/ruvector/setup.js.map +1 -1
  140. package/dist/src/commands/ruvector/status.js +419 -364
  141. package/dist/src/commands/ruvector/status.js.map +1 -1
  142. package/dist/src/commands/security.d.ts.map +1 -1
  143. package/dist/src/commands/security.js +610 -456
  144. package/dist/src/commands/security.js.map +1 -1
  145. package/dist/src/commands/session.d.ts +1 -1
  146. package/dist/src/commands/session.js +627 -505
  147. package/dist/src/commands/session.js.map +1 -1
  148. package/dist/src/commands/start.d.ts +1 -1
  149. package/dist/src/commands/start.js +368 -271
  150. package/dist/src/commands/start.js.map +1 -1
  151. package/dist/src/commands/status.d.ts +1 -1
  152. package/dist/src/commands/status.d.ts.map +1 -1
  153. package/dist/src/commands/status.js +492 -379
  154. package/dist/src/commands/status.js.map +1 -1
  155. package/dist/src/commands/swarm.js +488 -408
  156. package/dist/src/commands/swarm.js.map +1 -1
  157. package/dist/src/commands/task.d.ts +1 -1
  158. package/dist/src/commands/task.js +539 -424
  159. package/dist/src/commands/task.js.map +1 -1
  160. package/dist/src/commands/transfer-store.js +412 -322
  161. package/dist/src/commands/transfer-store.js.map +1 -1
  162. package/dist/src/commands/update.js +291 -196
  163. package/dist/src/commands/update.js.map +1 -1
  164. package/dist/src/commands/workflow.js +486 -386
  165. package/dist/src/commands/workflow.js.map +1 -1
  166. package/dist/src/config-adapter.js +40 -39
  167. package/dist/src/config-adapter.js.map +1 -1
  168. package/dist/src/index.js +416 -312
  169. package/dist/src/index.js.map +1 -1
  170. package/dist/src/infrastructure/in-memory-repositories.js +507 -246
  171. package/dist/src/infrastructure/in-memory-repositories.js.map +1 -1
  172. package/dist/src/init/claudemd-generator.js +78 -368
  173. package/dist/src/init/claudemd-generator.js.map +1 -1
  174. package/dist/src/init/executor.js +1019 -1345
  175. package/dist/src/init/executor.js.map +1 -1
  176. package/dist/src/init/helpers-generator.js +60 -635
  177. package/dist/src/init/helpers-generator.js.map +1 -1
  178. package/dist/src/init/index.d.ts +1 -1
  179. package/dist/src/init/index.d.ts.map +1 -1
  180. package/dist/src/init/index.js +1 -1
  181. package/dist/src/init/index.js.map +1 -1
  182. package/dist/src/init/mcp-generator.d.ts +0 -1
  183. package/dist/src/init/mcp-generator.d.ts.map +1 -1
  184. package/dist/src/init/mcp-generator.js +62 -42
  185. package/dist/src/init/mcp-generator.js.map +1 -1
  186. package/dist/src/init/settings-generator.d.ts.map +1 -1
  187. package/dist/src/init/settings-generator.js +167 -100
  188. package/dist/src/init/settings-generator.js.map +1 -1
  189. package/dist/src/init/statusline-generator.d.ts +16 -8
  190. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  191. package/dist/src/init/statusline-generator.js +20 -1300
  192. package/dist/src/init/statusline-generator.js.map +1 -1
  193. package/dist/src/init/types.d.ts +15 -5
  194. package/dist/src/init/types.d.ts.map +1 -1
  195. package/dist/src/init/types.js +66 -76
  196. package/dist/src/init/types.js.map +1 -1
  197. package/dist/src/mcp-client.js +130 -76
  198. package/dist/src/mcp-client.js.map +1 -1
  199. package/dist/src/mcp-server.js +758 -445
  200. package/dist/src/mcp-server.js.map +1 -1
  201. package/dist/src/mcp-tools/agent-tools.js +492 -391
  202. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  203. package/dist/src/mcp-tools/agentdb-tools.d.ts +30 -0
  204. package/dist/src/mcp-tools/agentdb-tools.d.ts.map +1 -0
  205. package/dist/src/mcp-tools/agentdb-tools.js +758 -0
  206. package/dist/src/mcp-tools/agentdb-tools.js.map +1 -0
  207. package/dist/src/mcp-tools/analyze-tools.js +236 -172
  208. package/dist/src/mcp-tools/analyze-tools.js.map +1 -1
  209. package/dist/src/mcp-tools/auto-install.js +142 -80
  210. package/dist/src/mcp-tools/auto-install.js.map +1 -1
  211. package/dist/src/mcp-tools/browser-tools.js +375 -252
  212. package/dist/src/mcp-tools/browser-tools.js.map +1 -1
  213. package/dist/src/mcp-tools/claims-tools.js +565 -473
  214. package/dist/src/mcp-tools/claims-tools.js.map +1 -1
  215. package/dist/src/mcp-tools/config-tools.d.ts.map +1 -1
  216. package/dist/src/mcp-tools/config-tools.js +284 -190
  217. package/dist/src/mcp-tools/config-tools.js.map +1 -1
  218. package/dist/src/mcp-tools/coordination-tools.d.ts.map +1 -1
  219. package/dist/src/mcp-tools/coordination-tools.js +600 -349
  220. package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
  221. package/dist/src/mcp-tools/daa-tools.js +367 -289
  222. package/dist/src/mcp-tools/daa-tools.js.map +1 -1
  223. package/dist/src/mcp-tools/embeddings-tools.js +693 -582
  224. package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
  225. package/dist/src/mcp-tools/github-tools.js +312 -261
  226. package/dist/src/mcp-tools/github-tools.js.map +1 -1
  227. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
  228. package/dist/src/mcp-tools/hive-mind-tools.js +718 -423
  229. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
  230. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  231. package/dist/src/mcp-tools/hooks-tools.js +2726 -1978
  232. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  233. package/dist/src/mcp-tools/index.d.ts +2 -0
  234. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  235. package/dist/src/mcp-tools/index.js +2 -0
  236. package/dist/src/mcp-tools/index.js.map +1 -1
  237. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  238. package/dist/src/mcp-tools/memory-tools.js +514 -329
  239. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  240. package/dist/src/mcp-tools/neural-tools.d.ts.map +1 -1
  241. package/dist/src/mcp-tools/neural-tools.js +428 -326
  242. package/dist/src/mcp-tools/neural-tools.js.map +1 -1
  243. package/dist/src/mcp-tools/performance-tools.js +480 -420
  244. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  245. package/dist/src/mcp-tools/progress-tools.js +278 -204
  246. package/dist/src/mcp-tools/progress-tools.js.map +1 -1
  247. package/dist/src/mcp-tools/ruvllm-tools.d.ts +9 -0
  248. package/dist/src/mcp-tools/ruvllm-tools.d.ts.map +1 -0
  249. package/dist/src/mcp-tools/ruvllm-tools.js +399 -0
  250. package/dist/src/mcp-tools/ruvllm-tools.js.map +1 -0
  251. package/dist/src/mcp-tools/security-tools.js +429 -297
  252. package/dist/src/mcp-tools/security-tools.js.map +1 -1
  253. package/dist/src/mcp-tools/session-tools.js +234 -185
  254. package/dist/src/mcp-tools/session-tools.js.map +1 -1
  255. package/dist/src/mcp-tools/swarm-tools.d.ts +2 -1
  256. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  257. package/dist/src/mcp-tools/swarm-tools.js +303 -64
  258. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  259. package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
  260. package/dist/src/mcp-tools/system-tools.js +352 -200
  261. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  262. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
  263. package/dist/src/mcp-tools/task-tools.js +357 -189
  264. package/dist/src/mcp-tools/task-tools.js.map +1 -1
  265. package/dist/src/mcp-tools/terminal-tools.js +196 -148
  266. package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
  267. package/dist/src/mcp-tools/transfer-tools.js +333 -186
  268. package/dist/src/mcp-tools/transfer-tools.js.map +1 -1
  269. package/dist/src/mcp-tools/wasm-agent-tools.d.ts +9 -0
  270. package/dist/src/mcp-tools/wasm-agent-tools.d.ts.map +1 -0
  271. package/dist/src/mcp-tools/wasm-agent-tools.js +377 -0
  272. package/dist/src/mcp-tools/wasm-agent-tools.js.map +1 -0
  273. package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -1
  274. package/dist/src/mcp-tools/workflow-tools.js +471 -335
  275. package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
  276. package/dist/src/memory/ewc-consolidation.js +345 -173
  277. package/dist/src/memory/ewc-consolidation.js.map +1 -1
  278. package/dist/src/memory/intelligence.js +841 -359
  279. package/dist/src/memory/intelligence.js.map +1 -1
  280. package/dist/src/memory/memory-bridge.js +1964 -0
  281. package/dist/src/memory/memory-bridge.js.map +1 -0
  282. package/dist/src/memory/memory-initializer.js +1895 -1602
  283. package/dist/src/memory/memory-initializer.js.map +1 -1
  284. package/dist/src/memory/sona-optimizer.js +329 -199
  285. package/dist/src/memory/sona-optimizer.js.map +1 -1
  286. package/dist/src/output.d.ts +2 -2
  287. package/dist/src/output.d.ts.map +1 -1
  288. package/dist/src/output.js +273 -242
  289. package/dist/src/output.js.map +1 -1
  290. package/dist/src/parser.js +217 -124
  291. package/dist/src/parser.js.map +1 -1
  292. package/dist/src/plugins/manager.js +531 -278
  293. package/dist/src/plugins/manager.js.map +1 -1
  294. package/dist/src/plugins/store/discovery.js +362 -275
  295. package/dist/src/plugins/store/discovery.js.map +1 -1
  296. package/dist/src/plugins/store/index.js +105 -48
  297. package/dist/src/plugins/store/index.js.map +1 -1
  298. package/dist/src/plugins/store/search.js +107 -69
  299. package/dist/src/plugins/store/search.js.map +1 -1
  300. package/dist/src/plugins/tests/demo-plugin-store.js +160 -113
  301. package/dist/src/plugins/tests/demo-plugin-store.js.map +1 -1
  302. package/dist/src/plugins/tests/standalone-test.js +223 -172
  303. package/dist/src/plugins/tests/standalone-test.js.map +1 -1
  304. package/dist/src/plugins/tests/test-plugin-store.js +228 -190
  305. package/dist/src/plugins/tests/test-plugin-store.js.map +1 -1
  306. package/dist/src/production/circuit-breaker.js +126 -62
  307. package/dist/src/production/circuit-breaker.js.map +1 -1
  308. package/dist/src/production/error-handler.js +156 -86
  309. package/dist/src/production/error-handler.js.map +1 -1
  310. package/dist/src/production/monitoring.js +220 -139
  311. package/dist/src/production/monitoring.js.map +1 -1
  312. package/dist/src/production/rate-limiter.js +93 -74
  313. package/dist/src/production/rate-limiter.js.map +1 -1
  314. package/dist/src/production/retry.js +167 -75
  315. package/dist/src/production/retry.js.map +1 -1
  316. package/dist/src/prompt.js +560 -436
  317. package/dist/src/prompt.js.map +1 -1
  318. package/dist/src/runtime/headless.js +289 -200
  319. package/dist/src/runtime/headless.js.map +1 -1
  320. package/dist/src/ruvector/agent-wasm.js +511 -0
  321. package/dist/src/ruvector/agent-wasm.js.map +1 -0
  322. package/dist/src/ruvector/ast-analyzer.js +232 -145
  323. package/dist/src/ruvector/ast-analyzer.js.map +1 -1
  324. package/dist/src/ruvector/coverage-router.js +419 -287
  325. package/dist/src/ruvector/coverage-router.js.map +1 -1
  326. package/dist/src/ruvector/coverage-tools.js +101 -56
  327. package/dist/src/ruvector/coverage-tools.js.map +1 -1
  328. package/dist/src/ruvector/diff-classifier.js +451 -324
  329. package/dist/src/ruvector/diff-classifier.js.map +1 -1
  330. package/dist/src/ruvector/enhanced-model-router.js +337 -251
  331. package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
  332. package/dist/src/ruvector/flash-attention.js +254 -223
  333. package/dist/src/ruvector/flash-attention.js.map +1 -1
  334. package/dist/src/ruvector/graph-analyzer.js +680 -486
  335. package/dist/src/ruvector/graph-analyzer.js.map +1 -1
  336. package/dist/src/ruvector/index.js +113 -27
  337. package/dist/src/ruvector/index.js.map +1 -1
  338. package/dist/src/ruvector/lora-adapter.js +248 -155
  339. package/dist/src/ruvector/lora-adapter.js.map +1 -1
  340. package/dist/src/ruvector/model-router.js +248 -175
  341. package/dist/src/ruvector/model-router.js.map +1 -1
  342. package/dist/src/ruvector/moe-router.js +286 -228
  343. package/dist/src/ruvector/moe-router.js.map +1 -1
  344. package/dist/src/ruvector/q-learning-router.js +338 -257
  345. package/dist/src/ruvector/q-learning-router.js.map +1 -1
  346. package/dist/src/ruvector/ruvllm-wasm.js +527 -0
  347. package/dist/src/ruvector/ruvllm-wasm.js.map +1 -0
  348. package/dist/src/ruvector/semantic-router.js +67 -60
  349. package/dist/src/ruvector/semantic-router.js.map +1 -1
  350. package/dist/src/ruvector/vector-db.js +205 -119
  351. package/dist/src/ruvector/vector-db.js.map +1 -1
  352. package/dist/src/services/agentic-flow-bridge.js +168 -0
  353. package/dist/src/services/agentic-flow-bridge.js.map +1 -0
  354. package/dist/src/services/claim-service.js +940 -615
  355. package/dist/src/services/claim-service.js.map +1 -1
  356. package/dist/src/services/container-worker-pool.js +669 -399
  357. package/dist/src/services/container-worker-pool.js.map +1 -1
  358. package/dist/src/services/headless-worker-executor.js +467 -441
  359. package/dist/src/services/headless-worker-executor.js.map +1 -1
  360. package/dist/src/services/index.d.ts +5 -5
  361. package/dist/src/services/index.d.ts.map +1 -1
  362. package/dist/src/services/index.js +4 -4
  363. package/dist/src/services/index.js.map +1 -1
  364. package/dist/src/services/registry-api.js +201 -93
  365. package/dist/src/services/registry-api.js.map +1 -1
  366. package/dist/src/services/ruvector-training.js +414 -144
  367. package/dist/src/services/ruvector-training.js.map +1 -1
  368. package/dist/src/services/worker-daemon.js +928 -531
  369. package/dist/src/services/worker-daemon.js.map +1 -1
  370. package/dist/src/services/worker-queue.js +550 -331
  371. package/dist/src/services/worker-queue.js.map +1 -1
  372. package/dist/src/suggest.js +55 -45
  373. package/dist/src/suggest.js.map +1 -1
  374. package/dist/src/transfer/anonymization/index.js +37 -29
  375. package/dist/src/transfer/anonymization/index.js.map +1 -1
  376. package/dist/src/transfer/deploy-seraphine.d.ts +1 -1
  377. package/dist/src/transfer/deploy-seraphine.js +156 -129
  378. package/dist/src/transfer/deploy-seraphine.js.map +1 -1
  379. package/dist/src/transfer/export.js +142 -84
  380. package/dist/src/transfer/export.js.map +1 -1
  381. package/dist/src/transfer/index.d.ts +1 -1
  382. package/dist/src/transfer/index.d.ts.map +1 -1
  383. package/dist/src/transfer/index.js +2 -0
  384. package/dist/src/transfer/index.js.map +1 -1
  385. package/dist/src/transfer/ipfs/client.js +337 -179
  386. package/dist/src/transfer/ipfs/client.js.map +1 -1
  387. package/dist/src/transfer/ipfs/upload.js +434 -290
  388. package/dist/src/transfer/ipfs/upload.js.map +1 -1
  389. package/dist/src/transfer/models/seraphine.js +58 -58
  390. package/dist/src/transfer/models/seraphine.js.map +1 -1
  391. package/dist/src/transfer/serialization/cfp.js +37 -33
  392. package/dist/src/transfer/serialization/cfp.js.map +1 -1
  393. package/dist/src/transfer/storage/gcs.js +248 -139
  394. package/dist/src/transfer/storage/gcs.js.map +1 -1
  395. package/dist/src/transfer/store/discovery.js +353 -243
  396. package/dist/src/transfer/store/discovery.js.map +1 -1
  397. package/dist/src/transfer/store/download.js +365 -243
  398. package/dist/src/transfer/store/download.js.map +1 -1
  399. package/dist/src/transfer/store/index.js +130 -63
  400. package/dist/src/transfer/store/index.js.map +1 -1
  401. package/dist/src/transfer/store/publish.js +258 -184
  402. package/dist/src/transfer/store/publish.js.map +1 -1
  403. package/dist/src/transfer/store/registry.js +73 -51
  404. package/dist/src/transfer/store/registry.js.map +1 -1
  405. package/dist/src/transfer/store/search.js +96 -64
  406. package/dist/src/transfer/store/search.js.map +1 -1
  407. package/dist/src/transfer/store/tests/standalone-test.js +231 -174
  408. package/dist/src/transfer/store/tests/standalone-test.js.map +1 -1
  409. package/dist/src/transfer/test-seraphine.js +130 -95
  410. package/dist/src/transfer/test-seraphine.js.map +1 -1
  411. package/dist/src/transfer/tests/test-store.js +239 -194
  412. package/dist/src/transfer/tests/test-store.js.map +1 -1
  413. package/dist/src/types.js +56 -27
  414. package/dist/src/types.js.map +1 -1
  415. package/dist/src/update/checker.js +183 -106
  416. package/dist/src/update/checker.js.map +1 -1
  417. package/dist/src/update/executor.js +198 -135
  418. package/dist/src/update/executor.js.map +1 -1
  419. package/dist/src/update/index.js +85 -38
  420. package/dist/src/update/index.js.map +1 -1
  421. package/dist/src/update/rate-limiter.js +31 -19
  422. package/dist/src/update/rate-limiter.js.map +1 -1
  423. package/dist/src/update/validator.js +64 -38
  424. package/dist/src/update/validator.js.map +1 -1
  425. package/dist/tsconfig.tsbuildinfo +1 -1
  426. package/package.json +13 -10
  427. package/.claude/agents/custom/accessibility-auditor.yaml +0 -56
  428. package/.claude/agents/custom/design-architect.yaml +0 -48
  429. package/.claude/agents/custom/ui-developer.yaml +0 -46
  430. package/.claude/agents/custom/ux-researcher.yaml +0 -60
  431. package/dist/src/benchmarks/pretrain/index.d.ts +0 -58
  432. package/dist/src/benchmarks/pretrain/index.d.ts.map +0 -1
  433. package/dist/src/commands/index.d.ts +0 -108
  434. package/dist/src/commands/index.d.ts.map +0 -1
  435. package/dist/src/config-adapter.d.ts +0 -15
  436. package/dist/src/config-adapter.d.ts.map +0 -1
  437. package/dist/src/index.d.ts +0 -76
  438. package/dist/src/index.d.ts.map +0 -1
  439. package/dist/src/infrastructure/in-memory-repositories.d.ts +0 -68
  440. package/dist/src/infrastructure/in-memory-repositories.d.ts.map +0 -1
  441. package/dist/src/init/claudemd-generator.d.ts +0 -25
  442. package/dist/src/init/claudemd-generator.d.ts.map +0 -1
  443. package/dist/src/init/executor.d.ts +0 -41
  444. package/dist/src/init/executor.d.ts.map +0 -1
  445. package/dist/src/init/helpers-generator.d.ts +0 -60
  446. package/dist/src/init/helpers-generator.d.ts.map +0 -1
  447. package/dist/src/mcp-client.d.ts +0 -92
  448. package/dist/src/mcp-client.d.ts.map +0 -1
  449. package/dist/src/mcp-server.d.ts +0 -161
  450. package/dist/src/mcp-server.d.ts.map +0 -1
  451. package/dist/src/mcp-tools/auto-install.d.ts +0 -83
  452. package/dist/src/mcp-tools/auto-install.d.ts.map +0 -1
  453. package/dist/src/mcp-tools/types.d.ts +0 -31
  454. package/dist/src/mcp-tools/types.d.ts.map +0 -1
  455. package/dist/src/memory/ewc-consolidation.d.ts +0 -271
  456. package/dist/src/memory/ewc-consolidation.d.ts.map +0 -1
  457. package/dist/src/memory/intelligence.d.ts +0 -285
  458. package/dist/src/memory/intelligence.d.ts.map +0 -1
  459. package/dist/src/memory/memory-initializer.d.ts +0 -396
  460. package/dist/src/memory/memory-initializer.d.ts.map +0 -1
  461. package/dist/src/memory/sona-optimizer.d.ts +0 -227
  462. package/dist/src/memory/sona-optimizer.d.ts.map +0 -1
  463. package/dist/src/parser.d.ts +0 -41
  464. package/dist/src/parser.d.ts.map +0 -1
  465. package/dist/src/plugins/manager.d.ts +0 -133
  466. package/dist/src/plugins/manager.d.ts.map +0 -1
  467. package/dist/src/plugins/store/discovery.d.ts +0 -88
  468. package/dist/src/plugins/store/discovery.d.ts.map +0 -1
  469. package/dist/src/plugins/store/index.d.ts +0 -76
  470. package/dist/src/plugins/store/index.d.ts.map +0 -1
  471. package/dist/src/plugins/store/search.d.ts +0 -46
  472. package/dist/src/plugins/store/search.d.ts.map +0 -1
  473. package/dist/src/plugins/store/types.d.ts +0 -274
  474. package/dist/src/plugins/store/types.d.ts.map +0 -1
  475. package/dist/src/production/circuit-breaker.d.ts +0 -101
  476. package/dist/src/production/circuit-breaker.d.ts.map +0 -1
  477. package/dist/src/production/error-handler.d.ts +0 -92
  478. package/dist/src/production/error-handler.d.ts.map +0 -1
  479. package/dist/src/production/monitoring.d.ts +0 -161
  480. package/dist/src/production/monitoring.d.ts.map +0 -1
  481. package/dist/src/production/rate-limiter.d.ts +0 -80
  482. package/dist/src/production/rate-limiter.d.ts.map +0 -1
  483. package/dist/src/production/retry.d.ts +0 -48
  484. package/dist/src/production/retry.d.ts.map +0 -1
  485. package/dist/src/prompt.d.ts +0 -44
  486. package/dist/src/prompt.d.ts.map +0 -1
  487. package/dist/src/runtime/headless.d.ts +0 -60
  488. package/dist/src/runtime/headless.d.ts.map +0 -1
  489. package/dist/src/ruvector/ast-analyzer.d.ts +0 -67
  490. package/dist/src/ruvector/ast-analyzer.d.ts.map +0 -1
  491. package/dist/src/ruvector/coverage-router.d.ts +0 -160
  492. package/dist/src/ruvector/coverage-router.d.ts.map +0 -1
  493. package/dist/src/ruvector/diff-classifier.d.ts +0 -175
  494. package/dist/src/ruvector/diff-classifier.d.ts.map +0 -1
  495. package/dist/src/ruvector/enhanced-model-router.d.ts +0 -146
  496. package/dist/src/ruvector/enhanced-model-router.d.ts.map +0 -1
  497. package/dist/src/ruvector/flash-attention.d.ts +0 -195
  498. package/dist/src/ruvector/flash-attention.d.ts.map +0 -1
  499. package/dist/src/ruvector/graph-analyzer.d.ts +0 -187
  500. package/dist/src/ruvector/graph-analyzer.d.ts.map +0 -1
  501. package/dist/src/ruvector/index.d.ts +0 -34
  502. package/dist/src/ruvector/index.d.ts.map +0 -1
  503. package/dist/src/ruvector/lora-adapter.d.ts +0 -218
  504. package/dist/src/ruvector/lora-adapter.d.ts.map +0 -1
  505. package/dist/src/ruvector/model-router.d.ts +0 -220
  506. package/dist/src/ruvector/model-router.d.ts.map +0 -1
  507. package/dist/src/ruvector/moe-router.d.ts +0 -206
  508. package/dist/src/ruvector/moe-router.d.ts.map +0 -1
  509. package/dist/src/ruvector/q-learning-router.d.ts +0 -211
  510. package/dist/src/ruvector/q-learning-router.d.ts.map +0 -1
  511. package/dist/src/ruvector/semantic-router.d.ts +0 -77
  512. package/dist/src/ruvector/semantic-router.d.ts.map +0 -1
  513. package/dist/src/ruvector/vector-db.d.ts +0 -69
  514. package/dist/src/ruvector/vector-db.d.ts.map +0 -1
  515. package/dist/src/services/claim-service.d.ts +0 -204
  516. package/dist/src/services/claim-service.d.ts.map +0 -1
  517. package/dist/src/services/container-worker-pool.d.ts +0 -197
  518. package/dist/src/services/container-worker-pool.d.ts.map +0 -1
  519. package/dist/src/services/headless-worker-executor.d.ts +0 -304
  520. package/dist/src/services/headless-worker-executor.d.ts.map +0 -1
  521. package/dist/src/services/registry-api.d.ts +0 -58
  522. package/dist/src/services/registry-api.d.ts.map +0 -1
  523. package/dist/src/services/ruvector-training.d.ts +0 -213
  524. package/dist/src/services/ruvector-training.d.ts.map +0 -1
  525. package/dist/src/services/worker-daemon.d.ts +0 -203
  526. package/dist/src/services/worker-daemon.d.ts.map +0 -1
  527. package/dist/src/services/worker-queue.d.ts +0 -194
  528. package/dist/src/services/worker-queue.d.ts.map +0 -1
  529. package/dist/src/suggest.d.ts +0 -53
  530. package/dist/src/suggest.d.ts.map +0 -1
  531. package/dist/src/transfer/export.d.ts +0 -25
  532. package/dist/src/transfer/export.d.ts.map +0 -1
  533. package/dist/src/transfer/ipfs/client.d.ts +0 -109
  534. package/dist/src/transfer/ipfs/client.d.ts.map +0 -1
  535. package/dist/src/transfer/ipfs/upload.d.ts +0 -95
  536. package/dist/src/transfer/ipfs/upload.d.ts.map +0 -1
  537. package/dist/src/transfer/models/seraphine.d.ts +0 -72
  538. package/dist/src/transfer/models/seraphine.d.ts.map +0 -1
  539. package/dist/src/transfer/serialization/cfp.d.ts +0 -49
  540. package/dist/src/transfer/serialization/cfp.d.ts.map +0 -1
  541. package/dist/src/transfer/storage/gcs.d.ts +0 -82
  542. package/dist/src/transfer/storage/gcs.d.ts.map +0 -1
  543. package/dist/src/transfer/store/discovery.d.ts +0 -84
  544. package/dist/src/transfer/store/discovery.d.ts.map +0 -1
  545. package/dist/src/transfer/store/download.d.ts +0 -70
  546. package/dist/src/transfer/store/download.d.ts.map +0 -1
  547. package/dist/src/transfer/store/index.d.ts +0 -84
  548. package/dist/src/transfer/store/index.d.ts.map +0 -1
  549. package/dist/src/transfer/store/publish.d.ts +0 -76
  550. package/dist/src/transfer/store/publish.d.ts.map +0 -1
  551. package/dist/src/transfer/store/search.d.ts +0 -54
  552. package/dist/src/transfer/store/search.d.ts.map +0 -1
  553. package/dist/src/transfer/types.d.ts +0 -245
  554. package/dist/src/transfer/types.d.ts.map +0 -1
  555. package/dist/src/types.d.ts +0 -198
  556. package/dist/src/types.d.ts.map +0 -1
  557. package/dist/src/update/checker.d.ts +0 -34
  558. package/dist/src/update/checker.d.ts.map +0 -1
  559. package/dist/src/update/executor.d.ts +0 -32
  560. package/dist/src/update/executor.d.ts.map +0 -1
  561. package/dist/src/update/index.d.ts +0 -33
  562. package/dist/src/update/index.d.ts.map +0 -1
  563. package/dist/src/update/rate-limiter.d.ts +0 -20
  564. package/dist/src/update/rate-limiter.d.ts.map +0 -1
  565. package/dist/src/update/validator.d.ts +0 -17
  566. package/dist/src/update/validator.d.ts.map +0 -1
@@ -1,1315 +1,35 @@
1
1
  /**
2
- * Statusline Configuration Generator
3
- * Creates statusline configuration for V3 progress display
2
+ * Statusline Configuration Generator (Optimized)
3
+ * Creates fast, reliable statusline for V3 progress display
4
+ *
5
+ * Performance:
6
+ * - Single combined git execSync call (not 8+ separate ones)
7
+ * - process.memoryUsage() instead of ps aux
8
+ * - No recursive test file content reading
9
+ * - Shared settings cache
10
+ * - Strict 2s timeouts on all shell calls
4
11
  */
5
12
  /**
6
- * Generate statusline configuration script
7
- * Matches the advanced format:
8
- * ▊ KynjalFlow● user │ ⎇ v3 │ Opus 4.5
13
+ * Generate optimized statusline script
14
+ * Output format:
15
+ * ▊ RuFlo V3.5 ● user │ ⎇ branch │ Opus 4.6 (1M context)
9
16
  * ─────────────────────────────────────────────────────
10
- * 🏗️ DDD Domains [●●●●●] 5/5 ⚡ HNSW 12500x (or 📚 22.9k patterns)
11
- * 🤖 Swarm ◉ [12/15] 👥 0 🟢 CVE 3/3 💾 5177MB 📂 56% 🧠 30%
12
- * 🔧 Architecture DDD100% │ SecurityCLEAN │ Memory ●AgentDBIntegration
17
+ * 🏗️ DDD Domains [●●○○○] 2/5 ⚡ HNSW 150x
18
+ * 🤖 Swarm ◉ [ 5/15] 👥 2 🪝 10/17 🟢 CVE 3/3 💾 4MB 🧠 63%
19
+ * 🔧 Architecture ADRs71% │ DDD13%SecurityCLEAN
20
+ * 📊 AgentDB Vectors ●3104⚡ │ Size 216KB │ Tests ●6 (~24 cases) │ MCP ●1/1
13
21
  */
14
22
  export function generateStatuslineScript(options) {
15
- const config = options.statusline;
16
- // Generate CommonJS script - use .cjs extension for ES module project compatibility
17
- return `#!/usr/bin/env node
18
- /**
19
- * KynjalFlow V3 Statusline Generator
20
- * Displays real-time V3 implementation progress and system status
21
- *
22
- * Usage: node statusline.cjs [--json] [--compact]
23
- *
24
- * IMPORTANT: This file uses .cjs extension to work in ES module projects.
25
- * The require() syntax is intentional for CommonJS compatibility.
26
- */
27
-
28
- /* eslint-disable @typescript-eslint/no-var-requires */
29
- const fs = require('fs');
30
- const path = require('path');
31
- const { execSync } = require('child_process');
32
-
33
- // Configuration
34
- const CONFIG = {
35
- enabled: ${config.enabled},
36
- showProgress: ${config.showProgress},
37
- showSecurity: ${config.showSecurity},
38
- showSwarm: ${config.showSwarm},
39
- showHooks: ${config.showHooks},
40
- showPerformance: ${config.showPerformance},
41
- refreshInterval: ${config.refreshInterval},
42
- maxAgents: ${options.runtime.maxAgents},
43
- topology: '${options.runtime.topology}',
44
- };
45
-
46
- // ANSI colors
47
- const c = {
48
- reset: '\\x1b[0m',
49
- bold: '\\x1b[1m',
50
- dim: '\\x1b[2m',
51
- red: '\\x1b[0;31m',
52
- green: '\\x1b[0;32m',
53
- yellow: '\\x1b[0;33m',
54
- blue: '\\x1b[0;34m',
55
- purple: '\\x1b[0;35m',
56
- cyan: '\\x1b[0;36m',
57
- brightRed: '\\x1b[1;31m',
58
- brightGreen: '\\x1b[1;32m',
59
- brightYellow: '\\x1b[1;33m',
60
- brightBlue: '\\x1b[1;34m',
61
- brightPurple: '\\x1b[1;35m',
62
- brightCyan: '\\x1b[1;36m',
63
- brightWhite: '\\x1b[1;37m',
64
- };
65
-
66
- // Get user info
67
- function getUserInfo() {
68
- let name = 'user';
69
- let gitBranch = '';
70
- let modelName = '🤖 Claude Code';
71
-
72
- try {
73
- name = execSync('git config user.name 2>/dev/null || echo "user"', { encoding: 'utf-8' }).trim();
74
- gitBranch = execSync('git branch --show-current 2>/dev/null || echo ""', { encoding: 'utf-8' }).trim();
75
- } catch (e) {
76
- // Ignore errors
77
- }
78
-
79
- // Auto-detect model from Claude Code's config
80
- try {
81
- const homedir = require('os').homedir();
82
- const claudeConfigPath = path.join(homedir, '.claude.json');
83
- if (fs.existsSync(claudeConfigPath)) {
84
- const claudeConfig = JSON.parse(fs.readFileSync(claudeConfigPath, 'utf-8'));
85
- // Try to find lastModelUsage - check current dir and parent dirs
86
- let lastModelUsage = null;
87
- const cwd = process.cwd();
88
- if (claudeConfig.projects) {
89
- // Try exact match first, then check if cwd starts with any project path
90
- for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
91
- if (cwd === projectPath || cwd.startsWith(projectPath + '/')) {
92
- lastModelUsage = projectConfig.lastModelUsage;
93
- break;
94
- }
95
- }
96
- }
97
- if (lastModelUsage) {
98
- const modelIds = Object.keys(lastModelUsage);
99
- if (modelIds.length > 0) {
100
- // Find the most recently used model by checking lastUsedAt timestamps
101
- // or fall back to the last key in the object (preserves insertion order in modern JS)
102
- let modelId = modelIds[modelIds.length - 1];
103
- let latestTimestamp = 0;
104
-
105
- for (const id of modelIds) {
106
- const usage = lastModelUsage[id];
107
- // Check for lastUsedAt timestamp (if available)
108
- if (usage.lastUsedAt) {
109
- const ts = new Date(usage.lastUsedAt).getTime();
110
- if (ts > latestTimestamp) {
111
- latestTimestamp = ts;
112
- modelId = id;
113
- }
114
- }
115
- }
116
-
117
- // Parse model ID to human-readable name
118
- if (modelId.includes('opus-4-6') || modelId.includes('opus-4.6')) modelName = 'Opus 4.6';
119
- else if (modelId.includes('opus')) modelName = 'Opus 4.5';
120
- else if (modelId.includes('sonnet-4-6') || modelId.includes('sonnet-4.6')) modelName = 'Sonnet 4.6';
121
- else if (modelId.includes('sonnet')) modelName = 'Sonnet 4';
122
- else if (modelId.includes('haiku')) modelName = 'Haiku 4.5';
123
- else modelName = modelId.split('-').slice(1, 3).join(' ');
124
- }
125
- }
126
- }
127
- } catch (e) {
128
- // Fallback to Unknown if can't read config
129
- }
130
-
131
- // Fallback: check project's .claude/settings.json for model
132
- if (modelName === 'Unknown') {
133
- try {
134
- const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
135
- if (fs.existsSync(settingsPath)) {
136
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
137
- if (settings.model) {
138
- if (settings.model.includes('opus-4-6') || settings.model.includes('opus-4.6')) modelName = 'Opus 4.6';
139
- else if (settings.model.includes('opus')) modelName = 'Opus 4.5';
140
- else if (settings.model.includes('sonnet-4-6') || settings.model.includes('sonnet-4.6')) modelName = 'Sonnet 4.6';
141
- else if (settings.model.includes('sonnet')) modelName = 'Sonnet 4';
142
- else if (settings.model.includes('haiku')) modelName = 'Haiku 4.5';
143
- else modelName = settings.model.split('-').slice(1, 3).join(' ');
144
- }
145
- }
146
- } catch (e) {
147
- // Keep Unknown
148
- }
149
- }
150
-
151
- return { name, gitBranch, modelName };
152
- }
153
-
154
- // Get learning stats from intelligence loop data (ADR-050)
155
- function getLearningStats() {
156
- let patterns = 0;
157
- let sessions = 0;
158
- let trajectories = 0;
159
- let edges = 0;
160
- let confidenceMean = 0;
161
- let accessedCount = 0;
162
- let trend = 'STABLE';
163
-
164
- // PRIMARY: Read from intelligence loop data files
165
- const dataDir = path.join(process.cwd(), '.claude-flow', 'data');
166
-
167
- // 1. graph-state.json — authoritative node/edge counts
168
- const graphPath = path.join(dataDir, 'graph-state.json');
169
- if (fs.existsSync(graphPath)) {
170
- try {
171
- const graph = JSON.parse(fs.readFileSync(graphPath, 'utf-8'));
172
- patterns = graph.nodes ? Object.keys(graph.nodes).length : 0;
173
- edges = Array.isArray(graph.edges) ? graph.edges.length : 0;
174
- } catch (e) { /* ignore */ }
175
- }
176
-
177
- // 2. ranked-context.json — confidence and access data
178
- const rankedPath = path.join(dataDir, 'ranked-context.json');
179
- if (fs.existsSync(rankedPath)) {
180
- try {
181
- const ranked = JSON.parse(fs.readFileSync(rankedPath, 'utf-8'));
182
- if (ranked.entries && ranked.entries.length > 0) {
183
- patterns = Math.max(patterns, ranked.entries.length);
184
- let confSum = 0;
185
- let accCount = 0;
186
- for (let i = 0; i < ranked.entries.length; i++) {
187
- confSum += (ranked.entries[i].confidence || 0);
188
- if ((ranked.entries[i].accessCount || 0) > 0) accCount++;
189
- }
190
- confidenceMean = confSum / ranked.entries.length;
191
- accessedCount = accCount;
192
- }
193
- } catch (e) { /* ignore */ }
194
- }
195
-
196
- // 3. intelligence-snapshot.json — trend history
197
- const snapshotPath = path.join(dataDir, 'intelligence-snapshot.json');
198
- if (fs.existsSync(snapshotPath)) {
199
- try {
200
- const snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));
201
- if (snapshot.history && snapshot.history.length >= 2) {
202
- const first = snapshot.history[0];
203
- const last = snapshot.history[snapshot.history.length - 1];
204
- const confDrift = (last.confidenceMean || 0) - (first.confidenceMean || 0);
205
- trend = confDrift > 0.01 ? 'IMPROVING' : confDrift < -0.01 ? 'DECLINING' : 'STABLE';
206
- sessions = Math.max(sessions, snapshot.history.length);
207
- }
208
- } catch (e) { /* ignore */ }
209
- }
210
-
211
- // 4. auto-memory-store.json — fallback entry count
212
- if (patterns === 0) {
213
- const autoMemPath = path.join(dataDir, 'auto-memory-store.json');
214
- if (fs.existsSync(autoMemPath)) {
215
- try {
216
- const data = JSON.parse(fs.readFileSync(autoMemPath, 'utf-8'));
217
- patterns = Array.isArray(data) ? data.length : (data.entries ? data.entries.length : 0);
218
- } catch (e) { /* ignore */ }
219
- }
220
- }
221
-
222
- // FALLBACK: Legacy memory.db file-size estimation
223
- if (patterns === 0) {
224
- const memoryPaths = [
225
- path.join(process.cwd(), '.swarm', 'memory.db'),
226
- path.join(process.cwd(), '.claude-flow', 'memory.db'),
227
- path.join(process.cwd(), '.claude', 'memory.db'),
228
- path.join(process.cwd(), 'data', 'memory.db'),
229
- path.join(process.cwd(), 'memory.db'),
230
- path.join(process.cwd(), '.agentdb', 'memory.db'),
231
- ];
232
- for (let j = 0; j < memoryPaths.length; j++) {
233
- if (fs.existsSync(memoryPaths[j])) {
234
- try {
235
- const dbStats = fs.statSync(memoryPaths[j]);
236
- patterns = Math.floor(dbStats.size / 1024 / 2);
237
- break;
238
- } catch (e) { /* ignore */ }
239
- }
240
- }
241
- }
242
-
243
- // Session count from session files
244
- const sessionsPath = path.join(process.cwd(), '.claude', 'sessions');
245
- if (fs.existsSync(sessionsPath)) {
246
- try {
247
- const sessionFiles = fs.readdirSync(sessionsPath).filter(f => f.endsWith('.json'));
248
- sessions = Math.max(sessions, sessionFiles.length);
249
- } catch (e) { /* ignore */ }
250
- }
251
-
252
- trajectories = Math.floor(patterns / 5);
253
-
254
- return { patterns, sessions, trajectories, edges, confidenceMean, accessedCount, trend };
255
- }
256
-
257
- // Get V3 progress from REAL metrics files
258
- function getV3Progress() {
259
- const learning = getLearningStats();
260
- const totalDomains = 5;
261
-
262
- let dddProgress = 0;
263
- let dddScore = 0;
264
- let dddMaxScore = 100;
265
- let moduleCount = 0;
266
-
267
- // Check ddd-progress.json for REAL DDD analysis
268
- const dddPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'ddd-progress.json');
269
- if (fs.existsSync(dddPath)) {
270
- try {
271
- const data = JSON.parse(fs.readFileSync(dddPath, 'utf-8'));
272
- dddProgress = data.progress || 0;
273
- dddScore = data.score || 0;
274
- dddMaxScore = data.maxScore || 100;
275
- moduleCount = data.modules ? Object.keys(data.modules).length : 0;
276
- } catch (e) {
277
- // Ignore - use fallback
278
- }
279
- }
280
-
281
- // Calculate domains completed from DDD progress (each 20% = 1 domain)
282
- let domainsCompleted = Math.min(5, Math.floor(dddProgress / 20));
283
-
284
- // Fallback: if no DDD data, use pattern-based calculation
285
- if (dddProgress === 0 && learning.patterns > 0) {
286
- if (learning.patterns >= 500) domainsCompleted = 5;
287
- else if (learning.patterns >= 200) domainsCompleted = 4;
288
- else if (learning.patterns >= 100) domainsCompleted = 3;
289
- else if (learning.patterns >= 50) domainsCompleted = 2;
290
- else if (learning.patterns >= 10) domainsCompleted = 1;
291
- dddProgress = Math.floor((domainsCompleted / totalDomains) * 100);
292
- }
293
-
294
- return {
295
- domainsCompleted,
296
- totalDomains,
297
- dddProgress,
298
- dddScore,
299
- dddMaxScore,
300
- moduleCount,
301
- patternsLearned: learning.patterns,
302
- sessionsCompleted: learning.sessions
303
- };
304
- }
305
-
306
- // Get security status based on actual scans
307
- function getSecurityStatus() {
308
- const totalCves = 3;
309
- let cvesFixed = 0;
310
-
311
- // Check audit-status.json first (created by init)
312
- const auditStatusPath = path.join(process.cwd(), '.claude-flow', 'security', 'audit-status.json');
313
- if (fs.existsSync(auditStatusPath)) {
314
- try {
315
- const data = JSON.parse(fs.readFileSync(auditStatusPath, 'utf-8'));
316
- return {
317
- status: data.status || 'PENDING',
318
- cvesFixed: data.cvesFixed || 0,
319
- totalCves: data.totalCves || 3,
320
- };
321
- } catch (e) {
322
- // Fall through to scan directory check
323
- }
324
- }
325
-
326
- // Check for security scan results in memory
327
- const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
328
- if (fs.existsSync(scanResultsPath)) {
329
- try {
330
- const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
331
- // Each successful scan file = 1 CVE addressed
332
- cvesFixed = Math.min(totalCves, scans.length);
333
- } catch (e) {
334
- // Ignore
335
- }
336
- }
337
-
338
- // Also check .swarm/security for audit results
339
- const swarmAuditPath = path.join(process.cwd(), '.swarm', 'security');
340
- if (fs.existsSync(swarmAuditPath)) {
341
- try {
342
- const audits = fs.readdirSync(swarmAuditPath).filter(f => f.includes('audit'));
343
- cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
344
- } catch (e) {
345
- // Ignore
346
- }
347
- }
348
-
349
- const status = cvesFixed >= totalCves ? 'CLEAN' : cvesFixed > 0 ? 'IN_PROGRESS' : 'PENDING';
350
-
351
- return {
352
- status,
353
- cvesFixed,
354
- totalCves,
355
- };
356
- }
357
-
358
- // Get swarm status (cross-platform)
359
- function getSwarmStatus() {
360
- let activeAgents = 0;
361
- let coordinationActive = false;
362
-
363
- // Check swarm-activity.json first (works on all platforms)
364
- const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
365
- if (fs.existsSync(activityPath)) {
366
- try {
367
- const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
368
- if (data.swarm) {
369
- return {
370
- activeAgents: data.swarm.agent_count || 0,
371
- maxAgents: CONFIG.maxAgents,
372
- coordinationActive: data.swarm.coordination_active || data.swarm.active || false,
373
- };
374
- }
375
- } catch (e) {
376
- // Fall through to v3-progress.json check
377
- }
378
- }
379
-
380
- // Also check v3-progress.json for swarm data (secondary source)
381
- const progressPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'v3-progress.json');
382
- if (fs.existsSync(progressPath)) {
383
- try {
384
- const data = JSON.parse(fs.readFileSync(progressPath, 'utf-8'));
385
- if (data.swarm) {
386
- return {
387
- activeAgents: data.swarm.activeAgents || data.swarm.agent_count || 0,
388
- maxAgents: data.swarm.totalAgents || CONFIG.maxAgents,
389
- coordinationActive: data.swarm.active || (data.swarm.activeAgents > 0),
390
- };
391
- }
392
- } catch (e) {
393
- // Fall through to process detection
394
- }
395
- }
396
-
397
- // Platform-specific process detection (fallback)
398
- const isWindows = process.platform === 'win32';
399
- try {
400
- if (isWindows) {
401
- // Windows: use tasklist
402
- const ps = execSync('tasklist /FI "IMAGENAME eq node.exe" /NH 2>nul || echo ""', { encoding: 'utf-8' });
403
- const nodeProcesses = (ps.match(/node\\.exe/gi) || []).length;
404
- activeAgents = Math.max(0, Math.floor(nodeProcesses / 3)); // Heuristic
405
- coordinationActive = nodeProcesses > 0;
406
- } else {
407
- // Unix: use ps - check for various agent process patterns
408
- try {
409
- const ps = execSync('ps aux 2>/dev/null | grep -E "(agentic-flow|claude-flow|mcp.*server)" | grep -v grep | wc -l', { encoding: 'utf-8' });
410
- activeAgents = Math.max(0, parseInt(ps.trim()));
411
- coordinationActive = activeAgents > 0;
412
- } catch (e) {
413
- // Fallback to simple agentic-flow check
414
- const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
415
- activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
416
- coordinationActive = activeAgents > 0;
417
- }
418
- }
419
- } catch (e) {
420
- // Ignore errors - return defaults
421
- }
422
-
423
- return {
424
- activeAgents,
425
- maxAgents: CONFIG.maxAgents,
426
- coordinationActive,
427
- };
428
- }
429
-
430
- // Get system metrics (cross-platform)
431
- function getSystemMetrics() {
432
- let memoryMB = 0;
433
- let subAgents = 0;
434
-
435
- // Check learning.json first for REAL intelligence metrics
436
- const learningMetricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'learning.json');
437
- let intelligenceFromFile = null;
438
- let contextFromFile = null;
439
- if (fs.existsSync(learningMetricsPath)) {
440
- try {
441
- const data = JSON.parse(fs.readFileSync(learningMetricsPath, 'utf-8'));
442
- // Use intelligence.score (the REAL metric) instead of routing.accuracy
443
- if (data.intelligence?.score !== undefined) {
444
- intelligenceFromFile = Math.min(100, Math.floor(data.intelligence.score));
445
- }
446
- if (data.sessions?.total !== undefined) {
447
- contextFromFile = Math.min(100, data.sessions.total * 5);
448
- }
449
- } catch (e) {
450
- // Fall through
451
- }
452
- }
453
-
454
- // Platform-specific memory detection
455
- const isWindows = process.platform === 'win32';
456
- try {
457
- if (isWindows) {
458
- // Windows: use process.memoryUsage() (most reliable cross-platform)
459
- memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
460
- } else {
461
- // Unix: try ps command, fallback to process.memoryUsage()
462
- try {
463
- const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \\'{sum += \\$6} END {print int(sum/1024)}\\'', { encoding: 'utf-8' });
464
- memoryMB = parseInt(mem.trim()) || 0;
465
- } catch (e) {
466
- memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
467
- }
468
- }
469
- } catch (e) {
470
- // Fallback to Node.js memory API
471
- memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
472
- }
473
-
474
- // Get learning stats for intelligence %
475
- const learning = getLearningStats();
476
-
477
- // Also get AgentDB stats for fallback intelligence calculation
478
- const agentdbStats = getAgentDBStats();
479
-
480
- // Intelligence % — priority chain (ADR-050):
481
- // 1. Intelligence loop data (confidenceMean + accessRatio + density)
482
- // 2. learning.json file metric
483
- // 3. Pattern count / vector count fallback
484
- // 4. Project maturity fallback (below)
485
- let intelligencePct = 0;
486
-
487
- // Priority 1: Intelligence loop real data
488
- if (learning.confidenceMean > 0 || (learning.patterns > 0 && learning.accessedCount > 0)) {
489
- const confScore = Math.min(100, Math.floor(learning.confidenceMean * 100));
490
- const accessRatio = learning.patterns > 0 ? (learning.accessedCount / learning.patterns) : 0;
491
- const accessScore = Math.min(100, Math.floor(accessRatio * 100));
492
- const densityScore = Math.min(100, Math.floor(learning.patterns / 5));
493
- intelligencePct = Math.floor(confScore * 0.4 + accessScore * 0.3 + densityScore * 0.3);
494
- }
495
-
496
- // Priority 2: learning.json file metric
497
- if (intelligencePct === 0 && intelligenceFromFile !== null) {
498
- intelligencePct = intelligenceFromFile;
499
- }
500
-
501
- // Priority 3: Pattern/vector count fallback
502
- if (intelligencePct === 0) {
503
- const fromPatterns = learning.patterns > 0 ? Math.min(100, Math.floor(learning.patterns / 10)) : 0;
504
- const fromVectors = agentdbStats.vectorCount > 0 ? Math.min(100, Math.floor(agentdbStats.vectorCount / 100)) : 0;
505
- intelligencePct = Math.max(fromPatterns, fromVectors);
506
- }
507
-
508
- // If still 0, use project maturity fallback
509
- if (intelligencePct === 0) {
510
- // Final fallback: estimate from project maturity indicators
511
- let maturityScore = 0;
512
-
513
- // Check git commit count (proxy for project development)
514
- try {
515
- const commitCount = parseInt(execSync('git rev-list --count HEAD 2>/dev/null || echo "0"', { encoding: 'utf-8' }).trim());
516
- maturityScore += Math.min(30, Math.floor(commitCount / 10)); // Max 30% from commits
517
- } catch (e) { /* ignore */ }
518
-
519
- // Check for Claude session history
520
- const sessionPaths = [
521
- path.join(process.cwd(), '.claude', 'sessions'),
522
- path.join(process.cwd(), '.claude-flow', 'sessions'),
523
- ];
524
- for (const sessPath of sessionPaths) {
525
- if (fs.existsSync(sessPath)) {
526
- try {
527
- const sessions = fs.readdirSync(sessPath).filter(f => f.endsWith('.json')).length;
528
- maturityScore += Math.min(20, sessions * 2); // Max 20% from sessions
529
- break;
530
- } catch (e) { /* ignore */ }
531
- }
532
- }
533
-
534
- // Check for source files (indicates codebase size)
535
- try {
536
- const srcDirs = ['src', 'lib', 'app', 'packages'];
537
- for (const dir of srcDirs) {
538
- const dirPath = path.join(process.cwd(), dir);
539
- if (fs.existsSync(dirPath)) {
540
- maturityScore += 15; // Base score for having source dir
541
- break;
542
- }
543
- }
544
- } catch (e) { /* ignore */ }
545
-
546
- // Check for test files
547
- try {
548
- const testDirs = ['tests', 'test', '__tests__', 'spec'];
549
- for (const dir of testDirs) {
550
- const dirPath = path.join(process.cwd(), dir);
551
- if (fs.existsSync(dirPath)) {
552
- maturityScore += 10; // Bonus for having tests
553
- break;
554
- }
555
- }
556
- } catch (e) { /* ignore */ }
557
-
558
- // Check for .claude directory (Claude Code usage)
559
- if (fs.existsSync(path.join(process.cwd(), '.claude'))) {
560
- maturityScore += 15; // Bonus for Claude Code integration
561
- }
562
-
563
- // Check for config files (project maturity)
564
- const configFiles = ['package.json', 'tsconfig.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
565
- for (const cfg of configFiles) {
566
- if (fs.existsSync(path.join(process.cwd(), cfg))) {
567
- maturityScore += 5;
568
- break;
569
- }
570
- }
571
-
572
- intelligencePct = Math.min(100, maturityScore);
573
- }
574
-
575
- // Context % based on session history (0 sessions = 0%, grows with usage)
576
- const contextPct = contextFromFile !== null
577
- ? contextFromFile
578
- : Math.min(100, Math.floor(learning.sessions * 5));
579
-
580
- // Count active sub-agents (cross-platform via metrics file)
581
- const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
582
- if (fs.existsSync(activityPath)) {
583
- try {
584
- const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
585
- subAgents = data.processes?.estimated_agents || 0;
586
- } catch (e) {
587
- // Ignore
588
- }
589
- }
590
-
591
- // Fallback to process detection on Unix only
592
- if (subAgents === 0 && !isWindows) {
593
- try {
594
- const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
595
- subAgents = Math.max(0, parseInt(agents.trim()) - 1);
596
- } catch (e) {
597
- // Ignore
598
- }
599
- }
600
-
601
- return {
602
- memoryMB,
603
- contextPct,
604
- intelligencePct,
605
- subAgents,
606
- };
607
- }
608
-
609
- // Get ADR (Architecture Decision Records) status from REAL compliance data
610
- function getADRStatus() {
611
- let compliance = 0;
612
- let totalChecks = 0;
613
- let compliantChecks = 0;
614
- let checks = {};
615
-
616
- // Check adr-compliance.json for REAL compliance data
617
- const compliancePath = path.join(process.cwd(), '.claude-flow', 'metrics', 'adr-compliance.json');
618
- if (fs.existsSync(compliancePath)) {
619
- try {
620
- const data = JSON.parse(fs.readFileSync(compliancePath, 'utf-8'));
621
- compliance = data.compliance || 0;
622
- checks = data.checks || {};
623
- totalChecks = Object.keys(checks).length;
624
- compliantChecks = Object.values(checks).filter(c => c.compliant).length;
625
- return { count: totalChecks, implemented: compliantChecks, compliance };
626
- } catch (e) {
627
- // Fall through to file-based detection
628
- }
629
- }
630
-
631
- // Fallback: count ADR files directly
632
- const adrPaths = [
633
- path.join(process.cwd(), 'docs', 'adrs'),
634
- path.join(process.cwd(), 'docs', 'adr'),
635
- path.join(process.cwd(), 'adr'),
636
- path.join(process.cwd(), 'ADR'),
637
- path.join(process.cwd(), '.claude-flow', 'adrs'),
638
- path.join(process.cwd(), 'v3', 'implementation', 'adrs'),
639
- path.join(process.cwd(), 'implementation', 'adrs'),
640
- ];
641
-
642
- let count = 0;
643
- let implemented = 0;
644
-
645
- for (const adrPath of adrPaths) {
646
- if (fs.existsSync(adrPath)) {
647
- try {
648
- const files = fs.readdirSync(adrPath).filter(f =>
649
- f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f))
650
- );
651
- count = files.length;
652
-
653
- for (const file of files) {
654
- try {
655
- const content = fs.readFileSync(path.join(adrPath, file), 'utf-8');
656
- if (content.includes('Status: Implemented') || content.includes('status: implemented') ||
657
- content.includes('Status: Accepted') || content.includes('status: accepted')) {
658
- implemented++;
659
- }
660
- } catch (e) {
661
- // Skip unreadable files
662
- }
663
- }
664
- break;
665
- } catch (e) {
666
- // Ignore
667
- }
668
- }
669
- }
670
-
671
- compliance = count > 0 ? Math.floor((implemented / count) * 100) : 0;
672
- return { count, implemented, compliance };
673
- }
674
-
675
- // Get hooks status (enabled/registered hooks)
676
- function getHooksStatus() {
677
- let enabled = 0;
678
- let total = 17; // V3 has 17 hook types
679
-
680
- // Check .claude/settings.json for hooks config
681
- const settingsPaths = [
682
- path.join(process.cwd(), '.claude', 'settings.json'),
683
- path.join(process.cwd(), '.claude', 'settings.local.json'),
684
- ];
685
-
686
- for (const settingsPath of settingsPaths) {
687
- if (fs.existsSync(settingsPath)) {
688
- try {
689
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
690
- if (settings.hooks) {
691
- // Claude Code native hooks format: PreToolUse, PostToolUse, SessionStart, etc.
692
- const hookCategories = Object.keys(settings.hooks);
693
- for (const category of hookCategories) {
694
- const categoryHooks = settings.hooks[category];
695
- if (Array.isArray(categoryHooks) && categoryHooks.length > 0) {
696
- // Count categories with at least one hook defined
697
- enabled++;
698
- }
699
- }
700
- }
701
- break;
702
- } catch (e) {
703
- // Ignore parse errors
704
- }
705
- }
706
- }
707
-
708
- // Also check for hook files in .claude/hooks
709
- const hooksDir = path.join(process.cwd(), '.claude', 'hooks');
710
- if (fs.existsSync(hooksDir)) {
711
- try {
712
- const hookFiles = fs.readdirSync(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.sh'));
713
- enabled = Math.max(enabled, hookFiles.length);
714
- } catch (e) {
715
- // Ignore
716
- }
717
- }
718
-
719
- return { enabled, total };
720
- }
721
-
722
- // Get AgentDB memory stats
723
- function getAgentDBStats() {
724
- let vectorCount = 0;
725
- let dbSizeKB = 0;
726
- let namespaces = 0;
727
- let hasHnsw = false;
728
-
729
- // Check for database directories
730
- const dbDirPaths = [
731
- path.join(process.cwd(), '.claude-flow', 'agentdb'),
732
- path.join(process.cwd(), '.swarm', 'agentdb'),
733
- path.join(process.cwd(), 'data', 'agentdb'),
734
- path.join(process.cwd(), '.claude', 'memory'),
735
- path.join(process.cwd(), '.agentdb'),
736
- ];
737
-
738
- // Check for direct database files (memory.db, etc.)
739
- const dbFilePaths = [
740
- path.join(process.cwd(), '.swarm', 'memory.db'),
741
- path.join(process.cwd(), '.claude-flow', 'memory.db'),
742
- path.join(process.cwd(), '.claude', 'memory.db'),
743
- path.join(process.cwd(), 'data', 'memory.db'),
744
- path.join(process.cwd(), 'memory.db'),
745
- ];
746
-
747
- // Check for HNSW index files
748
- const hnswPaths = [
749
- path.join(process.cwd(), '.swarm', 'hnsw.index'),
750
- path.join(process.cwd(), '.claude-flow', 'hnsw.index'),
751
- path.join(process.cwd(), 'data', 'hnsw.index'),
752
- ];
753
-
754
- // Check direct database files first
755
- for (const dbFile of dbFilePaths) {
756
- if (fs.existsSync(dbFile)) {
757
- try {
758
- const stats = fs.statSync(dbFile);
759
- dbSizeKB = stats.size / 1024;
760
- // Estimate vectors: ~2KB per vector for SQLite with embeddings
761
- vectorCount = Math.floor(dbSizeKB / 2);
762
- namespaces = 1;
763
- break;
764
- } catch (e) {
765
- // Ignore
766
- }
767
- }
768
- }
769
-
770
- // Check database directories if no direct file found
771
- if (vectorCount === 0) {
772
- for (const dbPath of dbDirPaths) {
773
- if (fs.existsSync(dbPath)) {
774
- try {
775
- const stats = fs.statSync(dbPath);
776
- if (stats.isDirectory()) {
777
- const files = fs.readdirSync(dbPath);
778
- namespaces = files.filter(f => f.endsWith('.db') || f.endsWith('.sqlite')).length;
779
-
780
- for (const file of files) {
781
- const filePath = path.join(dbPath, file);
782
- const fileStat = fs.statSync(filePath);
783
- if (fileStat.isFile()) {
784
- dbSizeKB += fileStat.size / 1024;
785
- }
786
- }
787
-
788
- vectorCount = Math.floor(dbSizeKB / 2);
789
- }
790
- break;
791
- } catch (e) {
792
- // Ignore
793
- }
794
- }
795
- }
796
- }
797
-
798
- // Check for HNSW index (indicates vector search capability)
799
- for (const hnswPath of hnswPaths) {
800
- if (fs.existsSync(hnswPath)) {
801
- hasHnsw = true;
802
- try {
803
- const stats = fs.statSync(hnswPath);
804
- // HNSW index: ~0.5KB per vector
805
- const hnswVectors = Math.floor(stats.size / 1024 / 0.5);
806
- vectorCount = Math.max(vectorCount, hnswVectors);
807
- } catch (e) {
808
- // Ignore
809
- }
810
- break;
811
- }
812
- }
813
-
814
- // Also check for vectors.json (simple vector store)
815
- const vectorsPath = path.join(process.cwd(), '.claude-flow', 'vectors.json');
816
- if (fs.existsSync(vectorsPath) && vectorCount === 0) {
817
- try {
818
- const data = JSON.parse(fs.readFileSync(vectorsPath, 'utf-8'));
819
- if (Array.isArray(data)) {
820
- vectorCount = data.length;
821
- } else if (data.vectors) {
822
- vectorCount = Object.keys(data.vectors).length;
823
- }
824
- } catch (e) {
825
- // Ignore
826
- }
827
- }
828
-
829
- return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces, hasHnsw };
830
- }
831
-
832
- // Get test statistics
833
- function getTestStats() {
834
- let testFiles = 0;
835
- let testCases = 0;
836
-
837
- const testDirs = [
838
- path.join(process.cwd(), 'tests'),
839
- path.join(process.cwd(), 'test'),
840
- path.join(process.cwd(), '__tests__'),
841
- path.join(process.cwd(), 'src', '__tests__'),
842
- path.join(process.cwd(), 'v3', '__tests__'),
843
- ];
844
-
845
- // Recursively count test files
846
- function countTestFiles(dir, depth = 0) {
847
- if (depth > 3) return; // Limit recursion
848
- if (!fs.existsSync(dir)) return;
849
-
850
- try {
851
- const entries = fs.readdirSync(dir, { withFileTypes: true });
852
- for (const entry of entries) {
853
- if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
854
- countTestFiles(path.join(dir, entry.name), depth + 1);
855
- } else if (entry.isFile()) {
856
- const name = entry.name;
857
- if (name.includes('.test.') || name.includes('.spec.') ||
858
- name.includes('_test.') || name.includes('_spec.') ||
859
- name.startsWith('test_') || name.startsWith('spec_')) {
860
- testFiles++;
861
-
862
- // Try to estimate test cases from file
863
- try {
864
- const content = fs.readFileSync(path.join(dir, name), 'utf-8');
865
- // Count it(), test(), describe() patterns
866
- const itMatches = (content.match(/\\bit\\s*\\(/g) || []).length;
867
- const testMatches = (content.match(/\\btest\\s*\\(/g) || []).length;
868
- testCases += itMatches + testMatches;
869
- } catch (e) {
870
- // Estimate 3 tests per file if can't read
871
- testCases += 3;
872
- }
873
- }
874
- }
875
- }
876
- } catch (e) {
877
- // Ignore
878
- }
879
- }
880
-
881
- for (const dir of testDirs) {
882
- countTestFiles(dir);
883
- }
884
-
885
- // Also check src directory for colocated tests
886
- const srcDir = path.join(process.cwd(), 'src');
887
- if (fs.existsSync(srcDir)) {
888
- countTestFiles(srcDir);
889
- }
890
-
891
- return { testFiles, testCases };
892
- }
893
-
894
- // Get integration status (MCP servers, external connections)
895
- function getIntegrationStatus() {
896
- let mcpServers = { total: 0, enabled: 0, names: [] };
897
- let hasDatabase = false;
898
- let hasCache = false;
899
- let hasApi = false;
900
-
901
- // Check for MCP servers in settings
902
- const settingsPaths = [
903
- path.join(process.cwd(), '.claude', 'settings.json'),
904
- path.join(process.cwd(), '.claude', 'settings.local.json'),
905
- ];
906
-
907
- for (const settingsPath of settingsPaths) {
908
- if (fs.existsSync(settingsPath)) {
909
- try {
910
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
911
-
912
- // Check mcpServers object
913
- if (settings.mcpServers && typeof settings.mcpServers === 'object') {
914
- const servers = Object.keys(settings.mcpServers);
915
- mcpServers.total = servers.length;
916
- mcpServers.names = servers;
917
-
918
- // Check enabledMcpjsonServers for enabled count
919
- if (settings.enabledMcpjsonServers && Array.isArray(settings.enabledMcpjsonServers)) {
920
- mcpServers.enabled = settings.enabledMcpjsonServers.filter(s => servers.includes(s)).length;
921
- } else {
922
- mcpServers.enabled = mcpServers.total; // Assume all enabled if not specified
923
- }
924
- }
925
- break;
926
- } catch (e) { /* ignore */ }
927
- }
928
- }
929
-
930
- // Also check .mcp.json or mcp.json
931
- const mcpConfigPaths = [
932
- path.join(process.cwd(), '.mcp.json'),
933
- path.join(process.cwd(), 'mcp.json'),
934
- path.join(require('os').homedir(), '.claude', 'mcp.json'),
935
- ];
936
-
937
- for (const mcpPath of mcpConfigPaths) {
938
- if (fs.existsSync(mcpPath) && mcpServers.total === 0) {
939
- try {
940
- const config = JSON.parse(fs.readFileSync(mcpPath, 'utf-8'));
941
- if (config.mcpServers) {
942
- const servers = Object.keys(config.mcpServers);
943
- mcpServers.total = servers.length;
944
- mcpServers.names = servers;
945
- mcpServers.enabled = servers.length;
946
- }
947
- } catch (e) { /* ignore */ }
948
- }
949
- }
950
-
951
- // Check for database (AgentDB, SQLite, etc.)
952
- const dbPaths = [
953
- path.join(process.cwd(), '.swarm', 'memory.db'),
954
- path.join(process.cwd(), '.claude-flow', 'memory.db'),
955
- path.join(process.cwd(), 'data', 'memory.db'),
956
- ];
957
- hasDatabase = dbPaths.some(p => fs.existsSync(p));
958
-
959
- // Check for cache
960
- const cachePaths = [
961
- path.join(process.cwd(), '.claude-flow', 'cache'),
962
- path.join(process.cwd(), '.cache'),
963
- path.join(process.cwd(), 'node_modules', '.cache'),
964
- ];
965
- hasCache = cachePaths.some(p => fs.existsSync(p));
966
-
967
- // Check for API configuration (env vars or config)
968
- try {
969
- hasApi = !!(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY);
970
- } catch (e) { /* ignore */ }
971
-
972
- return { mcpServers, hasDatabase, hasCache, hasApi };
973
- }
974
-
975
- // Get git status (uncommitted changes, untracked files) - cross-platform
976
- function getGitStatus() {
977
- let modified = 0;
978
- let untracked = 0;
979
- let staged = 0;
980
- let ahead = 0;
981
- let behind = 0;
982
- const isWindows = process.platform === 'win32';
983
-
984
- try {
985
- // Get modified and staged counts - works on all platforms
986
- const status = execSync('git status --porcelain', {
987
- encoding: 'utf-8',
988
- stdio: ['pipe', 'pipe', 'pipe'], // Suppress stderr
989
- timeout: 5000,
990
- });
991
- const lines = status.trim().split('\\n').filter(l => l);
992
- for (const line of lines) {
993
- const code = line.substring(0, 2);
994
- if (code.includes('M') || code.includes('D') || code.includes('R')) {
995
- if (code[0] !== ' ') staged++;
996
- if (code[1] !== ' ') modified++;
997
- }
998
- if (code.includes('?')) untracked++;
999
- if (code.includes('A')) staged++;
1000
- }
1001
-
1002
- // Get ahead/behind - may fail if no upstream
1003
- try {
1004
- const abStatus = execSync('git rev-list --left-right --count HEAD...@{upstream}', {
1005
- encoding: 'utf-8',
1006
- stdio: ['pipe', 'pipe', 'pipe'],
1007
- timeout: 5000,
1008
- });
1009
- const parts = abStatus.trim().split(/\\s+/);
1010
- ahead = parseInt(parts[0]) || 0;
1011
- behind = parseInt(parts[1]) || 0;
1012
- } catch (e) { /* no upstream or error - that's ok */ }
1013
-
1014
- } catch (e) {
1015
- // Not a git repo or git not installed - return zeros
1016
- }
1017
-
1018
- return { modified, untracked, staged, ahead, behind };
1019
- }
1020
-
1021
- // Get session statistics
1022
- function getSessionStats() {
1023
- let sessionStart = null;
1024
- let duration = '';
1025
- let lastActivity = '';
1026
- let operationsCount = 0;
1027
-
1028
- // Check for session file
1029
- const sessionPaths = [
1030
- path.join(process.cwd(), '.claude-flow', 'session.json'),
1031
- path.join(process.cwd(), '.claude', 'session.json'),
1032
- ];
1033
-
1034
- for (const sessPath of sessionPaths) {
1035
- if (fs.existsSync(sessPath)) {
1036
- try {
1037
- const data = JSON.parse(fs.readFileSync(sessPath, 'utf-8'));
1038
- if (data.startTime) {
1039
- sessionStart = new Date(data.startTime);
1040
- const now = new Date();
1041
- const diffMs = now.getTime() - sessionStart.getTime();
1042
- const diffMins = Math.floor(diffMs / 60000);
1043
- if (diffMins < 60) {
1044
- duration = \`\${diffMins}m\`;
1045
- } else {
1046
- const hours = Math.floor(diffMins / 60);
1047
- const mins = diffMins % 60;
1048
- duration = \`\${hours}h\${mins}m\`;
1049
- }
1050
- }
1051
- if (data.lastActivity) {
1052
- const last = new Date(data.lastActivity);
1053
- const now = new Date();
1054
- const diffMs = now.getTime() - last.getTime();
1055
- const diffMins = Math.floor(diffMs / 60000);
1056
- if (diffMins < 1) lastActivity = 'now';
1057
- else if (diffMins < 60) lastActivity = \`\${diffMins}m ago\`;
1058
- else lastActivity = \`\${Math.floor(diffMins / 60)}h ago\`;
1059
- }
1060
- operationsCount = data.operationsCount || data.commandCount || 0;
1061
- break;
1062
- } catch (e) { /* ignore */ }
1063
- }
1064
- }
1065
-
1066
- // Fallback: check metrics for activity
1067
- if (!duration) {
1068
- const metricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'activity.json');
1069
- if (fs.existsSync(metricsPath)) {
1070
- try {
1071
- const data = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
1072
- operationsCount = data.totalOperations || 0;
1073
- } catch (e) { /* ignore */ }
1074
- }
1075
- }
1076
-
1077
- return { duration, lastActivity, operationsCount };
1078
- }
1079
-
1080
- // Get trend indicator based on change
1081
- function getTrend(current, previous) {
1082
- if (previous === null || previous === undefined) return '';
1083
- if (current > previous) return \`\${c.brightGreen}↑\${c.reset}\`;
1084
- if (current < previous) return \`\${c.brightRed}↓\${c.reset}\`;
1085
- return \`\${c.dim}→\${c.reset}\`;
1086
- }
1087
-
1088
- // Store previous values for trends (persisted between calls)
1089
- let prevIntelligence = null;
1090
- try {
1091
- const trendPath = path.join(process.cwd(), '.claude-flow', '.trend-cache.json');
1092
- if (fs.existsSync(trendPath)) {
1093
- const data = JSON.parse(fs.readFileSync(trendPath, 'utf-8'));
1094
- prevIntelligence = data.intelligence;
1095
- }
1096
- } catch (e) { /* ignore */ }
1097
-
1098
- // Generate progress bar
1099
- function progressBar(current, total) {
1100
- const width = 5;
1101
- const filled = Math.round((current / total) * width);
1102
- const empty = width - filled;
1103
- return '[' + '\\u25CF'.repeat(filled) + '\\u25CB'.repeat(empty) + ']';
1104
- }
1105
-
1106
- // Generate full statusline
1107
- function generateStatusline() {
1108
- const user = getUserInfo();
1109
- const progress = getV3Progress();
1110
- const security = getSecurityStatus();
1111
- const swarm = getSwarmStatus();
1112
- const system = getSystemMetrics();
1113
- const adrs = getADRStatus();
1114
- const hooks = getHooksStatus();
1115
- const agentdb = getAgentDBStats();
1116
- const tests = getTestStats();
1117
- const git = getGitStatus();
1118
- const session = getSessionStats();
1119
- const integration = getIntegrationStatus();
1120
- const lines = [];
1121
-
1122
- // Calculate intelligence trend
1123
- const intellTrend = getTrend(system.intelligencePct, prevIntelligence);
1124
-
1125
- // Save current values for next trend calculation
1126
- try {
1127
- const trendPath = path.join(process.cwd(), '.claude-flow', '.trend-cache.json');
1128
- const trendDir = path.dirname(trendPath);
1129
- if (!fs.existsSync(trendDir)) fs.mkdirSync(trendDir, { recursive: true });
1130
- fs.writeFileSync(trendPath, JSON.stringify({ intelligence: system.intelligencePct, timestamp: Date.now() }));
1131
- } catch (e) { /* ignore */ }
1132
-
1133
- // Header Line with git changes indicator
1134
- let header = \`\${c.bold}\${c.brightPurple}▊ KynjalFlow\${c.reset}\`;
1135
- header += \`\${swarm.coordinationActive ? c.brightCyan : c.dim}● \${c.brightCyan}\${user.name}\${c.reset}\`;
1136
- if (user.gitBranch) {
1137
- header += \` \${c.dim}│\${c.reset} \${c.brightBlue}⎇ \${user.gitBranch}\${c.reset}\`;
1138
- // Add git changes indicator
1139
- const gitChanges = git.modified + git.staged + git.untracked;
1140
- if (gitChanges > 0) {
1141
- let gitIndicator = '';
1142
- if (git.staged > 0) gitIndicator += \`\${c.brightGreen}+\${git.staged}\${c.reset}\`;
1143
- if (git.modified > 0) gitIndicator += \`\${c.brightYellow}~\${git.modified}\${c.reset}\`;
1144
- if (git.untracked > 0) gitIndicator += \`\${c.dim}?\${git.untracked}\${c.reset}\`;
1145
- header += \` \${gitIndicator}\`;
1146
- }
1147
- // Add ahead/behind indicator
1148
- if (git.ahead > 0 || git.behind > 0) {
1149
- if (git.ahead > 0) header += \` \${c.brightGreen}↑\${git.ahead}\${c.reset}\`;
1150
- if (git.behind > 0) header += \` \${c.brightRed}↓\${git.behind}\${c.reset}\`;
1151
- }
1152
- }
1153
- header += \` \${c.dim}│\${c.reset} \${c.purple}\${user.modelName}\${c.reset}\`;
1154
- // Add session duration if available
1155
- if (session.duration) {
1156
- header += \` \${c.dim}│\${c.reset} \${c.cyan}⏱ \${session.duration}\${c.reset}\`;
1157
- }
1158
- lines.push(header);
1159
-
1160
- // Separator
1161
- lines.push(\`\${c.dim}─────────────────────────────────────────────────────\${c.reset}\`);
1162
-
1163
- // Line 1: DDD Domain Progress with dynamic performance indicator
1164
- const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
1165
- // Show HNSW speedup if enabled, otherwise show patterns learned
1166
- let perfIndicator = '';
1167
- if (agentdb.hasHnsw && agentdb.vectorCount > 0) {
1168
- // HNSW enabled: show estimated speedup (150x-12500x based on vector count)
1169
- const speedup = agentdb.vectorCount > 10000 ? '12500x' : agentdb.vectorCount > 1000 ? '150x' : '10x';
1170
- perfIndicator = \`\${c.brightGreen}⚡ HNSW \${speedup}\${c.reset}\`;
1171
- } else if (progress.patternsLearned > 0) {
1172
- // Show patterns learned
1173
- const patternsK = progress.patternsLearned >= 1000
1174
- ? \`\${(progress.patternsLearned / 1000).toFixed(1)}k\`
1175
- : String(progress.patternsLearned);
1176
- perfIndicator = \`\${c.brightYellow}📚 \${patternsK} patterns\${c.reset}\`;
1177
- } else {
1178
- // New project: show target
1179
- perfIndicator = \`\${c.dim}⚡ target: 150x-12500x\${c.reset}\`;
1180
- }
1181
- lines.push(
1182
- \`\${c.brightCyan}🏗️ DDD Domains\${c.reset} \${progressBar(progress.domainsCompleted, progress.totalDomains)} \` +
1183
- \`\${domainsColor}\${progress.domainsCompleted}\${c.reset}/\${c.brightWhite}\${progress.totalDomains}\${c.reset} \` +
1184
- perfIndicator
1185
- );
1186
-
1187
- // Line 2: Swarm + Hooks + CVE + Memory + Context + Intelligence
1188
- const swarmIndicator = swarm.coordinationActive ? \`\${c.brightGreen}◉\${c.reset}\` : \`\${c.dim}○\${c.reset}\`;
1189
- const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
1190
- let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
1191
- let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;
1192
- const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;
1193
-
1194
- lines.push(
1195
- \`\${c.brightYellow}🤖 Swarm\${c.reset} \${swarmIndicator} [\${agentsColor}\${String(swarm.activeAgents).padStart(2)}\${c.reset}/\${c.brightWhite}\${swarm.maxAgents}\${c.reset}] \` +
1196
- \`\${c.brightPurple}👥 \${system.subAgents}\${c.reset} \` +
1197
- \`\${c.brightBlue}🪝 \${hooksColor}\${hooks.enabled}\${c.reset}/\${c.brightWhite}\${hooks.total}\${c.reset} \` +
1198
- \`\${securityIcon} \${securityColor}CVE \${security.cvesFixed}\${c.reset}/\${c.brightWhite}\${security.totalCves}\${c.reset} \` +
1199
- \`\${c.brightCyan}💾 \${system.memoryMB}MB\${c.reset} \` +
1200
- \`\${system.intelligencePct >= 80 ? c.brightGreen : system.intelligencePct >= 40 ? c.brightYellow : c.dim}🧠 \${String(system.intelligencePct).padStart(3)}%\${intellTrend}\${c.reset}\`
1201
- );
1202
-
1203
- // Line 3: Architecture status with ADRs, AgentDB, Tests
1204
- const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
1205
- const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;
1206
- const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
1207
- const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;
1208
-
1209
- // Show ADR compliance % if from real data, otherwise show count
1210
- const adrDisplay = adrs.compliance > 0
1211
- ? \`\${adrColor}●\${adrs.compliance}%\${c.reset}\`
1212
- : \`\${adrColor}●\${adrs.implemented}/\${adrs.count}\${c.reset}\`;
1213
-
1214
- lines.push(
1215
- \`\${c.brightPurple}🔧 Architecture\${c.reset} \` +
1216
- \`\${c.cyan}ADRs\${c.reset} \${adrDisplay} \${c.dim}│\${c.reset} \` +
1217
- \`\${c.cyan}DDD\${c.reset} \${dddColor}●\${String(progress.dddProgress).padStart(3)}%\${c.reset} \${c.dim}│\${c.reset} \` +
1218
- \`\${c.cyan}Security\${c.reset} \${securityColor}●\${security.status}\${c.reset}\`
1219
- );
1220
-
1221
- // Line 4: Memory, Vectors, Tests
1222
- const hnswIndicator = agentdb.hasHnsw ? \`\${c.brightGreen}⚡\${c.reset}\` : '';
1223
- const sizeDisplay = agentdb.dbSizeKB >= 1024
1224
- ? \`\${(agentdb.dbSizeKB / 1024).toFixed(1)}MB\`
1225
- : \`\${agentdb.dbSizeKB}KB\`;
1226
- // Build integration status string
1227
- let integrationStr = '';
1228
- if (integration.mcpServers.total > 0) {
1229
- const mcpColor = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
1230
- integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
1231
- integrationStr += \`\${c.cyan}MCP\${c.reset} \${mcpColor}●\${integration.mcpServers.enabled}/\${integration.mcpServers.total}\${c.reset}\`;
1232
- }
1233
- if (integration.hasDatabase) {
1234
- integrationStr += (integrationStr ? ' ' : '') + \`\${c.brightGreen}◆\${c.reset}DB\`;
1235
- }
1236
- if (integration.hasApi) {
1237
- integrationStr += (integrationStr ? ' ' : '') + \`\${c.brightGreen}◆\${c.reset}API\`;
1238
- }
1239
- if (!integrationStr) {
1240
- integrationStr = \`\${c.dim}●none\${c.reset}\`;
1241
- }
1242
-
1243
- lines.push(
1244
- \`\${c.brightCyan}📊 AgentDB\${c.reset} \` +
1245
- \`\${c.cyan}Vectors\${c.reset} \${vectorColor}●\${agentdb.vectorCount}\${hnswIndicator}\${c.reset} \${c.dim}│\${c.reset} \` +
1246
- \`\${c.cyan}Size\${c.reset} \${c.brightWhite}\${sizeDisplay}\${c.reset} \${c.dim}│\${c.reset} \` +
1247
- \`\${c.cyan}Tests\${c.reset} \${testColor}●\${tests.testFiles}\${c.reset} \${c.dim}(\${tests.testCases} cases)\${c.reset} \${c.dim}│\${c.reset} \` +
1248
- integrationStr
1249
- );
1250
-
1251
- return lines.join('\\n');
1252
- }
1253
-
1254
- // Generate JSON data
1255
- function generateJSON() {
1256
- return {
1257
- user: getUserInfo(),
1258
- v3Progress: getV3Progress(),
1259
- security: getSecurityStatus(),
1260
- swarm: getSwarmStatus(),
1261
- system: getSystemMetrics(),
1262
- adrs: getADRStatus(),
1263
- hooks: getHooksStatus(),
1264
- agentdb: getAgentDBStats(),
1265
- tests: getTestStats(),
1266
- performance: {
1267
- flashAttentionTarget: '2.49x-7.47x',
1268
- searchImprovement: '150x-12,500x',
1269
- memoryReduction: '50-75%',
1270
- },
1271
- lastUpdated: new Date().toISOString(),
1272
- };
1273
- }
1274
-
1275
- // Main
1276
- if (process.argv.includes('--json')) {
1277
- console.log(JSON.stringify(generateJSON(), null, 2));
1278
- } else if (process.argv.includes('--compact')) {
1279
- console.log(JSON.stringify(generateJSON()));
1280
- } else {
1281
- console.log(generateStatusline());
1282
- }
1283
- `;
23
+ var maxAgents = options.runtime.maxAgents;
24
+ return "#!/usr/bin/env node\n/**\n * RuFlo V3 Statusline Generator (Optimized)\n * Displays real-time V3 implementation progress and system status\n *\n * Usage: node statusline.cjs [--json] [--compact]\n *\n * Performance notes:\n * - Single git execSync call (combines branch + status + upstream)\n * - No recursive file reading (only stat/readdir, never read test contents)\n * - No ps aux calls (uses process.memoryUsage() + file-based metrics)\n * - Strict 2s timeout on all execSync calls\n * - Shared settings cache across functions\n */\n\n/* eslint-disable @typescript-eslint/no-var-requires */\nconst fs = require('fs');\nconst path = require('path');\nconst { execSync } = require('child_process');\nconst os = require('os');\n\n// Configuration\nconst CONFIG = {\n maxAgents: " + maxAgents + ",\n};\n\nconst CWD = process.cwd();\n\n// ANSI colors\nconst c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[0;31m',\n green: '\\x1b[0;32m',\n yellow: '\\x1b[0;33m',\n blue: '\\x1b[0;34m',\n purple: '\\x1b[0;35m',\n cyan: '\\x1b[0;36m',\n brightRed: '\\x1b[1;31m',\n brightGreen: '\\x1b[1;32m',\n brightYellow: '\\x1b[1;33m',\n brightBlue: '\\x1b[1;34m',\n brightPurple: '\\x1b[1;35m',\n brightCyan: '\\x1b[1;36m',\n brightWhite: '\\x1b[1;37m',\n};\n\n// Safe execSync with strict timeout (returns empty string on failure)\nfunction safeExec(cmd, timeoutMs = 2000) {\n try {\n return execSync(cmd, {\n encoding: 'utf-8',\n timeout: timeoutMs,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return '';\n }\n}\n\n// Safe JSON file reader (returns null on failure)\nfunction readJSON(filePath) {\n try {\n if (fs.existsSync(filePath)) {\n return JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n }\n } catch { /* ignore */ }\n return null;\n}\n\n// Safe file stat (returns null on failure)\nfunction safeStat(filePath) {\n try {\n return fs.statSync(filePath);\n } catch { /* ignore */ }\n return null;\n}\n\n// Shared settings cache \u2014 read once, used by multiple functions\nlet _settingsCache = undefined;\nfunction getSettings() {\n if (_settingsCache !== undefined) return _settingsCache;\n _settingsCache = readJSON(path.join(CWD, '.claude', 'settings.json'))\n || readJSON(path.join(CWD, '.claude', 'settings.local.json'))\n || null;\n return _settingsCache;\n}\n\n// \u2500\u2500\u2500 Data Collection (all pure-Node.js or single-exec) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Get all git info in ONE shell call\nfunction getGitInfo() {\n const result = {\n name: 'user', gitBranch: '', modified: 0, untracked: 0,\n staged: 0, ahead: 0, behind: 0,\n };\n\n // Single shell: get user.name, branch, porcelain status, and upstream diff\n const script = [\n 'git config user.name 2>/dev/null || echo user',\n 'echo \"---SEP---\"',\n 'git branch --show-current 2>/dev/null',\n 'echo \"---SEP---\"',\n 'git status --porcelain 2>/dev/null',\n 'echo \"---SEP---\"',\n 'git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo \"0 0\"',\n ].join('; ');\n\n const raw = safeExec(\"sh -c '\" + script + \"'\", 3000);\n if (!raw) return result;\n\n const parts = raw.split('---SEP---').map(s => s.trim());\n if (parts.length >= 4) {\n result.name = parts[0] || 'user';\n result.gitBranch = parts[1] || '';\n\n // Parse porcelain status\n if (parts[2]) {\n for (const line of parts[2].split('\\n')) {\n if (!line || line.length < 2) continue;\n const x = line[0], y = line[1];\n if (x === '?' && y === '?') { result.untracked++; continue; }\n if (x !== ' ' && x !== '?') result.staged++;\n if (y !== ' ' && y !== '?') result.modified++;\n }\n }\n\n // Parse ahead/behind\n const ab = (parts[3] || '0 0').split(/\\s+/);\n result.ahead = parseInt(ab[0]) || 0;\n result.behind = parseInt(ab[1]) || 0;\n }\n\n return result;\n}\n\n// Detect model name from Claude config (pure file reads, no exec)\nfunction getModelName() {\n try {\n const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));\n if (claudeConfig && claudeConfig.projects) {\n for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {\n if (CWD === projectPath || CWD.startsWith(projectPath + '/')) {\n const usage = projectConfig.lastModelUsage;\n if (usage) {\n const ids = Object.keys(usage);\n if (ids.length > 0) {\n let modelId = ids[ids.length - 1];\n let latest = 0;\n for (const id of ids) {\n const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;\n if (ts > latest) { latest = ts; modelId = id; }\n }\n if (modelId.includes('opus')) return 'Opus 4.6 (1M context)';\n if (modelId.includes('sonnet')) return 'Sonnet 4.6';\n if (modelId.includes('haiku')) return 'Haiku 4.5';\n return modelId.split('-').slice(1, 3).join(' ');\n }\n }\n break;\n }\n }\n }\n } catch { /* ignore */ }\n\n // Fallback: settings.json model field\n const settings = getSettings();\n if (settings && settings.model) {\n const m = settings.model;\n if (m.includes('opus')) return 'Opus 4.6 (1M context)';\n if (m.includes('sonnet')) return 'Sonnet 4.6';\n if (m.includes('haiku')) return 'Haiku 4.5';\n }\n return 'Claude Code';\n}\n\n// Get learning stats from memory database (pure stat calls)\nfunction getLearningStats() {\n const memoryPaths = [\n path.join(CWD, '.swarm', 'memory.db'),\n path.join(CWD, '.claude-flow', 'memory.db'),\n path.join(CWD, '.claude', 'memory.db'),\n path.join(CWD, 'data', 'memory.db'),\n path.join(CWD, '.agentdb', 'memory.db'),\n ];\n\n for (const dbPath of memoryPaths) {\n const stat = safeStat(dbPath);\n if (stat) {\n const sizeKB = stat.size / 1024;\n const patterns = Math.floor(sizeKB / 2);\n return {\n patterns,\n sessions: Math.max(1, Math.floor(patterns / 10)),\n };\n }\n }\n\n // Check session files count\n let sessions = 0;\n try {\n const sessDir = path.join(CWD, '.claude', 'sessions');\n if (fs.existsSync(sessDir)) {\n sessions = fs.readdirSync(sessDir).filter(f => f.endsWith('.json')).length;\n }\n } catch { /* ignore */ }\n\n return { patterns: 0, sessions };\n}\n\n// V3 progress from metrics files (pure file reads)\nfunction getV3Progress() {\n const learning = getLearningStats();\n const totalDomains = 5;\n\n const dddData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'ddd-progress.json'));\n let dddProgress = dddData ? (dddData.progress || 0) : 0;\n let domainsCompleted = Math.min(5, Math.floor(dddProgress / 20));\n\n if (dddProgress === 0 && learning.patterns > 0) {\n if (learning.patterns >= 500) domainsCompleted = 5;\n else if (learning.patterns >= 200) domainsCompleted = 4;\n else if (learning.patterns >= 100) domainsCompleted = 3;\n else if (learning.patterns >= 50) domainsCompleted = 2;\n else if (learning.patterns >= 10) domainsCompleted = 1;\n dddProgress = Math.floor((domainsCompleted / totalDomains) * 100);\n }\n\n return {\n domainsCompleted, totalDomains, dddProgress,\n patternsLearned: learning.patterns,\n sessionsCompleted: learning.sessions,\n };\n}\n\n// Security status (pure file reads)\nfunction getSecurityStatus() {\n const auditData = readJSON(path.join(CWD, '.claude-flow', 'security', 'audit-status.json'));\n if (auditData) {\n const auditDate = auditData.lastAudit || auditData.lastScan;\n if (!auditDate) {\n return { status: 'PENDING', cvesFixed: 0, totalCves: 0 };\n }\n const auditAge = Date.now() - new Date(auditDate).getTime();\n const isStale = auditAge > 7 * 24 * 60 * 60 * 1000;\n return {\n status: isStale ? 'STALE' : (auditData.status || 'PENDING'),\n cvesFixed: auditData.cvesFixed || 0,\n totalCves: auditData.totalCves || 0,\n };\n }\n\n let scanCount = 0;\n try {\n const scanDir = path.join(CWD, '.claude', 'security-scans');\n if (fs.existsSync(scanDir)) {\n scanCount = fs.readdirSync(scanDir).filter(f => f.endsWith('.json')).length;\n }\n } catch { /* ignore */ }\n\n return {\n status: scanCount > 0 ? 'SCANNED' : 'NONE',\n cvesFixed: 0,\n totalCves: 0,\n };\n}\n\n// Swarm status (pure file reads, NO ps aux)\nfunction getSwarmStatus() {\n const staleThresholdMs = 5 * 60 * 1000;\n const now = Date.now();\n\n const swarmStatePath = path.join(CWD, '.claude-flow', 'swarm', 'swarm-state.json');\n const swarmState = readJSON(swarmStatePath);\n if (swarmState) {\n const updatedAt = swarmState.updatedAt || swarmState.startedAt;\n const age = updatedAt ? now - new Date(updatedAt).getTime() : Infinity;\n if (age < staleThresholdMs) {\n return {\n activeAgents: (swarmState.agents && swarmState.agents.length) || swarmState.agentCount || 0,\n maxAgents: swarmState.maxAgents || CONFIG.maxAgents,\n coordinationActive: true,\n };\n }\n }\n\n const activityData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'swarm-activity.json'));\n if (activityData && activityData.swarm) {\n const updatedAt = activityData.timestamp || (activityData.swarm && activityData.swarm.timestamp);\n const age = updatedAt ? now - new Date(updatedAt).getTime() : Infinity;\n if (age < staleThresholdMs) {\n return {\n activeAgents: activityData.swarm.agent_count || 0,\n maxAgents: CONFIG.maxAgents,\n coordinationActive: activityData.swarm.coordination_active || activityData.swarm.active || false,\n };\n }\n }\n\n return { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false };\n}\n\n// System metrics (uses process.memoryUsage() \u2014 no shell spawn)\nfunction getSystemMetrics() {\n const memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);\n const learning = getLearningStats();\n const agentdb = getAgentDBStats();\n\n // Intelligence from learning.json\n const learningData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'learning.json'));\n let intelligencePct = 0;\n let contextPct = 0;\n\n if (learningData && learningData.intelligence && learningData.intelligence.score !== undefined) {\n intelligencePct = Math.min(100, Math.floor(learningData.intelligence.score));\n } else {\n const fromPatterns = learning.patterns > 0 ? Math.min(100, Math.floor(learning.patterns / 20)) : 0;\n const fromVectors = agentdb.vectorCount > 0 ? Math.min(100, Math.floor(agentdb.vectorCount / 20)) : 0;\n intelligencePct = Math.max(fromPatterns, fromVectors);\n }\n\n // Maturity fallback (pure fs checks, no git exec)\n if (intelligencePct === 0) {\n let score = 0;\n if (fs.existsSync(path.join(CWD, '.claude'))) score += 15;\n const srcDirs = ['src', 'lib', 'app', 'packages', 'v3'];\n for (const d of srcDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 15; break; } }\n const testDirs = ['tests', 'test', '__tests__', 'spec'];\n for (const d of testDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 10; break; } }\n const cfgFiles = ['package.json', 'tsconfig.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];\n for (const f of cfgFiles) { if (fs.existsSync(path.join(CWD, f))) { score += 5; break; } }\n intelligencePct = Math.min(100, score);\n }\n\n if (learningData && learningData.sessions && learningData.sessions.total !== undefined) {\n contextPct = Math.min(100, learningData.sessions.total * 5);\n } else {\n contextPct = Math.min(100, Math.floor(learning.sessions * 5));\n }\n\n // Sub-agents from file metrics (no ps aux)\n let subAgents = 0;\n const activityData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'swarm-activity.json'));\n if (activityData && activityData.processes && activityData.processes.estimated_agents) {\n subAgents = activityData.processes.estimated_agents;\n }\n\n return { memoryMB, contextPct, intelligencePct, subAgents };\n}\n\n// ADR status (count files only \u2014 don't read contents)\nfunction getADRStatus() {\n // Count actual ADR files first \u2014 compliance JSON may be stale\n const adrPaths = [\n path.join(CWD, 'v3', 'implementation', 'adrs'),\n path.join(CWD, 'docs', 'adrs'),\n path.join(CWD, '.claude-flow', 'adrs'),\n ];\n\n for (const adrPath of adrPaths) {\n try {\n if (fs.existsSync(adrPath)) {\n const files = fs.readdirSync(adrPath).filter(f =>\n f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f))\n );\n return { count: files.length, implemented: files.length, compliance: 0 };\n }\n } catch { /* ignore */ }\n }\n\n return { count: 0, implemented: 0, compliance: 0 };\n}\n\n// Hooks status (shared settings cache)\nfunction getHooksStatus() {\n let enabled = 0;\n let total = 0;\n const settings = getSettings();\n\n if (settings && settings.hooks) {\n for (const category of Object.keys(settings.hooks)) {\n const matchers = settings.hooks[category];\n if (!Array.isArray(matchers)) continue;\n for (const matcher of matchers) {\n const hooks = matcher && matcher.hooks;\n if (Array.isArray(hooks)) {\n total += hooks.length;\n enabled += hooks.length;\n }\n }\n }\n }\n\n try {\n const hooksDir = path.join(CWD, '.claude', 'hooks');\n if (fs.existsSync(hooksDir)) {\n const hookFiles = fs.readdirSync(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.sh')).length;\n total = Math.max(total, hookFiles);\n enabled = Math.max(enabled, hookFiles);\n }\n } catch { /* ignore */ }\n\n return { enabled, total };\n}\n\n// AgentDB stats \u2014 count real entries, not file-size heuristics\nfunction getAgentDBStats() {\n let vectorCount = 0;\n let dbSizeKB = 0;\n let namespaces = 0;\n let hasHnsw = false;\n\n // 1. Count real entries from auto-memory-store.json\n const storePath = path.join(CWD, '.claude-flow', 'data', 'auto-memory-store.json');\n const storeStat = safeStat(storePath);\n if (storeStat) {\n dbSizeKB += storeStat.size / 1024;\n try {\n const store = JSON.parse(fs.readFileSync(storePath, 'utf-8'));\n if (Array.isArray(store)) vectorCount += store.length;\n else if (store && store.entries) vectorCount += store.entries.length;\n } catch { /* fall back */ }\n }\n\n // 2. Count entries from ranked-context.json\n try {\n const ranked = readJSON(path.join(CWD, '.claude-flow', 'data', 'ranked-context.json'));\n if (ranked && ranked.entries && ranked.entries.length > vectorCount) vectorCount = ranked.entries.length;\n } catch { /* ignore */ }\n\n // 3. Add DB file sizes\n const dbFiles = [\n path.join(CWD, 'data', 'memory.db'),\n path.join(CWD, '.claude-flow', 'memory.db'),\n path.join(CWD, '.swarm', 'memory.db'),\n ];\n for (const f of dbFiles) {\n const stat = safeStat(f);\n if (stat) {\n dbSizeKB += stat.size / 1024;\n namespaces++;\n }\n }\n\n // 4. Graph data size\n const graphStat = safeStat(path.join(CWD, 'data', 'memory.graph'));\n if (graphStat) dbSizeKB += graphStat.size / 1024;\n\n // 5. HNSW index or memory package\n const hnswPaths = [\n path.join(CWD, '.swarm', 'hnsw.index'),\n path.join(CWD, '.claude-flow', 'hnsw.index'),\n ];\n for (const p of hnswPaths) {\n if (safeStat(p)) { hasHnsw = true; break; }\n }\n if (!hasHnsw) {\n const memPkgPaths = [\n path.join(CWD, 'v3', '@claude-flow', 'memory', 'dist'),\n path.join(CWD, 'node_modules', '@claude-flow', 'memory'),\n ];\n for (const p of memPkgPaths) {\n if (fs.existsSync(p)) { hasHnsw = true; break; }\n }\n }\n\n return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces, hasHnsw };\n}\n\n// Test stats (count files only \u2014 NO reading file contents)\nfunction getTestStats() {\n let testFiles = 0;\n\n function countTestFiles(dir, depth) {\n if (depth === undefined) depth = 0;\n if (depth > 6) return;\n try {\n if (!fs.existsSync(dir)) return;\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {\n countTestFiles(path.join(dir, entry.name), depth + 1);\n } else if (entry.isFile()) {\n const n = entry.name;\n if (n.includes('.test.') || n.includes('.spec.') || n.includes('_test.') || n.includes('_spec.')) {\n testFiles++;\n }\n }\n }\n } catch { /* ignore */ }\n }\n\n var testDirNames = ['tests', 'test', '__tests__', 'src', 'v3'];\n for (var i = 0; i < testDirNames.length; i++) {\n countTestFiles(path.join(CWD, testDirNames[i]));\n }\n\n return { testFiles, testCases: testFiles * 4 };\n}\n\n// Integration status (shared settings + file checks)\nfunction getIntegrationStatus() {\n const mcpServers = { total: 0, enabled: 0 };\n const settings = getSettings();\n\n if (settings && settings.mcpServers && typeof settings.mcpServers === 'object') {\n const servers = Object.keys(settings.mcpServers);\n mcpServers.total = servers.length;\n mcpServers.enabled = settings.enabledMcpjsonServers\n ? settings.enabledMcpjsonServers.filter(s => servers.includes(s)).length\n : servers.length;\n }\n\n if (mcpServers.total === 0) {\n const mcpConfig = readJSON(path.join(CWD, '.mcp.json'))\n || readJSON(path.join(os.homedir(), '.claude', 'mcp.json'));\n if (mcpConfig && mcpConfig.mcpServers) {\n const s = Object.keys(mcpConfig.mcpServers);\n mcpServers.total = s.length;\n mcpServers.enabled = s.length;\n }\n }\n\n const hasDatabase = ['.swarm/memory.db', '.claude-flow/memory.db', 'data/memory.db']\n .some(p => fs.existsSync(path.join(CWD, p)));\n const hasApi = !!(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY);\n\n return { mcpServers, hasDatabase, hasApi };\n}\n\n// Session stats (pure file reads)\nfunction getSessionStats() {\n var sessionPaths = ['.claude-flow/session.json', '.claude/session.json'];\n for (var i = 0; i < sessionPaths.length; i++) {\n const data = readJSON(path.join(CWD, sessionPaths[i]));\n if (data && data.startTime) {\n const diffMs = Date.now() - new Date(data.startTime).getTime();\n const mins = Math.floor(diffMs / 60000);\n const duration = mins < 60 ? mins + 'm' : Math.floor(mins / 60) + 'h' + (mins % 60) + 'm';\n return { duration: duration };\n }\n }\n return { duration: '' };\n}\n\n// \u2500\u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction progressBar(current, total) {\n const width = 5;\n const filled = Math.round((current / total) * width);\n return '[' + '\\u25CF'.repeat(filled) + '\\u25CB'.repeat(width - filled) + ']';\n}\n\nfunction generateStatusline() {\n const git = getGitInfo();\n // Prefer model name from Claude Code stdin data, fallback to file-based detection\n const modelName = getModelFromStdin() || getModelName();\n const ctxInfo = getContextFromStdin();\n const costInfo = getCostFromStdin();\n const progress = getV3Progress();\n const security = getSecurityStatus();\n const swarm = getSwarmStatus();\n const system = getSystemMetrics();\n const adrs = getADRStatus();\n const hooks = getHooksStatus();\n const agentdb = getAgentDBStats();\n const tests = getTestStats();\n const session = getSessionStats();\n const integration = getIntegrationStatus();\n const lines = [];\n\n // Header\n let header = c.bold + c.brightPurple + '\\u258A RuFlo V3.5 ' + c.reset;\n header += (swarm.coordinationActive ? c.brightCyan : c.dim) + '\\u25CF ' + c.brightCyan + git.name + c.reset;\n if (git.gitBranch) {\n header += ' ' + c.dim + '\\u2502' + c.reset + ' ' + c.brightBlue + '\\u23C7 ' + git.gitBranch + c.reset;\n const changes = git.modified + git.staged + git.untracked;\n if (changes > 0) {\n let ind = '';\n if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;\n if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;\n if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;\n header += ' ' + ind;\n }\n if (git.ahead > 0) header += ' ' + c.brightGreen + '\\u2191' + git.ahead + c.reset;\n if (git.behind > 0) header += ' ' + c.brightRed + '\\u2193' + git.behind + c.reset;\n }\n header += ' ' + c.dim + '\\u2502' + c.reset + ' ' + c.purple + modelName + c.reset;\n // Show session duration from Claude Code stdin if available, else from local files\n const duration = costInfo ? costInfo.duration : session.duration;\n if (duration) header += ' ' + c.dim + '\\u2502' + c.reset + ' ' + c.cyan + '\\u23F1 ' + duration + c.reset;\n // Show context usage from Claude Code stdin if available\n if (ctxInfo && ctxInfo.usedPct > 0) {\n const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;\n header += ' ' + c.dim + '\\u2502' + c.reset + ' ' + ctxColor + '\\u25CF ' + ctxInfo.usedPct + '% ctx' + c.reset;\n }\n // Show cost from Claude Code stdin if available\n if (costInfo && costInfo.costUsd > 0) {\n header += ' ' + c.dim + '\\u2502' + c.reset + ' ' + c.brightYellow + '$' + costInfo.costUsd.toFixed(2) + c.reset;\n }\n lines.push(header);\n\n // Separator\n lines.push(c.dim + '\\u2500'.repeat(53) + c.reset);\n\n // Line 1: DDD Domains\n const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;\n let perfIndicator;\n if (agentdb.hasHnsw && agentdb.vectorCount > 0) {\n const speedup = agentdb.vectorCount > 10000 ? '12500x' : agentdb.vectorCount > 1000 ? '150x' : '10x';\n perfIndicator = c.brightGreen + '\\u26A1 HNSW ' + speedup + c.reset;\n } else if (progress.patternsLearned > 0) {\n const pk = progress.patternsLearned >= 1000 ? (progress.patternsLearned / 1000).toFixed(1) + 'k' : String(progress.patternsLearned);\n perfIndicator = c.brightYellow + '\\uD83D\\uDCDA ' + pk + ' patterns' + c.reset;\n } else {\n perfIndicator = c.dim + '\\u26A1 target: 150x-12500x' + c.reset;\n }\n lines.push(\n c.brightCyan + '\\uD83C\\uDFD7\\uFE0F DDD Domains' + c.reset + ' ' + progressBar(progress.domainsCompleted, progress.totalDomains) + ' ' +\n domainsColor + progress.domainsCompleted + c.reset + '/' + c.brightWhite + progress.totalDomains + c.reset + ' ' + perfIndicator\n );\n\n // Line 2: Swarm + Hooks + CVE + Memory + Intelligence\n const swarmInd = swarm.coordinationActive ? c.brightGreen + '\\u25C9' + c.reset : c.dim + '\\u25CB' + c.reset;\n const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;\n const secIcon = security.status === 'CLEAN' ? '\\uD83D\\uDFE2' : (security.status === 'IN_PROGRESS' || security.status === 'STALE') ? '\\uD83D\\uDFE1' : (security.status === 'NONE' ? '\\u26AA' : '\\uD83D\\uDD34');\n const secColor = security.status === 'CLEAN' ? c.brightGreen : (security.status === 'IN_PROGRESS' || security.status === 'STALE') ? c.brightYellow : (security.status === 'NONE' ? c.dim : c.brightRed);\n const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;\n const intellColor = system.intelligencePct >= 80 ? c.brightGreen : system.intelligencePct >= 40 ? c.brightYellow : c.dim;\n\n lines.push(\n c.brightYellow + '\\uD83E\\uDD16 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(swarm.activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + swarm.maxAgents + c.reset + '] ' +\n c.brightPurple + '\\uD83D\\uDC65 ' + system.subAgents + c.reset + ' ' +\n c.brightBlue + '\\uD83E\\uDE9D ' + hooksColor + hooks.enabled + c.reset + '/' + c.brightWhite + hooks.total + c.reset + ' ' +\n secIcon + ' ' + secColor + 'CVE ' + security.cvesFixed + c.reset + '/' + c.brightWhite + security.totalCves + c.reset + ' ' +\n c.brightCyan + '\\uD83D\\uDCBE ' + system.memoryMB + 'MB' + c.reset + ' ' +\n intellColor + '\\uD83E\\uDDE0 ' + String(system.intelligencePct).padStart(3) + '%' + c.reset\n );\n\n // Line 3: Architecture\n const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;\n const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;\n const adrDisplay = adrs.compliance > 0 ? adrColor + '\\u25CF' + adrs.compliance + '%' + c.reset : adrColor + '\\u25CF' + adrs.implemented + '/' + adrs.count + c.reset;\n\n lines.push(\n c.brightPurple + '\\uD83D\\uDD27 Architecture' + c.reset + ' ' +\n c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '\\u2502' + c.reset + ' ' +\n c.cyan + 'DDD' + c.reset + ' ' + dddColor + '\\u25CF' + String(progress.dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '\\u2502' + c.reset + ' ' +\n c.cyan + 'Security' + c.reset + ' ' + secColor + '\\u25CF' + security.status + c.reset\n );\n\n // Line 4: AgentDB, Tests, Integration\n const hnswInd = agentdb.hasHnsw ? c.brightGreen + '\\u26A1' + c.reset : '';\n const sizeDisp = agentdb.dbSizeKB >= 1024 ? (agentdb.dbSizeKB / 1024).toFixed(1) + 'MB' : agentdb.dbSizeKB + 'KB';\n const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;\n const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;\n\n let integStr = '';\n if (integration.mcpServers.total > 0) {\n const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :\n integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;\n integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '\\u25CF' + integration.mcpServers.enabled + '/' + integration.mcpServers.total + c.reset;\n }\n if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '\\u25C6' + c.reset + 'DB';\n if (integration.hasApi) integStr += (integStr ? ' ' : '') + c.brightGreen + '\\u25C6' + c.reset + 'API';\n if (!integStr) integStr = c.dim + '\\u25CF none' + c.reset;\n\n lines.push(\n c.brightCyan + '\\uD83D\\uDCCA AgentDB' + c.reset + ' ' +\n c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '\\u25CF' + agentdb.vectorCount + hnswInd + c.reset + ' ' + c.dim + '\\u2502' + c.reset + ' ' +\n c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '\\u2502' + c.reset + ' ' +\n c.cyan + 'Tests' + c.reset + ' ' + testColor + '\\u25CF' + tests.testFiles + c.reset + ' ' + c.dim + '(~' + tests.testCases + ' cases)' + c.reset + ' ' + c.dim + '\\u2502' + c.reset + ' ' +\n integStr\n );\n\n return lines.join('\\n');\n}\n\n// JSON output\nfunction generateJSON() {\n const git = getGitInfo();\n return {\n user: { name: git.name, gitBranch: git.gitBranch, modelName: getModelName() },\n v3Progress: getV3Progress(),\n security: getSecurityStatus(),\n swarm: getSwarmStatus(),\n system: getSystemMetrics(),\n adrs: getADRStatus(),\n hooks: getHooksStatus(),\n agentdb: getAgentDBStats(),\n tests: getTestStats(),\n git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },\n lastUpdated: new Date().toISOString(),\n };\n}\n\n// \u2500\u2500\u2500 Stdin reader (Claude Code pipes session JSON) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Claude Code sends session JSON via stdin (model, context, cost, etc.)\n// Read it synchronously so the script works both:\n// 1. When invoked by Claude Code (stdin has JSON)\n// 2. When invoked manually from terminal (stdin is empty/tty)\nlet _stdinData = null;\nfunction getStdinData() {\n if (_stdinData !== undefined && _stdinData !== null) return _stdinData;\n try {\n // Check if stdin is a TTY (manual run) \u2014 skip reading\n if (process.stdin.isTTY) { _stdinData = null; return null; }\n // Read stdin synchronously via fd 0\n const chunks = [];\n const buf = Buffer.alloc(4096);\n let bytesRead;\n try {\n while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {\n chunks.push(buf.slice(0, bytesRead));\n }\n } catch { /* EOF or read error */ }\n const raw = Buffer.concat(chunks).toString('utf-8').trim();\n if (raw && raw.startsWith('{')) {\n _stdinData = JSON.parse(raw);\n } else {\n _stdinData = null;\n }\n } catch {\n _stdinData = null;\n }\n return _stdinData;\n}\n\n// Override model detection to prefer stdin data from Claude Code\nfunction getModelFromStdin() {\n const data = getStdinData();\n if (data && data.model && data.model.display_name) return data.model.display_name;\n return null;\n}\n\n// Get context window info from Claude Code session\nfunction getContextFromStdin() {\n const data = getStdinData();\n if (data && data.context_window) {\n return {\n usedPct: Math.floor(data.context_window.used_percentage || 0),\n remainingPct: Math.floor(data.context_window.remaining_percentage || 100),\n };\n }\n return null;\n}\n\n// Get cost info from Claude Code session\nfunction getCostFromStdin() {\n const data = getStdinData();\n if (data && data.cost) {\n const durationMs = data.cost.total_duration_ms || 0;\n const mins = Math.floor(durationMs / 60000);\n const secs = Math.floor((durationMs % 60000) / 1000);\n return {\n costUsd: data.cost.total_cost_usd || 0,\n duration: mins > 0 ? mins + 'm' + secs + 's' : secs + 's',\n linesAdded: data.cost.total_lines_added || 0,\n linesRemoved: data.cost.total_lines_removed || 0,\n };\n }\n return null;\n}\n\n// \u2500\u2500\u2500 Main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nif (process.argv.includes('--json')) {\n console.log(JSON.stringify(generateJSON(), null, 2));\n} else if (process.argv.includes('--compact')) {\n console.log(JSON.stringify(generateJSON()));\n} else {\n console.log(generateStatusline());\n}\n";
1284
25
  }
1285
26
  /**
1286
27
  * Generate statusline hook for shell integration
1287
28
  */
1288
29
  export function generateStatuslineHook(options) {
1289
30
  if (!options.statusline.enabled) {
1290
- return '# Statusline disabled';
31
+ return '#!/bin/bash\n# Statusline disabled\n';
1291
32
  }
1292
- return `# KynjalFlow V3 Statusline Hook
1293
- # Add to your shell RC file (.bashrc, .zshrc, etc.)
1294
-
1295
- # Function to get statusline
1296
- claude_flow_statusline() {
1297
- local statusline_script="\${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs"
1298
- if [ -f "$statusline_script" ]; then
1299
- node "$statusline_script" 2>/dev/null || echo ""
1300
- fi
1301
- }
1302
-
1303
- # For bash PS1
1304
- # export PS1='$(claude_flow_statusline) \\n\\$ '
1305
-
1306
- # For zsh RPROMPT
1307
- # export RPROMPT='$(claude_flow_statusline)'
1308
-
1309
- # For starship (add to starship.toml)
1310
- # [custom.claude_flow]
1311
- # command = "node .claude/helpers/statusline.cjs 2>/dev/null"
1312
- # when = "test -f .claude/helpers/statusline.cjs"
1313
- `;
33
+ return "#!/bin/bash\n# RuFlo V3 Statusline Hook\n# Source this in your .bashrc/.zshrc for terminal statusline\n\n# Function to get statusline\nclaude_flow_statusline() {\n local statusline_script=\"${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs\"\n if [ -f \"$statusline_script\" ]; then\n node \"$statusline_script\" 2>/dev/null || echo \"\"\n fi\n}\n\n# Bash: Add to PS1\n# export PS1='$(claude_flow_statusline) \\n\\$ '\n\n# Zsh: Add to RPROMPT\n# export RPROMPT='$(claude_flow_statusline)'\n\n# Claude Code: Add to .claude/settings.json\n# \"statusLine\": {\n# \"type\": \"command\",\n# \"command\": \"node .claude/helpers/statusline.cjs 2>/dev/null\"\n# \"when\": \"test -f .claude/helpers/statusline.cjs\"\n# }\n";
1314
34
  }
1315
35
  //# sourceMappingURL=statusline-generator.js.map