agentic-qe 3.7.16 → 3.7.18
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.
- package/.claude/agents/v3/qe-devils-advocate.md +20 -0
- package/.claude/agents/v3/qe-gap-detector.md +25 -0
- package/.claude/agents/v3/qe-quality-gate.md +8 -0
- package/.claude/agents/v3/qe-requirements-validator.md +25 -0
- package/.claude/agents/v3/subagents/qe-code-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-integration-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-performance-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-security-reviewer.md +11 -0
- package/.claude/helpers/adr-compliance.sh +10 -10
- package/.claude/helpers/auto-memory-hook.mjs +24 -9
- package/.claude/helpers/brain-checkpoint.cjs +55 -145
- package/.claude/helpers/ddd-tracker.sh +2 -2
- package/.claude/helpers/guidance-hooks.sh +2 -2
- package/.claude/helpers/hook-handler.cjs +57 -18
- package/.claude/helpers/statusline.cjs +414 -595
- package/.claude/helpers/v3/quality-criteria/evidence-classification.md +116 -116
- package/.claude/helpers/v3/quality-criteria/htsm-categories.md +139 -139
- package/.claude/skills/README.md +8 -11
- package/.claude/skills/brutal-honesty-review/SKILL.md +3 -0
- package/.claude/skills/code-review-quality/SKILL.md +3 -0
- package/.claude/skills/qcsd-cicd-swarm/SKILL.md +79 -2075
- package/.claude/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +62 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/02-core-agents.md +33 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/03-batch1-results.md +21 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/05-decision-synthesis.md +30 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/06-report-generation.md +17 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +27 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/08-deployment-advisor.md +25 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/09-final-output.md +16 -0
- package/.claude/skills/qcsd-development-swarm/SKILL.md +79 -2027
- package/.claude/skills/qcsd-development-swarm/steps/01-flag-detection.md +50 -0
- package/.claude/skills/qcsd-development-swarm/steps/02-core-agents.md +29 -0
- package/.claude/skills/qcsd-development-swarm/steps/03-batch1-results.md +14 -0
- package/.claude/skills/qcsd-development-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-development-swarm/steps/05-decision-synthesis.md +30 -0
- package/.claude/skills/qcsd-development-swarm/steps/06-report-generation.md +16 -0
- package/.claude/skills/qcsd-development-swarm/steps/07-learning-persistence.md +25 -0
- package/.claude/skills/qcsd-development-swarm/steps/08-defect-predictor.md +25 -0
- package/.claude/skills/qcsd-development-swarm/steps/09-final-output.md +16 -0
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +94 -1894
- package/.claude/skills/qcsd-ideation-swarm/steps/01-flag-detection.md +57 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/02-core-agents.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/03-batch1-results.md +15 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/05-decision-synthesis.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/06-report-generation.md +18 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/08-final-output.md +18 -0
- package/.claude/skills/qcsd-production-swarm/SKILL.md +88 -2663
- package/.claude/skills/qcsd-production-swarm/steps/01-flag-detection.md +206 -0
- package/.claude/skills/qcsd-production-swarm/steps/02-core-agents.md +428 -0
- package/.claude/skills/qcsd-production-swarm/steps/03-batch1-results.md +101 -0
- package/.claude/skills/qcsd-production-swarm/steps/04-conditional-agents.md +125 -0
- package/.claude/skills/qcsd-production-swarm/steps/05-decision-synthesis.md +136 -0
- package/.claude/skills/qcsd-production-swarm/steps/06-report-generation.md +181 -0
- package/.claude/skills/qcsd-production-swarm/steps/07-learning-persistence.md +185 -0
- package/.claude/skills/qcsd-production-swarm/steps/08-feedback-loop.md +122 -0
- package/.claude/skills/qcsd-production-swarm/steps/09-final-output.md +140 -0
- package/.claude/skills/qcsd-refinement-swarm/SKILL.md +59 -2312
- package/.claude/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +91 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/02-core-agents.md +40 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/03-batch1-results.md +40 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/04-conditional-agents.md +35 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/05-decision-synthesis.md +43 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/06-report-generation.md +42 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +53 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/08-transformation.md +36 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/09-final-output.md +46 -0
- package/.claude/skills/sherlock-review/SKILL.md +3 -0
- package/.claude/skills/skill-builder/SKILL.md +103 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +29 -0
- package/assets/agents/v3/qe-devils-advocate.md +20 -0
- package/assets/agents/v3/qe-gap-detector.md +25 -0
- package/assets/agents/v3/qe-quality-gate.md +8 -0
- package/assets/agents/v3/qe-requirements-validator.md +25 -0
- package/assets/agents/v3/subagents/qe-code-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-integration-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-performance-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-security-reviewer.md +11 -0
- package/assets/helpers/statusline-v3.cjs +693 -0
- package/assets/skills/brutal-honesty-review/SKILL.md +3 -0
- package/assets/skills/code-review-quality/SKILL.md +3 -0
- package/assets/skills/qcsd-cicd-swarm/SKILL.md +79 -2075
- package/assets/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +62 -0
- package/assets/skills/qcsd-cicd-swarm/steps/02-core-agents.md +33 -0
- package/assets/skills/qcsd-cicd-swarm/steps/03-batch1-results.md +21 -0
- package/assets/skills/qcsd-cicd-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-cicd-swarm/steps/05-decision-synthesis.md +30 -0
- package/assets/skills/qcsd-cicd-swarm/steps/06-report-generation.md +17 -0
- package/assets/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +27 -0
- package/assets/skills/qcsd-cicd-swarm/steps/08-deployment-advisor.md +25 -0
- package/assets/skills/qcsd-cicd-swarm/steps/09-final-output.md +16 -0
- package/assets/skills/qcsd-development-swarm/SKILL.md +79 -2027
- package/assets/skills/qcsd-development-swarm/steps/01-flag-detection.md +50 -0
- package/assets/skills/qcsd-development-swarm/steps/02-core-agents.md +29 -0
- package/assets/skills/qcsd-development-swarm/steps/03-batch1-results.md +14 -0
- package/assets/skills/qcsd-development-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-development-swarm/steps/05-decision-synthesis.md +30 -0
- package/assets/skills/qcsd-development-swarm/steps/06-report-generation.md +16 -0
- package/assets/skills/qcsd-development-swarm/steps/07-learning-persistence.md +25 -0
- package/assets/skills/qcsd-development-swarm/steps/08-defect-predictor.md +25 -0
- package/assets/skills/qcsd-development-swarm/steps/09-final-output.md +16 -0
- package/assets/skills/qcsd-ideation-swarm/SKILL.md +94 -1894
- package/assets/skills/qcsd-ideation-swarm/steps/01-flag-detection.md +57 -0
- package/assets/skills/qcsd-ideation-swarm/steps/02-core-agents.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/03-batch1-results.md +15 -0
- package/assets/skills/qcsd-ideation-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-ideation-swarm/steps/05-decision-synthesis.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/06-report-generation.md +18 -0
- package/assets/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/08-final-output.md +18 -0
- package/assets/skills/qcsd-production-swarm/SKILL.md +88 -2663
- package/assets/skills/qcsd-production-swarm/steps/01-flag-detection.md +206 -0
- package/assets/skills/qcsd-production-swarm/steps/02-core-agents.md +428 -0
- package/assets/skills/qcsd-production-swarm/steps/03-batch1-results.md +101 -0
- package/assets/skills/qcsd-production-swarm/steps/04-conditional-agents.md +125 -0
- package/assets/skills/qcsd-production-swarm/steps/05-decision-synthesis.md +136 -0
- package/assets/skills/qcsd-production-swarm/steps/06-report-generation.md +181 -0
- package/assets/skills/qcsd-production-swarm/steps/07-learning-persistence.md +185 -0
- package/assets/skills/qcsd-production-swarm/steps/08-feedback-loop.md +122 -0
- package/assets/skills/qcsd-production-swarm/steps/09-final-output.md +140 -0
- package/assets/skills/qcsd-refinement-swarm/SKILL.md +59 -2312
- package/assets/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +91 -0
- package/assets/skills/qcsd-refinement-swarm/steps/02-core-agents.md +40 -0
- package/assets/skills/qcsd-refinement-swarm/steps/03-batch1-results.md +40 -0
- package/assets/skills/qcsd-refinement-swarm/steps/04-conditional-agents.md +35 -0
- package/assets/skills/qcsd-refinement-swarm/steps/05-decision-synthesis.md +43 -0
- package/assets/skills/qcsd-refinement-swarm/steps/06-report-generation.md +42 -0
- package/assets/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +53 -0
- package/assets/skills/qcsd-refinement-swarm/steps/08-transformation.md +36 -0
- package/assets/skills/qcsd-refinement-swarm/steps/09-final-output.md +46 -0
- package/assets/skills/sherlock-review/SKILL.md +3 -0
- package/assets/templates/agent-override-example.yaml +39 -0
- package/dist/agents/devils-advocate/agent.d.ts +25 -1
- package/dist/agents/devils-advocate/agent.js +108 -4
- package/dist/agents/devils-advocate/types.d.ts +54 -0
- package/dist/agents/devils-advocate/types.js +14 -0
- package/dist/agents/overlay-loader.d.ts +28 -0
- package/dist/agents/overlay-loader.js +232 -0
- package/dist/agents/overlay-schema.d.ts +56 -0
- package/dist/agents/overlay-schema.js +77 -0
- package/dist/analysis/branch-enumerator.d.ts +68 -0
- package/dist/analysis/branch-enumerator.js +393 -0
- package/dist/analysis/index.d.ts +2 -0
- package/dist/analysis/index.js +2 -0
- package/dist/cli/bundle.js +2415 -624
- package/dist/cli/commands/coverage.js +50 -0
- package/dist/context/compiler.d.ts +62 -0
- package/dist/context/compiler.js +143 -0
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.js +6 -0
- package/dist/context/sources/coverage-source.d.ts +15 -0
- package/dist/context/sources/coverage-source.js +77 -0
- package/dist/context/sources/git-source.d.ts +12 -0
- package/dist/context/sources/git-source.js +33 -0
- package/dist/context/sources/index.d.ts +6 -0
- package/dist/context/sources/index.js +5 -0
- package/dist/context/sources/memory-source.d.ts +17 -0
- package/dist/context/sources/memory-source.js +94 -0
- package/dist/context/sources/test-source.d.ts +13 -0
- package/dist/context/sources/test-source.js +53 -0
- package/dist/context/sources/types.d.ts +42 -0
- package/dist/context/sources/types.js +5 -0
- package/dist/init/agents-installer.d.ts +9 -0
- package/dist/init/agents-installer.js +79 -0
- package/dist/init/phases/07-hooks.d.ts +11 -0
- package/dist/init/phases/07-hooks.js +67 -0
- package/dist/init/phases/09-assets.js +18 -10
- package/dist/init/settings-merge.js +1 -1
- package/dist/mcp/bundle.js +4411 -3979
- package/dist/mcp/services/task-router.d.ts +11 -0
- package/dist/mcp/services/task-router.js +26 -0
- package/dist/routing/qe-agent-registry.d.ts +11 -0
- package/dist/routing/qe-agent-registry.js +34 -0
- package/dist/routing/qe-task-router.d.ts +1 -0
- package/dist/routing/qe-task-router.js +34 -2
- package/dist/routing/types.d.ts +2 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/pipeline.d.ts +80 -0
- package/dist/validation/pipeline.js +173 -0
- package/dist/validation/steps/requirements.d.ts +32 -0
- package/dist/validation/steps/requirements.js +596 -0
- package/package.json +6 -6
- package/.claude/agents/consensus/README.md +0 -253
- package/.claude/agents/deprecated/qe-api-contract-validator.md.v2 +0 -162
- package/.claude/agents/deprecated/qe-coverage-analyzer.md.v2 +0 -208
- package/.claude/agents/deprecated/qe-test-generator.md.v2 +0 -212
- package/.claude/agents/deprecated/qe-visual-tester.md.v2 +0 -216
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +0 -130
- package/.claude/agents/hive-mind/queen-coordinator.md +0 -203
- package/.claude/agents/hive-mind/scout-explorer.md +0 -242
- package/.claude/agents/hive-mind/swarm-memory-manager.md +0 -193
- package/.claude/agents/hive-mind/worker-specialist.md +0 -217
- package/.claude/agents/neural/safla-neural.md +0 -74
- package/.claude/agents/optimization/README.md +0 -250
- package/.claude/agents/reasoning/agent.md +0 -816
- package/.claude/agents/reasoning/goal-planner.md +0 -73
- package/.claude/agents/subagents/qe-code-reviewer.md +0 -76
- package/.claude/agents/subagents/qe-coverage-gap-analyzer.md +0 -76
- package/.claude/agents/subagents/qe-data-generator.md +0 -77
- package/.claude/agents/subagents/qe-flaky-investigator.md +0 -91
- package/.claude/agents/subagents/qe-integration-tester.md +0 -90
- package/.claude/agents/subagents/qe-performance-validator.md +0 -92
- package/.claude/agents/subagents/qe-security-auditor.md +0 -94
- package/.claude/agents/subagents/qe-test-data-architect-sub.md +0 -93
- package/.claude/agents/subagents/qe-test-implementer.md +0 -106
- package/.claude/agents/subagents/qe-test-refactorer.md +0 -117
- package/.claude/agents/subagents/qe-test-writer.md +0 -112
- package/.claude/agents/swarm/README.md +0 -190
- package/.claude/agents/templates/migration-plan.md +0 -746
- package/.claude/agents/testing/unit/tdd-london-swarm.md +0 -244
- package/.claude/agents/testing/validation/production-validator.md +0 -395
- package/.claude/agents/v3/README.md +0 -39
- package/.claude/agents/v3/typescript-specialist.yaml +0 -21
- package/.claude/agents/v3/v3-memory-specialist.md +0 -318
- package/.claude/agents/v3/v3-performance-engineer.md +0 -397
- package/.claude/agents/v3/v3-queen-coordinator.md +0 -98
- package/.claude/agents/v3/v3-security-architect.md +0 -174
- package/.claude/commands/README.md +0 -106
- package/.claude/commands/agents/README.md +0 -10
- package/.claude/commands/agents/agent-capabilities.md +0 -21
- package/.claude/commands/agents/agent-coordination.md +0 -28
- package/.claude/commands/agents/agent-spawning.md +0 -28
- package/.claude/commands/agents/agent-types.md +0 -26
- package/.claude/commands/coordination/README.md +0 -9
- package/.claude/commands/coordination/agent-spawn.md +0 -25
- package/.claude/commands/coordination/init.md +0 -44
- package/.claude/commands/coordination/orchestrate.md +0 -43
- package/.claude/commands/coordination/spawn.md +0 -45
- package/.claude/commands/coordination/swarm-init.md +0 -85
- package/.claude/commands/coordination/task-orchestrate.md +0 -25
- package/.claude/commands/hive-mind/README.md +0 -17
- package/.claude/commands/hive-mind/hive-mind-consensus.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-init.md +0 -18
- package/.claude/commands/hive-mind/hive-mind-memory.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-metrics.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-resume.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-sessions.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-spawn.md +0 -21
- package/.claude/commands/hive-mind/hive-mind-status.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-stop.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-wizard.md +0 -8
- package/.claude/commands/hive-mind/hive-mind.md +0 -27
- package/.claude/commands/memory/README.md +0 -9
- package/.claude/commands/memory/memory-persist.md +0 -25
- package/.claude/commands/memory/memory-search.md +0 -25
- package/.claude/commands/memory/memory-usage.md +0 -25
- package/.claude/commands/memory/neural.md +0 -47
- package/.claude/commands/swarm/README.md +0 -15
- package/.claude/commands/swarm/swarm-analysis.md +0 -8
- package/.claude/commands/swarm/swarm-background.md +0 -8
- package/.claude/commands/swarm/swarm-init.md +0 -19
- package/.claude/commands/swarm/swarm-modes.md +0 -8
- package/.claude/commands/swarm/swarm-monitor.md +0 -8
- package/.claude/commands/swarm/swarm-spawn.md +0 -19
- package/.claude/commands/swarm/swarm-status.md +0 -8
- package/.claude/commands/swarm/swarm-strategies.md +0 -8
- package/.claude/commands/swarm/swarm.md +0 -27
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/training/model-update.md +0 -25
- package/.claude/commands/training/neural-patterns.md +0 -74
- package/.claude/commands/training/neural-train.md +0 -25
- package/.claude/commands/training/pattern-learn.md +0 -25
- package/.claude/commands/training/specialization.md +0 -63
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/commands/workflows/development.md +0 -78
- package/.claude/commands/workflows/research.md +0 -63
- package/.claude/commands/workflows/workflow-create.md +0 -25
- package/.claude/commands/workflows/workflow-execute.md +0 -25
- package/.claude/commands/workflows/workflow-export.md +0 -25
- package/.claude/skills/agentic-jujutsu/SKILL.md +0 -645
- package/.claude/skills/hive-mind-advanced/SKILL.md +0 -712
- package/.claude/skills/iterative-loop/SKILL.md +0 -371
- package/.claude/skills/performance-analysis/SKILL.md +0 -569
- package/.claude/skills/performance-analysis/evals/performance-analysis.yaml +0 -144
- package/.claude/skills/performance-analysis/schemas/output.json +0 -588
- package/.claude/skills/performance-analysis/scripts/validate-config.json +0 -36
|
@@ -1,30 +1,48 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Claude Flow V3 Statusline Generator
|
|
3
|
+
* Claude Flow V3 Statusline Generator
|
|
4
4
|
* Displays real-time V3 implementation progress and system status
|
|
5
5
|
*
|
|
6
|
-
* Usage: node statusline.cjs [
|
|
6
|
+
* Usage: node statusline.cjs [options]
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
8
|
+
* Options:
|
|
9
|
+
* (default) Safe multi-line output with collision zone avoidance
|
|
10
|
+
* --single Single-line output (completely avoids collision)
|
|
11
|
+
* --unsafe Legacy multi-line without collision avoidance
|
|
12
|
+
* --legacy Alias for --unsafe
|
|
13
|
+
* --json JSON output with pretty printing
|
|
14
|
+
* --compact JSON output without formatting
|
|
15
|
+
*
|
|
16
|
+
* Collision Zone Fix (Issue #985):
|
|
17
|
+
* Claude Code writes its internal status (e.g., "7s • 1p") at absolute
|
|
18
|
+
* terminal coordinates (columns 15-25 on second-to-last line). The safe
|
|
19
|
+
* mode pads the collision line with spaces to push content past column 25.
|
|
20
|
+
*
|
|
21
|
+
* IMPORTANT: This file uses .cjs extension to work in ES module projects.
|
|
22
|
+
* The require() syntax is intentional for CommonJS compatibility.
|
|
14
23
|
*/
|
|
15
24
|
|
|
16
25
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
17
26
|
const fs = require('fs');
|
|
18
27
|
const path = require('path');
|
|
19
28
|
const { execSync } = require('child_process');
|
|
20
|
-
const os = require('os');
|
|
21
29
|
|
|
22
30
|
// Configuration
|
|
23
31
|
const CONFIG = {
|
|
32
|
+
enabled: true,
|
|
33
|
+
showProgress: true,
|
|
34
|
+
showSecurity: true,
|
|
35
|
+
showSwarm: true,
|
|
36
|
+
showHooks: true,
|
|
37
|
+
showPerformance: true,
|
|
38
|
+
refreshInterval: 5000,
|
|
24
39
|
maxAgents: 15,
|
|
40
|
+
topology: 'hierarchical-mesh',
|
|
25
41
|
};
|
|
26
42
|
|
|
27
|
-
|
|
43
|
+
// Cross-platform helpers
|
|
44
|
+
const isWindows = process.platform === 'win32';
|
|
45
|
+
const nullDevice = isWindows ? 'NUL' : '/dev/null';
|
|
28
46
|
|
|
29
47
|
// ANSI colors
|
|
30
48
|
const c = {
|
|
@@ -46,713 +64,514 @@ const c = {
|
|
|
46
64
|
brightWhite: '\x1b[1;37m',
|
|
47
65
|
};
|
|
48
66
|
|
|
49
|
-
//
|
|
50
|
-
function
|
|
67
|
+
// Get user info
|
|
68
|
+
function getUserInfo() {
|
|
69
|
+
let name = 'user';
|
|
70
|
+
let gitBranch = '';
|
|
71
|
+
let modelName = 'Unknown';
|
|
72
|
+
|
|
51
73
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
74
|
+
const gitUserCmd = isWindows
|
|
75
|
+
? 'git config user.name 2>NUL || echo user'
|
|
76
|
+
: 'git config user.name 2>/dev/null || echo "user"';
|
|
77
|
+
const gitBranchCmd = isWindows
|
|
78
|
+
? 'git branch --show-current 2>NUL || echo.'
|
|
79
|
+
: 'git branch --show-current 2>/dev/null || echo ""';
|
|
80
|
+
name = execSync(gitUserCmd, { encoding: 'utf-8' }).trim();
|
|
81
|
+
gitBranch = execSync(gitBranchCmd, { encoding: 'utf-8' }).trim();
|
|
82
|
+
if (gitBranch === '.') gitBranch = ''; // Windows echo. outputs a dot
|
|
83
|
+
} catch (e) {
|
|
84
|
+
// Ignore errors
|
|
59
85
|
}
|
|
60
|
-
}
|
|
61
86
|
|
|
62
|
-
//
|
|
63
|
-
function readJSON(filePath) {
|
|
87
|
+
// Auto-detect model from Claude Code's config
|
|
64
88
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
const homedir = require('os').homedir();
|
|
90
|
+
const claudeConfigPath = path.join(homedir, '.claude.json');
|
|
91
|
+
if (fs.existsSync(claudeConfigPath)) {
|
|
92
|
+
const claudeConfig = JSON.parse(fs.readFileSync(claudeConfigPath, 'utf-8'));
|
|
93
|
+
// Try to find lastModelUsage - check current dir and parent dirs
|
|
94
|
+
let lastModelUsage = null;
|
|
95
|
+
const cwd = process.cwd();
|
|
96
|
+
if (claudeConfig.projects) {
|
|
97
|
+
// Try exact match first, then check if cwd starts with any project path
|
|
98
|
+
for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
|
|
99
|
+
if (cwd === projectPath || cwd.startsWith(projectPath + '/')) {
|
|
100
|
+
lastModelUsage = projectConfig.lastModelUsage;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (lastModelUsage) {
|
|
106
|
+
const modelIds = Object.keys(lastModelUsage);
|
|
107
|
+
if (modelIds.length > 0) {
|
|
108
|
+
// Take the last model (most recently added to the object)
|
|
109
|
+
// Or find the one with most tokens (most actively used this session)
|
|
110
|
+
let modelId = modelIds[modelIds.length - 1];
|
|
111
|
+
if (modelIds.length > 1) {
|
|
112
|
+
// If multiple models, pick the one with most total tokens
|
|
113
|
+
let maxTokens = 0;
|
|
114
|
+
for (const id of modelIds) {
|
|
115
|
+
const usage = lastModelUsage[id];
|
|
116
|
+
const total = (usage.inputTokens || 0) + (usage.outputTokens || 0);
|
|
117
|
+
if (total > maxTokens) {
|
|
118
|
+
maxTokens = total;
|
|
119
|
+
modelId = id;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Parse model ID to human-readable name
|
|
124
|
+
if (modelId.includes('opus')) modelName = 'Opus 4.5';
|
|
125
|
+
else if (modelId.includes('sonnet')) modelName = 'Sonnet 4';
|
|
126
|
+
else if (modelId.includes('haiku')) modelName = 'Haiku 4.5';
|
|
127
|
+
else modelName = modelId.split('-').slice(1, 3).join(' ');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
67
130
|
}
|
|
68
|
-
} catch {
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Safe file stat (returns null on failure)
|
|
73
|
-
function safeStat(filePath) {
|
|
74
|
-
try {
|
|
75
|
-
return fs.statSync(filePath);
|
|
76
|
-
} catch { /* ignore */ }
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// Fallback to Unknown if can't read config
|
|
133
|
+
}
|
|
79
134
|
|
|
80
|
-
|
|
81
|
-
let _settingsCache = undefined;
|
|
82
|
-
function getSettings() {
|
|
83
|
-
if (_settingsCache !== undefined) return _settingsCache;
|
|
84
|
-
_settingsCache = readJSON(path.join(CWD, '.claude', 'settings.json'))
|
|
85
|
-
|| readJSON(path.join(CWD, '.claude', 'settings.local.json'))
|
|
86
|
-
|| null;
|
|
87
|
-
return _settingsCache;
|
|
135
|
+
return { name, gitBranch, modelName };
|
|
88
136
|
}
|
|
89
137
|
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
138
|
+
// Get learning stats from intelligence loop data (ADR-050)
|
|
139
|
+
function getLearningStats() {
|
|
140
|
+
let patterns = 0;
|
|
141
|
+
let sessions = 0;
|
|
142
|
+
let trajectories = 0;
|
|
143
|
+
let edges = 0;
|
|
144
|
+
let confidenceMean = 0;
|
|
145
|
+
let accessedCount = 0;
|
|
146
|
+
let trend = 'STABLE';
|
|
147
|
+
|
|
148
|
+
// PRIMARY: Read from intelligence loop data files
|
|
149
|
+
const dataDir = path.join(process.cwd(), '.claude-flow', 'data');
|
|
150
|
+
|
|
151
|
+
// 1. graph-state.json — authoritative node/edge counts
|
|
152
|
+
const graphPath = path.join(dataDir, 'graph-state.json');
|
|
153
|
+
if (fs.existsSync(graphPath)) {
|
|
154
|
+
try {
|
|
155
|
+
const graph = JSON.parse(fs.readFileSync(graphPath, 'utf-8'));
|
|
156
|
+
patterns = graph.nodes ? Object.keys(graph.nodes).length : 0;
|
|
157
|
+
edges = Array.isArray(graph.edges) ? graph.edges.length : 0;
|
|
158
|
+
} catch (e) { /* ignore */ }
|
|
159
|
+
}
|
|
98
160
|
|
|
99
|
-
//
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (parts.length >= 4) {
|
|
115
|
-
result.name = parts[0] || 'user';
|
|
116
|
-
result.gitBranch = parts[1] || '';
|
|
117
|
-
|
|
118
|
-
// Parse porcelain status
|
|
119
|
-
if (parts[2]) {
|
|
120
|
-
for (const line of parts[2].split('\n')) {
|
|
121
|
-
if (!line || line.length < 2) continue;
|
|
122
|
-
const x = line[0], y = line[1];
|
|
123
|
-
if (x === '?' && y === '?') { result.untracked++; continue; }
|
|
124
|
-
if (x !== ' ' && x !== '?') result.staged++;
|
|
125
|
-
if (y !== ' ' && y !== '?') result.modified++;
|
|
161
|
+
// 2. ranked-context.json — confidence and access data
|
|
162
|
+
const rankedPath = path.join(dataDir, 'ranked-context.json');
|
|
163
|
+
if (fs.existsSync(rankedPath)) {
|
|
164
|
+
try {
|
|
165
|
+
const ranked = JSON.parse(fs.readFileSync(rankedPath, 'utf-8'));
|
|
166
|
+
if (ranked.entries && ranked.entries.length > 0) {
|
|
167
|
+
patterns = Math.max(patterns, ranked.entries.length);
|
|
168
|
+
let confSum = 0;
|
|
169
|
+
let accCount = 0;
|
|
170
|
+
for (let i = 0; i < ranked.entries.length; i++) {
|
|
171
|
+
confSum += (ranked.entries[i].confidence || 0);
|
|
172
|
+
if ((ranked.entries[i].accessCount || 0) > 0) accCount++;
|
|
173
|
+
}
|
|
174
|
+
confidenceMean = confSum / ranked.entries.length;
|
|
175
|
+
accessedCount = accCount;
|
|
126
176
|
}
|
|
127
|
-
}
|
|
177
|
+
} catch (e) { /* ignore */ }
|
|
178
|
+
}
|
|
128
179
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
180
|
+
// 3. intelligence-snapshot.json — trend history
|
|
181
|
+
const snapshotPath = path.join(dataDir, 'intelligence-snapshot.json');
|
|
182
|
+
if (fs.existsSync(snapshotPath)) {
|
|
183
|
+
try {
|
|
184
|
+
const snapshot = JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));
|
|
185
|
+
if (snapshot.history && snapshot.history.length >= 2) {
|
|
186
|
+
const first = snapshot.history[0];
|
|
187
|
+
const last = snapshot.history[snapshot.history.length - 1];
|
|
188
|
+
const confDrift = (last.confidenceMean || 0) - (first.confidenceMean || 0);
|
|
189
|
+
trend = confDrift > 0.01 ? 'IMPROVING' : confDrift < -0.01 ? 'DECLINING' : 'STABLE';
|
|
190
|
+
sessions = Math.max(sessions, snapshot.history.length);
|
|
191
|
+
}
|
|
192
|
+
} catch (e) { /* ignore */ }
|
|
133
193
|
}
|
|
134
194
|
|
|
135
|
-
|
|
136
|
-
|
|
195
|
+
// 4. auto-memory-store.json — fallback entry count
|
|
196
|
+
if (patterns === 0) {
|
|
197
|
+
const autoMemPath = path.join(dataDir, 'auto-memory-store.json');
|
|
198
|
+
if (fs.existsSync(autoMemPath)) {
|
|
199
|
+
try {
|
|
200
|
+
const data = JSON.parse(fs.readFileSync(autoMemPath, 'utf-8'));
|
|
201
|
+
patterns = Array.isArray(data) ? data.length : (data.entries ? data.entries.length : 0);
|
|
202
|
+
} catch (e) { /* ignore */ }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
137
205
|
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
let latest = 0;
|
|
151
|
-
for (const id of ids) {
|
|
152
|
-
const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;
|
|
153
|
-
if (ts > latest) { latest = ts; modelId = id; }
|
|
154
|
-
}
|
|
155
|
-
if (modelId.includes('opus')) return 'Opus 4.6';
|
|
156
|
-
if (modelId.includes('sonnet')) return 'Sonnet 4.6';
|
|
157
|
-
if (modelId.includes('haiku')) return 'Haiku 4.5';
|
|
158
|
-
return modelId.split('-').slice(1, 3).join(' ');
|
|
159
|
-
}
|
|
160
|
-
}
|
|
206
|
+
// FALLBACK: Legacy memory.db file-size estimation
|
|
207
|
+
if (patterns === 0) {
|
|
208
|
+
const memoryPaths = [
|
|
209
|
+
path.join(process.cwd(), '.swarm', 'memory.db'),
|
|
210
|
+
path.join(process.cwd(), '.claude', 'memory.db'),
|
|
211
|
+
path.join(process.cwd(), 'data', 'memory.db'),
|
|
212
|
+
];
|
|
213
|
+
for (let j = 0; j < memoryPaths.length; j++) {
|
|
214
|
+
if (fs.existsSync(memoryPaths[j])) {
|
|
215
|
+
try {
|
|
216
|
+
const dbStats = fs.statSync(memoryPaths[j]);
|
|
217
|
+
patterns = Math.floor(dbStats.size / 1024 / 2);
|
|
161
218
|
break;
|
|
162
|
-
}
|
|
219
|
+
} catch (e) { /* ignore */ }
|
|
163
220
|
}
|
|
164
221
|
}
|
|
165
|
-
} catch { /* ignore */ }
|
|
166
|
-
|
|
167
|
-
// Fallback: settings.json model field
|
|
168
|
-
const settings = getSettings();
|
|
169
|
-
if (settings && settings.model) {
|
|
170
|
-
const m = settings.model;
|
|
171
|
-
if (m.includes('opus')) return 'Opus 4.6';
|
|
172
|
-
if (m.includes('sonnet')) return 'Sonnet 4.6';
|
|
173
|
-
if (m.includes('haiku')) return 'Haiku 4.5';
|
|
174
222
|
}
|
|
175
|
-
return 'Claude Code';
|
|
176
|
-
}
|
|
177
223
|
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
path.join(CWD, '.agentdb', 'memory.db'),
|
|
186
|
-
];
|
|
187
|
-
|
|
188
|
-
for (const dbPath of memoryPaths) {
|
|
189
|
-
const stat = safeStat(dbPath);
|
|
190
|
-
if (stat) {
|
|
191
|
-
const sizeKB = stat.size / 1024;
|
|
192
|
-
const patterns = Math.floor(sizeKB / 2);
|
|
193
|
-
return {
|
|
194
|
-
patterns,
|
|
195
|
-
sessions: Math.max(1, Math.floor(patterns / 10)),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
224
|
+
// Session count from session files
|
|
225
|
+
const sessionsPath = path.join(process.cwd(), '.claude', 'sessions');
|
|
226
|
+
if (fs.existsSync(sessionsPath)) {
|
|
227
|
+
try {
|
|
228
|
+
const sessionFiles = fs.readdirSync(sessionsPath).filter(f => f.endsWith('.json'));
|
|
229
|
+
sessions = Math.max(sessions, sessionFiles.length);
|
|
230
|
+
} catch (e) { /* ignore */ }
|
|
198
231
|
}
|
|
199
232
|
|
|
200
|
-
|
|
201
|
-
let sessions = 0;
|
|
202
|
-
try {
|
|
203
|
-
const sessDir = path.join(CWD, '.claude', 'sessions');
|
|
204
|
-
if (fs.existsSync(sessDir)) {
|
|
205
|
-
sessions = fs.readdirSync(sessDir).filter(f => f.endsWith('.json')).length;
|
|
206
|
-
}
|
|
207
|
-
} catch { /* ignore */ }
|
|
233
|
+
trajectories = Math.floor(patterns / 5);
|
|
208
234
|
|
|
209
|
-
return { patterns
|
|
235
|
+
return { patterns, sessions, trajectories, edges, confidenceMean, accessedCount, trend };
|
|
210
236
|
}
|
|
211
237
|
|
|
212
|
-
// V3 progress from
|
|
238
|
+
// Get V3 progress from learning state (grows as system learns)
|
|
213
239
|
function getV3Progress() {
|
|
214
240
|
const learning = getLearningStats();
|
|
215
|
-
const totalDomains = 5;
|
|
216
241
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
// DDD progress based on actual learned patterns
|
|
243
|
+
// New install: 0 patterns = 0/5 domains, 0% DDD
|
|
244
|
+
// As patterns grow: 10+ patterns = 1 domain, 50+ = 2, 100+ = 3, 200+ = 4, 500+ = 5
|
|
245
|
+
let domainsCompleted = 0;
|
|
246
|
+
if (learning.patterns >= 500) domainsCompleted = 5;
|
|
247
|
+
else if (learning.patterns >= 200) domainsCompleted = 4;
|
|
248
|
+
else if (learning.patterns >= 100) domainsCompleted = 3;
|
|
249
|
+
else if (learning.patterns >= 50) domainsCompleted = 2;
|
|
250
|
+
else if (learning.patterns >= 10) domainsCompleted = 1;
|
|
251
|
+
|
|
252
|
+
const totalDomains = 5;
|
|
253
|
+
const dddProgress = Math.min(100, Math.floor((domainsCompleted / totalDomains) * 100));
|
|
229
254
|
|
|
230
255
|
return {
|
|
231
|
-
domainsCompleted,
|
|
256
|
+
domainsCompleted,
|
|
257
|
+
totalDomains,
|
|
258
|
+
dddProgress,
|
|
232
259
|
patternsLearned: learning.patterns,
|
|
233
|
-
sessionsCompleted: learning.sessions
|
|
260
|
+
sessionsCompleted: learning.sessions
|
|
234
261
|
};
|
|
235
262
|
}
|
|
236
263
|
|
|
237
|
-
//
|
|
264
|
+
// Get security status based on actual scans
|
|
238
265
|
function getSecurityStatus() {
|
|
266
|
+
// Check for security scan results in memory
|
|
267
|
+
const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
|
|
268
|
+
let cvesFixed = 0;
|
|
239
269
|
const totalCves = 3;
|
|
240
|
-
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
270
|
+
|
|
271
|
+
if (fs.existsSync(scanResultsPath)) {
|
|
272
|
+
try {
|
|
273
|
+
const scans = fs.readdirSync(scanResultsPath).filter(f => f.endsWith('.json'));
|
|
274
|
+
// Each successful scan file = 1 CVE addressed
|
|
275
|
+
cvesFixed = Math.min(totalCves, scans.length);
|
|
276
|
+
} catch (e) {
|
|
277
|
+
// Ignore
|
|
278
|
+
}
|
|
247
279
|
}
|
|
248
280
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
281
|
+
// Also check .swarm/security for audit results
|
|
282
|
+
const auditPath = path.join(process.cwd(), '.swarm', 'security');
|
|
283
|
+
if (fs.existsSync(auditPath)) {
|
|
284
|
+
try {
|
|
285
|
+
const audits = fs.readdirSync(auditPath).filter(f => f.includes('audit'));
|
|
286
|
+
cvesFixed = Math.min(totalCves, Math.max(cvesFixed, audits.length));
|
|
287
|
+
} catch (e) {
|
|
288
|
+
// Ignore
|
|
254
289
|
}
|
|
255
|
-
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const status = cvesFixed >= totalCves ? 'CLEAN' : cvesFixed > 0 ? 'IN_PROGRESS' : 'PENDING';
|
|
256
293
|
|
|
257
294
|
return {
|
|
258
|
-
status
|
|
295
|
+
status,
|
|
259
296
|
cvesFixed,
|
|
260
297
|
totalCves,
|
|
261
298
|
};
|
|
262
299
|
}
|
|
263
300
|
|
|
264
|
-
//
|
|
301
|
+
// Get swarm status
|
|
265
302
|
function getSwarmStatus() {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return {
|
|
269
|
-
activeAgents: activityData.swarm.agent_count || 0,
|
|
270
|
-
maxAgents: CONFIG.maxAgents,
|
|
271
|
-
coordinationActive: activityData.swarm.coordination_active || activityData.swarm.active || false,
|
|
272
|
-
};
|
|
273
|
-
}
|
|
303
|
+
let activeAgents = 0;
|
|
304
|
+
let coordinationActive = false;
|
|
274
305
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
306
|
+
try {
|
|
307
|
+
if (isWindows) {
|
|
308
|
+
// Windows: use tasklist and findstr
|
|
309
|
+
const ps = execSync('tasklist 2>NUL | findstr /I "agentic-flow" 2>NUL | find /C /V "" 2>NUL || echo 0', { encoding: 'utf-8' });
|
|
310
|
+
activeAgents = Math.max(0, parseInt(ps.trim()) || 0);
|
|
311
|
+
} else {
|
|
312
|
+
const ps = execSync('ps aux 2>/dev/null | grep -c agentic-flow || echo "0"', { encoding: 'utf-8' });
|
|
313
|
+
activeAgents = Math.max(0, parseInt(ps.trim()) - 1);
|
|
314
|
+
}
|
|
315
|
+
coordinationActive = activeAgents > 0;
|
|
316
|
+
} catch (e) {
|
|
317
|
+
// Ignore errors - default to 0 agents
|
|
282
318
|
}
|
|
283
319
|
|
|
284
|
-
return {
|
|
320
|
+
return {
|
|
321
|
+
activeAgents,
|
|
322
|
+
maxAgents: CONFIG.maxAgents,
|
|
323
|
+
coordinationActive,
|
|
324
|
+
};
|
|
285
325
|
}
|
|
286
326
|
|
|
287
|
-
//
|
|
327
|
+
// Get system metrics (dynamic based on actual state)
|
|
288
328
|
function getSystemMetrics() {
|
|
289
|
-
|
|
290
|
-
const learning = getLearningStats();
|
|
291
|
-
const agentdb = getAgentDBStats();
|
|
292
|
-
|
|
293
|
-
// Intelligence from learning.json
|
|
294
|
-
const learningData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'learning.json'));
|
|
295
|
-
let intelligencePct = 0;
|
|
296
|
-
let contextPct = 0;
|
|
297
|
-
|
|
298
|
-
if (learningData && learningData.intelligence && learningData.intelligence.score !== undefined) {
|
|
299
|
-
intelligencePct = Math.min(100, Math.floor(learningData.intelligence.score));
|
|
300
|
-
} else {
|
|
301
|
-
const fromPatterns = learning.patterns > 0 ? Math.min(100, Math.floor(learning.patterns / 10)) : 0;
|
|
302
|
-
const fromVectors = agentdb.vectorCount > 0 ? Math.min(100, Math.floor(agentdb.vectorCount / 100)) : 0;
|
|
303
|
-
intelligencePct = Math.max(fromPatterns, fromVectors);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Maturity fallback (pure fs checks, no git exec)
|
|
307
|
-
if (intelligencePct === 0) {
|
|
308
|
-
let score = 0;
|
|
309
|
-
if (fs.existsSync(path.join(CWD, '.claude'))) score += 15;
|
|
310
|
-
const srcDirs = ['src', 'lib', 'app', 'packages'];
|
|
311
|
-
for (const d of srcDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 15; break; } }
|
|
312
|
-
const testDirs = ['tests', 'test', '__tests__', 'spec'];
|
|
313
|
-
for (const d of testDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 10; break; } }
|
|
314
|
-
const cfgFiles = ['package.json', 'tsconfig.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
|
|
315
|
-
for (const f of cfgFiles) { if (fs.existsSync(path.join(CWD, f))) { score += 5; break; } }
|
|
316
|
-
intelligencePct = Math.min(100, score);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (learningData && learningData.sessions && learningData.sessions.total !== undefined) {
|
|
320
|
-
contextPct = Math.min(100, learningData.sessions.total * 5);
|
|
321
|
-
} else {
|
|
322
|
-
contextPct = Math.min(100, Math.floor(learning.sessions * 5));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Sub-agents from file metrics (no ps aux)
|
|
329
|
+
let memoryMB = 0;
|
|
326
330
|
let subAgents = 0;
|
|
327
|
-
const activityData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'swarm-activity.json'));
|
|
328
|
-
if (activityData && activityData.processes && activityData.processes.estimated_agents) {
|
|
329
|
-
subAgents = activityData.processes.estimated_agents;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
return { memoryMB, contextPct, intelligencePct, subAgents };
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// ADR status (count files only — don't read contents)
|
|
336
|
-
function getADRStatus() {
|
|
337
|
-
const complianceData = readJSON(path.join(CWD, '.claude-flow', 'metrics', 'adr-compliance.json'));
|
|
338
|
-
if (complianceData) {
|
|
339
|
-
const checks = complianceData.checks || {};
|
|
340
|
-
const total = Object.keys(checks).length;
|
|
341
|
-
const impl = Object.values(checks).filter(c => c.compliant).length;
|
|
342
|
-
return { count: total, implemented: impl, compliance: complianceData.compliance || 0 };
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Fallback: just count ADR files (don't read them)
|
|
346
|
-
const adrPaths = [
|
|
347
|
-
path.join(CWD, 'docs', 'implementation', 'adrs'),
|
|
348
|
-
path.join(CWD, 'docs', 'adrs'),
|
|
349
|
-
path.join(CWD, '.claude-flow', 'adrs'),
|
|
350
|
-
];
|
|
351
|
-
|
|
352
|
-
for (const adrPath of adrPaths) {
|
|
353
|
-
try {
|
|
354
|
-
if (fs.existsSync(adrPath)) {
|
|
355
|
-
const files = fs.readdirSync(adrPath).filter(f =>
|
|
356
|
-
f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\d{4}-/.test(f))
|
|
357
|
-
);
|
|
358
|
-
const implemented = Math.floor(files.length * 0.7);
|
|
359
|
-
const compliance = files.length > 0 ? Math.floor((implemented / files.length) * 100) : 0;
|
|
360
|
-
return { count: files.length, implemented, compliance };
|
|
361
|
-
}
|
|
362
|
-
} catch { /* ignore */ }
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return { count: 0, implemented: 0, compliance: 0 };
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Hooks status (shared settings cache)
|
|
369
|
-
function getHooksStatus() {
|
|
370
|
-
let enabled = 0;
|
|
371
|
-
const total = 17;
|
|
372
|
-
const settings = getSettings();
|
|
373
|
-
|
|
374
|
-
if (settings && settings.hooks) {
|
|
375
|
-
for (const category of Object.keys(settings.hooks)) {
|
|
376
|
-
const h = settings.hooks[category];
|
|
377
|
-
if (Array.isArray(h) && h.length > 0) enabled++;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
331
|
|
|
381
332
|
try {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
return { enabled, total };
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// AgentDB stats (pure stat calls)
|
|
393
|
-
function getAgentDBStats() {
|
|
394
|
-
let vectorCount = 0;
|
|
395
|
-
let dbSizeKB = 0;
|
|
396
|
-
let namespaces = 0;
|
|
397
|
-
let hasHnsw = false;
|
|
398
|
-
|
|
399
|
-
const dbFiles = [
|
|
400
|
-
path.join(CWD, '.swarm', 'memory.db'),
|
|
401
|
-
path.join(CWD, '.claude-flow', 'memory.db'),
|
|
402
|
-
path.join(CWD, '.claude', 'memory.db'),
|
|
403
|
-
path.join(CWD, 'data', 'memory.db'),
|
|
404
|
-
];
|
|
405
|
-
|
|
406
|
-
for (const f of dbFiles) {
|
|
407
|
-
const stat = safeStat(f);
|
|
408
|
-
if (stat) {
|
|
409
|
-
dbSizeKB = stat.size / 1024;
|
|
410
|
-
vectorCount = Math.floor(dbSizeKB / 2);
|
|
411
|
-
namespaces = 1;
|
|
412
|
-
break;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (vectorCount === 0) {
|
|
417
|
-
const dbDirs = [
|
|
418
|
-
path.join(CWD, '.claude-flow', 'agentdb'),
|
|
419
|
-
path.join(CWD, '.swarm', 'agentdb'),
|
|
420
|
-
path.join(CWD, '.agentdb'),
|
|
421
|
-
];
|
|
422
|
-
for (const dir of dbDirs) {
|
|
423
|
-
try {
|
|
424
|
-
if (fs.existsSync(dir) && fs.statSync(dir).isDirectory()) {
|
|
425
|
-
const files = fs.readdirSync(dir);
|
|
426
|
-
namespaces = files.filter(f => f.endsWith('.db') || f.endsWith('.sqlite')).length;
|
|
427
|
-
for (const file of files) {
|
|
428
|
-
const stat = safeStat(path.join(dir, file));
|
|
429
|
-
if (stat && stat.isFile()) dbSizeKB += stat.size / 1024;
|
|
430
|
-
}
|
|
431
|
-
vectorCount = Math.floor(dbSizeKB / 2);
|
|
432
|
-
break;
|
|
433
|
-
}
|
|
434
|
-
} catch { /* ignore */ }
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const hnswPaths = [
|
|
439
|
-
path.join(CWD, '.swarm', 'hnsw.index'),
|
|
440
|
-
path.join(CWD, '.claude-flow', 'hnsw.index'),
|
|
441
|
-
];
|
|
442
|
-
for (const p of hnswPaths) {
|
|
443
|
-
const stat = safeStat(p);
|
|
444
|
-
if (stat) {
|
|
445
|
-
hasHnsw = true;
|
|
446
|
-
vectorCount = Math.max(vectorCount, Math.floor(stat.size / 512));
|
|
447
|
-
break;
|
|
333
|
+
if (isWindows) {
|
|
334
|
+
// Windows: use tasklist for memory info, fallback to process.memoryUsage
|
|
335
|
+
// tasklist memory column is complex to parse, use Node.js API instead
|
|
336
|
+
memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
337
|
+
} else {
|
|
338
|
+
const mem = execSync('ps aux | grep -E "(node|agentic|claude)" | grep -v grep | awk \'{sum += $6} END {print int(sum/1024)}\'', { encoding: 'utf-8' });
|
|
339
|
+
memoryMB = parseInt(mem.trim()) || 0;
|
|
448
340
|
}
|
|
341
|
+
} catch (e) {
|
|
342
|
+
// Fallback
|
|
343
|
+
memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
449
344
|
}
|
|
450
345
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
// Test stats (count files only — NO reading file contents)
|
|
455
|
-
function getTestStats() {
|
|
456
|
-
let testFiles = 0;
|
|
346
|
+
// Get learning stats for intelligence %
|
|
347
|
+
const learning = getLearningStats();
|
|
457
348
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
} else if (entry.isFile()) {
|
|
468
|
-
const n = entry.name;
|
|
469
|
-
if (n.includes('.test.') || n.includes('.spec.') || n.includes('_test.') || n.includes('_spec.')) {
|
|
470
|
-
testFiles++;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
} catch { /* ignore */ }
|
|
349
|
+
// Intelligence % from REAL intelligence loop data (ADR-050)
|
|
350
|
+
// Composite: 40% confidence mean + 30% access ratio + 30% pattern density
|
|
351
|
+
let intelligencePct = 0;
|
|
352
|
+
if (learning.confidenceMean > 0 || (learning.patterns > 0 && learning.accessedCount > 0)) {
|
|
353
|
+
const confScore = Math.min(100, Math.floor(learning.confidenceMean * 100));
|
|
354
|
+
const accessRatio = learning.patterns > 0 ? (learning.accessedCount / learning.patterns) : 0;
|
|
355
|
+
const accessScore = Math.min(100, Math.floor(accessRatio * 100));
|
|
356
|
+
const densityScore = Math.min(100, Math.floor(learning.patterns / 5));
|
|
357
|
+
intelligencePct = Math.floor(confScore * 0.4 + accessScore * 0.3 + densityScore * 0.3);
|
|
475
358
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
countTestFiles(path.join(CWD, testDirNames[i]));
|
|
359
|
+
// Fallback: legacy pattern count
|
|
360
|
+
if (intelligencePct === 0 && learning.patterns > 0) {
|
|
361
|
+
intelligencePct = Math.min(100, Math.floor(learning.patterns / 10));
|
|
480
362
|
}
|
|
481
|
-
countTestFiles(path.join(CWD, 'src'));
|
|
482
|
-
|
|
483
|
-
return { testFiles, testCases: testFiles * 4 };
|
|
484
|
-
}
|
|
485
363
|
|
|
486
|
-
//
|
|
487
|
-
|
|
488
|
-
const mcpServers = { total: 0, enabled: 0 };
|
|
489
|
-
const settings = getSettings();
|
|
490
|
-
|
|
491
|
-
if (settings && settings.mcpServers && typeof settings.mcpServers === 'object') {
|
|
492
|
-
const servers = Object.keys(settings.mcpServers);
|
|
493
|
-
mcpServers.total = servers.length;
|
|
494
|
-
mcpServers.enabled = settings.enabledMcpjsonServers
|
|
495
|
-
? settings.enabledMcpjsonServers.filter(s => servers.includes(s)).length
|
|
496
|
-
: servers.length;
|
|
497
|
-
}
|
|
364
|
+
// Context % based on session history
|
|
365
|
+
const contextPct = Math.min(100, Math.floor(learning.sessions * 5));
|
|
498
366
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
367
|
+
// Count active sub-agents from process list
|
|
368
|
+
try {
|
|
369
|
+
if (isWindows) {
|
|
370
|
+
// Windows: use tasklist and findstr for agent counting
|
|
371
|
+
const agents = execSync('tasklist 2>NUL | findstr /I "claude-flow" 2>NUL | find /C /V "" 2>NUL || echo 0', { encoding: 'utf-8' });
|
|
372
|
+
subAgents = Math.max(0, parseInt(agents.trim()) || 0);
|
|
373
|
+
} else {
|
|
374
|
+
const agents = execSync('ps aux 2>/dev/null | grep -c "claude-flow.*agent" || echo "0"', { encoding: 'utf-8' });
|
|
375
|
+
subAgents = Math.max(0, parseInt(agents.trim()) - 1);
|
|
506
376
|
}
|
|
377
|
+
} catch (e) {
|
|
378
|
+
// Ignore - default to 0
|
|
507
379
|
}
|
|
508
380
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Session stats (pure file reads)
|
|
517
|
-
function getSessionStats() {
|
|
518
|
-
var sessionPaths = ['.claude-flow/session.json', '.claude/session.json'];
|
|
519
|
-
for (var i = 0; i < sessionPaths.length; i++) {
|
|
520
|
-
const data = readJSON(path.join(CWD, sessionPaths[i]));
|
|
521
|
-
if (data && data.startTime) {
|
|
522
|
-
const diffMs = Date.now() - new Date(data.startTime).getTime();
|
|
523
|
-
const mins = Math.floor(diffMs / 60000);
|
|
524
|
-
const duration = mins < 60 ? mins + 'm' : Math.floor(mins / 60) + 'h' + (mins % 60) + 'm';
|
|
525
|
-
return { duration: duration };
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
return { duration: '' };
|
|
381
|
+
return {
|
|
382
|
+
memoryMB,
|
|
383
|
+
contextPct,
|
|
384
|
+
intelligencePct,
|
|
385
|
+
subAgents,
|
|
386
|
+
};
|
|
529
387
|
}
|
|
530
388
|
|
|
531
|
-
//
|
|
532
|
-
|
|
389
|
+
// Generate progress bar
|
|
533
390
|
function progressBar(current, total) {
|
|
534
391
|
const width = 5;
|
|
535
392
|
const filled = Math.round((current / total) * width);
|
|
536
|
-
|
|
393
|
+
const empty = width - filled;
|
|
394
|
+
return '[' + '\u25CF'.repeat(filled) + '\u25CB'.repeat(empty) + ']';
|
|
537
395
|
}
|
|
538
396
|
|
|
397
|
+
// Generate full statusline
|
|
539
398
|
function generateStatusline() {
|
|
540
|
-
const
|
|
541
|
-
// Prefer model name from Claude Code stdin data, fallback to file-based detection
|
|
542
|
-
const modelName = getModelFromStdin() || getModelName();
|
|
543
|
-
const ctxInfo = getContextFromStdin();
|
|
544
|
-
const costInfo = getCostFromStdin();
|
|
399
|
+
const user = getUserInfo();
|
|
545
400
|
const progress = getV3Progress();
|
|
546
401
|
const security = getSecurityStatus();
|
|
547
402
|
const swarm = getSwarmStatus();
|
|
548
403
|
const system = getSystemMetrics();
|
|
549
|
-
const adrs = getADRStatus();
|
|
550
|
-
const hooks = getHooksStatus();
|
|
551
|
-
const agentdb = getAgentDBStats();
|
|
552
|
-
const tests = getTestStats();
|
|
553
|
-
const session = getSessionStats();
|
|
554
|
-
const integration = getIntegrationStatus();
|
|
555
404
|
const lines = [];
|
|
556
405
|
|
|
557
|
-
// Header
|
|
558
|
-
let header = c.bold
|
|
559
|
-
header +=
|
|
560
|
-
if (
|
|
561
|
-
header +=
|
|
562
|
-
const changes = git.modified + git.staged + git.untracked;
|
|
563
|
-
if (changes > 0) {
|
|
564
|
-
let ind = '';
|
|
565
|
-
if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;
|
|
566
|
-
if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;
|
|
567
|
-
if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;
|
|
568
|
-
header += ' ' + ind;
|
|
569
|
-
}
|
|
570
|
-
if (git.ahead > 0) header += ' ' + c.brightGreen + '\u2191' + git.ahead + c.reset;
|
|
571
|
-
if (git.behind > 0) header += ' ' + c.brightRed + '\u2193' + git.behind + c.reset;
|
|
572
|
-
}
|
|
573
|
-
header += ' ' + c.dim + '\u2502' + c.reset + ' ' + c.purple + modelName + c.reset;
|
|
574
|
-
// Show session duration from Claude Code stdin if available, else from local files
|
|
575
|
-
const duration = costInfo ? costInfo.duration : session.duration;
|
|
576
|
-
if (duration) header += ' ' + c.dim + '\u2502' + c.reset + ' ' + c.cyan + '\u23F1 ' + duration + c.reset;
|
|
577
|
-
// Show context usage from Claude Code stdin if available
|
|
578
|
-
if (ctxInfo && ctxInfo.usedPct > 0) {
|
|
579
|
-
const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
|
|
580
|
-
header += ' ' + c.dim + '\u2502' + c.reset + ' ' + ctxColor + '\u25CF ' + ctxInfo.usedPct + '% ctx' + c.reset;
|
|
581
|
-
}
|
|
582
|
-
// Show cost from Claude Code stdin if available
|
|
583
|
-
if (costInfo && costInfo.costUsd > 0) {
|
|
584
|
-
header += ' ' + c.dim + '\u2502' + c.reset + ' ' + c.brightYellow + '$' + costInfo.costUsd.toFixed(2) + c.reset;
|
|
406
|
+
// Header Line
|
|
407
|
+
let header = `${c.bold}${c.brightPurple}▊ Claude Flow V3 ${c.reset}`;
|
|
408
|
+
header += `${swarm.coordinationActive ? c.brightCyan : c.dim}● ${c.brightCyan}${user.name}${c.reset}`;
|
|
409
|
+
if (user.gitBranch) {
|
|
410
|
+
header += ` ${c.dim}│${c.reset} ${c.brightBlue}⎇ ${user.gitBranch}${c.reset}`;
|
|
585
411
|
}
|
|
412
|
+
header += ` ${c.dim}│${c.reset} ${c.purple}${user.modelName}${c.reset}`;
|
|
586
413
|
lines.push(header);
|
|
587
414
|
|
|
588
415
|
// Separator
|
|
589
|
-
lines.push(c.dim
|
|
416
|
+
lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);
|
|
590
417
|
|
|
591
|
-
// Line 1: DDD
|
|
418
|
+
// Line 1: DDD Domain Progress
|
|
592
419
|
const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
|
|
593
|
-
let perfIndicator;
|
|
594
|
-
if (agentdb.hasHnsw && agentdb.vectorCount > 0) {
|
|
595
|
-
const speedup = agentdb.vectorCount > 10000 ? '12500x' : agentdb.vectorCount > 1000 ? '150x' : '10x';
|
|
596
|
-
perfIndicator = c.brightGreen + '\u26A1 HNSW ' + speedup + c.reset;
|
|
597
|
-
} else if (progress.patternsLearned > 0) {
|
|
598
|
-
const pk = progress.patternsLearned >= 1000 ? (progress.patternsLearned / 1000).toFixed(1) + 'k' : String(progress.patternsLearned);
|
|
599
|
-
perfIndicator = c.brightYellow + '\uD83D\uDCDA ' + pk + ' patterns' + c.reset;
|
|
600
|
-
} else {
|
|
601
|
-
perfIndicator = c.dim + '\u26A1 target: 150x-12500x' + c.reset;
|
|
602
|
-
}
|
|
603
420
|
lines.push(
|
|
604
|
-
c.brightCyan
|
|
605
|
-
domainsColor
|
|
421
|
+
`${c.brightCyan}🏗️ DDD Domains${c.reset} ${progressBar(progress.domainsCompleted, progress.totalDomains)} ` +
|
|
422
|
+
`${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset} ` +
|
|
423
|
+
`${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
|
|
606
424
|
);
|
|
607
425
|
|
|
608
|
-
// Line 2: Swarm +
|
|
609
|
-
const
|
|
426
|
+
// Line 2: Swarm + CVE + Memory + Context + Intelligence
|
|
427
|
+
const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
|
|
610
428
|
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;
|
|
614
|
-
const intellColor = system.intelligencePct >= 80 ? c.brightGreen : system.intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
429
|
+
let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
|
|
430
|
+
let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;
|
|
615
431
|
|
|
616
432
|
lines.push(
|
|
617
|
-
c.brightYellow
|
|
618
|
-
c.brightPurple
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
c.
|
|
622
|
-
|
|
433
|
+
`${c.brightYellow}🤖 Swarm${c.reset} ${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}] ` +
|
|
434
|
+
`${c.brightPurple}👥 ${system.subAgents}${c.reset} ` +
|
|
435
|
+
`${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset} ` +
|
|
436
|
+
`${c.brightCyan}💾 ${system.memoryMB}MB${c.reset} ` +
|
|
437
|
+
`${c.brightGreen}📂 ${String(system.contextPct).padStart(3)}%${c.reset} ` +
|
|
438
|
+
`${c.dim}🧠 ${String(system.intelligencePct).padStart(3)}%${c.reset}`
|
|
623
439
|
);
|
|
624
440
|
|
|
625
|
-
// Line 3: Architecture
|
|
441
|
+
// Line 3: Architecture status
|
|
626
442
|
const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
|
|
627
|
-
const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;
|
|
628
|
-
const adrDisplay = adrs.compliance > 0 ? adrColor + '\u25CF' + adrs.compliance + '%' + c.reset : adrColor + '\u25CF' + adrs.implemented + '/' + adrs.count + c.reset;
|
|
629
|
-
|
|
630
443
|
lines.push(
|
|
631
|
-
c.brightPurple
|
|
632
|
-
c.cyan
|
|
633
|
-
c.cyan
|
|
634
|
-
c.cyan
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
// Line 4: AgentDB, Tests, Integration
|
|
638
|
-
const hnswInd = agentdb.hasHnsw ? c.brightGreen + '\u26A1' + c.reset : '';
|
|
639
|
-
const sizeDisp = agentdb.dbSizeKB >= 1024 ? (agentdb.dbSizeKB / 1024).toFixed(1) + 'MB' : agentdb.dbSizeKB + 'KB';
|
|
640
|
-
const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
|
|
641
|
-
const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;
|
|
642
|
-
|
|
643
|
-
let integStr = '';
|
|
644
|
-
if (integration.mcpServers.total > 0) {
|
|
645
|
-
const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
|
|
646
|
-
integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
647
|
-
integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '\u25CF' + integration.mcpServers.enabled + '/' + integration.mcpServers.total + c.reset;
|
|
648
|
-
}
|
|
649
|
-
if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '\u25C6' + c.reset + 'DB';
|
|
650
|
-
if (integration.hasApi) integStr += (integStr ? ' ' : '') + c.brightGreen + '\u25C6' + c.reset + 'API';
|
|
651
|
-
if (!integStr) integStr = c.dim + '\u25CF none' + c.reset;
|
|
652
|
-
|
|
653
|
-
lines.push(
|
|
654
|
-
c.brightCyan + '\uD83D\uDCCA AgentDB' + c.reset + ' ' +
|
|
655
|
-
c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '\u25CF' + agentdb.vectorCount + hnswInd + c.reset + ' ' + c.dim + '\u2502' + c.reset + ' ' +
|
|
656
|
-
c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '\u2502' + c.reset + ' ' +
|
|
657
|
-
c.cyan + 'Tests' + c.reset + ' ' + testColor + '\u25CF' + tests.testFiles + c.reset + ' ' + c.dim + '(~' + tests.testCases + ' cases)' + c.reset + ' ' + c.dim + '\u2502' + c.reset + ' ' +
|
|
658
|
-
integStr
|
|
444
|
+
`${c.brightPurple}🔧 Architecture${c.reset} ` +
|
|
445
|
+
`${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset} ${c.dim}│${c.reset} ` +
|
|
446
|
+
`${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset} ${c.dim}│${c.reset} ` +
|
|
447
|
+
`${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset} ${c.dim}│${c.reset} ` +
|
|
448
|
+
`${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
|
|
659
449
|
);
|
|
660
450
|
|
|
661
451
|
return lines.join('\n');
|
|
662
452
|
}
|
|
663
453
|
|
|
664
|
-
// JSON
|
|
454
|
+
// Generate JSON data
|
|
665
455
|
function generateJSON() {
|
|
666
|
-
const git = getGitInfo();
|
|
667
456
|
return {
|
|
668
|
-
user:
|
|
457
|
+
user: getUserInfo(),
|
|
669
458
|
v3Progress: getV3Progress(),
|
|
670
459
|
security: getSecurityStatus(),
|
|
671
460
|
swarm: getSwarmStatus(),
|
|
672
461
|
system: getSystemMetrics(),
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
462
|
+
performance: {
|
|
463
|
+
flashAttentionTarget: '2.49x-7.47x',
|
|
464
|
+
searchImprovement: '150x-12,500x',
|
|
465
|
+
memoryReduction: '50-75%',
|
|
466
|
+
},
|
|
678
467
|
lastUpdated: new Date().toISOString(),
|
|
679
468
|
};
|
|
680
469
|
}
|
|
681
470
|
|
|
682
|
-
|
|
471
|
+
/**
|
|
472
|
+
* Generate single-line output for Claude Code compatibility
|
|
473
|
+
* This avoids the collision zone issue entirely by using one line
|
|
474
|
+
* @see https://github.com/ruvnet/claude-flow/issues/985
|
|
475
|
+
*/
|
|
476
|
+
function generateSingleLine() {
|
|
477
|
+
if (!CONFIG.enabled) return '';
|
|
683
478
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
function getStdinData() {
|
|
690
|
-
if (_stdinData !== undefined && _stdinData !== null) return _stdinData;
|
|
691
|
-
try {
|
|
692
|
-
// Check if stdin is a TTY (manual run) — skip reading
|
|
693
|
-
if (process.stdin.isTTY) { _stdinData = null; return null; }
|
|
694
|
-
// Read stdin synchronously via fd 0
|
|
695
|
-
const chunks = [];
|
|
696
|
-
const buf = Buffer.alloc(4096);
|
|
697
|
-
let bytesRead;
|
|
698
|
-
try {
|
|
699
|
-
while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {
|
|
700
|
-
chunks.push(buf.slice(0, bytesRead));
|
|
701
|
-
}
|
|
702
|
-
} catch { /* EOF or read error */ }
|
|
703
|
-
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
704
|
-
if (raw && raw.startsWith('{')) {
|
|
705
|
-
_stdinData = JSON.parse(raw);
|
|
706
|
-
} else {
|
|
707
|
-
_stdinData = null;
|
|
708
|
-
}
|
|
709
|
-
} catch {
|
|
710
|
-
_stdinData = null;
|
|
711
|
-
}
|
|
712
|
-
return _stdinData;
|
|
713
|
-
}
|
|
479
|
+
const user = getUserInfo();
|
|
480
|
+
const progress = getV3Progress();
|
|
481
|
+
const security = getSecurityStatus();
|
|
482
|
+
const swarm = getSwarmStatus();
|
|
483
|
+
const system = getSystemMetrics();
|
|
714
484
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
if (data && data.model && data.model.display_name) return data.model.display_name;
|
|
719
|
-
return null;
|
|
720
|
-
}
|
|
485
|
+
const swarmIndicator = swarm.coordinationActive ? '●' : '○';
|
|
486
|
+
const securityStatus = security.status === 'CLEAN' ? '✓' :
|
|
487
|
+
security.cvesFixed > 0 ? '~' : '✗';
|
|
721
488
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
usedPct: Math.floor(data.context_window.used_percentage || 0),
|
|
728
|
-
remainingPct: Math.floor(data.context_window.remaining_percentage || 100),
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
return null;
|
|
489
|
+
return `${c.brightPurple}CF-V3${c.reset} ${c.dim}|${c.reset} ` +
|
|
490
|
+
`${c.cyan}D:${progress.domainsCompleted}/${progress.totalDomains}${c.reset} ${c.dim}|${c.reset} ` +
|
|
491
|
+
`${c.yellow}S:${swarmIndicator}${swarm.activeAgents}/${swarm.maxAgents}${c.reset} ${c.dim}|${c.reset} ` +
|
|
492
|
+
`${security.status === 'CLEAN' ? c.green : c.red}CVE:${securityStatus}${security.cvesFixed}/${security.totalCves}${c.reset} ${c.dim}|${c.reset} ` +
|
|
493
|
+
`${c.dim}🧠${system.intelligencePct}%${c.reset}`;
|
|
732
494
|
}
|
|
733
495
|
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
496
|
+
/**
|
|
497
|
+
* Generate safe multi-line statusline that avoids Claude Code collision zone
|
|
498
|
+
* The collision zone is columns 15-25 on the second-to-last line.
|
|
499
|
+
* We pad that line with spaces to push content past column 25.
|
|
500
|
+
* @see https://github.com/ruvnet/claude-flow/issues/985
|
|
501
|
+
*/
|
|
502
|
+
function generateSafeStatusline() {
|
|
503
|
+
if (!CONFIG.enabled) return '';
|
|
504
|
+
|
|
505
|
+
const user = getUserInfo();
|
|
506
|
+
const progress = getV3Progress();
|
|
507
|
+
const security = getSecurityStatus();
|
|
508
|
+
const swarm = getSwarmStatus();
|
|
509
|
+
const system = getSystemMetrics();
|
|
510
|
+
const lines = [];
|
|
511
|
+
|
|
512
|
+
// Header Line
|
|
513
|
+
let header = `${c.bold}${c.brightPurple}▊ Claude Flow V3 ${c.reset}`;
|
|
514
|
+
header += `${swarm.coordinationActive ? c.brightCyan : c.dim}● ${c.brightCyan}${user.name}${c.reset}`;
|
|
515
|
+
if (user.gitBranch) {
|
|
516
|
+
header += ` ${c.dim}│${c.reset} ${c.brightBlue}⎇ ${user.gitBranch}${c.reset}`;
|
|
747
517
|
}
|
|
748
|
-
|
|
518
|
+
header += ` ${c.dim}│${c.reset} ${c.purple}${user.modelName}${c.reset}`;
|
|
519
|
+
lines.push(header);
|
|
520
|
+
|
|
521
|
+
// Separator
|
|
522
|
+
lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);
|
|
523
|
+
|
|
524
|
+
// Line 1: DDD Domain Progress
|
|
525
|
+
const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
|
|
526
|
+
lines.push(
|
|
527
|
+
`${c.brightCyan}🏗️ DDD Domains${c.reset} ${progressBar(progress.domainsCompleted, progress.totalDomains)} ` +
|
|
528
|
+
`${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset} ` +
|
|
529
|
+
`${c.brightYellow}⚡ 1.0x${c.reset} ${c.dim}→${c.reset} ${c.brightYellow}2.49x-7.47x${c.reset}`
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
// Line 2 (COLLISION LINE): Swarm status with 24 spaces padding after emoji
|
|
533
|
+
// The emoji (🤖) is 2 columns. 24 spaces pushes content to column 26, past the collision zone (15-25)
|
|
534
|
+
const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
|
|
535
|
+
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
536
|
+
let securityIcon = security.status === 'CLEAN' ? '🟢' : security.status === 'IN_PROGRESS' ? '🟡' : '🔴';
|
|
537
|
+
let securityColor = security.status === 'CLEAN' ? c.brightGreen : security.status === 'IN_PROGRESS' ? c.brightYellow : c.brightRed;
|
|
538
|
+
|
|
539
|
+
// CRITICAL: 24 spaces after 🤖 (emoji is 2 cols, so 2+24=26, past collision zone cols 15-25)
|
|
540
|
+
lines.push(
|
|
541
|
+
`${c.brightYellow}🤖${c.reset} ` + // 24 spaces padding
|
|
542
|
+
`${swarmIndicator} [${agentsColor}${String(swarm.activeAgents).padStart(2)}${c.reset}/${c.brightWhite}${swarm.maxAgents}${c.reset}] ` +
|
|
543
|
+
`${c.brightPurple}👥 ${system.subAgents}${c.reset} ` +
|
|
544
|
+
`${securityIcon} ${securityColor}CVE ${security.cvesFixed}${c.reset}/${c.brightWhite}${security.totalCves}${c.reset} ` +
|
|
545
|
+
`${c.brightCyan}💾 ${system.memoryMB}MB${c.reset} ` +
|
|
546
|
+
`${c.dim}🧠 ${system.intelligencePct}%${c.reset}`
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
// Line 3: Architecture status (this is the last line, not in collision zone)
|
|
550
|
+
const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
|
|
551
|
+
lines.push(
|
|
552
|
+
`${c.brightPurple}🔧 Architecture${c.reset} ` +
|
|
553
|
+
`${c.cyan}DDD${c.reset} ${dddColor}●${String(progress.dddProgress).padStart(3)}%${c.reset} ${c.dim}│${c.reset} ` +
|
|
554
|
+
`${c.cyan}Security${c.reset} ${securityColor}●${security.status}${c.reset} ${c.dim}│${c.reset} ` +
|
|
555
|
+
`${c.cyan}Memory${c.reset} ${c.brightGreen}●AgentDB${c.reset} ${c.dim}│${c.reset} ` +
|
|
556
|
+
`${c.cyan}Integration${c.reset} ${swarm.coordinationActive ? c.brightCyan : c.dim}●${c.reset}`
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
return lines.join('\n');
|
|
749
560
|
}
|
|
750
561
|
|
|
751
|
-
//
|
|
562
|
+
// Main
|
|
752
563
|
if (process.argv.includes('--json')) {
|
|
753
564
|
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
754
565
|
} else if (process.argv.includes('--compact')) {
|
|
755
566
|
console.log(JSON.stringify(generateJSON()));
|
|
756
|
-
} else {
|
|
567
|
+
} else if (process.argv.includes('--single')) {
|
|
568
|
+
// Single-line mode - completely avoids collision zone
|
|
569
|
+
console.log(generateSingleLine());
|
|
570
|
+
} else if (process.argv.includes('--unsafe') || process.argv.includes('--legacy')) {
|
|
571
|
+
// Legacy mode - original multi-line without collision avoidance
|
|
757
572
|
console.log(generateStatusline());
|
|
573
|
+
} else {
|
|
574
|
+
// Default: Safe multi-line mode with collision zone avoidance
|
|
575
|
+
// Use --unsafe or --legacy to get the original behavior
|
|
576
|
+
console.log(generateSafeStatusline());
|
|
758
577
|
}
|