@claude-flow/cli 3.0.0-alpha.128 → 3.0.0-alpha.129

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.
@@ -81,21 +81,23 @@ function getUserInfo() {
81
81
  if (lastModelUsage) {
82
82
  const modelIds = Object.keys(lastModelUsage);
83
83
  if (modelIds.length > 0) {
84
- // Take the last model (most recently added to the object)
85
- // Or find the one with most tokens (most actively used this session)
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
86
  let modelId = modelIds[modelIds.length - 1];
87
- if (modelIds.length > 1) {
88
- // If multiple models, pick the one with most total tokens
89
- let maxTokens = 0;
90
- for (const id of modelIds) {
91
- const usage = lastModelUsage[id];
92
- const total = (usage.inputTokens || 0) + (usage.outputTokens || 0);
93
- if (total > maxTokens) {
94
- maxTokens = total;
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;
95
96
  modelId = id;
96
97
  }
97
98
  }
98
99
  }
100
+
99
101
  // Parse model ID to human-readable name
100
102
  if (modelId.includes('opus')) modelName = 'Opus 4.5';
101
103
  else if (modelId.includes('sonnet')) modelName = 'Sonnet 4';
@@ -159,6 +161,25 @@ function getLearningStats() {
159
161
  function getV3Progress() {
160
162
  const learning = getLearningStats();
161
163
 
164
+ // Check for metrics file first (created by init)
165
+ const metricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'v3-progress.json');
166
+ if (fs.existsSync(metricsPath)) {
167
+ try {
168
+ const data = JSON.parse(fs.readFileSync(metricsPath, 'utf-8'));
169
+ if (data.domains && data.ddd) {
170
+ return {
171
+ domainsCompleted: data.domains.completed || 0,
172
+ totalDomains: data.domains.total || 5,
173
+ dddProgress: data.ddd.progress || 0,
174
+ patternsLearned: data.learning?.patternsLearned || learning.patterns,
175
+ sessionsCompleted: data.learning?.sessionsCompleted || learning.sessions
176
+ };
177
+ }
178
+ } catch (e) {
179
+ // Fall through to pattern-based calculation
180
+ }
181
+ }
182
+
162
183
  // DDD progress based on actual learned patterns
163
184
  // New install: 0 patterns = 0/5 domains, 0% DDD
164
185
  // As patterns grow: 10+ patterns = 1 domain, 50+ = 2, 100+ = 3, 200+ = 4, 500+ = 5
@@ -183,11 +204,26 @@ function getV3Progress() {
183
204
 
184
205
  // Get security status based on actual scans
185
206
  function getSecurityStatus() {
186
- // Check for security scan results in memory
187
- const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
188
- let cvesFixed = 0;
189
207
  const totalCves = 3;
208
+ let cvesFixed = 0;
209
+
210
+ // Check audit-status.json first (created by init)
211
+ const auditStatusPath = path.join(process.cwd(), '.claude-flow', 'security', 'audit-status.json');
212
+ if (fs.existsSync(auditStatusPath)) {
213
+ try {
214
+ const data = JSON.parse(fs.readFileSync(auditStatusPath, 'utf-8'));
215
+ return {
216
+ status: data.status || 'PENDING',
217
+ cvesFixed: data.cvesFixed || 0,
218
+ totalCves: data.totalCves || 3,
219
+ };
220
+ } catch (e) {
221
+ // Fall through to scan directory check
222
+ }
223
+ }
190
224
 
225
+ // Check for security scan results in memory
226
+ const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
191
227
  if (fs.existsSync(scanResultsPath)) {
192
228
  try {
193
229
  const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
@@ -199,10 +235,10 @@ function getSecurityStatus() {
199
235
  }
200
236
 
201
237
  // Also check .swarm/security for audit results
202
- const auditPath = path.join(process.cwd(), '.swarm', 'security');
203
- if (fs.existsSync(auditPath)) {
238
+ const swarmAuditPath = path.join(process.cwd(), '.swarm', 'security');
239
+ if (fs.existsSync(swarmAuditPath)) {
204
240
  try {
205
- const audits = fs.readdirSync(auditPath).filter(f => f.includes('audit'));
241
+ const audits = fs.readdirSync(swarmAuditPath).filter(f => f.includes('audit'));
206
242
  cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
207
243
  } catch (e) {
208
244
  // Ignore
@@ -218,17 +254,45 @@ function getSecurityStatus() {
218
254
  };
219
255
  }
220
256
 
221
- // Get swarm status
257
+ // Get swarm status (cross-platform)
222
258
  function getSwarmStatus() {
223
259
  let activeAgents = 0;
224
260
  let coordinationActive = false;
225
261
 
262
+ // Check swarm-activity.json first (works on all platforms)
263
+ const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
264
+ if (fs.existsSync(activityPath)) {
265
+ try {
266
+ const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
267
+ if (data.swarm) {
268
+ return {
269
+ activeAgents: data.swarm.agent_count || 0,
270
+ maxAgents: CONFIG.maxAgents,
271
+ coordinationActive: data.swarm.coordination_active || false,
272
+ };
273
+ }
274
+ } catch (e) {
275
+ // Fall through to process detection
276
+ }
277
+ }
278
+
279
+ // Platform-specific process detection
280
+ const isWindows = process.platform === 'win32';
226
281
  try {
227
- const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
228
- activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
229
- coordinationActive = activeAgents > 0;
282
+ if (isWindows) {
283
+ // Windows: use tasklist
284
+ const ps = execSync('tasklist /FI "IMAGENAME eq node.exe" /NH 2>nul || echo ""', { encoding: 'utf-8' });
285
+ const nodeProcesses = (ps.match(/node\.exe/gi) || []).length;
286
+ activeAgents = Math.max(0, Math.floor(nodeProcesses / 3)); // Heuristic
287
+ coordinationActive = nodeProcesses > 0;
288
+ } else {
289
+ // Unix: use ps
290
+ const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
291
+ activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
292
+ coordinationActive = activeAgents > 0;
293
+ }
230
294
  } catch (e) {
231
- // Ignore errors
295
+ // Ignore errors - return defaults
232
296
  }
233
297
 
234
298
  return {
@@ -238,16 +302,46 @@ function getSwarmStatus() {
238
302
  };
239
303
  }
240
304
 
241
- // Get system metrics (dynamic based on actual state)
305
+ // Get system metrics (cross-platform)
242
306
  function getSystemMetrics() {
243
307
  let memoryMB = 0;
244
308
  let subAgents = 0;
245
309
 
310
+ // Check learning.json first (works on all platforms)
311
+ const learningMetricsPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'learning.json');
312
+ let intelligenceFromFile = null;
313
+ let contextFromFile = null;
314
+ if (fs.existsSync(learningMetricsPath)) {
315
+ try {
316
+ const data = JSON.parse(fs.readFileSync(learningMetricsPath, 'utf-8'));
317
+ if (data.routing?.accuracy !== undefined) {
318
+ intelligenceFromFile = Math.min(100, Math.floor(data.routing.accuracy));
319
+ }
320
+ if (data.sessions?.total !== undefined) {
321
+ contextFromFile = Math.min(100, data.sessions.total * 5);
322
+ }
323
+ } catch (e) {
324
+ // Fall through
325
+ }
326
+ }
327
+
328
+ // Platform-specific memory detection
329
+ const isWindows = process.platform === 'win32';
246
330
  try {
247
- const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += \$6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
248
- memoryMB = parseInt(mem.trim()) || 0;
331
+ if (isWindows) {
332
+ // Windows: use process.memoryUsage() (most reliable cross-platform)
333
+ memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
334
+ } else {
335
+ // Unix: try ps command, fallback to process.memoryUsage()
336
+ try {
337
+ const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += \$6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
338
+ memoryMB = parseInt(mem.trim()) || 0;
339
+ } catch (e) {
340
+ memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
341
+ }
342
+ }
249
343
  } catch (e) {
250
- // Fallback
344
+ // Fallback to Node.js memory API
251
345
  memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
252
346
  }
253
347
 
@@ -255,17 +349,34 @@ function getSystemMetrics() {
255
349
  const learning = getLearningStats();
256
350
 
257
351
  // Intelligence % based on learned patterns (0 patterns = 0%, 1000+ = 100%)
258
- const intelligencePct = Math.min(100, Math.floor((learning.patterns / 10) * 1));
352
+ const intelligencePct = intelligenceFromFile !== null
353
+ ? intelligenceFromFile
354
+ : Math.min(100, Math.floor((learning.patterns / 10) * 1));
259
355
 
260
356
  // Context % based on session history (0 sessions = 0%, grows with usage)
261
- const contextPct = Math.min(100, Math.floor(learning.sessions * 5));
357
+ const contextPct = contextFromFile !== null
358
+ ? contextFromFile
359
+ : Math.min(100, Math.floor(learning.sessions * 5));
262
360
 
263
- // Count active sub-agents from process list
264
- try {
265
- const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
266
- subAgents = Math.max(0, parseInt(agents.trim()) - 1);
267
- } catch (e) {
268
- // Ignore
361
+ // Count active sub-agents (cross-platform via metrics file)
362
+ const activityPath = path.join(process.cwd(), '.claude-flow', 'metrics', 'swarm-activity.json');
363
+ if (fs.existsSync(activityPath)) {
364
+ try {
365
+ const data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
366
+ subAgents = data.processes?.estimated_agents || 0;
367
+ } catch (e) {
368
+ // Ignore
369
+ }
370
+ }
371
+
372
+ // Fallback to process detection on Unix only
373
+ if (subAgents === 0 && !isWindows) {
374
+ try {
375
+ const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
376
+ subAgents = Math.max(0, parseInt(agents.trim()) - 1);
377
+ } catch (e) {
378
+ // Ignore
379
+ }
269
380
  }
270
381
 
271
382
  return {
@@ -276,6 +387,221 @@ function getSystemMetrics() {
276
387
  };
277
388
  }
278
389
 
390
+ // Get ADR (Architecture Decision Records) status
391
+ function getADRStatus() {
392
+ const adrPaths = [
393
+ path.join(process.cwd(), 'docs', 'adrs'),
394
+ path.join(process.cwd(), 'docs', 'adr'),
395
+ path.join(process.cwd(), 'adr'),
396
+ path.join(process.cwd(), 'ADR'),
397
+ path.join(process.cwd(), '.claude-flow', 'adrs'),
398
+ path.join(process.cwd(), 'v3', 'implementation', 'adrs'),
399
+ path.join(process.cwd(), 'implementation', 'adrs'),
400
+ ];
401
+
402
+ let count = 0;
403
+ let implemented = 0;
404
+
405
+ for (const adrPath of adrPaths) {
406
+ if (fs.existsSync(adrPath)) {
407
+ try {
408
+ const files = fs.readdirSync(adrPath).filter(f =>
409
+ f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\d{4}-/.test(f))
410
+ );
411
+ count = files.length;
412
+
413
+ // Check for implemented status in ADR files
414
+ for (const file of files) {
415
+ try {
416
+ const content = fs.readFileSync(path.join(adrPath, file), 'utf-8');
417
+ if (content.includes('Status: Implemented') || content.includes('status: implemented') ||
418
+ content.includes('Status: Accepted') || content.includes('status: accepted')) {
419
+ implemented++;
420
+ }
421
+ } catch (e) {
422
+ // Skip unreadable files
423
+ }
424
+ }
425
+ break;
426
+ } catch (e) {
427
+ // Ignore
428
+ }
429
+ }
430
+ }
431
+
432
+ return { count, implemented };
433
+ }
434
+
435
+ // Get hooks status (enabled/registered hooks)
436
+ function getHooksStatus() {
437
+ let enabled = 0;
438
+ let total = 17; // V3 has 17 hook types
439
+
440
+ // Check .claude/settings.json for hooks config
441
+ const settingsPaths = [
442
+ path.join(process.cwd(), '.claude', 'settings.json'),
443
+ path.join(process.cwd(), '.claude', 'settings.local.json'),
444
+ ];
445
+
446
+ for (const settingsPath of settingsPaths) {
447
+ if (fs.existsSync(settingsPath)) {
448
+ try {
449
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
450
+ if (settings.hooks) {
451
+ // Count enabled hooks
452
+ const hookTypes = Object.keys(settings.hooks);
453
+ enabled = hookTypes.filter(h => {
454
+ const hook = settings.hooks[h];
455
+ return hook && (hook.enabled !== false) && (hook.command || hook.script);
456
+ }).length;
457
+ }
458
+ break;
459
+ } catch (e) {
460
+ // Ignore parse errors
461
+ }
462
+ }
463
+ }
464
+
465
+ // Also check for hook files in .claude/hooks
466
+ const hooksDir = path.join(process.cwd(), '.claude', 'hooks');
467
+ if (fs.existsSync(hooksDir)) {
468
+ try {
469
+ const hookFiles = fs.readdirSync(hooksDir).filter(f => f.endsWith('.js') || f.endsWith('.sh'));
470
+ enabled = Math.max(enabled, hookFiles.length);
471
+ } catch (e) {
472
+ // Ignore
473
+ }
474
+ }
475
+
476
+ return { enabled, total };
477
+ }
478
+
479
+ // Get AgentDB memory stats
480
+ function getAgentDBStats() {
481
+ let vectorCount = 0;
482
+ let dbSizeKB = 0;
483
+ let namespaces = 0;
484
+
485
+ const dbPaths = [
486
+ path.join(process.cwd(), '.claude-flow', 'agentdb'),
487
+ path.join(process.cwd(), '.swarm', 'agentdb'),
488
+ path.join(process.cwd(), 'data', 'agentdb'),
489
+ path.join(process.cwd(), '.claude', 'memory'),
490
+ ];
491
+
492
+ for (const dbPath of dbPaths) {
493
+ if (fs.existsSync(dbPath)) {
494
+ try {
495
+ const stats = fs.statSync(dbPath);
496
+ if (stats.isDirectory()) {
497
+ // Count database files and estimate vectors
498
+ const files = fs.readdirSync(dbPath);
499
+ namespaces = files.filter(f => f.endsWith('.db') || f.endsWith('.sqlite')).length;
500
+
501
+ // Calculate total size
502
+ for (const file of files) {
503
+ const filePath = path.join(dbPath, file);
504
+ const fileStat = fs.statSync(filePath);
505
+ if (fileStat.isFile()) {
506
+ dbSizeKB += fileStat.size / 1024;
507
+ }
508
+ }
509
+
510
+ // Estimate vector count (~0.5KB per vector on average)
511
+ vectorCount = Math.floor(dbSizeKB / 0.5);
512
+ } else {
513
+ // Single file database
514
+ dbSizeKB = stats.size / 1024;
515
+ vectorCount = Math.floor(dbSizeKB / 0.5);
516
+ namespaces = 1;
517
+ }
518
+ break;
519
+ } catch (e) {
520
+ // Ignore
521
+ }
522
+ }
523
+ }
524
+
525
+ // Also check for vectors.json (simple vector store)
526
+ const vectorsPath = path.join(process.cwd(), '.claude-flow', 'vectors.json');
527
+ if (fs.existsSync(vectorsPath) && vectorCount === 0) {
528
+ try {
529
+ const data = JSON.parse(fs.readFileSync(vectorsPath, 'utf-8'));
530
+ if (Array.isArray(data)) {
531
+ vectorCount = data.length;
532
+ } else if (data.vectors) {
533
+ vectorCount = Object.keys(data.vectors).length;
534
+ }
535
+ } catch (e) {
536
+ // Ignore
537
+ }
538
+ }
539
+
540
+ return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces };
541
+ }
542
+
543
+ // Get test statistics
544
+ function getTestStats() {
545
+ let testFiles = 0;
546
+ let testCases = 0;
547
+
548
+ const testDirs = [
549
+ path.join(process.cwd(), 'tests'),
550
+ path.join(process.cwd(), 'test'),
551
+ path.join(process.cwd(), '__tests__'),
552
+ path.join(process.cwd(), 'src', '__tests__'),
553
+ path.join(process.cwd(), 'v3', '__tests__'),
554
+ ];
555
+
556
+ // Recursively count test files
557
+ function countTestFiles(dir, depth = 0) {
558
+ if (depth > 3) return; // Limit recursion
559
+ if (!fs.existsSync(dir)) return;
560
+
561
+ try {
562
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
563
+ for (const entry of entries) {
564
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
565
+ countTestFiles(path.join(dir, entry.name), depth + 1);
566
+ } else if (entry.isFile()) {
567
+ const name = entry.name;
568
+ if (name.includes('.test.') || name.includes('.spec.') ||
569
+ name.includes('_test.') || name.includes('_spec.') ||
570
+ name.startsWith('test_') || name.startsWith('spec_')) {
571
+ testFiles++;
572
+
573
+ // Try to estimate test cases from file
574
+ try {
575
+ const content = fs.readFileSync(path.join(dir, name), 'utf-8');
576
+ // Count it(), test(), describe() patterns
577
+ const itMatches = (content.match(/\bit\s*\(/g) || []).length;
578
+ const testMatches = (content.match(/\btest\s*\(/g) || []).length;
579
+ testCases += itMatches + testMatches;
580
+ } catch (e) {
581
+ // Estimate 3 tests per file if can't read
582
+ testCases += 3;
583
+ }
584
+ }
585
+ }
586
+ }
587
+ } catch (e) {
588
+ // Ignore
589
+ }
590
+ }
591
+
592
+ for (const dir of testDirs) {
593
+ countTestFiles(dir);
594
+ }
595
+
596
+ // Also check src directory for colocated tests
597
+ const srcDir = path.join(process.cwd(), 'src');
598
+ if (fs.existsSync(srcDir)) {
599
+ countTestFiles(srcDir);
600
+ }
601
+
602
+ return { testFiles, testCases };
603
+ }
604
+
279
605
  // Generate progress bar
280
606
  function progressBar(current, total) {
281
607
  const width = 5;
@@ -291,6 +617,10 @@ function generateStatusline() {
291
617
  const security = getSecurityStatus();
292
618
  const swarm = getSwarmStatus();
293
619
  const system = getSystemMetrics();
620
+ const adrs = getADRStatus();
621
+ const hooks = getHooksStatus();
622
+ const agentdb = getAgentDBStats();
623
+ const tests = getTestStats();
294
624
  const lines = [];
295
625
 
296
626
  // Header Line
@@ -313,28 +643,41 @@ function generateStatusline() {
313
643
  `${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
314
644
  );
315
645
 
316
- // Line 2: Swarm + CVE + Memory + Context + Intelligence
646
+ // Line 2: Swarm + Hooks + CVE + Memory + Context + Intelligence
317
647
  const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
318
648
  const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
319
649
  let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
320
650
  let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;
651
+ const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;
321
652
 
322
653
  lines.push(
323
654
  `${c.brightYellow}🤖 Swarm${c.reset} ${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}] ` +
324
655
  `${c.brightPurple}👥 ${system.subAgents}${c.reset} ` +
656
+ `${c.brightBlue}🪝 ${hooksColor}${hooks.enabled}${c.reset}/${c.brightWhite}${hooks.total}${c.reset} ` +
325
657
  `${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset} ` +
326
658
  `${c.brightCyan}💾 ${system.memoryMB}MB${c.reset} ` +
327
- `${c.brightGreen}📂 ${String(system.contextPct).padStart(3)}%${c.reset} ` +
328
659
  `${c.dim}🧠 ${String(system.intelligencePct).padStart(3)}%${c.reset}`
329
660
  );
330
661
 
331
- // Line 3: Architecture status
662
+ // Line 3: Architecture status with ADRs, AgentDB, Tests
332
663
  const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
664
+ const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;
665
+ const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
666
+ const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;
667
+
333
668
  lines.push(
334
669
  `${c.brightPurple}🔧 Architecture${c.reset} ` +
670
+ `${c.cyan}ADRs${c.reset} ${adrColor}●${adrs.implemented}/${adrs.count}${c.reset} ${c.dim}│${c.reset} ` +
335
671
  `${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset} ${c.dim}│${c.reset} ` +
336
- `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset} ${c.dim}│${c.reset} ` +
337
- `${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset} ${c.dim}│${c.reset} ` +
672
+ `${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset}`
673
+ );
674
+
675
+ // Line 4: Memory, Vectors, Tests
676
+ lines.push(
677
+ `${c.brightCyan}📊 AgentDB${c.reset} ` +
678
+ `${c.cyan}Vectors${c.reset} ${vectorColor}●${agentdb.vectorCount}${c.reset} ${c.dim}│${c.reset} ` +
679
+ `${c.cyan}Size${c.reset} ${c.brightWhite}${agentdb.dbSizeKB}KB${c.reset} ${c.dim}│${c.reset} ` +
680
+ `${c.cyan}Tests${c.reset} ${testColor}●${tests.testFiles}${c.reset} ${c.dim}(${tests.testCases} cases)${c.reset} ${c.dim}│${c.reset} ` +
338
681
  `${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
339
682
  );
340
683
 
@@ -349,6 +692,10 @@ function generateJSON() {
349
692
  security: getSecurityStatus(),
350
693
  swarm: getSwarmStatus(),
351
694
  system: getSystemMetrics(),
695
+ adrs: getADRStatus(),
696
+ hooks: getHooksStatus(),
697
+ agentdb: getAgentDBStats(),
698
+ tests: getTestStats(),
352
699
  performance: {
353
700
  flashAttentionTarget: '2.49x-7.47x',
354
701
  searchImprovement: '150x-12,500x',
@@ -1 +1 @@
1
- {"version":3,"file":"statusline-generator.d.ts","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAEhE;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAoerE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA2BnE"}
1
+ {"version":3,"file":"statusline-generator.d.ts","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAEhE;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAgtBrE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA2BnE"}