claude-flow 3.25.6 → 3.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/.claude/helpers/hook-handler.cjs +129 -0
  2. package/.claude/helpers/intelligence.cjs +10 -0
  3. package/.claude/helpers/statusline.cjs +310 -123
  4. package/.claude/proven-config.json +1 -1
  5. package/.claude/security-scans/scan-all-standard.json +321 -0
  6. package/.claude/security-scans/scan-code-deep.json +1209 -0
  7. package/.claude/security-scans/scan-deps-full.json +14 -0
  8. package/package.json +3 -1
  9. package/v3/@claude-flow/cli/catalog-manifest.json +12 -0
  10. package/v3/@claude-flow/cli/dist/src/commands/advisor.d.ts +15 -0
  11. package/v3/@claude-flow/cli/dist/src/commands/advisor.js +94 -0
  12. package/v3/@claude-flow/cli/dist/src/commands/doctor.js +77 -3
  13. package/v3/@claude-flow/cli/dist/src/commands/funnel.d.ts +13 -0
  14. package/v3/@claude-flow/cli/dist/src/commands/funnel.js +103 -0
  15. package/v3/@claude-flow/cli/dist/src/commands/hooks.js +112 -46
  16. package/v3/@claude-flow/cli/dist/src/commands/index.js +10 -0
  17. package/v3/@claude-flow/cli/dist/src/commands/init.js +44 -0
  18. package/v3/@claude-flow/cli/dist/src/commands/proxy.d.ts +21 -0
  19. package/v3/@claude-flow/cli/dist/src/commands/proxy.js +310 -0
  20. package/v3/@claude-flow/cli/dist/src/commands/security.js +29 -0
  21. package/v3/@claude-flow/cli/dist/src/commands/settings.d.ts +19 -0
  22. package/v3/@claude-flow/cli/dist/src/commands/settings.js +180 -0
  23. package/v3/@claude-flow/cli/dist/src/commands/version.d.ts +42 -0
  24. package/v3/@claude-flow/cli/dist/src/commands/version.js +106 -0
  25. package/v3/@claude-flow/cli/dist/src/funnel/advisor-tip.d.ts +58 -0
  26. package/v3/@claude-flow/cli/dist/src/funnel/advisor-tip.js +92 -0
  27. package/v3/@claude-flow/cli/dist/src/funnel/attribution.d.ts +37 -0
  28. package/v3/@claude-flow/cli/dist/src/funnel/attribution.js +101 -0
  29. package/v3/@claude-flow/cli/dist/src/funnel/consent.d.ts +22 -0
  30. package/v3/@claude-flow/cli/dist/src/funnel/consent.js +55 -0
  31. package/v3/@claude-flow/cli/dist/src/funnel/credit-errors.d.ts +31 -0
  32. package/v3/@claude-flow/cli/dist/src/funnel/credit-errors.js +88 -0
  33. package/v3/@claude-flow/cli/dist/src/funnel/credit-notifier.d.ts +44 -0
  34. package/v3/@claude-flow/cli/dist/src/funnel/credit-notifier.js +74 -0
  35. package/v3/@claude-flow/cli/dist/src/funnel/disclosure.d.ts +46 -0
  36. package/v3/@claude-flow/cli/dist/src/funnel/disclosure.js +97 -0
  37. package/v3/@claude-flow/cli/dist/src/funnel/enrollment.d.ts +36 -0
  38. package/v3/@claude-flow/cli/dist/src/funnel/enrollment.js +64 -0
  39. package/v3/@claude-flow/cli/dist/src/funnel/environment.d.ts +17 -0
  40. package/v3/@claude-flow/cli/dist/src/funnel/environment.js +39 -0
  41. package/v3/@claude-flow/cli/dist/src/funnel/event-transport.d.ts +51 -0
  42. package/v3/@claude-flow/cli/dist/src/funnel/event-transport.js +199 -0
  43. package/v3/@claude-flow/cli/dist/src/funnel/events.d.ts +42 -0
  44. package/v3/@claude-flow/cli/dist/src/funnel/events.js +150 -0
  45. package/v3/@claude-flow/cli/dist/src/funnel/index.d.ts +20 -0
  46. package/v3/@claude-flow/cli/dist/src/funnel/index.js +20 -0
  47. package/v3/@claude-flow/cli/dist/src/funnel/insights.d.ts +49 -0
  48. package/v3/@claude-flow/cli/dist/src/funnel/insights.js +120 -0
  49. package/v3/@claude-flow/cli/dist/src/funnel/local-signals.d.ts +15 -0
  50. package/v3/@claude-flow/cli/dist/src/funnel/local-signals.js +68 -0
  51. package/v3/@claude-flow/cli/dist/src/funnel/message-transport.d.ts +51 -0
  52. package/v3/@claude-flow/cli/dist/src/funnel/message-transport.js +149 -0
  53. package/v3/@claude-flow/cli/dist/src/funnel/messages.d.ts +55 -0
  54. package/v3/@claude-flow/cli/dist/src/funnel/messages.js +160 -0
  55. package/v3/@claude-flow/cli/dist/src/funnel/power-saver-notifier.d.ts +44 -0
  56. package/v3/@claude-flow/cli/dist/src/funnel/power-saver-notifier.js +92 -0
  57. package/v3/@claude-flow/cli/dist/src/funnel/precedence.d.ts +16 -0
  58. package/v3/@claude-flow/cli/dist/src/funnel/precedence.js +85 -0
  59. package/v3/@claude-flow/cli/dist/src/funnel/promo.d.ts +41 -0
  60. package/v3/@claude-flow/cli/dist/src/funnel/promo.js +144 -0
  61. package/v3/@claude-flow/cli/dist/src/funnel/rate-limit-notifier.d.ts +55 -0
  62. package/v3/@claude-flow/cli/dist/src/funnel/rate-limit-notifier.js +102 -0
  63. package/v3/@claude-flow/cli/dist/src/funnel/rotation.d.ts +19 -0
  64. package/v3/@claude-flow/cli/dist/src/funnel/rotation.js +70 -0
  65. package/v3/@claude-flow/cli/dist/src/funnel/state.d.ts +13 -0
  66. package/v3/@claude-flow/cli/dist/src/funnel/state.js +52 -0
  67. package/v3/@claude-flow/cli/dist/src/funnel/toggle-cooldown.d.ts +17 -0
  68. package/v3/@claude-flow/cli/dist/src/funnel/toggle-cooldown.js +32 -0
  69. package/v3/@claude-flow/cli/dist/src/funnel/types.d.ts +86 -0
  70. package/v3/@claude-flow/cli/dist/src/funnel/types.js +26 -0
  71. package/v3/@claude-flow/cli/dist/src/init/executor.js +9 -3
  72. package/v3/@claude-flow/cli/dist/src/init/helper-refresh.d.ts +33 -2
  73. package/v3/@claude-flow/cli/dist/src/init/helper-refresh.js +102 -12
  74. package/v3/@claude-flow/cli/dist/src/init/helpers-generator.js +52 -0
  75. package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +292 -116
  76. package/v3/@claude-flow/cli/dist/src/services/daemon-autostart.js +28 -5
  77. package/v3/@claude-flow/cli/dist/src/services/fable-harness.d.ts +39 -0
  78. package/v3/@claude-flow/cli/dist/src/services/fable-harness.js +41 -0
  79. package/v3/@claude-flow/cli/package.json +13 -4
  80. package/.claude/coordinator/config.json +0 -24
  81. package/.claude/coordinator/state.json +0 -37
  82. package/.claude/coordinator/tick-log/tick-01.json +0 -17
  83. package/.claude/coordinator/tick-log/tick-02.json +0 -17
  84. package/.claude/coordinator/tick-log/tick-03.json +0 -17
  85. package/.claude/coordinator/tick-log/tick-04.json +0 -14
  86. package/.claude/coordinator/tick-log/tick-05.json +0 -16
  87. package/.claude/settings.local.json +0 -11
  88. package/v3/@claude-flow/cli/dist/src/ruvector/lattice-wasm.d.ts +0 -14
  89. package/v3/@claude-flow/cli/dist/src/ruvector/lattice-wasm.js +0 -144
  90. package/v3/@claude-flow/guidance/dist/adversarial.d.ts +0 -284
  91. package/v3/@claude-flow/guidance/dist/adversarial.js +0 -572
  92. package/v3/@claude-flow/guidance/dist/analyzer.d.ts +0 -530
  93. package/v3/@claude-flow/guidance/dist/analyzer.js +0 -2587
  94. package/v3/@claude-flow/guidance/dist/artifacts.d.ts +0 -283
  95. package/v3/@claude-flow/guidance/dist/artifacts.js +0 -356
  96. package/v3/@claude-flow/guidance/dist/authority.d.ts +0 -290
  97. package/v3/@claude-flow/guidance/dist/authority.js +0 -558
  98. package/v3/@claude-flow/guidance/dist/capabilities.d.ts +0 -209
  99. package/v3/@claude-flow/guidance/dist/capabilities.js +0 -485
  100. package/v3/@claude-flow/guidance/dist/coherence.d.ts +0 -233
  101. package/v3/@claude-flow/guidance/dist/coherence.js +0 -372
  102. package/v3/@claude-flow/guidance/dist/compiler.d.ts +0 -87
  103. package/v3/@claude-flow/guidance/dist/compiler.js +0 -410
  104. package/v3/@claude-flow/guidance/dist/conformance-kit.d.ts +0 -225
  105. package/v3/@claude-flow/guidance/dist/conformance-kit.js +0 -629
  106. package/v3/@claude-flow/guidance/dist/continue-gate.d.ts +0 -214
  107. package/v3/@claude-flow/guidance/dist/continue-gate.js +0 -353
  108. package/v3/@claude-flow/guidance/dist/crypto-utils.d.ts +0 -17
  109. package/v3/@claude-flow/guidance/dist/crypto-utils.js +0 -24
  110. package/v3/@claude-flow/guidance/dist/evolution.d.ts +0 -282
  111. package/v3/@claude-flow/guidance/dist/evolution.js +0 -500
  112. package/v3/@claude-flow/guidance/dist/gates.d.ts +0 -79
  113. package/v3/@claude-flow/guidance/dist/gates.js +0 -302
  114. package/v3/@claude-flow/guidance/dist/gateway.d.ts +0 -206
  115. package/v3/@claude-flow/guidance/dist/gateway.js +0 -452
  116. package/v3/@claude-flow/guidance/dist/generators.d.ts +0 -153
  117. package/v3/@claude-flow/guidance/dist/generators.js +0 -682
  118. package/v3/@claude-flow/guidance/dist/headless.d.ts +0 -177
  119. package/v3/@claude-flow/guidance/dist/headless.js +0 -342
  120. package/v3/@claude-flow/guidance/dist/hooks.d.ts +0 -109
  121. package/v3/@claude-flow/guidance/dist/hooks.js +0 -347
  122. package/v3/@claude-flow/guidance/dist/index.d.ts +0 -205
  123. package/v3/@claude-flow/guidance/dist/index.js +0 -321
  124. package/v3/@claude-flow/guidance/dist/ledger.d.ts +0 -162
  125. package/v3/@claude-flow/guidance/dist/ledger.js +0 -375
  126. package/v3/@claude-flow/guidance/dist/manifest-validator.d.ts +0 -289
  127. package/v3/@claude-flow/guidance/dist/manifest-validator.js +0 -838
  128. package/v3/@claude-flow/guidance/dist/memory-gate.d.ts +0 -222
  129. package/v3/@claude-flow/guidance/dist/memory-gate.js +0 -382
  130. package/v3/@claude-flow/guidance/dist/meta-governance.d.ts +0 -265
  131. package/v3/@claude-flow/guidance/dist/meta-governance.js +0 -348
  132. package/v3/@claude-flow/guidance/dist/optimizer.d.ts +0 -104
  133. package/v3/@claude-flow/guidance/dist/optimizer.js +0 -329
  134. package/v3/@claude-flow/guidance/dist/persistence.d.ts +0 -189
  135. package/v3/@claude-flow/guidance/dist/persistence.js +0 -464
  136. package/v3/@claude-flow/guidance/dist/proof.d.ts +0 -185
  137. package/v3/@claude-flow/guidance/dist/proof.js +0 -238
  138. package/v3/@claude-flow/guidance/dist/retriever.d.ts +0 -172
  139. package/v3/@claude-flow/guidance/dist/retriever.js +0 -596
  140. package/v3/@claude-flow/guidance/dist/ruvbot-integration.d.ts +0 -370
  141. package/v3/@claude-flow/guidance/dist/ruvbot-integration.js +0 -738
  142. package/v3/@claude-flow/guidance/dist/temporal.d.ts +0 -426
  143. package/v3/@claude-flow/guidance/dist/temporal.js +0 -658
  144. package/v3/@claude-flow/guidance/dist/trust.d.ts +0 -283
  145. package/v3/@claude-flow/guidance/dist/trust.js +0 -473
  146. package/v3/@claude-flow/guidance/dist/truth-anchors.d.ts +0 -276
  147. package/v3/@claude-flow/guidance/dist/truth-anchors.js +0 -488
  148. package/v3/@claude-flow/guidance/dist/types.d.ts +0 -378
  149. package/v3/@claude-flow/guidance/dist/types.js +0 -10
  150. package/v3/@claude-flow/guidance/dist/uncertainty.d.ts +0 -372
  151. package/v3/@claude-flow/guidance/dist/uncertainty.js +0 -619
  152. package/v3/@claude-flow/guidance/dist/wasm-kernel.d.ts +0 -48
  153. package/v3/@claude-flow/guidance/dist/wasm-kernel.js +0 -158
  154. package/v3/@claude-flow/shared/dist/core/config/defaults.d.ts +0 -41
  155. package/v3/@claude-flow/shared/dist/core/config/defaults.js +0 -186
  156. package/v3/@claude-flow/shared/dist/core/config/index.d.ts +0 -8
  157. package/v3/@claude-flow/shared/dist/core/config/index.js +0 -12
  158. package/v3/@claude-flow/shared/dist/core/config/loader.d.ts +0 -45
  159. package/v3/@claude-flow/shared/dist/core/config/loader.js +0 -238
  160. package/v3/@claude-flow/shared/dist/core/config/schema.d.ts +0 -1728
  161. package/v3/@claude-flow/shared/dist/core/config/schema.js +0 -160
  162. package/v3/@claude-flow/shared/dist/core/config/validator.d.ts +0 -92
  163. package/v3/@claude-flow/shared/dist/core/config/validator.js +0 -147
  164. package/v3/@claude-flow/shared/dist/core/event-bus.d.ts +0 -31
  165. package/v3/@claude-flow/shared/dist/core/event-bus.js +0 -197
  166. package/v3/@claude-flow/shared/dist/core/index.d.ts +0 -15
  167. package/v3/@claude-flow/shared/dist/core/index.js +0 -19
  168. package/v3/@claude-flow/shared/dist/core/interfaces/agent.interface.d.ts +0 -200
  169. package/v3/@claude-flow/shared/dist/core/interfaces/agent.interface.js +0 -6
  170. package/v3/@claude-flow/shared/dist/core/interfaces/coordinator.interface.d.ts +0 -310
  171. package/v3/@claude-flow/shared/dist/core/interfaces/coordinator.interface.js +0 -7
  172. package/v3/@claude-flow/shared/dist/core/interfaces/event.interface.d.ts +0 -224
  173. package/v3/@claude-flow/shared/dist/core/interfaces/event.interface.js +0 -46
  174. package/v3/@claude-flow/shared/dist/core/interfaces/index.d.ts +0 -10
  175. package/v3/@claude-flow/shared/dist/core/interfaces/index.js +0 -15
  176. package/v3/@claude-flow/shared/dist/core/interfaces/memory.interface.d.ts +0 -298
  177. package/v3/@claude-flow/shared/dist/core/interfaces/memory.interface.js +0 -7
  178. package/v3/@claude-flow/shared/dist/core/interfaces/task.interface.d.ts +0 -185
  179. package/v3/@claude-flow/shared/dist/core/interfaces/task.interface.js +0 -6
  180. package/v3/@claude-flow/shared/dist/core/orchestrator/event-coordinator.d.ts +0 -35
  181. package/v3/@claude-flow/shared/dist/core/orchestrator/event-coordinator.js +0 -101
  182. package/v3/@claude-flow/shared/dist/core/orchestrator/health-monitor.d.ts +0 -60
  183. package/v3/@claude-flow/shared/dist/core/orchestrator/health-monitor.js +0 -166
  184. package/v3/@claude-flow/shared/dist/core/orchestrator/index.d.ts +0 -46
  185. package/v3/@claude-flow/shared/dist/core/orchestrator/index.js +0 -64
  186. package/v3/@claude-flow/shared/dist/core/orchestrator/lifecycle-manager.d.ts +0 -56
  187. package/v3/@claude-flow/shared/dist/core/orchestrator/lifecycle-manager.js +0 -195
  188. package/v3/@claude-flow/shared/dist/core/orchestrator/session-manager.d.ts +0 -83
  189. package/v3/@claude-flow/shared/dist/core/orchestrator/session-manager.js +0 -193
  190. package/v3/@claude-flow/shared/dist/core/orchestrator/task-manager.d.ts +0 -49
  191. package/v3/@claude-flow/shared/dist/core/orchestrator/task-manager.js +0 -253
  192. package/v3/@claude-flow/shared/dist/events/domain-events.d.ts +0 -282
  193. package/v3/@claude-flow/shared/dist/events/domain-events.js +0 -165
  194. package/v3/@claude-flow/shared/dist/events/event-store.d.ts +0 -126
  195. package/v3/@claude-flow/shared/dist/events/event-store.js +0 -427
  196. package/v3/@claude-flow/shared/dist/events/event-store.test.d.ts +0 -8
  197. package/v3/@claude-flow/shared/dist/events/event-store.test.js +0 -293
  198. package/v3/@claude-flow/shared/dist/events/example-usage.d.ts +0 -10
  199. package/v3/@claude-flow/shared/dist/events/example-usage.js +0 -193
  200. package/v3/@claude-flow/shared/dist/events/index.d.ts +0 -21
  201. package/v3/@claude-flow/shared/dist/events/index.js +0 -22
  202. package/v3/@claude-flow/shared/dist/events/projections.d.ts +0 -177
  203. package/v3/@claude-flow/shared/dist/events/projections.js +0 -421
  204. package/v3/@claude-flow/shared/dist/events/rvf-event-log.d.ts +0 -82
  205. package/v3/@claude-flow/shared/dist/events/rvf-event-log.js +0 -340
  206. package/v3/@claude-flow/shared/dist/events/state-reconstructor.d.ts +0 -101
  207. package/v3/@claude-flow/shared/dist/events/state-reconstructor.js +0 -263
  208. package/v3/@claude-flow/shared/dist/events.d.ts +0 -80
  209. package/v3/@claude-flow/shared/dist/events.js +0 -249
  210. package/v3/@claude-flow/shared/dist/hooks/example-usage.d.ts +0 -42
  211. package/v3/@claude-flow/shared/dist/hooks/example-usage.js +0 -351
  212. package/v3/@claude-flow/shared/dist/hooks/executor.d.ts +0 -100
  213. package/v3/@claude-flow/shared/dist/hooks/executor.js +0 -267
  214. package/v3/@claude-flow/shared/dist/hooks/hooks.test.d.ts +0 -9
  215. package/v3/@claude-flow/shared/dist/hooks/hooks.test.js +0 -322
  216. package/v3/@claude-flow/shared/dist/hooks/index.d.ts +0 -52
  217. package/v3/@claude-flow/shared/dist/hooks/index.js +0 -51
  218. package/v3/@claude-flow/shared/dist/hooks/registry.d.ts +0 -133
  219. package/v3/@claude-flow/shared/dist/hooks/registry.js +0 -277
  220. package/v3/@claude-flow/shared/dist/hooks/safety/bash-safety.d.ts +0 -105
  221. package/v3/@claude-flow/shared/dist/hooks/safety/bash-safety.js +0 -481
  222. package/v3/@claude-flow/shared/dist/hooks/safety/file-organization.d.ts +0 -144
  223. package/v3/@claude-flow/shared/dist/hooks/safety/file-organization.js +0 -328
  224. package/v3/@claude-flow/shared/dist/hooks/safety/git-commit.d.ts +0 -158
  225. package/v3/@claude-flow/shared/dist/hooks/safety/git-commit.js +0 -450
  226. package/v3/@claude-flow/shared/dist/hooks/safety/index.d.ts +0 -17
  227. package/v3/@claude-flow/shared/dist/hooks/safety/index.js +0 -17
  228. package/v3/@claude-flow/shared/dist/hooks/session-hooks.d.ts +0 -234
  229. package/v3/@claude-flow/shared/dist/hooks/session-hooks.js +0 -334
  230. package/v3/@claude-flow/shared/dist/hooks/task-hooks.d.ts +0 -163
  231. package/v3/@claude-flow/shared/dist/hooks/task-hooks.js +0 -326
  232. package/v3/@claude-flow/shared/dist/hooks/types.d.ts +0 -267
  233. package/v3/@claude-flow/shared/dist/hooks/types.js +0 -62
  234. package/v3/@claude-flow/shared/dist/hooks/verify-exports.test.d.ts +0 -9
  235. package/v3/@claude-flow/shared/dist/hooks/verify-exports.test.js +0 -93
  236. package/v3/@claude-flow/shared/dist/index.d.ts +0 -20
  237. package/v3/@claude-flow/shared/dist/index.js +0 -50
  238. package/v3/@claude-flow/shared/dist/mcp/connection-pool.d.ts +0 -98
  239. package/v3/@claude-flow/shared/dist/mcp/connection-pool.js +0 -364
  240. package/v3/@claude-flow/shared/dist/mcp/index.d.ts +0 -69
  241. package/v3/@claude-flow/shared/dist/mcp/index.js +0 -84
  242. package/v3/@claude-flow/shared/dist/mcp/server.d.ts +0 -166
  243. package/v3/@claude-flow/shared/dist/mcp/server.js +0 -590
  244. package/v3/@claude-flow/shared/dist/mcp/session-manager.d.ts +0 -136
  245. package/v3/@claude-flow/shared/dist/mcp/session-manager.js +0 -335
  246. package/v3/@claude-flow/shared/dist/mcp/tool-registry.d.ts +0 -178
  247. package/v3/@claude-flow/shared/dist/mcp/tool-registry.js +0 -439
  248. package/v3/@claude-flow/shared/dist/mcp/transport/http.d.ts +0 -104
  249. package/v3/@claude-flow/shared/dist/mcp/transport/http.js +0 -476
  250. package/v3/@claude-flow/shared/dist/mcp/transport/index.d.ts +0 -102
  251. package/v3/@claude-flow/shared/dist/mcp/transport/index.js +0 -238
  252. package/v3/@claude-flow/shared/dist/mcp/transport/stdio.d.ts +0 -104
  253. package/v3/@claude-flow/shared/dist/mcp/transport/stdio.js +0 -263
  254. package/v3/@claude-flow/shared/dist/mcp/transport/websocket.d.ts +0 -133
  255. package/v3/@claude-flow/shared/dist/mcp/transport/websocket.js +0 -396
  256. package/v3/@claude-flow/shared/dist/mcp/types.d.ts +0 -436
  257. package/v3/@claude-flow/shared/dist/mcp/types.js +0 -54
  258. package/v3/@claude-flow/shared/dist/plugin-interface.d.ts +0 -544
  259. package/v3/@claude-flow/shared/dist/plugin-interface.js +0 -23
  260. package/v3/@claude-flow/shared/dist/plugin-loader.d.ts +0 -139
  261. package/v3/@claude-flow/shared/dist/plugin-loader.js +0 -434
  262. package/v3/@claude-flow/shared/dist/plugin-registry.d.ts +0 -183
  263. package/v3/@claude-flow/shared/dist/plugin-registry.js +0 -457
  264. package/v3/@claude-flow/shared/dist/plugins/index.d.ts +0 -10
  265. package/v3/@claude-flow/shared/dist/plugins/index.js +0 -10
  266. package/v3/@claude-flow/shared/dist/plugins/official/hive-mind-plugin.d.ts +0 -106
  267. package/v3/@claude-flow/shared/dist/plugins/official/hive-mind-plugin.js +0 -241
  268. package/v3/@claude-flow/shared/dist/plugins/official/index.d.ts +0 -10
  269. package/v3/@claude-flow/shared/dist/plugins/official/index.js +0 -10
  270. package/v3/@claude-flow/shared/dist/plugins/official/maestro-plugin.d.ts +0 -121
  271. package/v3/@claude-flow/shared/dist/plugins/official/maestro-plugin.js +0 -355
  272. package/v3/@claude-flow/shared/dist/plugins/types.d.ts +0 -93
  273. package/v3/@claude-flow/shared/dist/plugins/types.js +0 -9
  274. package/v3/@claude-flow/shared/dist/resilience/bulkhead.d.ts +0 -105
  275. package/v3/@claude-flow/shared/dist/resilience/bulkhead.js +0 -206
  276. package/v3/@claude-flow/shared/dist/resilience/circuit-breaker.d.ts +0 -132
  277. package/v3/@claude-flow/shared/dist/resilience/circuit-breaker.js +0 -233
  278. package/v3/@claude-flow/shared/dist/resilience/index.d.ts +0 -19
  279. package/v3/@claude-flow/shared/dist/resilience/index.js +0 -19
  280. package/v3/@claude-flow/shared/dist/resilience/rate-limiter.d.ts +0 -168
  281. package/v3/@claude-flow/shared/dist/resilience/rate-limiter.js +0 -314
  282. package/v3/@claude-flow/shared/dist/resilience/retry.d.ts +0 -91
  283. package/v3/@claude-flow/shared/dist/resilience/retry.js +0 -159
  284. package/v3/@claude-flow/shared/dist/security/index.d.ts +0 -10
  285. package/v3/@claude-flow/shared/dist/security/index.js +0 -12
  286. package/v3/@claude-flow/shared/dist/security/input-validation.d.ts +0 -73
  287. package/v3/@claude-flow/shared/dist/security/input-validation.js +0 -201
  288. package/v3/@claude-flow/shared/dist/security/secure-random.d.ts +0 -92
  289. package/v3/@claude-flow/shared/dist/security/secure-random.js +0 -142
  290. package/v3/@claude-flow/shared/dist/services/index.d.ts +0 -7
  291. package/v3/@claude-flow/shared/dist/services/index.js +0 -7
  292. package/v3/@claude-flow/shared/dist/services/v3-progress.service.d.ts +0 -124
  293. package/v3/@claude-flow/shared/dist/services/v3-progress.service.js +0 -402
  294. package/v3/@claude-flow/shared/dist/types/agent.types.d.ts +0 -137
  295. package/v3/@claude-flow/shared/dist/types/agent.types.js +0 -6
  296. package/v3/@claude-flow/shared/dist/types/index.d.ts +0 -11
  297. package/v3/@claude-flow/shared/dist/types/index.js +0 -17
  298. package/v3/@claude-flow/shared/dist/types/mcp.types.d.ts +0 -266
  299. package/v3/@claude-flow/shared/dist/types/mcp.types.js +0 -7
  300. package/v3/@claude-flow/shared/dist/types/memory.types.d.ts +0 -236
  301. package/v3/@claude-flow/shared/dist/types/memory.types.js +0 -7
  302. package/v3/@claude-flow/shared/dist/types/swarm.types.d.ts +0 -186
  303. package/v3/@claude-flow/shared/dist/types/swarm.types.js +0 -65
  304. package/v3/@claude-flow/shared/dist/types/task.types.d.ts +0 -178
  305. package/v3/@claude-flow/shared/dist/types/task.types.js +0 -32
  306. package/v3/@claude-flow/shared/dist/types.d.ts +0 -197
  307. package/v3/@claude-flow/shared/dist/types.js +0 -21
  308. package/v3/@claude-flow/shared/dist/utils/secure-logger.d.ts +0 -69
  309. package/v3/@claude-flow/shared/dist/utils/secure-logger.js +0 -208
@@ -72,6 +72,28 @@ const CWD = process.cwd();
72
72
  const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
73
73
  const CACHE_TTL_MS = 60000;
74
74
 
75
+ // The promo/insight row is designed to rotate on a 20s cadence (funnel/
76
+ // rotation.ts's ROTATION_SLOT_MS / funnel/promo.ts's insight-slot check —
77
+ // duplicated here as a bare number since this generated script has no
78
+ // runtime import of the funnel module; keep in sync if that constant ever
79
+ // changes). The rotation slot is only ever (re)computed SERVER-SIDE inside
80
+ // the CLI subprocess this file shells out to — so a general 60s data cache
81
+ // (correct and necessary for #2337) silently made that 20s design
82
+ // unreachable: cache.fresh stayed true across 2-3 whole rotation slots,
83
+ // so the row visibly "didn't rotate" (user report). Fix: track promo
84
+ // freshness on its OWN, tighter clock — when it lags behind the current
85
+ // slot, fall through to a real CLI call even though the REST of the
86
+ // cached data (security/swarm/system) is still within CACHE_TTL_MS. This
87
+ // does not touch or regress #2337's fix; it only adds a narrower check.
88
+ const PROMO_ROTATION_SLOT_MS = 20000;
89
+
90
+ // Persistent last-known-good promo record. Lives outside the /tmp cache so it
91
+ // survives a full cache wipe / cache write race / CLI failure combo. Written
92
+ // every time we successfully render a promo; read as a last resort so the row
93
+ // never blinks out mid-session (was: 'promo shows then hides' bug report).
94
+ const PROMO_MEMO_FILE = path.join(os.homedir(), '.ruflo', 'statusline-promo.json');
95
+ const PROMO_MEMO_TTL_MS = 6 * 60 * 60 * 1000; // 6h — long enough to bridge any hiccup, short enough that a real disable takes effect fast.
96
+
75
97
  // #2337: resolve an already-installed @claude-flow/cli (or ruflo) bin so we
76
98
  // can invoke it directly via \`node\`. The previous version called
77
99
  // \`npx --yes @claude-flow/cli@latest\` on every uncached render, which forces
@@ -79,18 +101,30 @@ const CACHE_TTL_MS = 60000;
79
101
  // multiple concurrent Claude Code sessions this storms the host (reporter
80
102
  // saw load average 40-65 on a 12-core box).
81
103
  //
82
- // Returns the absolute path to bin/cli.js or null. Mirrors getPkgVersion()'s
83
- // path probing (project, monorepo, plugin marketplace, global node_modules
84
- // including custom-prefix layouts like ~/.npm-global).
85
- function resolveCliBin() {
104
+ // Returns EVERY existing bin/cli.js candidate, in preference order (project,
105
+ // monorepo, plugin marketplace, global node_modules including custom-prefix
106
+ // layouts like ~/.npm-global) — mirrors getPkgVersion()'s own path probing.
107
+ //
108
+ // Returns a list, not a single winner: \`fs.existsSync\` only proves a file is
109
+ // present, not that it actually runs. A marketplace/npx-cached install can
110
+ // exist on disk but be broken (observed in practice: a stale marketplace
111
+ // checkout whose dist/ imports a workspace package, '@claude-flow/cli-core',
112
+ // that isn't bundled there — every invocation throws ERR_MODULE_NOT_FOUND).
113
+ // Picking the first EXISTING path and never falling through meant a single
114
+ // broken install silently killed the promo row for the entire session (the
115
+ // CLI call always failed, so the memo could never refresh and eventually
116
+ // expired). getStatuslineData() now walks this whole list and tries the next
117
+ // candidate on failure, so one broken install can't permanently wedge it.
118
+ function resolveCliBinCandidates() {
119
+ const candidates = [];
86
120
  try {
87
121
  const home = os.homedir();
88
- const candidates = [
122
+ candidates.push(
89
123
  path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'bin', 'cli.js'),
90
124
  path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'bin', 'cli.js'),
91
125
  path.join(CWD, 'node_modules', 'ruflo', 'bin', 'cli.js'),
92
126
  path.join(CWD, 'v3', '@claude-flow', 'cli', 'bin', 'cli.js'),
93
- ];
127
+ );
94
128
  try {
95
129
  const binDir = path.dirname(process.execPath);
96
130
  const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
@@ -104,27 +138,54 @@ function resolveCliBin() {
104
138
  );
105
139
  }
106
140
  } catch { /* ignore */ }
107
- for (const p of candidates) {
108
- if (fs.existsSync(p)) return p;
109
- }
110
141
  } catch { /* ignore */ }
111
- return null;
142
+ return candidates.filter((p) => { try { return fs.existsSync(p); } catch { return false; } });
112
143
  }
113
144
 
145
+ // Return { fresh, promoFresh, data }. 'fresh' is true only if within the TTL
146
+ // — but data is returned regardless (stale-while-revalidate). This lets us
147
+ // serve last known state (specifically the promo row) when the CLI is
148
+ // slow/unavailable, so users don't see the funnel row flicker in and out on
149
+ // cache expiry. 'promoFresh' is a SEPARATE, tighter check on the same clock
150
+ // as PROMO_ROTATION_SLOT_MS — see that constant's comment for why the promo
151
+ // row needs its own freshness bound distinct from the general 60s TTL.
114
152
  function readCache() {
115
153
  try {
116
154
  if (fs.existsSync(CACHE_FILE)) {
117
155
  const raw = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
118
- if (raw && raw._ts && (Date.now() - raw._ts) < CACHE_TTL_MS) {
119
- return raw.data;
156
+ if (raw && raw._ts && raw.data) {
157
+ const age = Date.now() - raw._ts;
158
+ return { fresh: age < CACHE_TTL_MS, promoFresh: age < PROMO_ROTATION_SLOT_MS, data: raw.data };
120
159
  }
121
160
  }
122
161
  } catch { /* ignore */ }
123
- return null;
162
+ return { fresh: false, promoFresh: false, data: null };
124
163
  }
125
164
 
126
165
  function writeCache(data) {
127
166
  try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ _ts: Date.now(), data }), 'utf-8'); } catch { /* ignore */ }
167
+ // Also memoize any promo we saw so the row can survive future CLI hiccups.
168
+ try {
169
+ if (data && data.promo && typeof data.promo === 'object') {
170
+ fs.mkdirSync(path.dirname(PROMO_MEMO_FILE), { recursive: true, mode: 0o700 });
171
+ fs.writeFileSync(PROMO_MEMO_FILE, JSON.stringify({ _ts: Date.now(), promo: data.promo }), { encoding: 'utf-8', mode: 0o600 });
172
+ }
173
+ } catch { /* ignore */ }
174
+ }
175
+
176
+ // Last resort: read a memoized promo (up to 6h old). Used when no cache and
177
+ // no CLI response is available — the row still renders, so users don't see
178
+ // the disclosure blink out. Returns null when the memo is absent, expired,
179
+ // or malformed. Never throws.
180
+ function readPromoMemo() {
181
+ try {
182
+ if (!fs.existsSync(PROMO_MEMO_FILE)) return null;
183
+ const raw = JSON.parse(fs.readFileSync(PROMO_MEMO_FILE, 'utf-8'));
184
+ if (raw && raw._ts && (Date.now() - raw._ts) < PROMO_MEMO_TTL_MS && raw.promo) {
185
+ return raw.promo;
186
+ }
187
+ } catch { /* ignore */ }
188
+ return null;
128
189
  }
129
190
 
130
191
  /**
@@ -135,37 +196,75 @@ function writeCache(data) {
135
196
  * (missed the .swarm/memory.db → AgentDB path), computed dddProgress wrong,
136
197
  * and only counted ADRs in v3/implementation/adrs/ (missed v3/docs/adr/).
137
198
  */
199
+ // Overlay the memoized promo onto any data object that's missing one. This is
200
+ // the safety net that keeps the funnel row rendered when an OLDER cached CLI
201
+ // version is picked up by npx — that older CLI succeeds but omits promo, so
202
+ // the JSON round-trips clean but without our row. We patch it back here.
203
+ function overlayMemoPromo(data) {
204
+ if (data && !data.promo) {
205
+ const memoPromo = readPromoMemo();
206
+ if (memoPromo) data.promo = memoPromo;
207
+ }
208
+ return data;
209
+ }
210
+
138
211
  function getStatuslineData() {
139
- const cached = readCache();
140
- if (cached) return cached;
212
+ const cache = readCache();
213
+ // Both clocks must be satisfied to skip the CLI call entirely: the general
214
+ // 60s TTL (#2337 — don't re-spawn the CLI on every rapid re-render) AND the
215
+ // tighter promo-rotation clock (this fix — don't let a still-fresh 60s
216
+ // cache silently freeze the promo/insight row across multiple 20s slots).
217
+ if (cache.fresh && cache.promoFresh) return overlayMemoPromo(cache.data);
218
+
219
+ // #2337: prefer an already-installed CLI bin via direct \`node\` invocation —
220
+ // no npx, no registry round-trip, no @latest re-resolve per render. Try
221
+ // every candidate that actually EXISTS (not just the first) before falling
222
+ // back to \`npx --prefer-offline @claude-flow/cli\` (no @latest); an existing
223
+ // but broken install (e.g. a stale marketplace checkout missing a bundled
224
+ // workspace dep) must not block trying the next one.
225
+ //
226
+ // No \`2>/dev/null\` here (deliberately) — the execSync call below already
227
+ // sets stdio: ['pipe','pipe','pipe'], which captures/discards stderr at the
228
+ // Node level regardless of shell. The redirect was redundant on POSIX and
229
+ // actively broke every candidate on Windows: cmd.exe (execSync's default
230
+ // shell there) doesn't understand /dev/null, so the CLI delegation always
231
+ // failed, silently degrading every render to buildLocalFallback() — 0%
232
+ // intelligence and an empty promo row (the memo cache that keeps the row
233
+ // populated across CLI hiccups is only ever written from a SUCCESSFUL
234
+ // delegation, so it could never get seeded on Windows either).
235
+ const cmds = resolveCliBinCandidates()
236
+ .map((bin) => '"' + process.execPath + '" "' + bin + '" hooks statusline --json')
237
+ .concat(['npx --prefer-offline @claude-flow/cli hooks statusline --json']);
238
+ for (const cmd of cmds) {
239
+ try {
240
+ const raw = execSync(
241
+ cmd,
242
+ { encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
243
+ ).trim();
244
+ // The CLI may emit preamble lines before the JSON — find the first '{'.
245
+ const jsonStart = raw.indexOf('{');
246
+ if (jsonStart === -1) throw new Error('no JSON in CLI output');
247
+ const data = JSON.parse(raw.slice(jsonStart));
248
+ // Overlay every block the CLI JSON omits (adrs/agentdb/tests/hooks/integration)
249
+ // with real local reads, so those segments reflect actual state instead of 0.
250
+ applyLocalOverlays(data);
251
+ overlayMemoPromo(data);
252
+ writeCache(data);
253
+ return data;
254
+ } catch { /* this candidate unavailable, broken, or timed out — try the next */ }
255
+ }
141
256
 
142
- try {
143
- // #2337: prefer an already-installed CLI bin via direct \`node\` invocation
144
- // — no npx, no registry round-trip, no @latest re-resolve per render.
145
- // Fall back to \`npx --prefer-offline @claude-flow/cli\` (no @latest) only
146
- // when nothing is installed locally, so a cold environment still works.
147
- const cliBin = resolveCliBin();
148
- const cmd = cliBin
149
- ? '"' + process.execPath + '" "' + cliBin + '" hooks statusline --json 2>/dev/null'
150
- : 'npx --prefer-offline @claude-flow/cli hooks statusline --json 2>/dev/null';
151
- const raw = execSync(
152
- cmd,
153
- { encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
154
- ).trim();
155
- // The CLI may emit preamble lines before the JSON — find the first '{'.
156
- const jsonStart = raw.indexOf('{');
157
- if (jsonStart === -1) throw new Error('no JSON in CLI output');
158
- const data = JSON.parse(raw.slice(jsonStart));
159
- // Overlay every block the CLI JSON omits (adrs/agentdb/tests/hooks/integration)
160
- // with real local reads, so those segments reflect actual state instead of 0.
161
- applyLocalOverlays(data);
162
- writeCache(data);
163
- return data;
164
- } catch { /* CLI unavailable or timed out */ }
165
-
166
- // Fallback: use local file probes only (will be less accurate, but non-zero
167
- // when CLI is available and accurate when it's not).
168
- return buildLocalFallback();
257
+ // Stale-while-revalidate: if we have any cached data, keep serving it so the
258
+ // funnel row doesn't flicker on CLI hiccups. Overlay fresh local reads for
259
+ // the segments the CLI JSON doesn't populate; the promo row survives.
260
+ if (cache.data) {
261
+ applyLocalOverlays(cache.data);
262
+ overlayMemoPromo(cache.data);
263
+ return cache.data;
264
+ }
265
+
266
+ // Last resort: local probes + memo. Users still see the funnel row.
267
+ return overlayMemoPromo(buildLocalFallback());
169
268
  }
170
269
 
171
270
  // Count ADRs from BOTH known directories (fix for ruflo#2195: old code missed
@@ -565,7 +664,11 @@ function generateStatusline() {
565
664
  const modelName = getModelFromStdin() || (d.user && d.user.modelName) || 'Claude Code';
566
665
  const ctxInfo = getContextFromStdin();
567
666
  const costInfo = getCostFromStdin();
568
- const pkgVersion = getPkgVersion();
667
+ // Named RUFLO_VERSION (not pkgVersion) so the #1951 regression guard
668
+ // (scripts/audit-fix-invariants.mjs) can pin its presence in the emitted
669
+ // .cjs artifact — without it the header silently reverts to a hard-coded
670
+ // "RuFlo V3.5" for anyone whose install doesn't match the first probe path.
671
+ const RUFLO_VERSION = getPkgVersion();
569
672
 
570
673
  const progress = d.v3Progress || {};
571
674
  const security = d.security || {};
@@ -601,8 +704,14 @@ function generateStatusline() {
601
704
 
602
705
  const lines = [];
603
706
 
604
- // Header
605
- let header = c.bold + c.brightPurple + '▊ RuFlo V' + pkgVersion + ' ' + c.reset;
707
+ // 3-line design (fits Claude Code's visible statusline area — line 4+ gets
708
+ // replaced by the system guidance / input prompt line):
709
+ // Line 1 — Header (RuFlo version · git · model · timing · context · cost)
710
+ // Line 2 — Compressed ops (Swarm · Hooks · 🧠 · 💾 · Health)
711
+ // Line 3 — Promo / disclosure row (funnel surface, ADR-301)
712
+
713
+ // ─── Line 1: header ────────────────────────────────────────────
714
+ let header = c.bold + c.brightPurple + '▊ RuFlo V' + RUFLO_VERSION + ' ' + c.reset;
606
715
  header += (coordinationActive ? c.brightCyan : c.dim) + '● ' + c.brightCyan + git.name + c.reset;
607
716
  if (git.gitBranch) {
608
717
  header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightBlue + '⏇ ' + git.gitBranch + c.reset;
@@ -629,81 +738,148 @@ function generateStatusline() {
629
738
  }
630
739
  lines.push(header);
631
740
 
632
- // Separator
633
- lines.push(c.dim + '─'.repeat(53) + c.reset);
634
-
635
- // Line 1: DDD Domains
636
- const domainsColor = domainsCompleted >= 3 ? c.brightGreen : domainsCompleted > 0 ? c.yellow : c.red;
637
- let perfIndicator;
638
- if (hasHnsw && vectorCount > 0) {
639
- const speedup = vectorCount > 10000 ? '12500x' : vectorCount > 1000 ? '150x' : '10x';
640
- perfIndicator = c.brightGreen + '⚡ HNSW ' + speedup + c.reset;
641
- } else if (patternsLearned > 0) {
642
- const pk = patternsLearned >= 1000 ? (patternsLearned / 1000).toFixed(1) + 'k' : String(patternsLearned);
643
- perfIndicator = c.brightYellow + '📚 ' + pk + ' patterns' + c.reset;
644
- } else {
645
- perfIndicator = c.dim + '⚡ target: 150x-12500x' + c.reset;
646
- }
647
- lines.push(
648
- c.brightCyan + '🏗️ DDD Domains' + c.reset + ' ' + progressBar(domainsCompleted, totalDomains) + ' ' +
649
- domainsColor + domainsCompleted + c.reset + '/' + c.brightWhite + totalDomains + c.reset + ' ' + perfIndicator
650
- );
651
-
652
- // Line 2: Swarm + Hooks + CVE + Memory + Intelligence
653
- const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset : c.dim + '○' + c.reset;
654
- const agentsColor = activeAgents > 0 ? c.brightGreen : c.red;
655
- const secIcon = secStatus === 'CLEAN' ? '🟢' : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? '🟡' : (secStatus === 'NONE' ? '⚪' : '🔴');
656
- const secColor = secStatus === 'CLEAN' ? c.brightGreen : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? c.brightYellow : (secStatus === 'NONE' ? c.dim : c.brightRed);
741
+ // ─── Line 2: compressed ops ────────────────────────────────────
742
+ // Everything actionable in one dense row. Show only what changes what you
743
+ // do next; diagnostic detail moves to \`ruflo status --verbose\`.
744
+ const agentsColor = activeAgents > 0 ? c.brightGreen : c.dim;
657
745
  const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
658
746
  const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
747
+ const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset + ' ' : c.dim + '○' + c.reset + ' ';
748
+ const cvesClean = totalCves === 0 || cvesFixed === totalCves;
749
+ const healthAllGreen = (secStatus === 'CLEAN' || secStatus === 'NONE') && cvesClean;
750
+ const opsParts = [];
751
+ opsParts.push(c.cyan + 'Swarm ' + swarmInd + agentsColor + activeAgents + c.reset + '/' + c.brightWhite + maxAgents + c.reset);
752
+ if (subAgents > 0) opsParts.push(c.brightPurple + '👥 ' + subAgents + c.reset);
753
+ opsParts.push(c.cyan + 'Hooks ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset);
754
+ opsParts.push(intellColor + '🧠 ' + intelligencePct + '%' + c.reset);
755
+ opsParts.push(c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset);
756
+ // Health: one glyph when green, terse copy when there's something to act on.
757
+ if (healthAllGreen) {
758
+ opsParts.push(c.brightGreen + '🛡 ✓' + c.reset);
759
+ } else {
760
+ if (secStatus === 'PENDING') opsParts.push(c.brightYellow + '🛡 scan pending' + c.reset);
761
+ else if (secStatus === 'IN_PROGRESS') opsParts.push(c.brightYellow + '🛡 scanning…' + c.reset);
762
+ else if (secStatus === 'STALE') opsParts.push(c.brightYellow + '🛡 scan stale' + c.reset);
763
+ else if (secStatus !== 'NONE' && secStatus !== 'CLEAN') opsParts.push(c.brightRed + '🛡 ' + secStatus.toLowerCase() + c.reset);
764
+ if (totalCves > 0 && cvesFixed < totalCves) {
765
+ const unfixed = totalCves - cvesFixed;
766
+ opsParts.push(c.brightRed + '⚠ ' + unfixed + ' CVE' + (unfixed === 1 ? '' : 's') + c.reset);
767
+ }
768
+ }
769
+ lines.push(opsParts.join(' ' + c.dim + '·' + c.reset + ' '));
770
+
771
+ // ─── Line 3: promo / disclosure / insight ───────────────────────
772
+ // Colored by content kind so it reads as *what it is*, not as noise:
773
+ // disclosure → brightCyan (announcement / capability link)
774
+ // promotional → brightPurple (Cognitum sponsor spot)
775
+ // educational → yellow (a tip)
776
+ // insight → brightRed (environment/task-aware, local, actionable —
777
+ // distinct from remote content on purpose)
778
+ const promoRow = getPromoRow(d);
779
+ if (promoRow) {
780
+ const kind = (d && d.promo && d.promo.kind) || 'disclosure';
781
+ const promoColor = kind === 'promotional' ? c.brightPurple
782
+ : kind === 'educational' ? c.yellow
783
+ : kind === 'insight' ? c.brightRed
784
+ : c.brightCyan;
785
+ lines.push(promoColor + promoRow + c.reset);
786
+ }
787
+
788
+ // Trailing blank line so Claude Code's input prompt gets breathing room
789
+ // instead of butting directly against the last statusline row.
790
+ return lines.join('\\n') + '\\n';
791
+ }
659
792
 
660
- lines.push(
661
- c.brightYellow + '🤖 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + maxAgents + c.reset + '] ' +
662
- c.brightPurple + '👥 ' + subAgents + c.reset + ' ' +
663
- c.brightBlue + '🪝 ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset + ' ' +
664
- secIcon + ' ' + secColor + 'CVE ' + cvesFixed + c.reset + '/' + c.brightWhite + totalCves + c.reset + ' ' +
665
- c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset + ' ' +
666
- intellColor + '🧠 ' + String(intelligencePct).padStart(3) + '%' + c.reset
667
- );
668
-
669
- // Line 3: Architecture
670
- const dddColor = dddProgress >= 50 ? c.brightGreen : dddProgress > 0 ? c.yellow : c.red;
671
- const adrColor = adrCount > 0 ? (adrImpl === adrCount ? c.brightGreen : c.yellow) : c.dim;
672
- const adrDisplay = adrColor + '●' + adrImpl + '/' + adrCount + c.reset;
673
-
674
- lines.push(
675
- c.brightPurple + '🔧 Architecture' + c.reset + ' ' +
676
- c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '│' + c.reset + ' ' +
677
- c.cyan + 'DDD' + c.reset + ' ' + dddColor + '●' + String(dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
678
- c.cyan + 'Security' + c.reset + ' ' + secColor + '●' + secStatus + c.reset
679
- );
680
-
681
- // Line 4: AgentDB, Tests, Integration
682
- const hnswInd = hasHnsw ? c.brightGreen + '⚡' + c.reset : '';
683
- const sizeDisp = dbSizeKB >= 1024 ? (dbSizeKB / 1024).toFixed(1) + 'MB' : dbSizeKB + 'KB';
684
- const vectorColor = vectorCount > 0 ? c.brightGreen : c.dim;
685
- const testColor = testFiles > 0 ? c.brightGreen : c.dim;
686
-
687
- // MCP / DB integration from data
688
- const integration = d.integration || {};
689
- const mcpServers = (integration.mcpServers) || {};
690
- let integStr = '';
691
- if (mcpServers.total > 0) {
692
- const mcpCol = mcpServers.enabled === mcpServers.total ? c.brightGreen : mcpServers.enabled > 0 ? c.brightYellow : c.red;
693
- integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '●' + mcpServers.enabled + '/' + mcpServers.total + c.reset;
793
+ // ─── Funnel promo row (ADR-301) ─────────────────────────────────
794
+ // Allowlist for OSC 8 hyperlink targets. Ships in code (not in payload) so
795
+ // no message can smuggle a link to an unapproved host.
796
+ //
797
+ // The final destination hosts (cognitum.one / agentics.org) AND the
798
+ // click-redirect host are both allowlisted here: promo.ts routes every
799
+ // clickable message through the server-side click-redirect (ADR-311 §7)
800
+ // so promo_open + geo are captured before the 302 to the real target —
801
+ // so the OSC 8 link the renderer emits points at the redirect host, not
802
+ // the final destination directly.
803
+ const PROMO_LINK_HOSTS = new Set([
804
+ 'cognitum.one', 'www.cognitum.one', 'docs.cognitum.one',
805
+ // agentics.org — OSS foundation, distinct sponsor domain. Kept in sync
806
+ // with messages.ts ALLOWED_URL_HOSTS.
807
+ 'agentics.org', 'www.agentics.org',
808
+ // Click-redirect host (funnel.ruv.io once its TLS cert is live; the raw
809
+ // Cloud Run hostname is allowlisted too since event-transport.ts /
810
+ // message-transport.ts / attribution.ts currently point at it as a TEMP
811
+ // fallback while the domain mapping's cert provisions).
812
+ 'funnel.ruv.io',
813
+ 'cognitum-analytics-63rzcdswba-uc.a.run.app',
814
+ ]);
815
+
816
+ // Emit OSC 8 hyperlinks unless the environment is known-broken. tmux mangles
817
+ // raw OSC 8 (see anthropics/claude-code#27047) — opt in via env if wrapped.
818
+ function terminalSupportsHyperlinks() {
819
+ if (process.env.CI || process.env.GITHUB_ACTIONS) return false;
820
+ if (process.env.TERM === 'dumb') return false;
821
+ if (/^(0|false|off|no)$/i.test(String(process.env.RUFLO_STATUSLINE_HYPERLINKS || ''))) return false;
822
+ if (process.env.TMUX && !process.env.RUFLO_STATUSLINE_HYPERLINKS_TMUX) return false;
823
+ return true;
824
+ }
825
+
826
+ // Wrap a label in an OSC 8 hyperlink escape sequence. Falls back to the raw
827
+ // label whenever the URL is not an allowlisted https target, when the terminal
828
+ // can't render hyperlinks, or when parsing fails — a broken link must never
829
+ // leave a raw URL or stray escape in the statusline output.
830
+ function safeTerminalLink(label, url) {
831
+ if (!terminalSupportsHyperlinks()) return label;
832
+ if (typeof url !== 'string' || url.length === 0) return label;
833
+ let parsed;
834
+ try { parsed = new URL(url); } catch { return label; }
835
+ if (parsed.protocol !== 'https:') return label;
836
+ if (!PROMO_LINK_HOSTS.has(parsed.hostname)) return label;
837
+ const cleanLabel = String(label).replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u202a-\\u202e\\u2066-\\u2069]/g, '');
838
+ if (cleanLabel.length === 0) return label;
839
+ const ESC = '\\u001b';
840
+ return ESC + ']8;;' + parsed.href + ESC + '\\\\' + cleanLabel + ESC + ']8;;' + ESC + '\\\\';
841
+ }
842
+
843
+ function getPromoRow(d) {
844
+ try {
845
+ if (process.env.CI || process.env.GITHUB_ACTIONS) return null;
846
+ if (/^(0|false|off|no)$/i.test(String(process.env.RUFLO_FUNNEL || ''))) return null;
847
+ const promo = d && d.promo;
848
+ if (!promo || typeof promo.text !== 'string') return null;
849
+ // Strip control chars / ANSI / bidi overrides and hard-cap length —
850
+ // promo copy is data and must never emit its own terminal sequences.
851
+ const text = promo.text
852
+ .replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u202a-\\u202e\\u2066-\\u2069]/g, '')
853
+ .slice(0, 100)
854
+ .trim();
855
+ if (text.length === 0) return null;
856
+ // Split the label from the trailing "· manage: ruflo settings" instruction
857
+ // so each part gets styling that matches what it actually IS:
858
+ // 1. label — OSC 8 hyperlink + underline. A real clickable link.
859
+ // 2. "manage:" — dim. Just a connector word, no action implied.
860
+ // 3. "ruflo settings" — bold/bright, NOT underlined. This is a shell
861
+ // command the user TYPES, not a link they CLICK — a terminal can
862
+ // never safely execute a command from a click (that would let any
863
+ // server-served message run arbitrary commands), so we deliberately
864
+ // avoid the underline/OSC8 cues that imply "clickable". Bold+bright
865
+ // instead signals "this is the important bit — copy/type it".
866
+ // Educational tips have no manage tail and no URL — plain text through.
867
+ const manageIdx = text.indexOf(' · manage: ');
868
+ const label = manageIdx > 0 ? text.slice(0, manageIdx) : text;
869
+ const manageWord = manageIdx > 0 ? ' · manage: ' : '';
870
+ const command = manageIdx > 0 ? text.slice(manageIdx + manageWord.length) : '';
871
+ const UL_ON = '\\u001b[4m';
872
+ const UL_OFF = '\\u001b[24m';
873
+ const DIM_ON = '\\u001b[2m';
874
+ const DIM_OFF = '\\u001b[22m';
875
+ const BOLD_ON = '\\u001b[1m';
876
+ const BOLD_OFF = '\\u001b[22m';
877
+ const linked = promo.url ? UL_ON + safeTerminalLink(label, promo.url) + UL_OFF : label;
878
+ if (!command) return linked;
879
+ return linked + DIM_ON + manageWord + DIM_OFF + BOLD_ON + command + BOLD_OFF;
880
+ } catch (e) {
881
+ return null; // the promo row must never break the statusline
694
882
  }
695
- if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '◆' + c.reset + 'DB';
696
- if (!integStr) integStr = c.dim + '● none' + c.reset;
697
-
698
- lines.push(
699
- c.brightCyan + '📊 AgentDB' + c.reset + ' ' +
700
- c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '●' + vectorCount + hnswInd + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
701
- c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
702
- c.cyan + 'Tests' + c.reset + ' ' + testColor + '●' + testFiles + c.reset + ' ' + c.dim + '(~' + testCases + ' cases)' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
703
- integStr
704
- );
705
-
706
- return lines.join('\\n');
707
883
  }
708
884
 
709
885
  // JSON output — delegates to CLI for accuracy; caller can use --json flag
@@ -10,7 +10,17 @@
10
10
  * own lock + checkExistingDaemon() — so a race spawns at most one survivor,
11
11
  * - bounded lifetime: the daemon self-terminates on TTL/idle (12h default,
12
12
  * RUFLO_DAEMON_TTL_SECS) — auto-start never means "runs forever",
13
- * - opt-out: RUFLO_DAEMON_AUTOSTART=0|false|no disables it entirely,
13
+ * - opt-out: RUFLO_DAEMON_AUTOSTART=0|false|no disables it entirely, OR a
14
+ * project-local `daemon.autostart: false` in claude-flow.config.json —
15
+ * the file-based opt-out exists because the env var only reaches a
16
+ * process that inherited it. A non-interactive shell (cron, CI, many
17
+ * tool-invoked shells — bash skips ~/.bashrc entirely for these; see
18
+ * its own `case $- in *i*) ;; *) return;; esac` guard) never re-sources
19
+ * a shell rc file per invocation, so `export RUFLO_DAEMON_AUTOSTART=0`
20
+ * in one such shell does NOT persist to the next one. A project config
21
+ * field has no such gap — it's read fresh from disk every time,
22
+ * independent of which shell (or whether any shell at all) launched
23
+ * the command,
14
24
  * - cheap: a pidfile read + a signal-0 liveness check on the fast path,
15
25
  * - best-effort + silent: never blocks or fails a command.
16
26
  *
@@ -41,8 +51,21 @@ export function isDaemonAlive(projectRoot) {
41
51
  return false;
42
52
  }
43
53
  }
44
- function autostartDisabled() {
45
- return /^(0|false|no|off)$/i.test(process.env.RUFLO_DAEMON_AUTOSTART ?? '');
54
+ /** Project-local opt-out: `{ "daemon": { "autostart": false } }` in claude-flow.config.json. */
55
+ function autostartDisabledByProjectConfig(projectRoot) {
56
+ try {
57
+ const raw = fs.readFileSync(path.join(projectRoot, 'claude-flow.config.json'), 'utf-8');
58
+ const cfg = JSON.parse(raw);
59
+ return cfg?.daemon?.autostart === false;
60
+ }
61
+ catch {
62
+ return false; // absent/malformed config = not disabled
63
+ }
64
+ }
65
+ function autostartDisabled(projectRoot) {
66
+ if (/^(0|false|no|off)$/i.test(process.env.RUFLO_DAEMON_AUTOSTART ?? ''))
67
+ return true;
68
+ return autostartDisabledByProjectConfig(projectRoot);
46
69
  }
47
70
  const defaultSpawn = (projectRoot) => {
48
71
  const cliBin = process.argv[1]; // the running bin/cli.js
@@ -60,8 +83,8 @@ const defaultSpawn = (projectRoot) => {
60
83
  */
61
84
  export function ensureDaemonRunning(projectRoot, opts = {}) {
62
85
  try {
63
- if (autostartDisabled())
64
- return { started: false, reason: 'disabled (RUFLO_DAEMON_AUTOSTART=0)' };
86
+ if (autostartDisabled(projectRoot))
87
+ return { started: false, reason: 'disabled (RUFLO_DAEMON_AUTOSTART=0 or project config)' };
65
88
  // Only in an initialized project (avoid scaffolding a daemon in a random dir).
66
89
  if (!fs.existsSync(path.join(projectRoot, '.claude-flow')) && !fs.existsSync(path.join(projectRoot, '.claude'))) {
67
90
  return { started: false, reason: 'not a ruflo project' };
@@ -79,6 +79,36 @@ export interface ReflectResult {
79
79
  diagnosis: string;
80
80
  mutationHint: string;
81
81
  }
82
+ /**
83
+ * ADR-316 — a compact, STRUCTURAL-ONLY snapshot of the current coding
84
+ * session for the statusline's co-pilot advisor tip. Every field here
85
+ * mirrors funnel/insights.ts's LocalInsightContext — no raw prompt/command/
86
+ * file content, ever (same bar as ADR-309, applied to a different, opt-in
87
+ * data flow). The model sees only what's already surfaced structurally
88
+ * elsewhere in the statusline.
89
+ */
90
+ export interface CoPilotSnapshot {
91
+ security?: {
92
+ status: string;
93
+ cvesFixed: number;
94
+ totalCves: number;
95
+ };
96
+ swarm?: {
97
+ activeAgents: number;
98
+ maxAgents: number;
99
+ coordinationActive: boolean;
100
+ };
101
+ gitUncommittedCount?: number;
102
+ contextPctUsed?: number;
103
+ }
104
+ /** A single proactive suggestion for the insight ticker. */
105
+ export interface CoPilotTip {
106
+ /** Short enough for a single statusline row (caller truncates further). */
107
+ headline: string;
108
+ /** One actionable sentence of extra detail. */
109
+ detail: string;
110
+ confidence: number;
111
+ }
82
112
  /** Result of a raw claude spawn. */
83
113
  export interface ClaudeSpawnResult {
84
114
  stdout: string;
@@ -147,6 +177,15 @@ export declare class FableHarness {
147
177
  * discipline as judgeBatch. Returns [] when no budget cap is configured.
148
178
  */
149
179
  reflectFailures(items: ReflectItem[]): Promise<ReflectResult[]>;
180
+ /**
181
+ * ADR-316 — one proactive co-pilot tip from a structural session snapshot
182
+ * (no raw prompt/command/file content). A single-item "batch" — same
183
+ * budget/cwd/parsing discipline as judgeBatch/reflectFailures, just with
184
+ * exactly one call instead of a loop. Returns null when disabled, over
185
+ * budget, or the model found nothing worth surfacing (an empty verdict
186
+ * array is a valid, non-error answer here, not a parse failure).
187
+ */
188
+ adviseCoPilotTip(snapshot: CoPilotSnapshot): Promise<CoPilotTip | null>;
150
189
  /** Build the argv for a `claude -p` call. Exposed shape for testability. */
151
190
  buildArgv(systemPrompt: string): string[];
152
191
  /**