@claude-flow/cli 3.10.35 → 3.10.37
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/analysis/analyze-code-quality.md +178 -178
- package/.claude/agents/analysis/code-analyzer.md +209 -209
- package/.claude/agents/analysis/code-review/analyze-code-quality.md +178 -178
- package/.claude/agents/architecture/arch-system-design.md +156 -156
- package/.claude/agents/architecture/system-design/arch-system-design.md +154 -154
- package/.claude/agents/browser/browser-agent.yaml +182 -182
- package/.claude/agents/consensus/byzantine-coordinator.md +62 -62
- package/.claude/agents/consensus/crdt-synchronizer.md +996 -996
- package/.claude/agents/consensus/gossip-coordinator.md +62 -62
- package/.claude/agents/consensus/performance-benchmarker.md +850 -850
- package/.claude/agents/consensus/quorum-manager.md +822 -822
- package/.claude/agents/consensus/raft-manager.md +62 -62
- package/.claude/agents/consensus/security-manager.md +621 -621
- package/.claude/agents/core/planner.md +374 -374
- package/.claude/agents/custom/test-long-runner.md +44 -44
- package/.claude/agents/data/data-ml-model.md +444 -444
- package/.claude/agents/data/ml/data-ml-model.md +192 -192
- package/.claude/agents/development/backend/dev-backend-api.md +141 -141
- package/.claude/agents/development/dev-backend-api.md +344 -344
- package/.claude/agents/devops/ci-cd/ops-cicd-github.md +163 -163
- package/.claude/agents/devops/ops-cicd-github.md +164 -164
- package/.claude/agents/documentation/api-docs/docs-api-openapi.md +173 -173
- package/.claude/agents/documentation/docs-api-openapi.md +354 -354
- package/.claude/agents/flow-nexus/app-store.md +87 -87
- package/.claude/agents/flow-nexus/authentication.md +68 -68
- package/.claude/agents/flow-nexus/challenges.md +80 -80
- package/.claude/agents/flow-nexus/neural-network.md +87 -87
- package/.claude/agents/flow-nexus/payments.md +82 -82
- package/.claude/agents/flow-nexus/sandbox.md +75 -75
- package/.claude/agents/flow-nexus/swarm.md +75 -75
- package/.claude/agents/flow-nexus/user-tools.md +95 -95
- package/.claude/agents/flow-nexus/workflow.md +83 -83
- package/.claude/agents/github/code-review-swarm.md +377 -377
- package/.claude/agents/github/github-modes.md +172 -172
- package/.claude/agents/github/issue-tracker.md +575 -575
- package/.claude/agents/github/multi-repo-swarm.md +552 -552
- package/.claude/agents/github/pr-manager.md +437 -437
- package/.claude/agents/github/project-board-sync.md +508 -508
- package/.claude/agents/github/release-manager.md +604 -604
- package/.claude/agents/github/release-swarm.md +582 -582
- package/.claude/agents/github/repo-architect.md +397 -397
- package/.claude/agents/github/swarm-issue.md +572 -572
- package/.claude/agents/github/swarm-pr.md +427 -427
- package/.claude/agents/github/sync-coordinator.md +451 -451
- package/.claude/agents/github/workflow-automation.md +902 -902
- package/.claude/agents/goal/agent.md +815 -815
- package/.claude/agents/optimization/benchmark-suite.md +664 -664
- package/.claude/agents/optimization/load-balancer.md +430 -430
- package/.claude/agents/optimization/performance-monitor.md +671 -671
- package/.claude/agents/optimization/resource-allocator.md +673 -673
- package/.claude/agents/optimization/topology-optimizer.md +807 -807
- package/.claude/agents/payments/agentic-payments.md +126 -126
- package/.claude/agents/sona/sona-learning-optimizer.md +74 -74
- package/.claude/agents/sparc/architecture.md +698 -698
- package/.claude/agents/sparc/pseudocode.md +519 -519
- package/.claude/agents/sparc/refinement.md +801 -801
- package/.claude/agents/sparc/specification.md +477 -477
- package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +224 -224
- package/.claude/agents/specialized/spec-mobile-react-native.md +226 -226
- package/.claude/agents/sublinear/consensus-coordinator.md +337 -337
- package/.claude/agents/sublinear/matrix-optimizer.md +184 -184
- package/.claude/agents/sublinear/pagerank-analyzer.md +298 -298
- package/.claude/agents/sublinear/performance-optimizer.md +367 -367
- package/.claude/agents/sublinear/trading-predictor.md +245 -245
- package/.claude/agents/swarm/adaptive-coordinator.md +1126 -1126
- package/.claude/agents/swarm/hierarchical-coordinator.md +709 -709
- package/.claude/agents/swarm/mesh-coordinator.md +962 -962
- package/.claude/agents/templates/automation-smart-agent.md +204 -204
- package/.claude/agents/templates/base-template-generator.md +289 -289
- package/.claude/agents/templates/coordinator-swarm-init.md +89 -89
- package/.claude/agents/templates/github-pr-manager.md +176 -176
- package/.claude/agents/templates/implementer-sparc-coder.md +258 -258
- package/.claude/agents/templates/memory-coordinator.md +186 -186
- package/.claude/agents/templates/orchestrator-task.md +138 -138
- package/.claude/agents/templates/performance-analyzer.md +198 -198
- package/.claude/agents/templates/sparc-coordinator.md +513 -513
- package/.claude/agents/testing/production-validator.md +394 -394
- package/.claude/agents/testing/tdd-london-swarm.md +243 -243
- package/.claude/agents/v3/aidefence-guardian.md +282 -282
- package/.claude/agents/v3/claims-authorizer.md +208 -208
- package/.claude/agents/v3/collective-intelligence-coordinator.md +993 -993
- package/.claude/agents/v3/ddd-domain-expert.md +220 -220
- package/.claude/agents/v3/injection-analyst.md +236 -236
- package/.claude/agents/v3/performance-engineer.md +1233 -1233
- package/.claude/agents/v3/pii-detector.md +151 -151
- package/.claude/agents/v3/reasoningbank-learner.md +213 -213
- package/.claude/agents/v3/security-architect-aidefence.md +410 -410
- package/.claude/agents/v3/security-architect.md +867 -867
- package/.claude/agents/v3/swarm-memory-manager.md +157 -157
- package/.claude/agents/v3/v3-integration-architect.md +205 -205
- package/.claude/commands/agents/README.md +50 -50
- package/.claude/commands/agents/agent-capabilities.md +140 -140
- package/.claude/commands/agents/agent-coordination.md +28 -28
- package/.claude/commands/agents/agent-spawning.md +28 -28
- package/.claude/commands/agents/agent-types.md +216 -216
- package/.claude/commands/agents/health.md +139 -139
- package/.claude/commands/agents/list.md +100 -100
- package/.claude/commands/agents/logs.md +130 -130
- package/.claude/commands/agents/metrics.md +122 -122
- package/.claude/commands/agents/pool.md +127 -127
- package/.claude/commands/agents/spawn.md +140 -140
- package/.claude/commands/agents/status.md +115 -115
- package/.claude/commands/agents/stop.md +102 -102
- package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +53 -53
- package/.claude/commands/analysis/README.md +9 -9
- package/.claude/commands/analysis/bottleneck-detect.md +162 -162
- package/.claude/commands/analysis/performance-bottlenecks.md +58 -58
- package/.claude/commands/analysis/performance-report.md +25 -25
- package/.claude/commands/analysis/token-efficiency.md +44 -44
- package/.claude/commands/analysis/token-usage.md +25 -25
- package/.claude/commands/automation/README.md +9 -9
- package/.claude/commands/automation/auto-agent.md +122 -122
- package/.claude/commands/automation/self-healing.md +105 -105
- package/.claude/commands/automation/session-memory.md +89 -89
- package/.claude/commands/automation/smart-agents.md +72 -72
- package/.claude/commands/automation/smart-spawn.md +25 -25
- package/.claude/commands/automation/workflow-select.md +25 -25
- package/.claude/commands/claude-flow-help.md +103 -103
- package/.claude/commands/claude-flow-memory.md +107 -107
- package/.claude/commands/claude-flow-swarm.md +205 -205
- package/.claude/commands/coordination/README.md +9 -9
- package/.claude/commands/coordination/agent-spawn.md +25 -25
- package/.claude/commands/coordination/init.md +44 -44
- package/.claude/commands/coordination/orchestrate.md +43 -43
- package/.claude/commands/coordination/spawn.md +45 -45
- package/.claude/commands/coordination/swarm-init.md +85 -85
- package/.claude/commands/coordination/task-orchestrate.md +25 -25
- package/.claude/commands/github/README.md +11 -11
- package/.claude/commands/github/code-review-swarm.md +513 -513
- package/.claude/commands/github/code-review.md +25 -25
- package/.claude/commands/github/github-modes.md +146 -146
- package/.claude/commands/github/github-swarm.md +121 -121
- package/.claude/commands/github/issue-tracker.md +291 -291
- package/.claude/commands/github/issue-triage.md +25 -25
- package/.claude/commands/github/multi-repo-swarm.md +518 -518
- package/.claude/commands/github/pr-enhance.md +26 -26
- package/.claude/commands/github/pr-manager.md +169 -169
- package/.claude/commands/github/project-board-sync.md +470 -470
- package/.claude/commands/github/release-manager.md +339 -339
- package/.claude/commands/github/release-swarm.md +543 -543
- package/.claude/commands/github/repo-analyze.md +25 -25
- package/.claude/commands/github/repo-architect.md +366 -366
- package/.claude/commands/github/swarm-issue.md +484 -484
- package/.claude/commands/github/swarm-pr.md +287 -287
- package/.claude/commands/github/sync-coordinator.md +302 -302
- package/.claude/commands/github/workflow-automation.md +441 -441
- package/.claude/commands/hive-mind/README.md +17 -17
- package/.claude/commands/hive-mind/hive-mind-consensus.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-init.md +18 -18
- package/.claude/commands/hive-mind/hive-mind-memory.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-metrics.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-resume.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-sessions.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-spawn.md +21 -21
- package/.claude/commands/hive-mind/hive-mind-status.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-stop.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-wizard.md +8 -8
- package/.claude/commands/hive-mind/hive-mind.md +27 -27
- package/.claude/commands/hooks/README.md +11 -11
- package/.claude/commands/hooks/overview.md +57 -57
- package/.claude/commands/hooks/post-edit.md +117 -117
- package/.claude/commands/hooks/post-task.md +112 -112
- package/.claude/commands/hooks/pre-edit.md +113 -113
- package/.claude/commands/hooks/pre-task.md +111 -111
- package/.claude/commands/hooks/session-end.md +118 -118
- package/.claude/commands/hooks/setup.md +102 -102
- package/.claude/commands/memory/README.md +9 -9
- package/.claude/commands/memory/memory-persist.md +25 -25
- package/.claude/commands/memory/memory-search.md +25 -25
- package/.claude/commands/memory/memory-usage.md +25 -25
- package/.claude/commands/memory/neural.md +47 -47
- package/.claude/commands/monitoring/README.md +9 -9
- package/.claude/commands/monitoring/agent-metrics.md +25 -25
- package/.claude/commands/monitoring/agents.md +44 -44
- package/.claude/commands/monitoring/real-time-view.md +25 -25
- package/.claude/commands/monitoring/status.md +46 -46
- package/.claude/commands/monitoring/swarm-monitor.md +25 -25
- package/.claude/commands/optimization/README.md +9 -9
- package/.claude/commands/optimization/auto-topology.md +61 -61
- package/.claude/commands/optimization/cache-manage.md +25 -25
- package/.claude/commands/optimization/parallel-execute.md +25 -25
- package/.claude/commands/optimization/parallel-execution.md +49 -49
- package/.claude/commands/optimization/topology-optimize.md +25 -25
- package/.claude/commands/pair/README.md +260 -260
- package/.claude/commands/pair/commands.md +545 -545
- package/.claude/commands/pair/config.md +509 -509
- package/.claude/commands/pair/examples.md +511 -511
- package/.claude/commands/pair/modes.md +347 -347
- package/.claude/commands/pair/session.md +406 -406
- package/.claude/commands/pair/start.md +208 -208
- package/.claude/commands/sparc/analyzer.md +51 -51
- package/.claude/commands/sparc/architect.md +53 -53
- package/.claude/commands/sparc/ask.md +97 -97
- package/.claude/commands/sparc/batch-executor.md +54 -54
- package/.claude/commands/sparc/code.md +89 -89
- package/.claude/commands/sparc/coder.md +54 -54
- package/.claude/commands/sparc/debug.md +83 -83
- package/.claude/commands/sparc/debugger.md +54 -54
- package/.claude/commands/sparc/designer.md +53 -53
- package/.claude/commands/sparc/devops.md +109 -109
- package/.claude/commands/sparc/docs-writer.md +80 -80
- package/.claude/commands/sparc/documenter.md +54 -54
- package/.claude/commands/sparc/innovator.md +54 -54
- package/.claude/commands/sparc/integration.md +83 -83
- package/.claude/commands/sparc/mcp.md +117 -117
- package/.claude/commands/sparc/memory-manager.md +54 -54
- package/.claude/commands/sparc/optimizer.md +54 -54
- package/.claude/commands/sparc/orchestrator.md +131 -131
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +83 -83
- package/.claude/commands/sparc/refinement-optimization-mode.md +83 -83
- package/.claude/commands/sparc/researcher.md +54 -54
- package/.claude/commands/sparc/reviewer.md +54 -54
- package/.claude/commands/sparc/security-review.md +80 -80
- package/.claude/commands/sparc/sparc-modes.md +174 -174
- package/.claude/commands/sparc/sparc.md +111 -111
- package/.claude/commands/sparc/spec-pseudocode.md +80 -80
- package/.claude/commands/sparc/supabase-admin.md +348 -348
- package/.claude/commands/sparc/swarm-coordinator.md +54 -54
- package/.claude/commands/sparc/tdd.md +54 -54
- package/.claude/commands/sparc/tester.md +54 -54
- package/.claude/commands/sparc/tutorial.md +79 -79
- package/.claude/commands/sparc/workflow-manager.md +54 -54
- package/.claude/commands/sparc.md +166 -166
- package/.claude/commands/stream-chain/pipeline.md +120 -120
- package/.claude/commands/stream-chain/run.md +69 -69
- package/.claude/commands/swarm/README.md +15 -15
- package/.claude/commands/swarm/analysis.md +95 -95
- package/.claude/commands/swarm/development.md +96 -96
- package/.claude/commands/swarm/examples.md +168 -168
- package/.claude/commands/swarm/maintenance.md +102 -102
- package/.claude/commands/swarm/optimization.md +117 -117
- package/.claude/commands/swarm/research.md +136 -136
- package/.claude/commands/swarm/swarm-analysis.md +8 -8
- package/.claude/commands/swarm/swarm-background.md +8 -8
- package/.claude/commands/swarm/swarm-init.md +19 -19
- package/.claude/commands/swarm/swarm-modes.md +8 -8
- package/.claude/commands/swarm/swarm-monitor.md +8 -8
- package/.claude/commands/swarm/swarm-spawn.md +19 -19
- package/.claude/commands/swarm/swarm-status.md +8 -8
- package/.claude/commands/swarm/swarm-strategies.md +8 -8
- package/.claude/commands/swarm/swarm.md +87 -87
- package/.claude/commands/swarm/testing.md +131 -131
- package/.claude/commands/training/README.md +9 -9
- package/.claude/commands/training/model-update.md +25 -25
- package/.claude/commands/training/neural-patterns.md +107 -107
- package/.claude/commands/training/neural-train.md +75 -75
- package/.claude/commands/training/pattern-learn.md +25 -25
- package/.claude/commands/training/specialization.md +62 -62
- package/.claude/commands/truth/start.md +142 -142
- package/.claude/commands/verify/check.md +49 -49
- package/.claude/commands/verify/start.md +127 -127
- package/.claude/commands/workflows/README.md +9 -9
- package/.claude/commands/workflows/development.md +77 -77
- package/.claude/commands/workflows/research.md +62 -62
- package/.claude/commands/workflows/workflow-create.md +25 -25
- package/.claude/commands/workflows/workflow-execute.md +25 -25
- package/.claude/commands/workflows/workflow-export.md +25 -25
- package/.claude/helpers/README.md +96 -96
- package/.claude/helpers/adr-compliance.sh +186 -186
- package/.claude/helpers/auto-commit.sh +178 -178
- package/.claude/helpers/auto-memory-hook.mjs +368 -368
- package/.claude/helpers/checkpoint-manager.sh +251 -251
- package/.claude/helpers/daemon-manager.sh +252 -252
- package/.claude/helpers/ddd-tracker.sh +144 -144
- package/.claude/helpers/github-safe.js +156 -156
- package/.claude/helpers/github-setup.sh +45 -45
- package/.claude/helpers/guidance-hook.sh +13 -13
- package/.claude/helpers/guidance-hooks.sh +102 -102
- package/.claude/helpers/health-monitor.sh +108 -108
- package/.claude/helpers/hook-handler.cjs +286 -286
- package/.claude/helpers/intelligence.cjs +1031 -1031
- package/.claude/helpers/learning-hooks.sh +329 -329
- package/.claude/helpers/learning-optimizer.sh +127 -127
- package/.claude/helpers/learning-service.mjs +1144 -1144
- package/.claude/helpers/memory.js +83 -83
- package/.claude/helpers/metrics-db.mjs +488 -488
- package/.claude/helpers/pattern-consolidator.sh +86 -86
- package/.claude/helpers/perf-worker.sh +160 -160
- package/.claude/helpers/post-commit +16 -16
- package/.claude/helpers/pre-commit +26 -26
- package/.claude/helpers/quick-start.sh +19 -19
- package/.claude/helpers/router.js +105 -105
- package/.claude/helpers/security-scanner.sh +127 -127
- package/.claude/helpers/session.js +135 -135
- package/.claude/helpers/setup-mcp.sh +18 -18
- package/.claude/helpers/standard-checkpoint-hooks.sh +189 -189
- package/.claude/helpers/statusline-hook.sh +21 -21
- package/.claude/helpers/statusline.cjs +604 -604
- package/.claude/helpers/statusline.js +352 -352
- package/.claude/helpers/swarm-comms.sh +353 -353
- package/.claude/helpers/swarm-hooks.sh +761 -761
- package/.claude/helpers/swarm-monitor.sh +210 -210
- package/.claude/helpers/sync-v3-metrics.sh +245 -245
- package/.claude/helpers/update-v3-progress.sh +165 -165
- package/.claude/helpers/v3-quick-status.sh +57 -57
- package/.claude/helpers/v3.sh +110 -110
- package/.claude/helpers/validate-v3-config.sh +215 -215
- package/.claude/helpers/worker-manager.sh +170 -170
- package/.claude/settings.json +182 -182
- package/.claude/skills/agentdb-advanced/SKILL.md +550 -550
- package/.claude/skills/agentdb-learning/SKILL.md +545 -545
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +339 -339
- package/.claude/skills/agentdb-optimization/SKILL.md +509 -509
- package/.claude/skills/agentdb-vector-search/SKILL.md +339 -339
- package/.claude/skills/browser/SKILL.md +204 -204
- package/.claude/skills/dual-mode/README.md +71 -71
- package/.claude/skills/dual-mode/dual-collect.md +103 -103
- package/.claude/skills/dual-mode/dual-coordinate.md +85 -85
- package/.claude/skills/dual-mode/dual-spawn.md +81 -81
- package/.claude/skills/flow-nexus-neural/SKILL.md +727 -727
- package/.claude/skills/flow-nexus-platform/SKILL.md +1154 -1154
- package/.claude/skills/flow-nexus-swarm/SKILL.md +604 -604
- package/.claude/skills/github-code-review/SKILL.md +1125 -1125
- package/.claude/skills/github-multi-repo/SKILL.md +862 -862
- package/.claude/skills/github-project-management/SKILL.md +1262 -1262
- package/.claude/skills/github-release-management/SKILL.md +1064 -1064
- package/.claude/skills/github-workflow-automation/SKILL.md +1047 -1047
- package/.claude/skills/hooks-automation/SKILL.md +1201 -1201
- package/.claude/skills/pair-programming/SKILL.md +1202 -1202
- package/.claude/skills/reasoningbank-agentdb/SKILL.md +446 -446
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +201 -201
- package/.claude/skills/skill-builder/SKILL.md +910 -910
- package/.claude/skills/sparc-methodology/SKILL.md +1106 -1106
- package/.claude/skills/stream-chain/SKILL.md +560 -560
- package/.claude/skills/swarm-advanced/SKILL.md +970 -970
- package/.claude/skills/swarm-orchestration/SKILL.md +179 -179
- package/.claude/skills/v3-cli-modernization/SKILL.md +871 -871
- package/.claude/skills/v3-core-implementation/SKILL.md +796 -796
- package/.claude/skills/v3-ddd-architecture/SKILL.md +441 -441
- package/.claude/skills/v3-integration-deep/SKILL.md +240 -240
- package/.claude/skills/v3-mcp-optimization/SKILL.md +776 -776
- package/.claude/skills/v3-memory-unification/SKILL.md +173 -173
- package/.claude/skills/v3-performance-optimization/SKILL.md +389 -389
- package/.claude/skills/v3-security-overhaul/SKILL.md +81 -81
- package/.claude/skills/v3-swarm-coordination/SKILL.md +339 -339
- package/.claude/skills/verification-quality/SKILL.md +691 -691
- package/README.md +416 -416
- package/bin/cli.js +314 -286
- package/bin/mcp-server.js +224 -224
- package/bin/preinstall.cjs +2 -2
- package/dist/src/benchmarks/gaia-critic.js +24 -24
- package/dist/src/commands/completions.js +409 -409
- package/dist/src/commands/daemon.js +44 -44
- package/dist/src/commands/embeddings.js +29 -29
- package/dist/src/commands/embeddings.js.map +1 -1
- package/dist/src/commands/hive-mind.js +97 -97
- package/dist/src/commands/hooks.js +9 -9
- package/dist/src/commands/ruvector/backup.js +23 -23
- package/dist/src/commands/ruvector/benchmark.js +31 -31
- package/dist/src/commands/ruvector/import.js +14 -14
- package/dist/src/commands/ruvector/init.js +115 -115
- package/dist/src/commands/ruvector/migrate.js +99 -99
- package/dist/src/commands/ruvector/optimize.js +51 -51
- package/dist/src/commands/ruvector/setup.js +624 -624
- package/dist/src/commands/ruvector/status.js +38 -38
- package/dist/src/init/claudemd-generator.js +227 -227
- package/dist/src/init/executor.js +453 -453
- package/dist/src/init/helpers-generator.js +727 -727
- package/dist/src/init/statusline-generator.js +570 -570
- package/dist/src/log-filters.d.ts +21 -8
- package/dist/src/log-filters.d.ts.map +1 -1
- package/dist/src/log-filters.js +45 -8
- package/dist/src/log-filters.js.map +1 -1
- package/dist/src/mcp-tools/agentdb-tools.js +15 -15
- package/dist/src/memory/graph-edge-writer.js +18 -18
- package/dist/src/memory/memory-bridge.js +84 -84
- package/dist/src/memory/memory-initializer.js +393 -393
- package/dist/src/memory/rabitq-index.js +5 -5
- package/dist/src/runtime/headless.js +28 -28
- package/dist/src/ruvector/flash-attention.d.ts +195 -0
- package/dist/src/ruvector/flash-attention.d.ts.map +1 -0
- package/dist/src/ruvector/flash-attention.js +643 -0
- package/dist/src/ruvector/flash-attention.js.map +1 -0
- package/dist/src/ruvector/moe-router.d.ts +206 -0
- package/dist/src/ruvector/moe-router.d.ts.map +1 -0
- package/dist/src/ruvector/moe-router.js +626 -0
- package/dist/src/ruvector/moe-router.js.map +1 -0
- package/dist/src/services/event-stream.d.ts +25 -0
- package/dist/src/services/event-stream.js +27 -0
- package/dist/src/services/headless-worker-executor.js +84 -84
- package/dist/src/services/loop-worker-runner.d.ts +16 -0
- package/dist/src/services/loop-worker-runner.js +34 -0
- package/dist/src/services/runtime-capabilities.d.ts +22 -0
- package/dist/src/services/runtime-capabilities.js +45 -0
- package/dist/src/transfer/deploy-seraphine.js +23 -23
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +134 -134
- package/scripts/beir-bootstrap-significance.mjs +162 -162
- package/scripts/bench-rvagent.mjs +312 -312
- package/scripts/benchmark-codemods.mjs +127 -127
- package/scripts/benchmark-cross-repo.mjs +206 -206
- package/scripts/benchmark-pretrained-retrieval.mjs +305 -305
- package/scripts/benchmark-self-learning.mjs +241 -241
- package/scripts/benchmark-trajectory-mrr.mjs +191 -191
- package/scripts/deploy-ipfs-node.sh +153 -153
- package/scripts/grid-search-retrieval.mjs +216 -216
- package/scripts/postinstall.cjs +153 -153
- package/scripts/pretrain-from-github.mjs +358 -358
- package/scripts/publish-registry.ts +345 -345
- package/scripts/publish.sh +57 -57
- package/scripts/run-beir-bge.mjs +324 -336
- package/scripts/run-beir-hybrid.mjs +261 -263
- package/scripts/run-beir-lucene-bm25.mjs +154 -154
- package/scripts/run-beir-nfcorpus.mjs +231 -231
- package/scripts/run-beir-rrf-ablation.mjs +221 -221
- package/scripts/setup-ipfs-registry.md +366 -366
- package/dist/src/benchmarks/capability-tasks.d.ts +0 -126
- package/dist/src/benchmarks/capability-tasks.d.ts.map +0 -1
- package/dist/src/benchmarks/capability-tasks.js +0 -147
- package/dist/src/benchmarks/capability-tasks.js.map +0 -1
- package/dist/src/benchmarks/gaia-agent-contrastive.d.ts +0 -53
- package/dist/src/benchmarks/gaia-agent-contrastive.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-agent-contrastive.js +0 -177
- package/dist/src/benchmarks/gaia-agent-contrastive.js.map +0 -1
- package/dist/src/benchmarks/gaia-agent-gemini.d.ts +0 -51
- package/dist/src/benchmarks/gaia-agent-gemini.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-agent-gemini.js +0 -352
- package/dist/src/benchmarks/gaia-agent-gemini.js.map +0 -1
- package/dist/src/benchmarks/gaia-claude-p.d.ts +0 -105
- package/dist/src/benchmarks/gaia-claude-p.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-claude-p.js +0 -269
- package/dist/src/benchmarks/gaia-claude-p.js.map +0 -1
- package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts +0 -20
- package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-claude-p.smoke.js +0 -168
- package/dist/src/benchmarks/gaia-claude-p.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-codeagent-runner.py +0 -556
- package/dist/src/benchmarks/gaia-codeagent.d.ts +0 -129
- package/dist/src/benchmarks/gaia-codeagent.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-codeagent.js +0 -590
- package/dist/src/benchmarks/gaia-codeagent.js.map +0 -1
- package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts +0 -33
- package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-codeagent.smoke.js +0 -241
- package/dist/src/benchmarks/gaia-codeagent.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-dag-pilot.d.ts +0 -22
- package/dist/src/benchmarks/gaia-dag-pilot.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-dag-pilot.js +0 -158
- package/dist/src/benchmarks/gaia-dag-pilot.js.map +0 -1
- package/dist/src/benchmarks/gaia-dag.d.ts +0 -110
- package/dist/src/benchmarks/gaia-dag.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-dag.js +0 -658
- package/dist/src/benchmarks/gaia-dag.js.map +0 -1
- package/dist/src/benchmarks/gaia-dag.smoke.d.ts +0 -21
- package/dist/src/benchmarks/gaia-dag.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-dag.smoke.js +0 -290
- package/dist/src/benchmarks/gaia-dag.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts +0 -17
- package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-ensemble-pilot.js +0 -106
- package/dist/src/benchmarks/gaia-ensemble-pilot.js.map +0 -1
- package/dist/src/benchmarks/gaia-ensemble.d.ts +0 -103
- package/dist/src/benchmarks/gaia-ensemble.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-ensemble.js +0 -462
- package/dist/src/benchmarks/gaia-ensemble.js.map +0 -1
- package/dist/src/benchmarks/gaia-gemini-pilot.d.ts +0 -17
- package/dist/src/benchmarks/gaia-gemini-pilot.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-gemini-pilot.js +0 -168
- package/dist/src/benchmarks/gaia-gemini-pilot.js.map +0 -1
- package/dist/src/benchmarks/gaia-mode-router.d.ts +0 -67
- package/dist/src/benchmarks/gaia-mode-router.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-mode-router.js +0 -126
- package/dist/src/benchmarks/gaia-mode-router.js.map +0 -1
- package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts +0 -15
- package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-mode-router.smoke.js +0 -131
- package/dist/src/benchmarks/gaia-mode-router.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts +0 -24
- package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js +0 -276
- package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/image_describe.d.ts +0 -45
- package/dist/src/benchmarks/gaia-tools/image_describe.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/image_describe.js +0 -222
- package/dist/src/benchmarks/gaia-tools/image_describe.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts +0 -24
- package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js +0 -169
- package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts +0 -27
- package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/pdf_read.js +0 -226
- package/dist/src/benchmarks/gaia-tools/pdf_read.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/python_exec.d.ts +0 -31
- package/dist/src/benchmarks/gaia-tools/python_exec.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/python_exec.js +0 -94
- package/dist/src/benchmarks/gaia-tools/python_exec.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts +0 -13
- package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js +0 -98
- package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts +0 -52
- package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/visit_webpage.js +0 -304
- package/dist/src/benchmarks/gaia-tools/visit_webpage.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_browse.d.ts +0 -61
- package/dist/src/benchmarks/gaia-tools/web_browse.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_browse.js +0 -217
- package/dist/src/benchmarks/gaia-tools/web_browse.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts +0 -26
- package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js +0 -152
- package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts +0 -24
- package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_search.smoke.js +0 -311
- package/dist/src/benchmarks/gaia-tools/web_search.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts +0 -25
- package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-visit-webpage.smoke.js +0 -304
- package/dist/src/benchmarks/gaia-visit-webpage.smoke.js.map +0 -1
- package/dist/src/commands/performance-capability.d.ts +0 -30
- package/dist/src/commands/performance-capability.d.ts.map +0 -1
- package/dist/src/commands/performance-capability.js +0 -349
- package/dist/src/commands/performance-capability.js.map +0 -1
|
@@ -21,552 +21,552 @@
|
|
|
21
21
|
*/
|
|
22
22
|
export function generateStatuslineScript(options) {
|
|
23
23
|
const maxAgents = options.runtime.maxAgents;
|
|
24
|
-
return `#!/usr/bin/env node
|
|
25
|
-
/**
|
|
26
|
-
* RuFlo V3 Statusline — delegation build (#2195)
|
|
27
|
-
*
|
|
28
|
-
* Fix for ruvnet/ruflo#2195: the previous version re-implemented all data
|
|
29
|
-
* readers locally using fragile file probes that missed AgentDB patterns,
|
|
30
|
-
* the v3/docs/adr/ ADR directory, and the real vector count.
|
|
31
|
-
*
|
|
32
|
-
* This version delegates to 'npx @claude-flow/cli hooks statusline --json'
|
|
33
|
-
* as the single source of truth. That command queries AgentDB directly,
|
|
34
|
-
* counts ADRs in both directories, and reports the real intelligence pct.
|
|
35
|
-
*
|
|
36
|
-
* ADR counting falls back to local file reads so the display still works
|
|
37
|
-
* without network access (counts both v3/docs/adr/ and v3/implementation/adrs/).
|
|
38
|
-
*
|
|
39
|
-
* Cache: JSON result is cached in /tmp for 10s so rapid prompt triggers
|
|
40
|
-
* (every keystroke in some shells) don't hammer the CLI on every call.
|
|
41
|
-
*
|
|
42
|
-
* Usage: node statusline.cjs [--json] [--compact] [--dashboard]
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
46
|
-
const fs = require('fs');
|
|
47
|
-
const path = require('path');
|
|
48
|
-
const { execSync } = require('child_process');
|
|
49
|
-
const os = require('os');
|
|
50
|
-
|
|
51
|
-
// Configuration
|
|
52
|
-
const CONFIG = {
|
|
53
|
-
maxAgents: ${maxAgents},
|
|
54
|
-
// Session-cost display. Claude Code's cost.total_cost_usd is a client-side
|
|
55
|
-
// estimate that "may differ from your actual bill" and reads as misleading on
|
|
56
|
-
// subscription plans, where token usage is not billed per dollar. These let
|
|
57
|
-
// each user pick what the segment means to them without changing the default.
|
|
58
|
-
// RUFLO_STATUSLINE_COST_SYMBOL override the leading '$' (e.g. ⚡, €, 🌱);
|
|
59
|
-
// set to an empty string for the number alone.
|
|
60
|
-
// RUFLO_STATUSLINE_HIDE_COST 1/true/yes/on removes the segment entirely.
|
|
61
|
-
costSymbol: process.env.RUFLO_STATUSLINE_COST_SYMBOL ?? '$',
|
|
62
|
-
hideCost: /^(1|true|yes|on)$/i.test(process.env.RUFLO_STATUSLINE_HIDE_COST || ''),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const CWD = process.cwd();
|
|
66
|
-
|
|
67
|
-
// ─── Delegation cache ───────────────────────────────────────────
|
|
68
|
-
// Cache the CLI JSON result for 10s so rapid prompt re-renders
|
|
69
|
-
// (e.g. every keypress in some shells) don't re-invoke npx each time.
|
|
70
|
-
const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
|
|
71
|
-
const CACHE_TTL_MS = 10000;
|
|
72
|
-
|
|
73
|
-
function readCache() {
|
|
74
|
-
try {
|
|
75
|
-
if (fs.existsSync(CACHE_FILE)) {
|
|
76
|
-
const raw = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
|
|
77
|
-
if (raw && raw._ts && (Date.now() - raw._ts) < CACHE_TTL_MS) {
|
|
78
|
-
return raw.data;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} catch { /* ignore */ }
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function writeCache(data) {
|
|
86
|
-
try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ _ts: Date.now(), data }), 'utf-8'); } catch { /* ignore */ }
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Single source of truth: delegate to the CLI hooks statusline --json command.
|
|
91
|
-
* Falls back to a minimal static object on failure so the statusline still renders.
|
|
92
|
-
*
|
|
93
|
-
* Fix for ruflo#2195: the previous local readers returned 0 for AgentDB patterns
|
|
94
|
-
* (missed the .swarm/memory.db → AgentDB path), computed dddProgress wrong,
|
|
95
|
-
* and only counted ADRs in v3/implementation/adrs/ (missed v3/docs/adr/).
|
|
96
|
-
*/
|
|
97
|
-
function getStatuslineData() {
|
|
98
|
-
const cached = readCache();
|
|
99
|
-
if (cached) return cached;
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
const raw = execSync(
|
|
103
|
-
'npx --yes @claude-flow/cli@latest hooks statusline --json 2>/dev/null',
|
|
104
|
-
{ encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
|
|
105
|
-
).trim();
|
|
106
|
-
// The CLI may emit preamble lines before the JSON — find the first '{'.
|
|
107
|
-
const jsonStart = raw.indexOf('{');
|
|
108
|
-
if (jsonStart === -1) throw new Error('no JSON in CLI output');
|
|
109
|
-
const data = JSON.parse(raw.slice(jsonStart));
|
|
110
|
-
// Overlay real ADR count from both local directories (fast, no network).
|
|
111
|
-
data.adrs = getLocalADRCount();
|
|
112
|
-
writeCache(data);
|
|
113
|
-
return data;
|
|
114
|
-
} catch { /* CLI unavailable or timed out */ }
|
|
115
|
-
|
|
116
|
-
// Fallback: use local file probes only (will be less accurate, but non-zero
|
|
117
|
-
// when CLI is available and accurate when it's not).
|
|
118
|
-
return buildLocalFallback();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Count ADRs from BOTH known directories (fix for ruflo#2195: old code missed
|
|
122
|
-
// v3/docs/adr/ which holds ADR-088..ADR-137, i.e. 41 of the 128 total ADRs).
|
|
123
|
-
function getLocalADRCount() {
|
|
124
|
-
const adrDirs = [
|
|
125
|
-
path.join(CWD, 'v3', 'implementation', 'adrs'),
|
|
126
|
-
path.join(CWD, 'v3', 'docs', 'adr'),
|
|
127
|
-
path.join(CWD, 'docs', 'adrs'),
|
|
128
|
-
path.join(CWD, '.claude-flow', 'adrs'),
|
|
129
|
-
];
|
|
130
|
-
let total = 0;
|
|
131
|
-
for (const dir of adrDirs) {
|
|
132
|
-
try {
|
|
133
|
-
if (fs.existsSync(dir)) {
|
|
134
|
-
const files = fs.readdirSync(dir).filter(function(f) {
|
|
135
|
-
return f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f));
|
|
136
|
-
});
|
|
137
|
-
total += files.length;
|
|
138
|
-
}
|
|
139
|
-
} catch { /* ignore */ }
|
|
140
|
-
}
|
|
141
|
-
return { count: total, implemented: total, compliance: 0 };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Minimal local fallback when the CLI is not installed or times out.
|
|
145
|
-
// Returns a structure that matches the CLI JSON schema so the renderer works.
|
|
146
|
-
function buildLocalFallback() {
|
|
147
|
-
const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
148
|
-
const adrs = getLocalADRCount();
|
|
149
|
-
|
|
150
|
-
// Test file count (pure directory walk, no file reads)
|
|
151
|
-
let testFiles = 0;
|
|
152
|
-
function countTests(dir, depth) {
|
|
153
|
-
if ((depth || 0) > 4) return;
|
|
154
|
-
try {
|
|
155
|
-
if (!fs.existsSync(dir)) return;
|
|
156
|
-
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
157
|
-
if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules') {
|
|
158
|
-
countTests(path.join(dir, e.name), (depth || 0) + 1);
|
|
159
|
-
} else if (e.isFile() && (e.name.includes('.test.') || e.name.includes('.spec.') || e.name.startsWith('test_') || e.name.startsWith('spec_'))) {
|
|
160
|
-
testFiles++;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
} catch { /* ignore */ }
|
|
164
|
-
}
|
|
165
|
-
for (const d of ['tests', 'test', '__tests__', 'src', 'v3']) countTests(path.join(CWD, d));
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
user: { name: 'user', gitBranch: '', modelName: 'Claude Code' },
|
|
169
|
-
v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
|
|
170
|
-
security: { status: 'NONE', cvesFixed: 0, totalCves: 0 },
|
|
171
|
-
swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
|
|
172
|
-
system: { memoryMB: memMB, contextPct: 0, intelligencePct: 0, subAgents: 0 },
|
|
173
|
-
adrs,
|
|
174
|
-
hooks: { enabled: 0, total: 0 },
|
|
175
|
-
agentdb: { vectorCount: 0, dbSizeKB: 0, hasHnsw: false },
|
|
176
|
-
tests: { testFiles, testCases: testFiles * 4 },
|
|
177
|
-
lastUpdated: new Date().toISOString(),
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// ANSI colors
|
|
182
|
-
const c = {
|
|
183
|
-
reset: '\\x1b[0m',
|
|
184
|
-
bold: '\\x1b[1m',
|
|
185
|
-
dim: '\\x1b[2m',
|
|
186
|
-
red: '\\x1b[0;31m',
|
|
187
|
-
green: '\\x1b[0;32m',
|
|
188
|
-
yellow: '\\x1b[0;33m',
|
|
189
|
-
blue: '\\x1b[0;34m',
|
|
190
|
-
purple: '\\x1b[0;35m',
|
|
191
|
-
cyan: '\\x1b[0;36m',
|
|
192
|
-
brightRed: '\\x1b[1;31m',
|
|
193
|
-
brightGreen: '\\x1b[1;32m',
|
|
194
|
-
brightYellow: '\\x1b[1;33m',
|
|
195
|
-
brightBlue: '\\x1b[1;34m',
|
|
196
|
-
brightPurple: '\\x1b[1;35m',
|
|
197
|
-
brightCyan: '\\x1b[1;36m',
|
|
198
|
-
brightWhite: '\\x1b[1;37m',
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
// Safe execSync with strict timeout (returns empty string on failure)
|
|
202
|
-
function safeExec(cmd, timeoutMs) {
|
|
203
|
-
try {
|
|
204
|
-
return execSync(cmd, {
|
|
205
|
-
encoding: 'utf-8',
|
|
206
|
-
timeout: timeoutMs || 2000,
|
|
207
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
208
|
-
}).trim();
|
|
209
|
-
} catch {
|
|
210
|
-
return '';
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Safe JSON file reader (returns null on failure)
|
|
215
|
-
function readJSON(filePath) {
|
|
216
|
-
try {
|
|
217
|
-
if (fs.existsSync(filePath)) {
|
|
218
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
219
|
-
}
|
|
220
|
-
} catch { /* ignore */ }
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// ─── Git info (pure-Node / single exec — needed for branch display) ──────────
|
|
225
|
-
|
|
226
|
-
function getGitInfo() {
|
|
227
|
-
const result = {
|
|
228
|
-
name: 'user', gitBranch: '', modified: 0, untracked: 0,
|
|
229
|
-
staged: 0, ahead: 0, behind: 0,
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
const script = [
|
|
233
|
-
'git config user.name 2>/dev/null || echo user',
|
|
234
|
-
'echo "---SEP---"',
|
|
235
|
-
'git branch --show-current 2>/dev/null',
|
|
236
|
-
'echo "---SEP---"',
|
|
237
|
-
'git status --porcelain 2>/dev/null',
|
|
238
|
-
'echo "---SEP---"',
|
|
239
|
-
'git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo "0 0"',
|
|
240
|
-
].join('; ');
|
|
241
|
-
|
|
242
|
-
const raw = safeExec("sh -c '" + script + "'", 3000);
|
|
243
|
-
if (!raw) return result;
|
|
244
|
-
|
|
245
|
-
const parts = raw.split('---SEP---').map(function(s) { return s.trim(); });
|
|
246
|
-
if (parts.length >= 4) {
|
|
247
|
-
result.name = parts[0] || 'user';
|
|
248
|
-
result.gitBranch = parts[1] || '';
|
|
249
|
-
|
|
250
|
-
if (parts[2]) {
|
|
251
|
-
for (const line of parts[2].split('\\n')) {
|
|
252
|
-
if (!line || line.length < 2) continue;
|
|
253
|
-
const x = line[0], y = line[1];
|
|
254
|
-
if (x === '?' && y === '?') { result.untracked++; continue; }
|
|
255
|
-
if (x !== ' ' && x !== '?') result.staged++;
|
|
256
|
-
if (y !== ' ' && y !== '?') result.modified++;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const ab = (parts[3] || '0 0').split(/\\s+/);
|
|
261
|
-
result.ahead = parseInt(ab[0]) || 0;
|
|
262
|
-
result.behind = parseInt(ab[1]) || 0;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return result;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Detect model name from Claude config (pure file reads, no exec)
|
|
269
|
-
function getModelName() {
|
|
270
|
-
try {
|
|
271
|
-
const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));
|
|
272
|
-
if (claudeConfig && claudeConfig.projects) {
|
|
273
|
-
for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
|
|
274
|
-
if (CWD === projectPath || CWD.startsWith(projectPath + '/')) {
|
|
275
|
-
const usage = projectConfig.lastModelUsage;
|
|
276
|
-
if (usage) {
|
|
277
|
-
const ids = Object.keys(usage);
|
|
278
|
-
if (ids.length > 0) {
|
|
279
|
-
let modelId = ids[ids.length - 1];
|
|
280
|
-
let latest = 0;
|
|
281
|
-
for (const id of ids) {
|
|
282
|
-
const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;
|
|
283
|
-
if (ts > latest) { latest = ts; modelId = id; }
|
|
284
|
-
}
|
|
285
|
-
if (modelId.includes('opus')) return 'Opus 4.8';
|
|
286
|
-
if (modelId.includes('sonnet')) return 'Sonnet 4.6';
|
|
287
|
-
if (modelId.includes('haiku')) return 'Haiku 4.5';
|
|
288
|
-
return modelId.split('-').slice(1, 3).join(' ');
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
break;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
} catch { /* ignore */ }
|
|
296
|
-
|
|
297
|
-
// Fallback: settings.json model field
|
|
298
|
-
const settings = getSettings();
|
|
299
|
-
if (settings && settings.model) {
|
|
300
|
-
const m = settings.model;
|
|
301
|
-
if (m.includes('opus')) return 'Opus 4.8';
|
|
302
|
-
if (m.includes('sonnet')) return 'Sonnet 4.6';
|
|
303
|
-
if (m.includes('haiku')) return 'Haiku 4.5';
|
|
304
|
-
}
|
|
305
|
-
return 'Claude Code';
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// ─── Stdin reader (Claude Code pipes session JSON) ──────────────
|
|
309
|
-
// Claude Code sends session JSON via stdin. Read synchronously so the
|
|
310
|
-
// script works both when invoked by Claude Code (stdin has JSON) and
|
|
311
|
-
// when run manually from terminal (stdin is empty/tty).
|
|
312
|
-
let _stdinData = null;
|
|
313
|
-
function getStdinData() {
|
|
314
|
-
if (_stdinData !== undefined && _stdinData !== null) return _stdinData;
|
|
315
|
-
try {
|
|
316
|
-
if (process.stdin.isTTY) { _stdinData = null; return null; }
|
|
317
|
-
const chunks = [];
|
|
318
|
-
const buf = Buffer.alloc(4096);
|
|
319
|
-
let bytesRead;
|
|
320
|
-
try {
|
|
321
|
-
while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {
|
|
322
|
-
chunks.push(buf.slice(0, bytesRead));
|
|
323
|
-
}
|
|
324
|
-
} catch { /* EOF or read error */ }
|
|
325
|
-
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
326
|
-
_stdinData = (raw && raw.startsWith('{')) ? JSON.parse(raw) : null;
|
|
327
|
-
} catch {
|
|
328
|
-
_stdinData = null;
|
|
329
|
-
}
|
|
330
|
-
return _stdinData;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
function getModelFromStdin() {
|
|
334
|
-
const data = getStdinData();
|
|
335
|
-
return (data && data.model && data.model.display_name) ? data.model.display_name : null;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function getContextFromStdin() {
|
|
339
|
-
const data = getStdinData();
|
|
340
|
-
if (data && data.context_window) {
|
|
341
|
-
return { usedPct: Math.floor(data.context_window.used_percentage || 0) };
|
|
342
|
-
}
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function getCostFromStdin() {
|
|
347
|
-
const data = getStdinData();
|
|
348
|
-
if (data && data.cost) {
|
|
349
|
-
const durationMs = data.cost.total_duration_ms || 0;
|
|
350
|
-
const mins = Math.floor(durationMs / 60000);
|
|
351
|
-
const secs = Math.floor((durationMs % 60000) / 1000);
|
|
352
|
-
return {
|
|
353
|
-
costUsd: data.cost.total_cost_usd || 0,
|
|
354
|
-
duration: mins > 0 ? mins + 'm' + secs + 's' : secs + 's',
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
return null;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Read package version from the first package.json we find.
|
|
361
|
-
function getPkgVersion() {
|
|
362
|
-
let ver = '3.6';
|
|
363
|
-
try {
|
|
364
|
-
const home = os.homedir();
|
|
365
|
-
const pkgPaths = [
|
|
366
|
-
path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'package.json'),
|
|
367
|
-
path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'package.json'),
|
|
368
|
-
path.join(CWD, 'node_modules', 'ruflo', 'package.json'),
|
|
369
|
-
path.join(CWD, 'v3', '@claude-flow', 'cli', 'package.json'),
|
|
370
|
-
];
|
|
371
|
-
// #2221: global installs (npm i -g ruflo) live outside CWD/node_modules, so the
|
|
372
|
-
// probes above all miss and the version falls back to the hard-coded default.
|
|
373
|
-
// Derive the global node_modules dir from the running node binary (no npm spawn —
|
|
374
|
-
// statusline renders often). Covers nvm/mise (bin/../lib/node_modules) and Windows
|
|
375
|
-
// (bin/node_modules) layouts.
|
|
376
|
-
try {
|
|
377
|
-
const binDir = path.dirname(process.execPath);
|
|
378
|
-
for (const gm of [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')]) {
|
|
379
|
-
pkgPaths.push(
|
|
380
|
-
path.join(gm, 'ruflo', 'package.json'),
|
|
381
|
-
path.join(gm, '@claude-flow', 'cli', 'package.json'),
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
} catch { /* ignore */ }
|
|
385
|
-
for (const p of pkgPaths) {
|
|
386
|
-
if (!fs.existsSync(p)) continue;
|
|
387
|
-
try {
|
|
388
|
-
const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
389
|
-
if (pkg && typeof pkg.version === 'string' && pkg.version.length > 0) { ver = pkg.version; break; }
|
|
390
|
-
} catch { /* ignore */ }
|
|
391
|
-
}
|
|
392
|
-
} catch { /* ignore */ }
|
|
393
|
-
return ver;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// ─── Rendering ──────────────────────────────────────────────────
|
|
397
|
-
|
|
398
|
-
function progressBar(current, total) {
|
|
399
|
-
const width = 5;
|
|
400
|
-
const filled = Math.round((current / total) * width);
|
|
401
|
-
return '[' + '●'.repeat(filled) + '○'.repeat(width - filled) + ']';
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
function generateStatusline() {
|
|
405
|
-
const d = getStatuslineData();
|
|
406
|
-
const git = getGitInfo();
|
|
407
|
-
const modelName = getModelFromStdin() || (d.user && d.user.modelName) || 'Claude Code';
|
|
408
|
-
const ctxInfo = getContextFromStdin();
|
|
409
|
-
const costInfo = getCostFromStdin();
|
|
410
|
-
const pkgVersion = getPkgVersion();
|
|
411
|
-
|
|
412
|
-
const progress = d.v3Progress || {};
|
|
413
|
-
const security = d.security || {};
|
|
414
|
-
const swarm = d.swarm || {};
|
|
415
|
-
const system = d.system || {};
|
|
416
|
-
const adrs = d.adrs || {};
|
|
417
|
-
const hooks = d.hooks || {};
|
|
418
|
-
const agentdb = d.agentdb || {};
|
|
419
|
-
const tests = d.tests || {};
|
|
420
|
-
|
|
421
|
-
const domainsCompleted = progress.domainsCompleted || 0;
|
|
422
|
-
const totalDomains = progress.totalDomains || 5;
|
|
423
|
-
const dddProgress = progress.dddProgress || 0;
|
|
424
|
-
const patternsLearned = progress.patternsLearned || 0;
|
|
425
|
-
const activeAgents = swarm.activeAgents || 0;
|
|
426
|
-
const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
|
|
427
|
-
const coordinationActive = swarm.coordinationActive || false;
|
|
428
|
-
const intelligencePct = system.intelligencePct || 0;
|
|
429
|
-
const memoryMB = system.memoryMB || 0;
|
|
430
|
-
const subAgents = system.subAgents || 0;
|
|
431
|
-
const cvesFixed = security.cvesFixed || 0;
|
|
432
|
-
const totalCves = security.totalCves || 0;
|
|
433
|
-
const secStatus = security.status || 'NONE';
|
|
434
|
-
const adrCount = adrs.count || 0;
|
|
435
|
-
const adrImpl = adrs.implemented || 0;
|
|
436
|
-
const hooksEnabled = hooks.enabled || 0;
|
|
437
|
-
const hooksTotal = hooks.total || 0;
|
|
438
|
-
const vectorCount = agentdb.vectorCount || 0;
|
|
439
|
-
const hasHnsw = agentdb.hasHnsw || false;
|
|
440
|
-
const dbSizeKB = agentdb.dbSizeKB || 0;
|
|
441
|
-
const testFiles = tests.testFiles || 0;
|
|
442
|
-
const testCases = tests.testCases || testFiles * 4;
|
|
443
|
-
|
|
444
|
-
const lines = [];
|
|
445
|
-
|
|
446
|
-
// Header
|
|
447
|
-
let header = c.bold + c.brightPurple + '▊ RuFlo V' + pkgVersion + ' ' + c.reset;
|
|
448
|
-
header += (coordinationActive ? c.brightCyan : c.dim) + '● ' + c.brightCyan + git.name + c.reset;
|
|
449
|
-
if (git.gitBranch) {
|
|
450
|
-
header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightBlue + '⏇ ' + git.gitBranch + c.reset;
|
|
451
|
-
const changes = git.modified + git.staged + git.untracked;
|
|
452
|
-
if (changes > 0) {
|
|
453
|
-
let ind = '';
|
|
454
|
-
if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;
|
|
455
|
-
if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;
|
|
456
|
-
if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;
|
|
457
|
-
header += ' ' + ind;
|
|
458
|
-
}
|
|
459
|
-
if (git.ahead > 0) header += ' ' + c.brightGreen + '↑' + git.ahead + c.reset;
|
|
460
|
-
if (git.behind > 0) header += ' ' + c.brightRed + '↓' + git.behind + c.reset;
|
|
461
|
-
}
|
|
462
|
-
header += ' ' + c.dim + '│' + c.reset + ' ' + c.purple + modelName + c.reset;
|
|
463
|
-
const duration = costInfo ? costInfo.duration : '';
|
|
464
|
-
if (duration) header += ' ' + c.dim + '│' + c.reset + ' ' + c.cyan + '⏱ ' + duration + c.reset;
|
|
465
|
-
if (ctxInfo && ctxInfo.usedPct > 0) {
|
|
466
|
-
const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
|
|
467
|
-
header += ' ' + c.dim + '│' + c.reset + ' ' + ctxColor + '● ' + ctxInfo.usedPct + '% ctx' + c.reset;
|
|
468
|
-
}
|
|
469
|
-
if (!CONFIG.hideCost && costInfo && costInfo.costUsd > 0) {
|
|
470
|
-
header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightYellow + CONFIG.costSymbol + costInfo.costUsd.toFixed(2) + c.reset;
|
|
471
|
-
}
|
|
472
|
-
lines.push(header);
|
|
473
|
-
|
|
474
|
-
// Separator
|
|
475
|
-
lines.push(c.dim + '─'.repeat(53) + c.reset);
|
|
476
|
-
|
|
477
|
-
// Line 1: DDD Domains
|
|
478
|
-
const domainsColor = domainsCompleted >= 3 ? c.brightGreen : domainsCompleted > 0 ? c.yellow : c.red;
|
|
479
|
-
let perfIndicator;
|
|
480
|
-
if (hasHnsw && vectorCount > 0) {
|
|
481
|
-
const speedup = vectorCount > 10000 ? '12500x' : vectorCount > 1000 ? '150x' : '10x';
|
|
482
|
-
perfIndicator = c.brightGreen + '⚡ HNSW ' + speedup + c.reset;
|
|
483
|
-
} else if (patternsLearned > 0) {
|
|
484
|
-
const pk = patternsLearned >= 1000 ? (patternsLearned / 1000).toFixed(1) + 'k' : String(patternsLearned);
|
|
485
|
-
perfIndicator = c.brightYellow + '📚 ' + pk + ' patterns' + c.reset;
|
|
486
|
-
} else {
|
|
487
|
-
perfIndicator = c.dim + '⚡ target: 150x-12500x' + c.reset;
|
|
488
|
-
}
|
|
489
|
-
lines.push(
|
|
490
|
-
c.brightCyan + '🏗️ DDD Domains' + c.reset + ' ' + progressBar(domainsCompleted, totalDomains) + ' ' +
|
|
491
|
-
domainsColor + domainsCompleted + c.reset + '/' + c.brightWhite + totalDomains + c.reset + ' ' + perfIndicator
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
// Line 2: Swarm + Hooks + CVE + Memory + Intelligence
|
|
495
|
-
const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset : c.dim + '○' + c.reset;
|
|
496
|
-
const agentsColor = activeAgents > 0 ? c.brightGreen : c.red;
|
|
497
|
-
const secIcon = secStatus === 'CLEAN' ? '🟢' : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? '🟡' : (secStatus === 'NONE' ? '⚪' : '🔴');
|
|
498
|
-
const secColor = secStatus === 'CLEAN' ? c.brightGreen : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? c.brightYellow : (secStatus === 'NONE' ? c.dim : c.brightRed);
|
|
499
|
-
const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
|
|
500
|
-
const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
501
|
-
|
|
502
|
-
lines.push(
|
|
503
|
-
c.brightYellow + '🤖 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + maxAgents + c.reset + '] ' +
|
|
504
|
-
c.brightPurple + '👥 ' + subAgents + c.reset + ' ' +
|
|
505
|
-
c.brightBlue + '🪝 ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset + ' ' +
|
|
506
|
-
secIcon + ' ' + secColor + 'CVE ' + cvesFixed + c.reset + '/' + c.brightWhite + totalCves + c.reset + ' ' +
|
|
507
|
-
c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset + ' ' +
|
|
508
|
-
intellColor + '🧠 ' + String(intelligencePct).padStart(3) + '%' + c.reset
|
|
509
|
-
);
|
|
510
|
-
|
|
511
|
-
// Line 3: Architecture
|
|
512
|
-
const dddColor = dddProgress >= 50 ? c.brightGreen : dddProgress > 0 ? c.yellow : c.red;
|
|
513
|
-
const adrColor = adrCount > 0 ? (adrImpl === adrCount ? c.brightGreen : c.yellow) : c.dim;
|
|
514
|
-
const adrDisplay = adrColor + '●' + adrImpl + '/' + adrCount + c.reset;
|
|
515
|
-
|
|
516
|
-
lines.push(
|
|
517
|
-
c.brightPurple + '🔧 Architecture' + c.reset + ' ' +
|
|
518
|
-
c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
519
|
-
c.cyan + 'DDD' + c.reset + ' ' + dddColor + '●' + String(dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
520
|
-
c.cyan + 'Security' + c.reset + ' ' + secColor + '●' + secStatus + c.reset
|
|
521
|
-
);
|
|
522
|
-
|
|
523
|
-
// Line 4: AgentDB, Tests, Integration
|
|
524
|
-
const hnswInd = hasHnsw ? c.brightGreen + '⚡' + c.reset : '';
|
|
525
|
-
const sizeDisp = dbSizeKB >= 1024 ? (dbSizeKB / 1024).toFixed(1) + 'MB' : dbSizeKB + 'KB';
|
|
526
|
-
const vectorColor = vectorCount > 0 ? c.brightGreen : c.dim;
|
|
527
|
-
const testColor = testFiles > 0 ? c.brightGreen : c.dim;
|
|
528
|
-
|
|
529
|
-
// MCP / DB integration from data
|
|
530
|
-
const integration = d.integration || {};
|
|
531
|
-
const mcpServers = (integration.mcpServers) || {};
|
|
532
|
-
let integStr = '';
|
|
533
|
-
if (mcpServers.total > 0) {
|
|
534
|
-
const mcpCol = mcpServers.enabled === mcpServers.total ? c.brightGreen : mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
535
|
-
integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '●' + mcpServers.enabled + '/' + mcpServers.total + c.reset;
|
|
536
|
-
}
|
|
537
|
-
if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '◆' + c.reset + 'DB';
|
|
538
|
-
if (!integStr) integStr = c.dim + '● none' + c.reset;
|
|
539
|
-
|
|
540
|
-
lines.push(
|
|
541
|
-
c.brightCyan + '📊 AgentDB' + c.reset + ' ' +
|
|
542
|
-
c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '●' + vectorCount + hnswInd + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
543
|
-
c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
544
|
-
c.cyan + 'Tests' + c.reset + ' ' + testColor + '●' + testFiles + c.reset + ' ' + c.dim + '(~' + testCases + ' cases)' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
545
|
-
integStr
|
|
546
|
-
);
|
|
547
|
-
|
|
548
|
-
return lines.join('\\n');
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// JSON output — delegates to CLI for accuracy; caller can use --json flag
|
|
552
|
-
function generateJSON() {
|
|
553
|
-
const d = getStatuslineData();
|
|
554
|
-
const git = getGitInfo();
|
|
555
|
-
return Object.assign({}, d, {
|
|
556
|
-
user: Object.assign({ name: git.name, gitBranch: git.gitBranch }, d.user || {}),
|
|
557
|
-
git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
|
|
558
|
-
lastUpdated: new Date().toISOString(),
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// ─── Main ───────────────────────────────────────────────────────
|
|
563
|
-
if (process.argv.includes('--json')) {
|
|
564
|
-
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
565
|
-
} else if (process.argv.includes('--compact')) {
|
|
566
|
-
console.log(JSON.stringify(generateJSON()));
|
|
567
|
-
} else {
|
|
568
|
-
console.log(generateStatusline());
|
|
569
|
-
}
|
|
24
|
+
return `#!/usr/bin/env node
|
|
25
|
+
/**
|
|
26
|
+
* RuFlo V3 Statusline — delegation build (#2195)
|
|
27
|
+
*
|
|
28
|
+
* Fix for ruvnet/ruflo#2195: the previous version re-implemented all data
|
|
29
|
+
* readers locally using fragile file probes that missed AgentDB patterns,
|
|
30
|
+
* the v3/docs/adr/ ADR directory, and the real vector count.
|
|
31
|
+
*
|
|
32
|
+
* This version delegates to 'npx @claude-flow/cli hooks statusline --json'
|
|
33
|
+
* as the single source of truth. That command queries AgentDB directly,
|
|
34
|
+
* counts ADRs in both directories, and reports the real intelligence pct.
|
|
35
|
+
*
|
|
36
|
+
* ADR counting falls back to local file reads so the display still works
|
|
37
|
+
* without network access (counts both v3/docs/adr/ and v3/implementation/adrs/).
|
|
38
|
+
*
|
|
39
|
+
* Cache: JSON result is cached in /tmp for 10s so rapid prompt triggers
|
|
40
|
+
* (every keystroke in some shells) don't hammer the CLI on every call.
|
|
41
|
+
*
|
|
42
|
+
* Usage: node statusline.cjs [--json] [--compact] [--dashboard]
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
46
|
+
const fs = require('fs');
|
|
47
|
+
const path = require('path');
|
|
48
|
+
const { execSync } = require('child_process');
|
|
49
|
+
const os = require('os');
|
|
50
|
+
|
|
51
|
+
// Configuration
|
|
52
|
+
const CONFIG = {
|
|
53
|
+
maxAgents: ${maxAgents},
|
|
54
|
+
// Session-cost display. Claude Code's cost.total_cost_usd is a client-side
|
|
55
|
+
// estimate that "may differ from your actual bill" and reads as misleading on
|
|
56
|
+
// subscription plans, where token usage is not billed per dollar. These let
|
|
57
|
+
// each user pick what the segment means to them without changing the default.
|
|
58
|
+
// RUFLO_STATUSLINE_COST_SYMBOL override the leading '$' (e.g. ⚡, €, 🌱);
|
|
59
|
+
// set to an empty string for the number alone.
|
|
60
|
+
// RUFLO_STATUSLINE_HIDE_COST 1/true/yes/on removes the segment entirely.
|
|
61
|
+
costSymbol: process.env.RUFLO_STATUSLINE_COST_SYMBOL ?? '$',
|
|
62
|
+
hideCost: /^(1|true|yes|on)$/i.test(process.env.RUFLO_STATUSLINE_HIDE_COST || ''),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const CWD = process.cwd();
|
|
66
|
+
|
|
67
|
+
// ─── Delegation cache ───────────────────────────────────────────
|
|
68
|
+
// Cache the CLI JSON result for 10s so rapid prompt re-renders
|
|
69
|
+
// (e.g. every keypress in some shells) don't re-invoke npx each time.
|
|
70
|
+
const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
|
|
71
|
+
const CACHE_TTL_MS = 10000;
|
|
72
|
+
|
|
73
|
+
function readCache() {
|
|
74
|
+
try {
|
|
75
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
76
|
+
const raw = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
|
|
77
|
+
if (raw && raw._ts && (Date.now() - raw._ts) < CACHE_TTL_MS) {
|
|
78
|
+
return raw.data;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} catch { /* ignore */ }
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function writeCache(data) {
|
|
86
|
+
try { fs.writeFileSync(CACHE_FILE, JSON.stringify({ _ts: Date.now(), data }), 'utf-8'); } catch { /* ignore */ }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Single source of truth: delegate to the CLI hooks statusline --json command.
|
|
91
|
+
* Falls back to a minimal static object on failure so the statusline still renders.
|
|
92
|
+
*
|
|
93
|
+
* Fix for ruflo#2195: the previous local readers returned 0 for AgentDB patterns
|
|
94
|
+
* (missed the .swarm/memory.db → AgentDB path), computed dddProgress wrong,
|
|
95
|
+
* and only counted ADRs in v3/implementation/adrs/ (missed v3/docs/adr/).
|
|
96
|
+
*/
|
|
97
|
+
function getStatuslineData() {
|
|
98
|
+
const cached = readCache();
|
|
99
|
+
if (cached) return cached;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const raw = execSync(
|
|
103
|
+
'npx --yes @claude-flow/cli@latest hooks statusline --json 2>/dev/null',
|
|
104
|
+
{ encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
|
|
105
|
+
).trim();
|
|
106
|
+
// The CLI may emit preamble lines before the JSON — find the first '{'.
|
|
107
|
+
const jsonStart = raw.indexOf('{');
|
|
108
|
+
if (jsonStart === -1) throw new Error('no JSON in CLI output');
|
|
109
|
+
const data = JSON.parse(raw.slice(jsonStart));
|
|
110
|
+
// Overlay real ADR count from both local directories (fast, no network).
|
|
111
|
+
data.adrs = getLocalADRCount();
|
|
112
|
+
writeCache(data);
|
|
113
|
+
return data;
|
|
114
|
+
} catch { /* CLI unavailable or timed out */ }
|
|
115
|
+
|
|
116
|
+
// Fallback: use local file probes only (will be less accurate, but non-zero
|
|
117
|
+
// when CLI is available and accurate when it's not).
|
|
118
|
+
return buildLocalFallback();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Count ADRs from BOTH known directories (fix for ruflo#2195: old code missed
|
|
122
|
+
// v3/docs/adr/ which holds ADR-088..ADR-137, i.e. 41 of the 128 total ADRs).
|
|
123
|
+
function getLocalADRCount() {
|
|
124
|
+
const adrDirs = [
|
|
125
|
+
path.join(CWD, 'v3', 'implementation', 'adrs'),
|
|
126
|
+
path.join(CWD, 'v3', 'docs', 'adr'),
|
|
127
|
+
path.join(CWD, 'docs', 'adrs'),
|
|
128
|
+
path.join(CWD, '.claude-flow', 'adrs'),
|
|
129
|
+
];
|
|
130
|
+
let total = 0;
|
|
131
|
+
for (const dir of adrDirs) {
|
|
132
|
+
try {
|
|
133
|
+
if (fs.existsSync(dir)) {
|
|
134
|
+
const files = fs.readdirSync(dir).filter(function(f) {
|
|
135
|
+
return f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\\d{4}-/.test(f));
|
|
136
|
+
});
|
|
137
|
+
total += files.length;
|
|
138
|
+
}
|
|
139
|
+
} catch { /* ignore */ }
|
|
140
|
+
}
|
|
141
|
+
return { count: total, implemented: total, compliance: 0 };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Minimal local fallback when the CLI is not installed or times out.
|
|
145
|
+
// Returns a structure that matches the CLI JSON schema so the renderer works.
|
|
146
|
+
function buildLocalFallback() {
|
|
147
|
+
const memMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
148
|
+
const adrs = getLocalADRCount();
|
|
149
|
+
|
|
150
|
+
// Test file count (pure directory walk, no file reads)
|
|
151
|
+
let testFiles = 0;
|
|
152
|
+
function countTests(dir, depth) {
|
|
153
|
+
if ((depth || 0) > 4) return;
|
|
154
|
+
try {
|
|
155
|
+
if (!fs.existsSync(dir)) return;
|
|
156
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
157
|
+
if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules') {
|
|
158
|
+
countTests(path.join(dir, e.name), (depth || 0) + 1);
|
|
159
|
+
} else if (e.isFile() && (e.name.includes('.test.') || e.name.includes('.spec.') || e.name.startsWith('test_') || e.name.startsWith('spec_'))) {
|
|
160
|
+
testFiles++;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch { /* ignore */ }
|
|
164
|
+
}
|
|
165
|
+
for (const d of ['tests', 'test', '__tests__', 'src', 'v3']) countTests(path.join(CWD, d));
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
user: { name: 'user', gitBranch: '', modelName: 'Claude Code' },
|
|
169
|
+
v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
|
|
170
|
+
security: { status: 'NONE', cvesFixed: 0, totalCves: 0 },
|
|
171
|
+
swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
|
|
172
|
+
system: { memoryMB: memMB, contextPct: 0, intelligencePct: 0, subAgents: 0 },
|
|
173
|
+
adrs,
|
|
174
|
+
hooks: { enabled: 0, total: 0 },
|
|
175
|
+
agentdb: { vectorCount: 0, dbSizeKB: 0, hasHnsw: false },
|
|
176
|
+
tests: { testFiles, testCases: testFiles * 4 },
|
|
177
|
+
lastUpdated: new Date().toISOString(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ANSI colors
|
|
182
|
+
const c = {
|
|
183
|
+
reset: '\\x1b[0m',
|
|
184
|
+
bold: '\\x1b[1m',
|
|
185
|
+
dim: '\\x1b[2m',
|
|
186
|
+
red: '\\x1b[0;31m',
|
|
187
|
+
green: '\\x1b[0;32m',
|
|
188
|
+
yellow: '\\x1b[0;33m',
|
|
189
|
+
blue: '\\x1b[0;34m',
|
|
190
|
+
purple: '\\x1b[0;35m',
|
|
191
|
+
cyan: '\\x1b[0;36m',
|
|
192
|
+
brightRed: '\\x1b[1;31m',
|
|
193
|
+
brightGreen: '\\x1b[1;32m',
|
|
194
|
+
brightYellow: '\\x1b[1;33m',
|
|
195
|
+
brightBlue: '\\x1b[1;34m',
|
|
196
|
+
brightPurple: '\\x1b[1;35m',
|
|
197
|
+
brightCyan: '\\x1b[1;36m',
|
|
198
|
+
brightWhite: '\\x1b[1;37m',
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Safe execSync with strict timeout (returns empty string on failure)
|
|
202
|
+
function safeExec(cmd, timeoutMs) {
|
|
203
|
+
try {
|
|
204
|
+
return execSync(cmd, {
|
|
205
|
+
encoding: 'utf-8',
|
|
206
|
+
timeout: timeoutMs || 2000,
|
|
207
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
208
|
+
}).trim();
|
|
209
|
+
} catch {
|
|
210
|
+
return '';
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Safe JSON file reader (returns null on failure)
|
|
215
|
+
function readJSON(filePath) {
|
|
216
|
+
try {
|
|
217
|
+
if (fs.existsSync(filePath)) {
|
|
218
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
219
|
+
}
|
|
220
|
+
} catch { /* ignore */ }
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ─── Git info (pure-Node / single exec — needed for branch display) ──────────
|
|
225
|
+
|
|
226
|
+
function getGitInfo() {
|
|
227
|
+
const result = {
|
|
228
|
+
name: 'user', gitBranch: '', modified: 0, untracked: 0,
|
|
229
|
+
staged: 0, ahead: 0, behind: 0,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const script = [
|
|
233
|
+
'git config user.name 2>/dev/null || echo user',
|
|
234
|
+
'echo "---SEP---"',
|
|
235
|
+
'git branch --show-current 2>/dev/null',
|
|
236
|
+
'echo "---SEP---"',
|
|
237
|
+
'git status --porcelain 2>/dev/null',
|
|
238
|
+
'echo "---SEP---"',
|
|
239
|
+
'git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo "0 0"',
|
|
240
|
+
].join('; ');
|
|
241
|
+
|
|
242
|
+
const raw = safeExec("sh -c '" + script + "'", 3000);
|
|
243
|
+
if (!raw) return result;
|
|
244
|
+
|
|
245
|
+
const parts = raw.split('---SEP---').map(function(s) { return s.trim(); });
|
|
246
|
+
if (parts.length >= 4) {
|
|
247
|
+
result.name = parts[0] || 'user';
|
|
248
|
+
result.gitBranch = parts[1] || '';
|
|
249
|
+
|
|
250
|
+
if (parts[2]) {
|
|
251
|
+
for (const line of parts[2].split('\\n')) {
|
|
252
|
+
if (!line || line.length < 2) continue;
|
|
253
|
+
const x = line[0], y = line[1];
|
|
254
|
+
if (x === '?' && y === '?') { result.untracked++; continue; }
|
|
255
|
+
if (x !== ' ' && x !== '?') result.staged++;
|
|
256
|
+
if (y !== ' ' && y !== '?') result.modified++;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const ab = (parts[3] || '0 0').split(/\\s+/);
|
|
261
|
+
result.ahead = parseInt(ab[0]) || 0;
|
|
262
|
+
result.behind = parseInt(ab[1]) || 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Detect model name from Claude config (pure file reads, no exec)
|
|
269
|
+
function getModelName() {
|
|
270
|
+
try {
|
|
271
|
+
const claudeConfig = readJSON(path.join(os.homedir(), '.claude.json'));
|
|
272
|
+
if (claudeConfig && claudeConfig.projects) {
|
|
273
|
+
for (const [projectPath, projectConfig] of Object.entries(claudeConfig.projects)) {
|
|
274
|
+
if (CWD === projectPath || CWD.startsWith(projectPath + '/')) {
|
|
275
|
+
const usage = projectConfig.lastModelUsage;
|
|
276
|
+
if (usage) {
|
|
277
|
+
const ids = Object.keys(usage);
|
|
278
|
+
if (ids.length > 0) {
|
|
279
|
+
let modelId = ids[ids.length - 1];
|
|
280
|
+
let latest = 0;
|
|
281
|
+
for (const id of ids) {
|
|
282
|
+
const ts = usage[id] && usage[id].lastUsedAt ? new Date(usage[id].lastUsedAt).getTime() : 0;
|
|
283
|
+
if (ts > latest) { latest = ts; modelId = id; }
|
|
284
|
+
}
|
|
285
|
+
if (modelId.includes('opus')) return 'Opus 4.8';
|
|
286
|
+
if (modelId.includes('sonnet')) return 'Sonnet 4.6';
|
|
287
|
+
if (modelId.includes('haiku')) return 'Haiku 4.5';
|
|
288
|
+
return modelId.split('-').slice(1, 3).join(' ');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
} catch { /* ignore */ }
|
|
296
|
+
|
|
297
|
+
// Fallback: settings.json model field
|
|
298
|
+
const settings = getSettings();
|
|
299
|
+
if (settings && settings.model) {
|
|
300
|
+
const m = settings.model;
|
|
301
|
+
if (m.includes('opus')) return 'Opus 4.8';
|
|
302
|
+
if (m.includes('sonnet')) return 'Sonnet 4.6';
|
|
303
|
+
if (m.includes('haiku')) return 'Haiku 4.5';
|
|
304
|
+
}
|
|
305
|
+
return 'Claude Code';
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ─── Stdin reader (Claude Code pipes session JSON) ──────────────
|
|
309
|
+
// Claude Code sends session JSON via stdin. Read synchronously so the
|
|
310
|
+
// script works both when invoked by Claude Code (stdin has JSON) and
|
|
311
|
+
// when run manually from terminal (stdin is empty/tty).
|
|
312
|
+
let _stdinData = null;
|
|
313
|
+
function getStdinData() {
|
|
314
|
+
if (_stdinData !== undefined && _stdinData !== null) return _stdinData;
|
|
315
|
+
try {
|
|
316
|
+
if (process.stdin.isTTY) { _stdinData = null; return null; }
|
|
317
|
+
const chunks = [];
|
|
318
|
+
const buf = Buffer.alloc(4096);
|
|
319
|
+
let bytesRead;
|
|
320
|
+
try {
|
|
321
|
+
while ((bytesRead = fs.readSync(0, buf, 0, buf.length, null)) > 0) {
|
|
322
|
+
chunks.push(buf.slice(0, bytesRead));
|
|
323
|
+
}
|
|
324
|
+
} catch { /* EOF or read error */ }
|
|
325
|
+
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
326
|
+
_stdinData = (raw && raw.startsWith('{')) ? JSON.parse(raw) : null;
|
|
327
|
+
} catch {
|
|
328
|
+
_stdinData = null;
|
|
329
|
+
}
|
|
330
|
+
return _stdinData;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function getModelFromStdin() {
|
|
334
|
+
const data = getStdinData();
|
|
335
|
+
return (data && data.model && data.model.display_name) ? data.model.display_name : null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function getContextFromStdin() {
|
|
339
|
+
const data = getStdinData();
|
|
340
|
+
if (data && data.context_window) {
|
|
341
|
+
return { usedPct: Math.floor(data.context_window.used_percentage || 0) };
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function getCostFromStdin() {
|
|
347
|
+
const data = getStdinData();
|
|
348
|
+
if (data && data.cost) {
|
|
349
|
+
const durationMs = data.cost.total_duration_ms || 0;
|
|
350
|
+
const mins = Math.floor(durationMs / 60000);
|
|
351
|
+
const secs = Math.floor((durationMs % 60000) / 1000);
|
|
352
|
+
return {
|
|
353
|
+
costUsd: data.cost.total_cost_usd || 0,
|
|
354
|
+
duration: mins > 0 ? mins + 'm' + secs + 's' : secs + 's',
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Read package version from the first package.json we find.
|
|
361
|
+
function getPkgVersion() {
|
|
362
|
+
let ver = '3.6';
|
|
363
|
+
try {
|
|
364
|
+
const home = os.homedir();
|
|
365
|
+
const pkgPaths = [
|
|
366
|
+
path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'package.json'),
|
|
367
|
+
path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'package.json'),
|
|
368
|
+
path.join(CWD, 'node_modules', 'ruflo', 'package.json'),
|
|
369
|
+
path.join(CWD, 'v3', '@claude-flow', 'cli', 'package.json'),
|
|
370
|
+
];
|
|
371
|
+
// #2221: global installs (npm i -g ruflo) live outside CWD/node_modules, so the
|
|
372
|
+
// probes above all miss and the version falls back to the hard-coded default.
|
|
373
|
+
// Derive the global node_modules dir from the running node binary (no npm spawn —
|
|
374
|
+
// statusline renders often). Covers nvm/mise (bin/../lib/node_modules) and Windows
|
|
375
|
+
// (bin/node_modules) layouts.
|
|
376
|
+
try {
|
|
377
|
+
const binDir = path.dirname(process.execPath);
|
|
378
|
+
for (const gm of [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')]) {
|
|
379
|
+
pkgPaths.push(
|
|
380
|
+
path.join(gm, 'ruflo', 'package.json'),
|
|
381
|
+
path.join(gm, '@claude-flow', 'cli', 'package.json'),
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
} catch { /* ignore */ }
|
|
385
|
+
for (const p of pkgPaths) {
|
|
386
|
+
if (!fs.existsSync(p)) continue;
|
|
387
|
+
try {
|
|
388
|
+
const pkg = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
389
|
+
if (pkg && typeof pkg.version === 'string' && pkg.version.length > 0) { ver = pkg.version; break; }
|
|
390
|
+
} catch { /* ignore */ }
|
|
391
|
+
}
|
|
392
|
+
} catch { /* ignore */ }
|
|
393
|
+
return ver;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// ─── Rendering ──────────────────────────────────────────────────
|
|
397
|
+
|
|
398
|
+
function progressBar(current, total) {
|
|
399
|
+
const width = 5;
|
|
400
|
+
const filled = Math.round((current / total) * width);
|
|
401
|
+
return '[' + '●'.repeat(filled) + '○'.repeat(width - filled) + ']';
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function generateStatusline() {
|
|
405
|
+
const d = getStatuslineData();
|
|
406
|
+
const git = getGitInfo();
|
|
407
|
+
const modelName = getModelFromStdin() || (d.user && d.user.modelName) || 'Claude Code';
|
|
408
|
+
const ctxInfo = getContextFromStdin();
|
|
409
|
+
const costInfo = getCostFromStdin();
|
|
410
|
+
const pkgVersion = getPkgVersion();
|
|
411
|
+
|
|
412
|
+
const progress = d.v3Progress || {};
|
|
413
|
+
const security = d.security || {};
|
|
414
|
+
const swarm = d.swarm || {};
|
|
415
|
+
const system = d.system || {};
|
|
416
|
+
const adrs = d.adrs || {};
|
|
417
|
+
const hooks = d.hooks || {};
|
|
418
|
+
const agentdb = d.agentdb || {};
|
|
419
|
+
const tests = d.tests || {};
|
|
420
|
+
|
|
421
|
+
const domainsCompleted = progress.domainsCompleted || 0;
|
|
422
|
+
const totalDomains = progress.totalDomains || 5;
|
|
423
|
+
const dddProgress = progress.dddProgress || 0;
|
|
424
|
+
const patternsLearned = progress.patternsLearned || 0;
|
|
425
|
+
const activeAgents = swarm.activeAgents || 0;
|
|
426
|
+
const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
|
|
427
|
+
const coordinationActive = swarm.coordinationActive || false;
|
|
428
|
+
const intelligencePct = system.intelligencePct || 0;
|
|
429
|
+
const memoryMB = system.memoryMB || 0;
|
|
430
|
+
const subAgents = system.subAgents || 0;
|
|
431
|
+
const cvesFixed = security.cvesFixed || 0;
|
|
432
|
+
const totalCves = security.totalCves || 0;
|
|
433
|
+
const secStatus = security.status || 'NONE';
|
|
434
|
+
const adrCount = adrs.count || 0;
|
|
435
|
+
const adrImpl = adrs.implemented || 0;
|
|
436
|
+
const hooksEnabled = hooks.enabled || 0;
|
|
437
|
+
const hooksTotal = hooks.total || 0;
|
|
438
|
+
const vectorCount = agentdb.vectorCount || 0;
|
|
439
|
+
const hasHnsw = agentdb.hasHnsw || false;
|
|
440
|
+
const dbSizeKB = agentdb.dbSizeKB || 0;
|
|
441
|
+
const testFiles = tests.testFiles || 0;
|
|
442
|
+
const testCases = tests.testCases || testFiles * 4;
|
|
443
|
+
|
|
444
|
+
const lines = [];
|
|
445
|
+
|
|
446
|
+
// Header
|
|
447
|
+
let header = c.bold + c.brightPurple + '▊ RuFlo V' + pkgVersion + ' ' + c.reset;
|
|
448
|
+
header += (coordinationActive ? c.brightCyan : c.dim) + '● ' + c.brightCyan + git.name + c.reset;
|
|
449
|
+
if (git.gitBranch) {
|
|
450
|
+
header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightBlue + '⏇ ' + git.gitBranch + c.reset;
|
|
451
|
+
const changes = git.modified + git.staged + git.untracked;
|
|
452
|
+
if (changes > 0) {
|
|
453
|
+
let ind = '';
|
|
454
|
+
if (git.staged > 0) ind += c.brightGreen + '+' + git.staged + c.reset;
|
|
455
|
+
if (git.modified > 0) ind += c.brightYellow + '~' + git.modified + c.reset;
|
|
456
|
+
if (git.untracked > 0) ind += c.dim + '?' + git.untracked + c.reset;
|
|
457
|
+
header += ' ' + ind;
|
|
458
|
+
}
|
|
459
|
+
if (git.ahead > 0) header += ' ' + c.brightGreen + '↑' + git.ahead + c.reset;
|
|
460
|
+
if (git.behind > 0) header += ' ' + c.brightRed + '↓' + git.behind + c.reset;
|
|
461
|
+
}
|
|
462
|
+
header += ' ' + c.dim + '│' + c.reset + ' ' + c.purple + modelName + c.reset;
|
|
463
|
+
const duration = costInfo ? costInfo.duration : '';
|
|
464
|
+
if (duration) header += ' ' + c.dim + '│' + c.reset + ' ' + c.cyan + '⏱ ' + duration + c.reset;
|
|
465
|
+
if (ctxInfo && ctxInfo.usedPct > 0) {
|
|
466
|
+
const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
|
|
467
|
+
header += ' ' + c.dim + '│' + c.reset + ' ' + ctxColor + '● ' + ctxInfo.usedPct + '% ctx' + c.reset;
|
|
468
|
+
}
|
|
469
|
+
if (!CONFIG.hideCost && costInfo && costInfo.costUsd > 0) {
|
|
470
|
+
header += ' ' + c.dim + '│' + c.reset + ' ' + c.brightYellow + CONFIG.costSymbol + costInfo.costUsd.toFixed(2) + c.reset;
|
|
471
|
+
}
|
|
472
|
+
lines.push(header);
|
|
473
|
+
|
|
474
|
+
// Separator
|
|
475
|
+
lines.push(c.dim + '─'.repeat(53) + c.reset);
|
|
476
|
+
|
|
477
|
+
// Line 1: DDD Domains
|
|
478
|
+
const domainsColor = domainsCompleted >= 3 ? c.brightGreen : domainsCompleted > 0 ? c.yellow : c.red;
|
|
479
|
+
let perfIndicator;
|
|
480
|
+
if (hasHnsw && vectorCount > 0) {
|
|
481
|
+
const speedup = vectorCount > 10000 ? '12500x' : vectorCount > 1000 ? '150x' : '10x';
|
|
482
|
+
perfIndicator = c.brightGreen + '⚡ HNSW ' + speedup + c.reset;
|
|
483
|
+
} else if (patternsLearned > 0) {
|
|
484
|
+
const pk = patternsLearned >= 1000 ? (patternsLearned / 1000).toFixed(1) + 'k' : String(patternsLearned);
|
|
485
|
+
perfIndicator = c.brightYellow + '📚 ' + pk + ' patterns' + c.reset;
|
|
486
|
+
} else {
|
|
487
|
+
perfIndicator = c.dim + '⚡ target: 150x-12500x' + c.reset;
|
|
488
|
+
}
|
|
489
|
+
lines.push(
|
|
490
|
+
c.brightCyan + '🏗️ DDD Domains' + c.reset + ' ' + progressBar(domainsCompleted, totalDomains) + ' ' +
|
|
491
|
+
domainsColor + domainsCompleted + c.reset + '/' + c.brightWhite + totalDomains + c.reset + ' ' + perfIndicator
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
// Line 2: Swarm + Hooks + CVE + Memory + Intelligence
|
|
495
|
+
const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset : c.dim + '○' + c.reset;
|
|
496
|
+
const agentsColor = activeAgents > 0 ? c.brightGreen : c.red;
|
|
497
|
+
const secIcon = secStatus === 'CLEAN' ? '🟢' : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? '🟡' : (secStatus === 'NONE' ? '⚪' : '🔴');
|
|
498
|
+
const secColor = secStatus === 'CLEAN' ? c.brightGreen : (secStatus === 'IN_PROGRESS' || secStatus === 'STALE') ? c.brightYellow : (secStatus === 'NONE' ? c.dim : c.brightRed);
|
|
499
|
+
const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
|
|
500
|
+
const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
501
|
+
|
|
502
|
+
lines.push(
|
|
503
|
+
c.brightYellow + '🤖 Swarm' + c.reset + ' ' + swarmInd + ' [' + agentsColor + String(activeAgents).padStart(2) + c.reset + '/' + c.brightWhite + maxAgents + c.reset + '] ' +
|
|
504
|
+
c.brightPurple + '👥 ' + subAgents + c.reset + ' ' +
|
|
505
|
+
c.brightBlue + '🪝 ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset + ' ' +
|
|
506
|
+
secIcon + ' ' + secColor + 'CVE ' + cvesFixed + c.reset + '/' + c.brightWhite + totalCves + c.reset + ' ' +
|
|
507
|
+
c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset + ' ' +
|
|
508
|
+
intellColor + '🧠 ' + String(intelligencePct).padStart(3) + '%' + c.reset
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
// Line 3: Architecture
|
|
512
|
+
const dddColor = dddProgress >= 50 ? c.brightGreen : dddProgress > 0 ? c.yellow : c.red;
|
|
513
|
+
const adrColor = adrCount > 0 ? (adrImpl === adrCount ? c.brightGreen : c.yellow) : c.dim;
|
|
514
|
+
const adrDisplay = adrColor + '●' + adrImpl + '/' + adrCount + c.reset;
|
|
515
|
+
|
|
516
|
+
lines.push(
|
|
517
|
+
c.brightPurple + '🔧 Architecture' + c.reset + ' ' +
|
|
518
|
+
c.cyan + 'ADRs' + c.reset + ' ' + adrDisplay + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
519
|
+
c.cyan + 'DDD' + c.reset + ' ' + dddColor + '●' + String(dddProgress).padStart(3) + '%' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
520
|
+
c.cyan + 'Security' + c.reset + ' ' + secColor + '●' + secStatus + c.reset
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
// Line 4: AgentDB, Tests, Integration
|
|
524
|
+
const hnswInd = hasHnsw ? c.brightGreen + '⚡' + c.reset : '';
|
|
525
|
+
const sizeDisp = dbSizeKB >= 1024 ? (dbSizeKB / 1024).toFixed(1) + 'MB' : dbSizeKB + 'KB';
|
|
526
|
+
const vectorColor = vectorCount > 0 ? c.brightGreen : c.dim;
|
|
527
|
+
const testColor = testFiles > 0 ? c.brightGreen : c.dim;
|
|
528
|
+
|
|
529
|
+
// MCP / DB integration from data
|
|
530
|
+
const integration = d.integration || {};
|
|
531
|
+
const mcpServers = (integration.mcpServers) || {};
|
|
532
|
+
let integStr = '';
|
|
533
|
+
if (mcpServers.total > 0) {
|
|
534
|
+
const mcpCol = mcpServers.enabled === mcpServers.total ? c.brightGreen : mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
535
|
+
integStr += c.cyan + 'MCP' + c.reset + ' ' + mcpCol + '●' + mcpServers.enabled + '/' + mcpServers.total + c.reset;
|
|
536
|
+
}
|
|
537
|
+
if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + c.brightGreen + '◆' + c.reset + 'DB';
|
|
538
|
+
if (!integStr) integStr = c.dim + '● none' + c.reset;
|
|
539
|
+
|
|
540
|
+
lines.push(
|
|
541
|
+
c.brightCyan + '📊 AgentDB' + c.reset + ' ' +
|
|
542
|
+
c.cyan + 'Vectors' + c.reset + ' ' + vectorColor + '●' + vectorCount + hnswInd + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
543
|
+
c.cyan + 'Size' + c.reset + ' ' + c.brightWhite + sizeDisp + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
544
|
+
c.cyan + 'Tests' + c.reset + ' ' + testColor + '●' + testFiles + c.reset + ' ' + c.dim + '(~' + testCases + ' cases)' + c.reset + ' ' + c.dim + '│' + c.reset + ' ' +
|
|
545
|
+
integStr
|
|
546
|
+
);
|
|
547
|
+
|
|
548
|
+
return lines.join('\\n');
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// JSON output — delegates to CLI for accuracy; caller can use --json flag
|
|
552
|
+
function generateJSON() {
|
|
553
|
+
const d = getStatuslineData();
|
|
554
|
+
const git = getGitInfo();
|
|
555
|
+
return Object.assign({}, d, {
|
|
556
|
+
user: Object.assign({ name: git.name, gitBranch: git.gitBranch }, d.user || {}),
|
|
557
|
+
git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
|
|
558
|
+
lastUpdated: new Date().toISOString(),
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// ─── Main ───────────────────────────────────────────────────────
|
|
563
|
+
if (process.argv.includes('--json')) {
|
|
564
|
+
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
565
|
+
} else if (process.argv.includes('--compact')) {
|
|
566
|
+
console.log(JSON.stringify(generateJSON()));
|
|
567
|
+
} else {
|
|
568
|
+
console.log(generateStatusline());
|
|
569
|
+
}
|
|
570
570
|
`;
|
|
571
571
|
}
|
|
572
572
|
/**
|
|
@@ -576,30 +576,30 @@ export function generateStatuslineHook(options) {
|
|
|
576
576
|
if (!options.statusline.enabled) {
|
|
577
577
|
return '#!/bin/bash\n# Statusline disabled\n';
|
|
578
578
|
}
|
|
579
|
-
return `#!/bin/bash
|
|
580
|
-
# RuFlo V3 Statusline Hook
|
|
581
|
-
# Source this in your .bashrc/.zshrc for terminal statusline
|
|
582
|
-
|
|
583
|
-
# Function to get statusline
|
|
584
|
-
claude_flow_statusline() {
|
|
585
|
-
local statusline_script="\${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs"
|
|
586
|
-
if [ -f "$statusline_script" ]; then
|
|
587
|
-
node "$statusline_script" 2>/dev/null || echo ""
|
|
588
|
-
fi
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
# Bash: Add to PS1
|
|
592
|
-
# export PS1='$(claude_flow_statusline) \\n\\$ '
|
|
593
|
-
|
|
594
|
-
# Zsh: Add to RPROMPT
|
|
595
|
-
# export RPROMPT='$(claude_flow_statusline)'
|
|
596
|
-
|
|
597
|
-
# Claude Code: Add to .claude/settings.json
|
|
598
|
-
# "statusLine": {
|
|
599
|
-
# "type": "command",
|
|
600
|
-
# "command": "node .claude/helpers/statusline.cjs 2>/dev/null"
|
|
601
|
-
# "when": "test -f .claude/helpers/statusline.cjs"
|
|
602
|
-
# }
|
|
579
|
+
return `#!/bin/bash
|
|
580
|
+
# RuFlo V3 Statusline Hook
|
|
581
|
+
# Source this in your .bashrc/.zshrc for terminal statusline
|
|
582
|
+
|
|
583
|
+
# Function to get statusline
|
|
584
|
+
claude_flow_statusline() {
|
|
585
|
+
local statusline_script="\${CLAUDE_FLOW_DIR:-.claude}/helpers/statusline.cjs"
|
|
586
|
+
if [ -f "$statusline_script" ]; then
|
|
587
|
+
node "$statusline_script" 2>/dev/null || echo ""
|
|
588
|
+
fi
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
# Bash: Add to PS1
|
|
592
|
+
# export PS1='$(claude_flow_statusline) \\n\\$ '
|
|
593
|
+
|
|
594
|
+
# Zsh: Add to RPROMPT
|
|
595
|
+
# export RPROMPT='$(claude_flow_statusline)'
|
|
596
|
+
|
|
597
|
+
# Claude Code: Add to .claude/settings.json
|
|
598
|
+
# "statusLine": {
|
|
599
|
+
# "type": "command",
|
|
600
|
+
# "command": "node .claude/helpers/statusline.cjs 2>/dev/null"
|
|
601
|
+
# "when": "test -f .claude/helpers/statusline.cjs"
|
|
602
|
+
# }
|
|
603
603
|
`;
|
|
604
604
|
}
|
|
605
605
|
//# sourceMappingURL=statusline-generator.js.map
|