agentic-qe 3.5.0 → 3.5.2

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 (203) hide show
  1. package/.claude/agents/n8n/n8n-base-agent.md +3 -3
  2. package/.claude/agents/n8n/n8n-bdd-scenario-tester.md +2 -2
  3. package/.claude/agents/n8n/n8n-chaos-tester.md +2 -2
  4. package/.claude/agents/n8n/n8n-ci-orchestrator.md +2 -2
  5. package/.claude/agents/n8n/n8n-compliance-validator.md +2 -2
  6. package/.claude/agents/n8n/n8n-expression-validator.md +2 -2
  7. package/.claude/agents/n8n/n8n-integration-test.md +2 -2
  8. package/.claude/agents/n8n/n8n-monitoring-validator.md +2 -2
  9. package/.claude/agents/n8n/n8n-node-validator.md +2 -2
  10. package/.claude/agents/n8n/n8n-performance-tester.md +2 -2
  11. package/.claude/agents/n8n/n8n-security-auditor.md +2 -2
  12. package/.claude/agents/n8n/n8n-trigger-test.md +2 -2
  13. package/.claude/agents/n8n/n8n-unit-tester.md +2 -2
  14. package/.claude/agents/n8n/n8n-version-comparator.md +2 -2
  15. package/.claude/agents/n8n/n8n-workflow-executor.md +2 -2
  16. package/.claude/agents/subagents/qe-code-reviewer.md +2 -2
  17. package/.claude/agents/subagents/qe-coverage-gap-analyzer.md +2 -2
  18. package/.claude/agents/subagents/qe-data-generator.md +2 -2
  19. package/.claude/agents/subagents/qe-flaky-investigator.md +2 -2
  20. package/.claude/agents/subagents/qe-integration-tester.md +2 -2
  21. package/.claude/agents/subagents/qe-performance-validator.md +2 -2
  22. package/.claude/agents/subagents/qe-security-auditor.md +2 -2
  23. package/.claude/agents/subagents/qe-test-data-architect-sub.md +2 -2
  24. package/.claude/agents/subagents/qe-test-implementer.md +2 -2
  25. package/.claude/agents/subagents/qe-test-refactorer.md +2 -2
  26. package/.claude/agents/subagents/qe-test-writer.md +2 -2
  27. package/.claude/agents/v3/qe-accessibility-auditor.md +3 -3
  28. package/.claude/agents/v3/qe-bdd-generator.md +4 -4
  29. package/.claude/agents/v3/qe-chaos-engineer.md +3 -3
  30. package/.claude/agents/v3/qe-code-complexity.md +3 -3
  31. package/.claude/agents/v3/qe-code-intelligence.md +3 -3
  32. package/.claude/agents/v3/qe-contract-validator.md +3 -3
  33. package/.claude/agents/v3/qe-coverage-specialist.md +4 -4
  34. package/.claude/agents/v3/qe-defect-predictor.md +4 -4
  35. package/.claude/agents/v3/qe-dependency-mapper.md +3 -3
  36. package/.claude/agents/v3/qe-deployment-advisor.md +3 -3
  37. package/.claude/agents/v3/qe-flaky-hunter.md +3 -3
  38. package/.claude/agents/v3/qe-fleet-commander.md +3 -3
  39. package/.claude/agents/v3/qe-gap-detector.md +4 -4
  40. package/.claude/agents/v3/qe-graphql-tester.md +3 -3
  41. package/.claude/agents/v3/qe-impact-analyzer.md +3 -3
  42. package/.claude/agents/v3/qe-integration-architect.md +2 -2
  43. package/.claude/agents/v3/qe-integration-tester.md +3 -3
  44. package/.claude/agents/v3/qe-kg-builder.md +3 -3
  45. package/.claude/agents/v3/qe-learning-coordinator.md +24 -15
  46. package/.claude/agents/v3/qe-load-tester.md +3 -3
  47. package/.claude/agents/v3/qe-metrics-optimizer.md +3 -3
  48. package/.claude/agents/v3/qe-mutation-tester.md +3 -3
  49. package/.claude/agents/v3/qe-parallel-executor.md +4 -4
  50. package/.claude/agents/v3/qe-pattern-learner.md +16 -12
  51. package/.claude/agents/v3/qe-performance-tester.md +3 -3
  52. package/.claude/agents/v3/qe-product-factors-assessor.md +4 -4
  53. package/.claude/agents/v3/qe-property-tester.md +3 -3
  54. package/.claude/agents/v3/qe-quality-criteria-recommender.md +4 -4
  55. package/.claude/agents/v3/qe-quality-gate.md +4 -4
  56. package/.claude/agents/v3/qe-qx-partner.md +3 -3
  57. package/.claude/agents/v3/qe-regression-analyzer.md +3 -3
  58. package/.claude/agents/v3/qe-requirements-validator.md +4 -4
  59. package/.claude/agents/v3/qe-responsive-tester.md +3 -3
  60. package/.claude/agents/v3/qe-retry-handler.md +3 -3
  61. package/.claude/agents/v3/qe-risk-assessor.md +4 -4
  62. package/.claude/agents/v3/qe-root-cause-analyzer.md +3 -3
  63. package/.claude/agents/v3/qe-security-auditor.md +3 -3
  64. package/.claude/agents/v3/qe-security-scanner.md +3 -3
  65. package/.claude/agents/v3/qe-tdd-specialist.md +4 -4
  66. package/.claude/agents/v3/qe-test-architect.md +4 -4
  67. package/.claude/agents/v3/qe-test-idea-rewriter.md +3 -3
  68. package/.claude/agents/v3/qe-transfer-specialist.md +3 -3
  69. package/.claude/agents/v3/qe-visual-tester.md +3 -3
  70. package/.claude/agents/v3/reasoningbank-learner.md +4 -4
  71. package/.claude/agents/v3/subagents/qe-code-reviewer.md +3 -3
  72. package/.claude/agents/v3/subagents/qe-integration-reviewer.md +3 -3
  73. package/.claude/agents/v3/subagents/qe-performance-reviewer.md +3 -3
  74. package/.claude/agents/v3/subagents/qe-security-reviewer.md +3 -3
  75. package/.claude/agents/v3/subagents/qe-tdd-green.md +3 -3
  76. package/.claude/agents/v3/subagents/qe-tdd-red.md +3 -3
  77. package/.claude/agents/v3/subagents/qe-tdd-refactor.md +3 -3
  78. package/.claude/helpers/daemon-manager.sh +10 -10
  79. package/.claude/helpers/github-safe.js +10 -10
  80. package/.claude/helpers/statusline-v3.cjs +9 -3
  81. package/.claude/helpers/statusline.cjs +891 -59
  82. package/.claude/skills/agentic-quality-engineering/SKILL.md +6 -6
  83. package/.claude/skills/qcsd-cicd-swarm/SKILL.md +14 -14
  84. package/.claude/skills/qcsd-development-swarm/SKILL.md +14 -14
  85. package/.claude/skills/qcsd-ideation-swarm/SKILL.md +21 -21
  86. package/.claude/skills/qcsd-refinement-swarm/SKILL.md +22 -22
  87. package/.claude/skills/qe-iterative-loop/SKILL.md +4 -4
  88. package/.claude/skills/skills-manifest.json +17 -9
  89. package/.claude/skills/verification-quality/SKILL.md +0 -6
  90. package/CHANGELOG.md +52 -0
  91. package/README.md +22 -10
  92. package/package.json +5 -3
  93. package/v3/CHANGELOG.md +51 -3
  94. package/v3/README.md +9 -9
  95. package/v3/assets/agents/v3/qe-accessibility-auditor.md +12 -8
  96. package/v3/assets/agents/v3/qe-bdd-generator.md +13 -9
  97. package/v3/assets/agents/v3/qe-chaos-engineer.md +12 -8
  98. package/v3/assets/agents/v3/qe-code-complexity.md +12 -8
  99. package/v3/assets/agents/v3/qe-code-intelligence.md +12 -8
  100. package/v3/assets/agents/v3/qe-contract-validator.md +12 -8
  101. package/v3/assets/agents/v3/qe-coverage-specialist.md +13 -9
  102. package/v3/assets/agents/v3/qe-defect-predictor.md +13 -9
  103. package/v3/assets/agents/v3/qe-dependency-mapper.md +12 -8
  104. package/v3/assets/agents/v3/qe-deployment-advisor.md +12 -8
  105. package/v3/assets/agents/v3/qe-flaky-hunter.md +12 -8
  106. package/v3/assets/agents/v3/qe-fleet-commander.md +12 -8
  107. package/v3/assets/agents/v3/qe-gap-detector.md +13 -9
  108. package/v3/assets/agents/v3/qe-graphql-tester.md +12 -8
  109. package/v3/assets/agents/v3/qe-impact-analyzer.md +12 -8
  110. package/v3/assets/agents/v3/qe-integration-architect.md +2 -2
  111. package/v3/assets/agents/v3/qe-integration-tester.md +3 -3
  112. package/v3/assets/agents/v3/qe-kg-builder.md +12 -8
  113. package/v3/assets/agents/v3/qe-learning-coordinator.md +24 -15
  114. package/v3/assets/agents/v3/qe-load-tester.md +12 -8
  115. package/v3/assets/agents/v3/qe-metrics-optimizer.md +12 -8
  116. package/v3/assets/agents/v3/qe-mutation-tester.md +12 -8
  117. package/v3/assets/agents/v3/qe-parallel-executor.md +4 -4
  118. package/v3/assets/agents/v3/qe-pattern-learner.md +16 -12
  119. package/v3/assets/agents/v3/qe-performance-tester.md +12 -8
  120. package/v3/assets/agents/v3/qe-product-factors-assessor.md +4 -4
  121. package/v3/assets/agents/v3/qe-property-tester.md +12 -8
  122. package/v3/assets/agents/v3/qe-quality-criteria-recommender.md +4 -4
  123. package/v3/assets/agents/v3/qe-quality-gate.md +4 -4
  124. package/v3/assets/agents/v3/qe-qx-partner.md +12 -8
  125. package/v3/assets/agents/v3/qe-regression-analyzer.md +12 -8
  126. package/v3/assets/agents/v3/qe-requirements-validator.md +13 -9
  127. package/v3/assets/agents/v3/qe-responsive-tester.md +12 -8
  128. package/v3/assets/agents/v3/qe-retry-handler.md +12 -8
  129. package/v3/assets/agents/v3/qe-risk-assessor.md +13 -9
  130. package/v3/assets/agents/v3/qe-root-cause-analyzer.md +12 -8
  131. package/v3/assets/agents/v3/qe-security-auditor.md +12 -8
  132. package/v3/assets/agents/v3/qe-security-scanner.md +12 -8
  133. package/v3/assets/agents/v3/qe-tdd-specialist.md +4 -4
  134. package/v3/assets/agents/v3/qe-test-architect.md +13 -9
  135. package/v3/assets/agents/v3/qe-test-idea-rewriter.md +3 -3
  136. package/v3/assets/agents/v3/qe-transfer-specialist.md +12 -8
  137. package/v3/assets/agents/v3/qe-visual-tester.md +3 -3
  138. package/v3/assets/agents/v3/subagents/qe-code-reviewer.md +12 -8
  139. package/v3/assets/agents/v3/subagents/qe-integration-reviewer.md +12 -8
  140. package/v3/assets/agents/v3/subagents/qe-performance-reviewer.md +12 -8
  141. package/v3/assets/agents/v3/subagents/qe-security-reviewer.md +12 -8
  142. package/v3/assets/agents/v3/subagents/qe-tdd-green.md +12 -8
  143. package/v3/assets/agents/v3/subagents/qe-tdd-red.md +12 -8
  144. package/v3/assets/agents/v3/subagents/qe-tdd-refactor.md +12 -8
  145. package/v3/assets/skills/agentic-quality-engineering/SKILL.md +6 -6
  146. package/v3/assets/skills/qcsd-ideation-swarm/SKILL.md +21 -21
  147. package/v3/assets/skills/qe-iterative-loop/SKILL.md +4 -4
  148. package/v3/dist/cli/bundle.js +2508 -816
  149. package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
  150. package/v3/dist/cli/commands/hooks.js +34 -21
  151. package/v3/dist/cli/commands/hooks.js.map +1 -1
  152. package/v3/dist/cli/commands/learning.d.ts +23 -0
  153. package/v3/dist/cli/commands/learning.d.ts.map +1 -0
  154. package/v3/dist/cli/commands/learning.js +1448 -0
  155. package/v3/dist/cli/commands/learning.js.map +1 -0
  156. package/v3/dist/cli/index.js +2 -0
  157. package/v3/dist/cli/index.js.map +1 -1
  158. package/v3/dist/init/init-wizard.d.ts +2 -1
  159. package/v3/dist/init/init-wizard.d.ts.map +1 -1
  160. package/v3/dist/init/init-wizard.js +25 -23
  161. package/v3/dist/init/init-wizard.js.map +1 -1
  162. package/v3/dist/init/phases/07-hooks.d.ts +3 -0
  163. package/v3/dist/init/phases/07-hooks.d.ts.map +1 -1
  164. package/v3/dist/init/phases/07-hooks.js +12 -9
  165. package/v3/dist/init/phases/07-hooks.js.map +1 -1
  166. package/v3/dist/kernel/unified-memory.d.ts +8 -3
  167. package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
  168. package/v3/dist/kernel/unified-memory.js +39 -9
  169. package/v3/dist/kernel/unified-memory.js.map +1 -1
  170. package/v3/dist/learning/aqe-learning-engine.d.ts +26 -0
  171. package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -1
  172. package/v3/dist/learning/aqe-learning-engine.js +116 -2
  173. package/v3/dist/learning/aqe-learning-engine.js.map +1 -1
  174. package/v3/dist/learning/index.d.ts +4 -0
  175. package/v3/dist/learning/index.d.ts.map +1 -1
  176. package/v3/dist/learning/index.js +8 -0
  177. package/v3/dist/learning/index.js.map +1 -1
  178. package/v3/dist/learning/metrics-tracker.d.ts +133 -0
  179. package/v3/dist/learning/metrics-tracker.d.ts.map +1 -0
  180. package/v3/dist/learning/metrics-tracker.js +396 -0
  181. package/v3/dist/learning/metrics-tracker.js.map +1 -0
  182. package/v3/dist/learning/pattern-lifecycle.d.ts +203 -0
  183. package/v3/dist/learning/pattern-lifecycle.d.ts.map +1 -0
  184. package/v3/dist/learning/pattern-lifecycle.js +614 -0
  185. package/v3/dist/learning/pattern-lifecycle.js.map +1 -0
  186. package/v3/dist/learning/sqlite-persistence.d.ts +30 -0
  187. package/v3/dist/learning/sqlite-persistence.d.ts.map +1 -1
  188. package/v3/dist/learning/sqlite-persistence.js +137 -0
  189. package/v3/dist/learning/sqlite-persistence.js.map +1 -1
  190. package/v3/dist/mcp/bundle.js +104568 -102038
  191. package/v3/dist/mcp/handlers/handler-factory.d.ts +5 -0
  192. package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -1
  193. package/v3/dist/mcp/handlers/handler-factory.js +84 -0
  194. package/v3/dist/mcp/handlers/handler-factory.js.map +1 -1
  195. package/v3/dist/mcp/services/task-router.d.ts +32 -0
  196. package/v3/dist/mcp/services/task-router.d.ts.map +1 -1
  197. package/v3/dist/mcp/services/task-router.js +28 -0
  198. package/v3/dist/mcp/services/task-router.js.map +1 -1
  199. package/v3/dist/workers/workers/learning-consolidation.d.ts +29 -0
  200. package/v3/dist/workers/workers/learning-consolidation.d.ts.map +1 -1
  201. package/v3/dist/workers/workers/learning-consolidation.js +294 -3
  202. package/v3/dist/workers/workers/learning-consolidation.js.map +1 -1
  203. package/v3/package.json +3 -2
@@ -24,7 +24,7 @@ const CONFIG = {
24
24
  showPerformance: true,
25
25
  refreshInterval: 5000,
26
26
  maxAgents: 15,
27
- topology: 'hierarchical-mesh',
27
+ topology: 'hierarchical',
28
28
  };
29
29
 
30
30
  // ANSI colors
@@ -51,7 +51,7 @@ const c = {
51
51
  function getUserInfo() {
52
52
  let name = 'user';
53
53
  let gitBranch = '';
54
- let modelName = 'Opus 4.5';
54
+ let modelName = '🤖 Claude Code';
55
55
 
56
56
  try {
57
57
  name = execSync('git config user.name 2>/dev/null || echo "user"', { encoding: 'utf-8' }).trim();
@@ -60,16 +60,86 @@ function getUserInfo() {
60
60
  // Ignore errors
61
61
  }
62
62
 
63
+ // Auto-detect model from Claude Code's config
64
+ try {
65
+ const homedir = require('os').homedir();
66
+ const claudeConfigPath = path.join(homedir, '.claude.json');
67
+ if (fs.existsSync(claudeConfigPath)) {
68
+ const claudeConfig = JSON.parse(fs.readFileSync(claudeConfigPath, 'utf-8'));
69
+ // Try to find lastModelUsage - check current dir and parent dirs
70
+ let lastModelUsage = null;
71
+ const cwd = process.cwd();
72
+ if (claudeConfig.projects) {
73
+ // Try exact match first, then check if cwd starts with any project path
74
+ for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
75
+ if (cwd === projectPath || cwd.startsWith(projectPath + '/')) {
76
+ lastModelUsage = projectConfig.lastModelUsage;
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ if (lastModelUsage) {
82
+ const modelIds = Object.keys(lastModelUsage);
83
+ if (modelIds.length > 0) {
84
+ // Find the most recently used model by checking lastUsedAt timestamps
85
+ // or fall back to the last key in the object (preserves insertion order in modern JS)
86
+ let modelId = modelIds[modelIds.length - 1];
87
+ let latestTimestamp = 0;
88
+
89
+ for (const id of modelIds) {
90
+ const usage = lastModelUsage[id];
91
+ // Check for lastUsedAt timestamp (if available)
92
+ if (usage.lastUsedAt) {
93
+ const ts = new Date(usage.lastUsedAt).getTime();
94
+ if (ts > latestTimestamp) {
95
+ latestTimestamp = ts;
96
+ modelId = id;
97
+ }
98
+ }
99
+ }
100
+
101
+ // Parse model ID to human-readable name
102
+ if (modelId.includes('opus')) modelName = 'Opus 4.5';
103
+ else if (modelId.includes('sonnet')) modelName = 'Sonnet 4';
104
+ else if (modelId.includes('haiku')) modelName = 'Haiku 4.5';
105
+ else modelName = modelId.split('-').slice(1, 3).join(' ');
106
+ }
107
+ }
108
+ }
109
+ } catch (e) {
110
+ // Fallback to Unknown if can't read config
111
+ }
112
+
113
+ // Fallback: check project's .claude/settings.json for model
114
+ if (modelName === 'Unknown') {
115
+ try {
116
+ const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
117
+ if (fs.existsSync(settingsPath)) {
118
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
119
+ if (settings.model) {
120
+ if (settings.model.includes('opus')) modelName = 'Opus 4.5';
121
+ else if (settings.model.includes('sonnet')) modelName = 'Sonnet 4';
122
+ else if (settings.model.includes('haiku')) modelName = 'Haiku 4.5';
123
+ else modelName = settings.model.split('-').slice(1, 3).join(' ');
124
+ }
125
+ }
126
+ } catch (e) {
127
+ // Keep Unknown
128
+ }
129
+ }
130
+
63
131
  return { name, gitBranch, modelName };
64
132
  }
65
133
 
66
134
  // Get learning stats from memory database
67
135
  function getLearningStats() {
68
136
  const memoryPaths = [
69
- path.join(process.cwd(), '.agentic-qe', 'memory.db'), // AQE v3 primary location
70
137
  path.join(process.cwd(), '.swarm', 'memory.db'),
138
+ path.join(process.cwd(), '.claude-flow', 'memory.db'),
71
139
  path.join(process.cwd(), '.claude', 'memory.db'),
72
140
  path.join(process.cwd(), 'data', 'memory.db'),
141
+ path.join(process.cwd(), 'memory.db'),
142
+ path.join(process.cwd(), '.agentdb', 'memory.db'),
73
143
  ];
74
144
 
75
145
  let patterns = 0;
@@ -112,6 +182,31 @@ function getLearningStats() {
112
182
  function getV3Progress() {
113
183
  const learning = getLearningStats();
114
184
 
185
+ // Check for metrics file first (created by init)
186
+ const metricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'v3-progress.json');
187
+ if (fs.existsSync(metricsPath)) {
188
+ try {
189
+ const data = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
190
+ if (data.domains) {
191
+ const domainsCompleted = data.domains.completed || 0;
192
+ const totalDomains = data.domains.total || 5;
193
+ // Use ddd.progress if provided and > 0, otherwise calculate from domains
194
+ const dddProgress = (data.ddd?.progress > 0)
195
+ ? data.ddd.progress
196
+ : Math.min(100, Math.floor((domainsCompleted / totalDomains) * 100));
197
+ return {
198
+ domainsCompleted,
199
+ totalDomains,
200
+ dddProgress,
201
+ patternsLearned: data.learning?.patternsLearned || learning.patterns,
202
+ sessionsCompleted: data.learning?.sessionsCompleted || learning.sessions
203
+ };
204
+ }
205
+ } catch (e) {
206
+ // Fall through to pattern-based calculation
207
+ }
208
+ }
209
+
115
210
  // DDD progress based on actual learned patterns
116
211
  // New install: 0 patterns = 0/5 domains, 0% DDD
117
212
  // As patterns grow: 10+ patterns = 1 domain, 50+ = 2, 100+ = 3, 200+ = 4, 500+ = 5
@@ -134,45 +229,46 @@ function getV3Progress() {
134
229
  };
135
230
  }
136
231
 
137
- // Get security status based on actual scans and npm audit
232
+ // Get security status based on actual scans
138
233
  function getSecurityStatus() {
139
234
  const totalCves = 3;
140
235
  let cvesFixed = 0;
141
236
 
142
- // First check CVE cache file (updated by npm audit fix)
143
- const cveCachePath = path.join(process.cwd(), '.agentic-qe', '.cve-cache');
144
- if (fs.existsSync(cveCachePath)) {
237
+ // Check audit-status.json first (created by init)
238
+ const auditStatusPath = path.join(process.cwd(), '.claude-flow', 'security', 'audit-status.json');
239
+ if (fs.existsSync(auditStatusPath)) {
145
240
  try {
146
- const cache = JSON.parse(fs.readFileSync(cveCachePath, 'utf-8'));
147
- if (cache.cves !== undefined) {
148
- cvesFixed = cache.cves;
149
- }
241
+ const data = JSON.parse(fs.readFileSync(auditStatusPath, 'utf-8'));
242
+ return {
243
+ status: data.status || 'PENDING',
244
+ cvesFixed: data.cvesFixed || 0,
245
+ totalCves: data.totalCves || 3,
246
+ };
150
247
  } catch (e) {
151
- // Ignore parse errors
248
+ // Fall through to scan directory check
152
249
  }
153
250
  }
154
251
 
155
- // Fallback: check for security scan results in memory
156
- if (cvesFixed === 0) {
157
- const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
158
- if (fs.existsSync(scanResultsPath)) {
159
- try {
160
- const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
161
- cvesFixed = Math.min(totalCves, scans.length);
162
- } catch (e) {
163
- // Ignore
164
- }
252
+ // Check for security scan results in memory
253
+ const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
254
+ if (fs.existsSync(scanResultsPath)) {
255
+ try {
256
+ const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
257
+ // Each successful scan file = 1 CVE addressed
258
+ cvesFixed = Math.min(totalCves, scans.length);
259
+ } catch (e) {
260
+ // Ignore
165
261
  }
262
+ }
166
263
 
167
- // Also check .swarm/security for audit results
168
- const auditPath = path.join(process.cwd(), '.swarm', 'security');
169
- if (fs.existsSync(auditPath)) {
170
- try {
171
- const audits = fs.readdirSync(auditPath).filter(f => f.includes('audit'));
172
- cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
173
- } catch (e) {
174
- // Ignore
175
- }
264
+ // Also check .swarm/security for audit results
265
+ const swarmAuditPath = path.join(process.cwd(), '.swarm', 'security');
266
+ if (fs.existsSync(swarmAuditPath)) {
267
+ try {
268
+ const audits = fs.readdirSync(swarmAuditPath).filter(f => f.includes('audit'));
269
+ cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
270
+ } catch (e) {
271
+ // Ignore
176
272
  }
177
273
  }
178
274
 
@@ -185,17 +281,69 @@ function getSecurityStatus() {
185
281
  };
186
282
  }
187
283
 
188
- // Get swarm status
284
+ // Get swarm status (cross-platform)
189
285
  function getSwarmStatus() {
190
286
  let activeAgents = 0;
191
287
  let coordinationActive = false;
192
288
 
289
+ // Check swarm-activity.json first (works on all platforms)
290
+ const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
291
+ if (fs.existsSync(activityPath)) {
292
+ try {
293
+ const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
294
+ if (data.swarm) {
295
+ return {
296
+ activeAgents: data.swarm.agent_count || 0,
297
+ maxAgents: CONFIG.maxAgents,
298
+ coordinationActive: data.swarm.coordination_active || data.swarm.active || false,
299
+ };
300
+ }
301
+ } catch (e) {
302
+ // Fall through to v3-progress.json check
303
+ }
304
+ }
305
+
306
+ // Also check v3-progress.json for swarm data (secondary source)
307
+ const progressPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'v3-progress.json');
308
+ if (fs.existsSync(progressPath)) {
309
+ try {
310
+ const data = JSON.parse(fs.readFileSync(progressPath, 'utf-8'));
311
+ if (data.swarm) {
312
+ return {
313
+ activeAgents: data.swarm.activeAgents || data.swarm.agent_count || 0,
314
+ maxAgents: data.swarm.totalAgents || CONFIG.maxAgents,
315
+ coordinationActive: data.swarm.active || (data.swarm.activeAgents > 0),
316
+ };
317
+ }
318
+ } catch (e) {
319
+ // Fall through to process detection
320
+ }
321
+ }
322
+
323
+ // Platform-specific process detection (fallback)
324
+ const isWindows = process.platform === 'win32';
193
325
  try {
194
- const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
195
- activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
196
- coordinationActive = activeAgents > 0;
326
+ if (isWindows) {
327
+ // Windows: use tasklist
328
+ const ps = execSync('tasklist /FI "IMAGENAME eq node.exe" /NH 2>nul || echo ""', { encoding: 'utf-8' });
329
+ const nodeProcesses = (ps.match(/node\.exe/gi) || []).length;
330
+ activeAgents = Math.max(0, Math.floor(nodeProcesses / 3)); // Heuristic
331
+ coordinationActive = nodeProcesses > 0;
332
+ } else {
333
+ // Unix: use ps - check for various agent process patterns
334
+ try {
335
+ const ps = execSync('ps aux 2>/dev/null | grep -E "(agentic-flow|claude-flow|mcp.*server)" | grep -v grep | wc -l', { encoding: 'utf-8' });
336
+ activeAgents = Math.max(0, parseInt(ps.trim()));
337
+ coordinationActive = activeAgents > 0;
338
+ } catch (e) {
339
+ // Fallback to simple agentic-flow check
340
+ const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
341
+ activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
342
+ coordinationActive = activeAgents > 0;
343
+ }
344
+ }
197
345
  } catch (e) {
198
- // Ignore errors
346
+ // Ignore errors - return defaults
199
347
  }
200
348
 
201
349
  return {
@@ -205,34 +353,160 @@ function getSwarmStatus() {
205
353
  };
206
354
  }
207
355
 
208
- // Get system metrics (dynamic based on actual state)
356
+ // Get system metrics (cross-platform)
209
357
  function getSystemMetrics() {
210
358
  let memoryMB = 0;
211
359
  let subAgents = 0;
212
360
 
361
+ // Check learning.json first (works on all platforms)
362
+ const learningMetricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'learning.json');
363
+ let intelligenceFromFile = null;
364
+ let contextFromFile = null;
365
+ if (fs.existsSync(learningMetricsPath)) {
366
+ try {
367
+ const data = JSON.parse(fs.readFileSync(learningMetricsPath, 'utf-8'));
368
+ if (data.routing?.accuracy !== undefined) {
369
+ intelligenceFromFile = Math.min(100, Math.floor(data.routing.accuracy));
370
+ }
371
+ if (data.sessions?.total !== undefined) {
372
+ contextFromFile = Math.min(100, data.sessions.total * 5);
373
+ }
374
+ } catch (e) {
375
+ // Fall through
376
+ }
377
+ }
378
+
379
+ // Platform-specific memory detection
380
+ const isWindows = process.platform === 'win32';
213
381
  try {
214
- const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += \$6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
215
- memoryMB = parseInt(mem.trim()) || 0;
382
+ if (isWindows) {
383
+ // Windows: use process.memoryUsage() (most reliable cross-platform)
384
+ memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
385
+ } else {
386
+ // Unix: try ps command, fallback to process.memoryUsage()
387
+ try {
388
+ const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += \$6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
389
+ memoryMB = parseInt(mem.trim()) || 0;
390
+ } catch (e) {
391
+ memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
392
+ }
393
+ }
216
394
  } catch (e) {
217
- // Fallback
395
+ // Fallback to Node.js memory API
218
396
  memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
219
397
  }
220
398
 
221
399
  // Get learning stats for intelligence %
222
400
  const learning = getLearningStats();
223
401
 
224
- // Intelligence % based on learned patterns (0 patterns = 0%, 1000+ = 100%)
225
- const intelligencePct = Math.min(100, Math.floor((learning.patterns / 10) * 1));
402
+ // Also get AgentDB stats for fallback intelligence calculation
403
+ const agentdbStats = getAgentDBStats();
404
+
405
+ // Intelligence % based on learned patterns, vectors, or project maturity
406
+ // Calculate all sources and take the maximum
407
+ let intelligencePct = 0;
408
+
409
+ if (intelligenceFromFile !== null) {
410
+ intelligencePct = intelligenceFromFile;
411
+ } else {
412
+ // Calculate from multiple sources and take the best
413
+ const fromPatterns = learning.patterns > 0 ? Math.min(100, Math.floor(learning.patterns / 10)) : 0;
414
+ const fromVectors = agentdbStats.vectorCount > 0 ? Math.min(100, Math.floor(agentdbStats.vectorCount / 100)) : 0;
415
+
416
+ intelligencePct = Math.max(fromPatterns, fromVectors);
417
+ }
418
+
419
+ // If still 0, use project maturity fallback
420
+ if (intelligencePct === 0) {
421
+ // Final fallback: estimate from project maturity indicators
422
+ let maturityScore = 0;
423
+
424
+ // Check git commit count (proxy for project development)
425
+ try {
426
+ const commitCount = parseInt(execSync('git rev-list --count HEAD 2>/dev/null || echo "0"', { encoding: 'utf-8' }).trim());
427
+ maturityScore += Math.min(30, Math.floor(commitCount / 10)); // Max 30% from commits
428
+ } catch (e) { /* ignore */ }
429
+
430
+ // Check for Claude session history
431
+ const sessionPaths = [
432
+ path.join(process.cwd(), '.claude', 'sessions'),
433
+ path.join(process.cwd(), '.claude-flow', 'sessions'),
434
+ ];
435
+ for (const sessPath of sessionPaths) {
436
+ if (fs.existsSync(sessPath)) {
437
+ try {
438
+ const sessions = fs.readdirSync(sessPath).filter(f => f.endsWith('.json')).length;
439
+ maturityScore += Math.min(20, sessions * 2); // Max 20% from sessions
440
+ break;
441
+ } catch (e) { /* ignore */ }
442
+ }
443
+ }
444
+
445
+ // Check for source files (indicates codebase size)
446
+ try {
447
+ const srcDirs = ['src', 'lib', 'app', 'packages'];
448
+ for (const dir of srcDirs) {
449
+ const dirPath = path.join(process.cwd(), dir);
450
+ if (fs.existsSync(dirPath)) {
451
+ maturityScore += 15; // Base score for having source dir
452
+ break;
453
+ }
454
+ }
455
+ } catch (e) { /* ignore */ }
456
+
457
+ // Check for test files
458
+ try {
459
+ const testDirs = ['tests', 'test', '__tests__', 'spec'];
460
+ for (const dir of testDirs) {
461
+ const dirPath = path.join(process.cwd(), dir);
462
+ if (fs.existsSync(dirPath)) {
463
+ maturityScore += 10; // Bonus for having tests
464
+ break;
465
+ }
466
+ }
467
+ } catch (e) { /* ignore */ }
468
+
469
+ // Check for .claude directory (Claude Code usage)
470
+ if (fs.existsSync(path.join(process.cwd(), '.claude'))) {
471
+ maturityScore += 15; // Bonus for Claude Code integration
472
+ }
473
+
474
+ // Check for config files (project maturity)
475
+ const configFiles = ['package.json', 'tsconfig.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
476
+ for (const cfg of configFiles) {
477
+ if (fs.existsSync(path.join(process.cwd(), cfg))) {
478
+ maturityScore += 5;
479
+ break;
480
+ }
481
+ }
482
+
483
+ intelligencePct = Math.min(100, maturityScore);
484
+ }
226
485
 
227
486
  // Context % based on session history (0 sessions = 0%, grows with usage)
228
- const contextPct = Math.min(100, Math.floor(learning.sessions * 5));
487
+ const contextPct = contextFromFile !== null
488
+ ? contextFromFile
489
+ : Math.min(100, Math.floor(learning.sessions * 5));
229
490
 
230
- // Count active sub-agents from process list
231
- try {
232
- const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
233
- subAgents = Math.max(0, parseInt(agents.trim()) - 1);
234
- } catch (e) {
235
- // Ignore
491
+ // Count active sub-agents (cross-platform via metrics file)
492
+ const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
493
+ if (fs.existsSync(activityPath)) {
494
+ try {
495
+ const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
496
+ subAgents = data.processes?.estimated_agents || 0;
497
+ } catch (e) {
498
+ // Ignore
499
+ }
500
+ }
501
+
502
+ // Fallback to process detection on Unix only
503
+ if (subAgents === 0 && !isWindows) {
504
+ try {
505
+ const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
506
+ subAgents = Math.max(0, parseInt(agents.trim()) - 1);
507
+ } catch (e) {
508
+ // Ignore
509
+ }
236
510
  }
237
511
 
238
512
  return {
@@ -243,6 +517,474 @@ function getSystemMetrics() {
243
517
  };
244
518
  }
245
519
 
520
+ // Get ADR (Architecture Decision Records) status
521
+ function getADRStatus() {
522
+ const adrPaths = [
523
+ path.join(process.cwd(), 'docs', 'adrs'),
524
+ path.join(process.cwd(), 'docs', 'adr'),
525
+ path.join(process.cwd(), 'adr'),
526
+ path.join(process.cwd(), 'ADR'),
527
+ path.join(process.cwd(), '.claude-flow', 'adrs'),
528
+ path.join(process.cwd(), 'v3', 'implementation', 'adrs'),
529
+ path.join(process.cwd(), 'implementation', 'adrs'),
530
+ ];
531
+
532
+ let count = 0;
533
+ let implemented = 0;
534
+
535
+ for (const adrPath of adrPaths) {
536
+ if (fs.existsSync(adrPath)) {
537
+ try {
538
+ const files = fs.readdirSync(adrPath).filter(f =>
539
+ f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\d{4}-/.test(f))
540
+ );
541
+ count = files.length;
542
+
543
+ // Check for implemented status in ADR files
544
+ for (const file of files) {
545
+ try {
546
+ const content = fs.readFileSync(path.join(adrPath, file), 'utf-8');
547
+ if (content.includes('Status: Implemented') || content.includes('status: implemented') ||
548
+ content.includes('Status: Accepted') || content.includes('status: accepted')) {
549
+ implemented++;
550
+ }
551
+ } catch (e) {
552
+ // Skip unreadable files
553
+ }
554
+ }
555
+ break;
556
+ } catch (e) {
557
+ // Ignore
558
+ }
559
+ }
560
+ }
561
+
562
+ return { count, implemented };
563
+ }
564
+
565
+ // Get hooks status (enabled/registered hooks)
566
+ function getHooksStatus() {
567
+ let enabled = 0;
568
+ let total = 17; // V3 has 17 hook types
569
+
570
+ // Check .claude/settings.json for hooks config
571
+ const settingsPaths = [
572
+ path.join(process.cwd(), '.claude', 'settings.json'),
573
+ path.join(process.cwd(), '.claude', 'settings.local.json'),
574
+ ];
575
+
576
+ for (const settingsPath of settingsPaths) {
577
+ if (fs.existsSync(settingsPath)) {
578
+ try {
579
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
580
+ if (settings.hooks) {
581
+ // Claude Code native hooks format: PreToolUse, PostToolUse, SessionStart, etc.
582
+ const hookCategories = Object.keys(settings.hooks);
583
+ for (const category of hookCategories) {
584
+ const categoryHooks = settings.hooks[category];
585
+ if (Array.isArray(categoryHooks) && categoryHooks.length > 0) {
586
+ // Count categories with at least one hook defined
587
+ enabled++;
588
+ }
589
+ }
590
+ }
591
+ break;
592
+ } catch (e) {
593
+ // Ignore parse errors
594
+ }
595
+ }
596
+ }
597
+
598
+ // Also check for hook files in .claude/hooks
599
+ const hooksDir = path.join(process.cwd(), '.claude', 'hooks');
600
+ if (fs.existsSync(hooksDir)) {
601
+ try {
602
+ const hookFiles = fs.readdirSync(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.sh'));
603
+ enabled = Math.max(enabled, hookFiles.length);
604
+ } catch (e) {
605
+ // Ignore
606
+ }
607
+ }
608
+
609
+ return { enabled, total };
610
+ }
611
+
612
+ // Get AgentDB memory stats
613
+ function getAgentDBStats() {
614
+ let vectorCount = 0;
615
+ let dbSizeKB = 0;
616
+ let namespaces = 0;
617
+ let hasHnsw = false;
618
+
619
+ // Check for database directories
620
+ const dbDirPaths = [
621
+ path.join(process.cwd(), '.claude-flow', 'agentdb'),
622
+ path.join(process.cwd(), '.swarm', 'agentdb'),
623
+ path.join(process.cwd(), 'data', 'agentdb'),
624
+ path.join(process.cwd(), '.claude', 'memory'),
625
+ path.join(process.cwd(), '.agentdb'),
626
+ ];
627
+
628
+ // Check for direct database files (memory.db, etc.)
629
+ const dbFilePaths = [
630
+ path.join(process.cwd(), '.swarm', 'memory.db'),
631
+ path.join(process.cwd(), '.claude-flow', 'memory.db'),
632
+ path.join(process.cwd(), '.claude', 'memory.db'),
633
+ path.join(process.cwd(), 'data', 'memory.db'),
634
+ path.join(process.cwd(), 'memory.db'),
635
+ ];
636
+
637
+ // Check for HNSW index files
638
+ const hnswPaths = [
639
+ path.join(process.cwd(), '.swarm', 'hnsw.index'),
640
+ path.join(process.cwd(), '.claude-flow', 'hnsw.index'),
641
+ path.join(process.cwd(), 'data', 'hnsw.index'),
642
+ ];
643
+
644
+ // Check direct database files first
645
+ for (const dbFile of dbFilePaths) {
646
+ if (fs.existsSync(dbFile)) {
647
+ try {
648
+ const stats = fs.statSync(dbFile);
649
+ dbSizeKB = stats.size / 1024;
650
+ // Estimate vectors: ~2KB per vector for SQLite with embeddings
651
+ vectorCount = Math.floor(dbSizeKB / 2);
652
+ namespaces = 1;
653
+ break;
654
+ } catch (e) {
655
+ // Ignore
656
+ }
657
+ }
658
+ }
659
+
660
+ // Check database directories if no direct file found
661
+ if (vectorCount === 0) {
662
+ for (const dbPath of dbDirPaths) {
663
+ if (fs.existsSync(dbPath)) {
664
+ try {
665
+ const stats = fs.statSync(dbPath);
666
+ if (stats.isDirectory()) {
667
+ const files = fs.readdirSync(dbPath);
668
+ namespaces = files.filter(f => f.endsWith('.db') || f.endsWith('.sqlite')).length;
669
+
670
+ for (const file of files) {
671
+ const filePath = path.join(dbPath, file);
672
+ const fileStat = fs.statSync(filePath);
673
+ if (fileStat.isFile()) {
674
+ dbSizeKB += fileStat.size / 1024;
675
+ }
676
+ }
677
+
678
+ vectorCount = Math.floor(dbSizeKB / 2);
679
+ }
680
+ break;
681
+ } catch (e) {
682
+ // Ignore
683
+ }
684
+ }
685
+ }
686
+ }
687
+
688
+ // Check for HNSW index (indicates vector search capability)
689
+ for (const hnswPath of hnswPaths) {
690
+ if (fs.existsSync(hnswPath)) {
691
+ hasHnsw = true;
692
+ try {
693
+ const stats = fs.statSync(hnswPath);
694
+ // HNSW index: ~0.5KB per vector
695
+ const hnswVectors = Math.floor(stats.size / 1024 / 0.5);
696
+ vectorCount = Math.max(vectorCount, hnswVectors);
697
+ } catch (e) {
698
+ // Ignore
699
+ }
700
+ break;
701
+ }
702
+ }
703
+
704
+ // Also check for vectors.json (simple vector store)
705
+ const vectorsPath = path.join(process.cwd(), '.claude-flow', 'vectors.json');
706
+ if (fs.existsSync(vectorsPath) && vectorCount === 0) {
707
+ try {
708
+ const data = JSON.parse(fs.readFileSync(vectorsPath, 'utf-8'));
709
+ if (Array.isArray(data)) {
710
+ vectorCount = data.length;
711
+ } else if (data.vectors) {
712
+ vectorCount = Object.keys(data.vectors).length;
713
+ }
714
+ } catch (e) {
715
+ // Ignore
716
+ }
717
+ }
718
+
719
+ return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces, hasHnsw };
720
+ }
721
+
722
+ // Get test statistics
723
+ function getTestStats() {
724
+ let testFiles = 0;
725
+ let testCases = 0;
726
+
727
+ const testDirs = [
728
+ path.join(process.cwd(), 'tests'),
729
+ path.join(process.cwd(), 'test'),
730
+ path.join(process.cwd(), '__tests__'),
731
+ path.join(process.cwd(), 'src', '__tests__'),
732
+ path.join(process.cwd(), 'v3', '__tests__'),
733
+ ];
734
+
735
+ // Recursively count test files
736
+ function countTestFiles(dir, depth = 0) {
737
+ if (depth > 3) return; // Limit recursion
738
+ if (!fs.existsSync(dir)) return;
739
+
740
+ try {
741
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
742
+ for (const entry of entries) {
743
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
744
+ countTestFiles(path.join(dir, entry.name), depth + 1);
745
+ } else if (entry.isFile()) {
746
+ const name = entry.name;
747
+ if (name.includes('.test.') || name.includes('.spec.') ||
748
+ name.includes('_test.') || name.includes('_spec.') ||
749
+ name.startsWith('test_') || name.startsWith('spec_')) {
750
+ testFiles++;
751
+
752
+ // Try to estimate test cases from file
753
+ try {
754
+ const content = fs.readFileSync(path.join(dir, name), 'utf-8');
755
+ // Count it(), test(), describe() patterns
756
+ const itMatches = (content.match(/\bit\s*\(/g) || []).length;
757
+ const testMatches = (content.match(/\btest\s*\(/g) || []).length;
758
+ testCases += itMatches + testMatches;
759
+ } catch (e) {
760
+ // Estimate 3 tests per file if can't read
761
+ testCases += 3;
762
+ }
763
+ }
764
+ }
765
+ }
766
+ } catch (e) {
767
+ // Ignore
768
+ }
769
+ }
770
+
771
+ for (const dir of testDirs) {
772
+ countTestFiles(dir);
773
+ }
774
+
775
+ // Also check src directory for colocated tests
776
+ const srcDir = path.join(process.cwd(), 'src');
777
+ if (fs.existsSync(srcDir)) {
778
+ countTestFiles(srcDir);
779
+ }
780
+
781
+ return { testFiles, testCases };
782
+ }
783
+
784
+ // Get integration status (MCP servers, external connections)
785
+ function getIntegrationStatus() {
786
+ let mcpServers = { total: 0, enabled: 0, names: [] };
787
+ let hasDatabase = false;
788
+ let hasCache = false;
789
+ let hasApi = false;
790
+
791
+ // Check for MCP servers in settings
792
+ const settingsPaths = [
793
+ path.join(process.cwd(), '.claude', 'settings.json'),
794
+ path.join(process.cwd(), '.claude', 'settings.local.json'),
795
+ ];
796
+
797
+ for (const settingsPath of settingsPaths) {
798
+ if (fs.existsSync(settingsPath)) {
799
+ try {
800
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
801
+
802
+ // Check mcpServers object
803
+ if (settings.mcpServers && typeof settings.mcpServers === 'object') {
804
+ const servers = Object.keys(settings.mcpServers);
805
+ mcpServers.total = servers.length;
806
+ mcpServers.names = servers;
807
+
808
+ // Check enabledMcpjsonServers for enabled count
809
+ if (settings.enabledMcpjsonServers && Array.isArray(settings.enabledMcpjsonServers)) {
810
+ mcpServers.enabled = settings.enabledMcpjsonServers.filter(s => servers.includes(s)).length;
811
+ } else {
812
+ mcpServers.enabled = mcpServers.total; // Assume all enabled if not specified
813
+ }
814
+ }
815
+ break;
816
+ } catch (e) { /* ignore */ }
817
+ }
818
+ }
819
+
820
+ // Also check .mcp.json or mcp.json
821
+ const mcpConfigPaths = [
822
+ path.join(process.cwd(), '.mcp.json'),
823
+ path.join(process.cwd(), 'mcp.json'),
824
+ path.join(require('os').homedir(), '.claude', 'mcp.json'),
825
+ ];
826
+
827
+ for (const mcpPath of mcpConfigPaths) {
828
+ if (fs.existsSync(mcpPath) && mcpServers.total === 0) {
829
+ try {
830
+ const config = JSON.parse(fs.readFileSync(mcpPath, 'utf-8'));
831
+ if (config.mcpServers) {
832
+ const servers = Object.keys(config.mcpServers);
833
+ mcpServers.total = servers.length;
834
+ mcpServers.names = servers;
835
+ mcpServers.enabled = servers.length;
836
+ }
837
+ } catch (e) { /* ignore */ }
838
+ }
839
+ }
840
+
841
+ // Check for database (AgentDB, SQLite, etc.)
842
+ const dbPaths = [
843
+ path.join(process.cwd(), '.swarm', 'memory.db'),
844
+ path.join(process.cwd(), '.claude-flow', 'memory.db'),
845
+ path.join(process.cwd(), 'data', 'memory.db'),
846
+ ];
847
+ hasDatabase = dbPaths.some(p => fs.existsSync(p));
848
+
849
+ // Check for cache
850
+ const cachePaths = [
851
+ path.join(process.cwd(), '.claude-flow', 'cache'),
852
+ path.join(process.cwd(), '.cache'),
853
+ path.join(process.cwd(), 'node_modules', '.cache'),
854
+ ];
855
+ hasCache = cachePaths.some(p => fs.existsSync(p));
856
+
857
+ // Check for API configuration (env vars or config)
858
+ try {
859
+ hasApi = !!(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY);
860
+ } catch (e) { /* ignore */ }
861
+
862
+ return { mcpServers, hasDatabase, hasCache, hasApi };
863
+ }
864
+
865
+ // Get git status (uncommitted changes, untracked files) - cross-platform
866
+ function getGitStatus() {
867
+ let modified = 0;
868
+ let untracked = 0;
869
+ let staged = 0;
870
+ let ahead = 0;
871
+ let behind = 0;
872
+ const isWindows = process.platform === 'win32';
873
+
874
+ try {
875
+ // Get modified and staged counts - works on all platforms
876
+ const status = execSync('git status --porcelain', {
877
+ encoding: 'utf-8',
878
+ stdio: ['pipe', 'pipe', 'pipe'], // Suppress stderr
879
+ timeout: 5000,
880
+ });
881
+ const lines = status.trim().split('\n').filter(l => l);
882
+ for (const line of lines) {
883
+ const code = line.substring(0, 2);
884
+ if (code.includes('M') || code.includes('D') || code.includes('R')) {
885
+ if (code[0] !== ' ') staged++;
886
+ if (code[1] !== ' ') modified++;
887
+ }
888
+ if (code.includes('?')) untracked++;
889
+ if (code.includes('A')) staged++;
890
+ }
891
+
892
+ // Get ahead/behind - may fail if no upstream
893
+ try {
894
+ const abStatus = execSync('git rev-list --left-right --count HEAD...@{upstream}', {
895
+ encoding: 'utf-8',
896
+ stdio: ['pipe', 'pipe', 'pipe'],
897
+ timeout: 5000,
898
+ });
899
+ const parts = abStatus.trim().split(/\s+/);
900
+ ahead = parseInt(parts[0]) || 0;
901
+ behind = parseInt(parts[1]) || 0;
902
+ } catch (e) { /* no upstream or error - that's ok */ }
903
+
904
+ } catch (e) {
905
+ // Not a git repo or git not installed - return zeros
906
+ }
907
+
908
+ return { modified, untracked, staged, ahead, behind };
909
+ }
910
+
911
+ // Get session statistics
912
+ function getSessionStats() {
913
+ let sessionStart = null;
914
+ let duration = '';
915
+ let lastActivity = '';
916
+ let operationsCount = 0;
917
+
918
+ // Check for session file
919
+ const sessionPaths = [
920
+ path.join(process.cwd(), '.claude-flow', 'session.json'),
921
+ path.join(process.cwd(), '.claude', 'session.json'),
922
+ ];
923
+
924
+ for (const sessPath of sessionPaths) {
925
+ if (fs.existsSync(sessPath)) {
926
+ try {
927
+ const data = JSON.parse(fs.readFileSync(sessPath, 'utf-8'));
928
+ if (data.startTime) {
929
+ sessionStart = new Date(data.startTime);
930
+ const now = new Date();
931
+ const diffMs = now.getTime() - sessionStart.getTime();
932
+ const diffMins = Math.floor(diffMs / 60000);
933
+ if (diffMins < 60) {
934
+ duration = `${diffMins}m`;
935
+ } else {
936
+ const hours = Math.floor(diffMins / 60);
937
+ const mins = diffMins % 60;
938
+ duration = `${hours}h${mins}m`;
939
+ }
940
+ }
941
+ if (data.lastActivity) {
942
+ const last = new Date(data.lastActivity);
943
+ const now = new Date();
944
+ const diffMs = now.getTime() - last.getTime();
945
+ const diffMins = Math.floor(diffMs / 60000);
946
+ if (diffMins < 1) lastActivity = 'now';
947
+ else if (diffMins < 60) lastActivity = `${diffMins}m ago`;
948
+ else lastActivity = `${Math.floor(diffMins / 60)}h ago`;
949
+ }
950
+ operationsCount = data.operationsCount || data.commandCount || 0;
951
+ break;
952
+ } catch (e) { /* ignore */ }
953
+ }
954
+ }
955
+
956
+ // Fallback: check metrics for activity
957
+ if (!duration) {
958
+ const metricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'activity.json');
959
+ if (fs.existsSync(metricsPath)) {
960
+ try {
961
+ const data = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
962
+ operationsCount = data.totalOperations || 0;
963
+ } catch (e) { /* ignore */ }
964
+ }
965
+ }
966
+
967
+ return { duration, lastActivity, operationsCount };
968
+ }
969
+
970
+ // Get trend indicator based on change
971
+ function getTrend(current, previous) {
972
+ if (previous === null || previous === undefined) return '';
973
+ if (current > previous) return `${c.brightGreen}↑${c.reset}`;
974
+ if (current < previous) return `${c.brightRed}↓${c.reset}`;
975
+ return `${c.dim}→${c.reset}`;
976
+ }
977
+
978
+ // Store previous values for trends (persisted between calls)
979
+ let prevIntelligence = null;
980
+ try {
981
+ const trendPath = path.join(process.cwd(), '.claude-flow', '.trend-cache.json');
982
+ if (fs.existsSync(trendPath)) {
983
+ const data = JSON.parse(fs.readFileSync(trendPath, 'utf-8'));
984
+ prevIntelligence = data.intelligence;
985
+ }
986
+ } catch (e) { /* ignore */ }
987
+
246
988
  // Generate progress bar
247
989
  function progressBar(current, total) {
248
990
  const width = 5;
@@ -258,51 +1000,137 @@ function generateStatusline() {
258
1000
  const security = getSecurityStatus();
259
1001
  const swarm = getSwarmStatus();
260
1002
  const system = getSystemMetrics();
1003
+ const adrs = getADRStatus();
1004
+ const hooks = getHooksStatus();
1005
+ const agentdb = getAgentDBStats();
1006
+ const tests = getTestStats();
1007
+ const git = getGitStatus();
1008
+ const session = getSessionStats();
1009
+ const integration = getIntegrationStatus();
261
1010
  const lines = [];
262
1011
 
263
- // Header Line
1012
+ // Calculate intelligence trend
1013
+ const intellTrend = getTrend(system.intelligencePct, prevIntelligence);
1014
+
1015
+ // Save current values for next trend calculation
1016
+ try {
1017
+ const trendPath = path.join(process.cwd(), '.claude-flow', '.trend-cache.json');
1018
+ const trendDir = path.dirname(trendPath);
1019
+ if (!fs.existsSync(trendDir)) fs.mkdirSync(trendDir, { recursive: true });
1020
+ fs.writeFileSync(trendPath, JSON.stringify({ intelligence: system.intelligencePct, timestamp: Date.now() }));
1021
+ } catch (e) { /* ignore */ }
1022
+
1023
+ // Header Line with git changes indicator
264
1024
  let header = `${c.bold}${c.brightPurple}▊ Claude Flow V3 ${c.reset}`;
265
1025
  header += `${swarm.coordinationActive ? c.brightCyan : c.dim}● ${c.brightCyan}${user.name}${c.reset}`;
266
1026
  if (user.gitBranch) {
267
1027
  header += ` ${c.dim}│${c.reset} ${c.brightBlue}⎇ ${user.gitBranch}${c.reset}`;
1028
+ // Add git changes indicator
1029
+ const gitChanges = git.modified + git.staged + git.untracked;
1030
+ if (gitChanges > 0) {
1031
+ let gitIndicator = '';
1032
+ if (git.staged > 0) gitIndicator += `${c.brightGreen}+${git.staged}${c.reset}`;
1033
+ if (git.modified > 0) gitIndicator += `${c.brightYellow}~${git.modified}${c.reset}`;
1034
+ if (git.untracked > 0) gitIndicator += `${c.dim}?${git.untracked}${c.reset}`;
1035
+ header += ` ${gitIndicator}`;
1036
+ }
1037
+ // Add ahead/behind indicator
1038
+ if (git.ahead > 0 || git.behind > 0) {
1039
+ if (git.ahead > 0) header += ` ${c.brightGreen}↑${git.ahead}${c.reset}`;
1040
+ if (git.behind > 0) header += ` ${c.brightRed}↓${git.behind}${c.reset}`;
1041
+ }
268
1042
  }
269
1043
  header += ` ${c.dim}│${c.reset} ${c.purple}${user.modelName}${c.reset}`;
1044
+ // Add session duration if available
1045
+ if (session.duration) {
1046
+ header += ` ${c.dim}│${c.reset} ${c.cyan}⏱ ${session.duration}${c.reset}`;
1047
+ }
270
1048
  lines.push(header);
271
1049
 
272
1050
  // Separator
273
1051
  lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);
274
1052
 
275
- // Line 1: DDD Domain Progress
1053
+ // Line 1: DDD Domain Progress with dynamic performance indicator
276
1054
  const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
1055
+ // Show HNSW speedup if enabled, otherwise show patterns learned
1056
+ let perfIndicator = '';
1057
+ if (agentdb.hasHnsw && agentdb.vectorCount > 0) {
1058
+ // HNSW enabled: show estimated speedup (150x-12500x based on vector count)
1059
+ const speedup = agentdb.vectorCount > 10000 ? '12500x' : agentdb.vectorCount > 1000 ? '150x' : '10x';
1060
+ perfIndicator = `${c.brightGreen}⚡ HNSW ${speedup}${c.reset}`;
1061
+ } else if (progress.patternsLearned > 0) {
1062
+ // Show patterns learned
1063
+ const patternsK = progress.patternsLearned >= 1000
1064
+ ? `${(progress.patternsLearned / 1000).toFixed(1)}k`
1065
+ : String(progress.patternsLearned);
1066
+ perfIndicator = `${c.brightYellow}📚 ${patternsK} patterns${c.reset}`;
1067
+ } else {
1068
+ // New project: show target
1069
+ perfIndicator = `${c.dim}⚡ target: 150x-12500x${c.reset}`;
1070
+ }
277
1071
  lines.push(
278
1072
  `${c.brightCyan}🏗️ DDD Domains${c.reset} ${progressBar(progress.domainsCompleted, progress.totalDomains)} ` +
279
1073
  `${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset} ` +
280
- `${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
1074
+ perfIndicator
281
1075
  );
282
1076
 
283
- // Line 2: Swarm + CVE + Memory + Context + Intelligence
1077
+ // Line 2: Swarm + Hooks + CVE + Memory + Context + Intelligence
284
1078
  const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
285
1079
  const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
286
1080
  let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
287
1081
  let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;
1082
+ const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;
288
1083
 
289
1084
  lines.push(
290
1085
  `${c.brightYellow}🤖 Swarm${c.reset} ${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}] ` +
291
1086
  `${c.brightPurple}👥 ${system.subAgents}${c.reset} ` +
1087
+ `${c.brightBlue}🪝 ${hooksColor}${hooks.enabled}${c.reset}/${c.brightWhite}${hooks.total}${c.reset} ` +
292
1088
  `${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset} ` +
293
1089
  `${c.brightCyan}💾 ${system.memoryMB}MB${c.reset} ` +
294
- `${c.brightGreen}📂 ${String(system.contextPct).padStart(3)}%${c.reset} ` +
295
- `${c.dim}🧠 ${String(system.intelligencePct).padStart(3)}%${c.reset}`
1090
+ `${system.intelligencePct >= 80 ? c.brightGreen : system.intelligencePct >= 40 ? c.brightYellow : c.dim}🧠 ${String(system.intelligencePct).padStart(3)}%${intellTrend}${c.reset}`
296
1091
  );
297
1092
 
298
- // Line 3: Architecture status
1093
+ // Line 3: Architecture status with ADRs, AgentDB, Tests
299
1094
  const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
1095
+ const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;
1096
+ const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
1097
+ const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;
1098
+
300
1099
  lines.push(
301
1100
  `${c.brightPurple}🔧 Architecture${c.reset} ` +
1101
+ `${c.cyan}ADRs${c.reset} ${adrColor}●${adrs.implemented}/${adrs.count}${c.reset} ${c.dim}│${c.reset} ` +
302
1102
  `${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset} ${c.dim}│${c.reset} ` +
303
- `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset} ${c.dim}│${c.reset} ` +
304
- `${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset} ${c.dim}│${c.reset} ` +
305
- `${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
1103
+ `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset}`
1104
+ );
1105
+
1106
+ // Line 4: Memory, Vectors, Tests
1107
+ const hnswIndicator = agentdb.hasHnsw ? `${c.brightGreen}⚡${c.reset}` : '';
1108
+ const sizeDisplay = agentdb.dbSizeKB >= 1024
1109
+ ? `${(agentdb.dbSizeKB / 1024).toFixed(1)}MB`
1110
+ : `${agentdb.dbSizeKB}KB`;
1111
+ // Build integration status string
1112
+ let integrationStr = '';
1113
+ if (integration.mcpServers.total > 0) {
1114
+ const mcpColor = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
1115
+ integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
1116
+ integrationStr += `${c.cyan}MCP${c.reset} ${mcpColor}●${integration.mcpServers.enabled}/${integration.mcpServers.total}${c.reset}`;
1117
+ }
1118
+ if (integration.hasDatabase) {
1119
+ integrationStr += (integrationStr ? ' ' : '') + `${c.brightGreen}◆${c.reset}DB`;
1120
+ }
1121
+ if (integration.hasApi) {
1122
+ integrationStr += (integrationStr ? ' ' : '') + `${c.brightGreen}◆${c.reset}API`;
1123
+ }
1124
+ if (!integrationStr) {
1125
+ integrationStr = `${c.dim}●none${c.reset}`;
1126
+ }
1127
+
1128
+ lines.push(
1129
+ `${c.brightCyan}📊 AgentDB${c.reset} ` +
1130
+ `${c.cyan}Vectors${c.reset} ${vectorColor}●${agentdb.vectorCount}${hnswIndicator}${c.reset} ${c.dim}│${c.reset} ` +
1131
+ `${c.cyan}Size${c.reset} ${c.brightWhite}${sizeDisplay}${c.reset} ${c.dim}│${c.reset} ` +
1132
+ `${c.cyan}Tests${c.reset} ${testColor}●${tests.testFiles}${c.reset} ${c.dim}(${tests.testCases} cases)${c.reset} ${c.dim}│${c.reset} ` +
1133
+ integrationStr
306
1134
  );
307
1135
 
308
1136
  return lines.join('\n');
@@ -316,6 +1144,10 @@ function generateJSON() {
316
1144
  security: getSecurityStatus(),
317
1145
  swarm: getSwarmStatus(),
318
1146
  system: getSystemMetrics(),
1147
+ adrs: getADRStatus(),
1148
+ hooks: getHooksStatus(),
1149
+ agentdb: getAgentDBStats(),
1150
+ tests: getTestStats(),
319
1151
  performance: {
320
1152
  flashAttentionTarget: '2.49x-7.47x',
321
1153
  searchImprovement: '150x-12,500x',