kynjal-cli 3.1.4 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/core/coder.md +1 -1
- package/.claude/agents/core/planner.md +2 -2
- package/.claude/agents/core/researcher.md +1 -1
- package/.claude/agents/core/reviewer.md +1 -1
- package/.claude/agents/core/tester.md +1 -1
- package/.claude/agents/data/data-ml-model.md +4 -4
- package/.claude/agents/development/dev-backend-api.md +4 -4
- package/.claude/agents/documentation/docs-api-openapi.md +4 -4
- package/.claude/agents/github/code-review-swarm.md +2 -2
- package/.claude/agents/github/issue-tracker.md +2 -2
- package/.claude/agents/github/pr-manager.md +2 -2
- package/.claude/agents/github/release-manager.md +2 -2
- package/.claude/agents/github/workflow-automation.md +2 -2
- package/.claude/agents/sparc/architecture.md +3 -3
- package/.claude/agents/sparc/pseudocode.md +2 -2
- package/.claude/agents/sparc/refinement.md +3 -3
- package/.claude/agents/sparc/specification.md +2 -2
- package/.claude/agents/swarm/adaptive-coordinator.md +1 -1
- package/.claude/agents/swarm/hierarchical-coordinator.md +1 -1
- package/.claude/agents/swarm/mesh-coordinator.md +1 -1
- package/.claude/agents/templates/base-template-generator.md +25 -4
- package/.claude/agents/templates/sparc-coordinator.md +3 -3
- package/.claude/helpers/auto-commit.sh +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +27 -9
- package/.claude/helpers/hook-handler.cjs +58 -18
- package/.claude/helpers/statusline.cjs +420 -613
- package/.claude/helpers/statusline.js +3 -3
- package/.claude/settings.json +9 -9
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +2 -2
- package/.claude/skills/swarm-orchestration/SKILL.md +1 -1
- package/README.md +383 -170
- package/bin/cli.js +6 -6
- package/bin/mcp-server.js +1 -1
- package/bin/preinstall.cjs +2 -0
- package/dist/src/appliance/gguf-engine.d.ts +91 -0
- package/dist/src/appliance/gguf-engine.d.ts.map +1 -0
- package/dist/src/appliance/gguf-engine.js +425 -0
- package/dist/src/appliance/gguf-engine.js.map +1 -0
- package/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
- package/dist/src/appliance/ruvllm-bridge.d.ts.map +1 -0
- package/dist/src/appliance/ruvllm-bridge.js +292 -0
- package/dist/src/appliance/ruvllm-bridge.js.map +1 -0
- package/dist/src/appliance/rvfa-builder.d.ts +44 -0
- package/dist/src/appliance/rvfa-builder.d.ts.map +1 -0
- package/dist/src/appliance/rvfa-builder.js +329 -0
- package/dist/src/appliance/rvfa-builder.js.map +1 -0
- package/dist/src/appliance/rvfa-distribution.d.ts +97 -0
- package/dist/src/appliance/rvfa-distribution.d.ts.map +1 -0
- package/dist/src/appliance/rvfa-distribution.js +370 -0
- package/dist/src/appliance/rvfa-distribution.js.map +1 -0
- package/dist/src/appliance/rvfa-format.d.ts +111 -0
- package/dist/src/appliance/rvfa-format.d.ts.map +1 -0
- package/dist/src/appliance/rvfa-format.js +393 -0
- package/dist/src/appliance/rvfa-format.js.map +1 -0
- package/dist/src/appliance/rvfa-runner.d.ts +69 -0
- package/dist/src/appliance/rvfa-runner.d.ts.map +1 -0
- package/dist/src/appliance/rvfa-runner.js +237 -0
- package/dist/src/appliance/rvfa-runner.js.map +1 -0
- package/dist/src/appliance/rvfa-signing.d.ts +123 -0
- package/dist/src/appliance/rvfa-signing.d.ts.map +1 -0
- package/dist/src/appliance/rvfa-signing.js +347 -0
- package/dist/src/appliance/rvfa-signing.js.map +1 -0
- package/dist/src/commands/agent.d.ts.map +1 -1
- package/dist/src/commands/agent.js +121 -21
- package/dist/src/commands/agent.js.map +1 -1
- package/dist/src/commands/appliance-advanced.d.ts +9 -0
- package/dist/src/commands/appliance-advanced.d.ts.map +1 -0
- package/dist/src/commands/appliance-advanced.js +215 -0
- package/dist/src/commands/appliance-advanced.js.map +1 -0
- package/dist/src/commands/appliance.d.ts +8 -0
- package/dist/src/commands/appliance.d.ts.map +1 -0
- package/dist/src/commands/appliance.js +406 -0
- package/dist/src/commands/appliance.js.map +1 -0
- package/dist/src/commands/benchmark.js +2 -2
- package/dist/src/commands/benchmark.js.map +1 -1
- package/dist/src/commands/claims.js +1 -1
- package/dist/src/commands/claims.js.map +1 -1
- package/dist/src/commands/cleanup.d.ts +13 -0
- package/dist/src/commands/cleanup.d.ts.map +1 -0
- package/dist/src/commands/cleanup.js +218 -0
- package/dist/src/commands/cleanup.js.map +1 -0
- package/dist/src/commands/config.js +1 -1
- package/dist/src/commands/config.js.map +1 -1
- package/dist/src/commands/daemon.d.ts.map +1 -1
- package/dist/src/commands/daemon.js +81 -18
- package/dist/src/commands/daemon.js.map +1 -1
- package/dist/src/commands/deployment.js +1 -1
- package/dist/src/commands/deployment.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +99 -51
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/embeddings.js +1 -1
- package/dist/src/commands/embeddings.js.map +1 -1
- package/dist/src/commands/hive-mind.js +26 -26
- package/dist/src/commands/hive-mind.js.map +1 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +800 -100
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/index.d.ts +9 -2
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +20 -2
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/init.d.ts +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +22 -18
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/mcp.d.ts.map +1 -1
- package/dist/src/commands/mcp.js +23 -5
- package/dist/src/commands/mcp.js.map +1 -1
- package/dist/src/commands/memory.d.ts.map +1 -1
- package/dist/src/commands/memory.js +24 -0
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/neural.d.ts.map +1 -1
- package/dist/src/commands/neural.js +13 -7
- package/dist/src/commands/neural.js.map +1 -1
- package/dist/src/commands/performance.js +1 -1
- package/dist/src/commands/performance.js.map +1 -1
- package/dist/src/commands/plugins.js +1 -1
- package/dist/src/commands/plugins.js.map +1 -1
- package/dist/src/commands/providers.js +1 -1
- package/dist/src/commands/providers.js.map +1 -1
- package/dist/src/commands/ruvector/import.js +2 -2
- package/dist/src/commands/ruvector/import.js.map +1 -1
- package/dist/src/commands/ruvector/index.js +1 -1
- package/dist/src/commands/ruvector/index.js.map +1 -1
- package/dist/src/commands/ruvector/setup.js +6 -6
- package/dist/src/commands/security.d.ts.map +1 -1
- package/dist/src/commands/security.js +47 -16
- package/dist/src/commands/security.js.map +1 -1
- package/dist/src/commands/session.d.ts +1 -1
- package/dist/src/commands/session.js +1 -1
- package/dist/src/commands/start.d.ts +1 -1
- package/dist/src/commands/start.js +12 -12
- package/dist/src/commands/start.js.map +1 -1
- package/dist/src/commands/status.d.ts +1 -1
- package/dist/src/commands/status.d.ts.map +1 -1
- package/dist/src/commands/status.js +13 -6
- package/dist/src/commands/status.js.map +1 -1
- package/dist/src/commands/swarm.js +2 -2
- package/dist/src/commands/swarm.js.map +1 -1
- package/dist/src/commands/task.d.ts +1 -1
- package/dist/src/commands/task.js +1 -1
- package/dist/src/commands/transfer-store.js +1 -1
- package/dist/src/commands/transfer-store.js.map +1 -1
- package/dist/src/config-adapter.js +1 -1
- package/dist/src/config-adapter.js.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/claudemd-generator.js +30 -30
- package/dist/src/init/claudemd-generator.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +86 -101
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/helpers-generator.d.ts.map +1 -1
- package/dist/src/init/helpers-generator.js +96 -26
- package/dist/src/init/helpers-generator.js.map +1 -1
- package/dist/src/init/mcp-generator.d.ts +0 -1
- package/dist/src/init/mcp-generator.d.ts.map +1 -1
- package/dist/src/init/mcp-generator.js +34 -18
- package/dist/src/init/mcp-generator.js.map +1 -1
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +107 -41
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/init/statusline-generator.d.ts +16 -8
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +537 -1019
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/init/types.d.ts +14 -4
- package/dist/src/init/types.d.ts.map +1 -1
- package/dist/src/init/types.js +9 -2
- package/dist/src/init/types.js.map +1 -1
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +10 -0
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +30 -4
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp-tools/agentdb-tools.d.ts +30 -0
- package/dist/src/mcp-tools/agentdb-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/agentdb-tools.js +557 -0
- package/dist/src/mcp-tools/agentdb-tools.js.map +1 -0
- package/dist/src/mcp-tools/browser-tools.js +2 -2
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/config-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/config-tools.js +21 -2
- package/dist/src/mcp-tools/config-tools.js.map +1 -1
- package/dist/src/mcp-tools/coordination-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/coordination-tools.js +192 -13
- package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
- package/dist/src/mcp-tools/daa-tools.js +5 -5
- package/dist/src/mcp-tools/daa-tools.js.map +1 -1
- package/dist/src/mcp-tools/github-tools.js +2 -2
- package/dist/src/mcp-tools/github-tools.js.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.js +263 -35
- package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +355 -40
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/mcp-tools/index.d.ts +2 -0
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +2 -0
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/memory-tools.js +31 -1
- package/dist/src/mcp-tools/memory-tools.js.map +1 -1
- package/dist/src/mcp-tools/neural-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/neural-tools.js +32 -27
- package/dist/src/mcp-tools/neural-tools.js.map +1 -1
- package/dist/src/mcp-tools/performance-tools.js +1 -1
- package/dist/src/mcp-tools/performance-tools.js.map +1 -1
- package/dist/src/mcp-tools/ruvllm-tools.d.ts +9 -0
- package/dist/src/mcp-tools/ruvllm-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/ruvllm-tools.js +283 -0
- package/dist/src/mcp-tools/ruvllm-tools.js.map +1 -0
- package/dist/src/mcp-tools/swarm-tools.d.ts +2 -1
- package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/swarm-tools.js +216 -30
- package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
- package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/system-tools.js +109 -6
- package/dist/src/mcp-tools/system-tools.js.map +1 -1
- package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/task-tools.js +102 -0
- package/dist/src/mcp-tools/task-tools.js.map +1 -1
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts +9 -0
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/wasm-agent-tools.js +230 -0
- package/dist/src/mcp-tools/wasm-agent-tools.js.map +1 -0
- package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/workflow-tools.js +91 -0
- package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
- package/dist/src/memory/ewc-consolidation.d.ts +24 -0
- package/dist/src/memory/ewc-consolidation.d.ts.map +1 -1
- package/dist/src/memory/ewc-consolidation.js +59 -0
- package/dist/src/memory/ewc-consolidation.js.map +1 -1
- package/dist/src/memory/intelligence.d.ts +53 -0
- package/dist/src/memory/intelligence.d.ts.map +1 -1
- package/dist/src/memory/intelligence.js +264 -7
- package/dist/src/memory/intelligence.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts +407 -0
- package/dist/src/memory/memory-bridge.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge.js +1494 -0
- package/dist/src/memory/memory-bridge.js.map +1 -0
- package/dist/src/memory/memory-initializer.d.ts +17 -1
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +320 -42
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/output.d.ts.map +1 -1
- package/dist/src/output.js +1 -0
- package/dist/src/output.js.map +1 -1
- package/dist/src/parser.d.ts +10 -0
- package/dist/src/parser.d.ts.map +1 -1
- package/dist/src/parser.js +49 -3
- package/dist/src/parser.js.map +1 -1
- package/dist/src/plugins/manager.d.ts.map +1 -1
- package/dist/src/plugins/manager.js +31 -14
- package/dist/src/plugins/manager.js.map +1 -1
- package/dist/src/plugins/store/discovery.js +5 -5
- package/dist/src/plugins/store/discovery.js.map +1 -1
- package/dist/src/plugins/tests/standalone-test.js +4 -4
- package/dist/src/plugins/tests/standalone-test.js.map +1 -1
- package/dist/src/production/error-handler.js +1 -1
- package/dist/src/production/error-handler.js.map +1 -1
- package/dist/src/runtime/headless.d.ts +3 -3
- package/dist/src/runtime/headless.js +6 -6
- package/dist/src/runtime/headless.js.map +1 -1
- package/dist/src/ruvector/agent-wasm.d.ts +182 -0
- package/dist/src/ruvector/agent-wasm.d.ts.map +1 -0
- package/dist/src/ruvector/agent-wasm.js +316 -0
- package/dist/src/ruvector/agent-wasm.js.map +1 -0
- package/dist/src/ruvector/enhanced-model-router.d.ts.map +1 -1
- package/dist/src/ruvector/enhanced-model-router.js +25 -15
- package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
- package/dist/src/ruvector/index.d.ts +7 -1
- package/dist/src/ruvector/index.d.ts.map +1 -1
- package/dist/src/ruvector/index.js +17 -1
- package/dist/src/ruvector/index.js.map +1 -1
- package/dist/src/ruvector/ruvllm-wasm.d.ts +179 -0
- package/dist/src/ruvector/ruvllm-wasm.d.ts.map +1 -0
- package/dist/src/ruvector/ruvllm-wasm.js +363 -0
- package/dist/src/ruvector/ruvllm-wasm.js.map +1 -0
- package/dist/src/services/agentic-flow-bridge.d.ts +50 -0
- package/dist/src/services/agentic-flow-bridge.d.ts.map +1 -0
- package/dist/src/services/agentic-flow-bridge.js +95 -0
- package/dist/src/services/agentic-flow-bridge.js.map +1 -0
- package/dist/src/services/claim-service.js +1 -1
- package/dist/src/services/claim-service.js.map +1 -1
- package/dist/src/services/container-worker-pool.d.ts.map +1 -1
- package/dist/src/services/container-worker-pool.js +3 -1
- package/dist/src/services/container-worker-pool.js.map +1 -1
- package/dist/src/services/index.d.ts +1 -1
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/registry-api.d.ts +1 -1
- package/dist/src/services/registry-api.js +1 -1
- package/dist/src/services/ruvector-training.d.ts +11 -2
- package/dist/src/services/ruvector-training.d.ts.map +1 -1
- package/dist/src/services/ruvector-training.js +233 -43
- package/dist/src/services/ruvector-training.js.map +1 -1
- package/dist/src/services/worker-daemon.d.ts +28 -3
- package/dist/src/services/worker-daemon.d.ts.map +1 -1
- package/dist/src/services/worker-daemon.js +156 -17
- package/dist/src/services/worker-daemon.js.map +1 -1
- package/dist/src/services/worker-queue.d.ts.map +1 -1
- package/dist/src/services/worker-queue.js +2 -0
- package/dist/src/services/worker-queue.js.map +1 -1
- package/dist/src/transfer/deploy-seraphine.d.ts +1 -1
- package/dist/src/transfer/deploy-seraphine.js +4 -4
- package/dist/src/transfer/deploy-seraphine.js.map +1 -1
- package/dist/src/transfer/ipfs/client.d.ts.map +1 -1
- package/dist/src/transfer/ipfs/client.js +8 -0
- package/dist/src/transfer/ipfs/client.js.map +1 -1
- package/dist/src/transfer/ipfs/upload.d.ts.map +1 -1
- package/dist/src/transfer/ipfs/upload.js +0 -2
- package/dist/src/transfer/ipfs/upload.js.map +1 -1
- package/dist/src/transfer/models/seraphine.d.ts +1 -1
- package/dist/src/transfer/models/seraphine.js +5 -5
- package/dist/src/transfer/models/seraphine.js.map +1 -1
- package/dist/src/transfer/serialization/cfp.d.ts +1 -1
- package/dist/src/transfer/serialization/cfp.d.ts.map +1 -1
- package/dist/src/transfer/serialization/cfp.js +9 -6
- package/dist/src/transfer/serialization/cfp.js.map +1 -1
- package/dist/src/transfer/storage/gcs.d.ts.map +1 -1
- package/dist/src/transfer/storage/gcs.js +71 -29
- package/dist/src/transfer/storage/gcs.js.map +1 -1
- package/dist/src/transfer/store/discovery.js +4 -4
- package/dist/src/transfer/store/discovery.js.map +1 -1
- package/dist/src/transfer/store/registry.js +1 -1
- package/dist/src/transfer/store/registry.js.map +1 -1
- package/dist/src/transfer/store/tests/standalone-test.js +4 -4
- package/dist/src/transfer/store/tests/standalone-test.js.map +1 -1
- package/dist/src/transfer/types.d.ts +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.js +1 -1
- package/dist/src/update/validator.js +1 -1
- package/dist/src/update/validator.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -10
- package/.claude/agents/custom/accessibility-auditor.yaml +0 -56
- package/.claude/agents/custom/design-architect.yaml +0 -48
- package/.claude/agents/custom/ui-developer.yaml +0 -46
- package/.claude/agents/custom/ux-researcher.yaml +0 -60
|
@@ -1,30 +1,48 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* RuFlo V3.5 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,725 +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.6 (1M context)';
|
|
125
|
+
else if (modelId.includes('sonnet')) modelName = 'Sonnet 4.6';
|
|
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]?.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?.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() {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
266
|
+
// Check for security scan results in memory
|
|
267
|
+
const scanResultsPath = path.join(process.cwd(), '.claude', 'security-scans');
|
|
268
|
+
let cvesFixed = 0;
|
|
269
|
+
const totalCves = 3;
|
|
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
|
|
245
278
|
}
|
|
246
|
-
const auditAge = Date.now() - new Date(auditDate).getTime();
|
|
247
|
-
const isStale = auditAge > 7 * 24 * 60 * 60 * 1000;
|
|
248
|
-
return {
|
|
249
|
-
status: isStale ? 'STALE' : (auditData.status || 'PENDING'),
|
|
250
|
-
cvesFixed: auditData.cvesFixed || 0,
|
|
251
|
-
totalCves: auditData.totalCves || 0,
|
|
252
|
-
};
|
|
253
279
|
}
|
|
254
280
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
260
289
|
}
|
|
261
|
-
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const status = cvesFixed >= totalCves ? 'CLEAN' : cvesFixed > 0 ? 'IN_PROGRESS' : 'PENDING';
|
|
262
293
|
|
|
263
294
|
return {
|
|
264
|
-
status
|
|
265
|
-
cvesFixed
|
|
266
|
-
totalCves
|
|
295
|
+
status,
|
|
296
|
+
cvesFixed,
|
|
297
|
+
totalCves,
|
|
267
298
|
};
|
|
268
299
|
}
|
|
269
300
|
|
|
270
|
-
//
|
|
301
|
+
// Get swarm status
|
|
271
302
|
function getSwarmStatus() {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const now = Date.now();
|
|
275
|
-
|
|
276
|
-
const swarmStatePath = path.join(CWD, '.kynjalflow', 'swarm', 'swarm-state.json');
|
|
277
|
-
const swarmState = readJSON(swarmStatePath);
|
|
278
|
-
if (swarmState) {
|
|
279
|
-
const updatedAt = swarmState.updatedAt || swarmState.startedAt;
|
|
280
|
-
const age = updatedAt ? now - new Date(updatedAt).getTime() : Infinity;
|
|
281
|
-
if (age < staleThresholdMs) {
|
|
282
|
-
return {
|
|
283
|
-
activeAgents: swarmState.agents?.length || swarmState.agentCount || 0,
|
|
284
|
-
maxAgents: swarmState.maxAgents || CONFIG.maxAgents,
|
|
285
|
-
coordinationActive: true,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
}
|
|
303
|
+
let activeAgents = 0;
|
|
304
|
+
let coordinationActive = false;
|
|
289
305
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
coordinationActive: activityData.swarm.coordination_active || activityData.swarm.active || false,
|
|
299
|
-
};
|
|
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);
|
|
300
314
|
}
|
|
315
|
+
coordinationActive = activeAgents > 0;
|
|
316
|
+
} catch (e) {
|
|
317
|
+
// Ignore errors - default to 0 agents
|
|
301
318
|
}
|
|
302
319
|
|
|
303
|
-
return {
|
|
320
|
+
return {
|
|
321
|
+
activeAgents,
|
|
322
|
+
maxAgents: CONFIG.maxAgents,
|
|
323
|
+
coordinationActive,
|
|
324
|
+
};
|
|
304
325
|
}
|
|
305
326
|
|
|
306
|
-
//
|
|
327
|
+
// Get system metrics (dynamic based on actual state)
|
|
307
328
|
function getSystemMetrics() {
|
|
308
|
-
|
|
309
|
-
const learning = getLearningStats();
|
|
310
|
-
const agentdb = getAgentDBStats();
|
|
311
|
-
|
|
312
|
-
// Intelligence from learning.json
|
|
313
|
-
const learningData = readJSON(path.join(CWD, '.kynjalflow', 'metrics', 'learning.json'));
|
|
314
|
-
let intelligencePct = 0;
|
|
315
|
-
let contextPct = 0;
|
|
316
|
-
|
|
317
|
-
if (learningData?.intelligence?.score !== undefined) {
|
|
318
|
-
intelligencePct = Math.min(100, Math.floor(learningData.intelligence.score));
|
|
319
|
-
} else {
|
|
320
|
-
// Use actual vector/entry counts — 2000 entries = 100%
|
|
321
|
-
const fromPatterns = learning.patterns > 0 ? Math.min(100, Math.floor(learning.patterns / 20)) : 0;
|
|
322
|
-
const fromVectors = agentdb.vectorCount > 0 ? Math.min(100, Math.floor(agentdb.vectorCount / 20)) : 0;
|
|
323
|
-
intelligencePct = Math.max(fromPatterns, fromVectors);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Maturity fallback (pure fs checks, no git exec)
|
|
327
|
-
if (intelligencePct === 0) {
|
|
328
|
-
let score = 0;
|
|
329
|
-
if (fs.existsSync(path.join(CWD, '.claude'))) score += 15;
|
|
330
|
-
const srcDirs = ['src', 'lib', 'app', 'packages', 'v3'];
|
|
331
|
-
for (const d of srcDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 15; break; } }
|
|
332
|
-
const testDirs = ['tests', 'test', '__tests__', 'spec'];
|
|
333
|
-
for (const d of testDirs) { if (fs.existsSync(path.join(CWD, d))) { score += 10; break; } }
|
|
334
|
-
const cfgFiles = ['package.json', 'tsconfig.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
|
|
335
|
-
for (const f of cfgFiles) { if (fs.existsSync(path.join(CWD, f))) { score += 5; break; } }
|
|
336
|
-
intelligencePct = Math.min(100, score);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (learningData?.sessions?.total !== undefined) {
|
|
340
|
-
contextPct = Math.min(100, learningData.sessions.total * 5);
|
|
341
|
-
} else {
|
|
342
|
-
contextPct = Math.min(100, Math.floor(learning.sessions * 5));
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Sub-agents from file metrics (no ps aux)
|
|
329
|
+
let memoryMB = 0;
|
|
346
330
|
let subAgents = 0;
|
|
347
|
-
const activityData = readJSON(path.join(CWD, '.kynjalflow', 'metrics', 'swarm-activity.json'));
|
|
348
|
-
if (activityData?.processes?.estimated_agents) {
|
|
349
|
-
subAgents = activityData.processes.estimated_agents;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return { memoryMB, contextPct, intelligencePct, subAgents };
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// ADR status (count files only — don't read contents)
|
|
356
|
-
function getADRStatus() {
|
|
357
|
-
// Count actual ADR files first — compliance JSON may be stale
|
|
358
|
-
const adrPaths = [
|
|
359
|
-
path.join(CWD, 'v3', 'implementation', 'adrs'),
|
|
360
|
-
path.join(CWD, 'docs', 'adrs'),
|
|
361
|
-
path.join(CWD, '.kynjalflow', 'adrs'),
|
|
362
|
-
];
|
|
363
|
-
|
|
364
|
-
for (const adrPath of adrPaths) {
|
|
365
|
-
try {
|
|
366
|
-
if (fs.existsSync(adrPath)) {
|
|
367
|
-
const files = fs.readdirSync(adrPath).filter(f =>
|
|
368
|
-
f.endsWith('.md') && (f.startsWith('ADR-') || f.startsWith('adr-') || /^\d{4}-/.test(f))
|
|
369
|
-
);
|
|
370
|
-
// Report actual count — don't guess compliance without reading files
|
|
371
|
-
return { count: files.length, implemented: files.length, compliance: 0 };
|
|
372
|
-
}
|
|
373
|
-
} catch { /* ignore */ }
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return { count: 0, implemented: 0, compliance: 0 };
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Hooks status (shared settings cache)
|
|
380
|
-
function getHooksStatus() {
|
|
381
|
-
let enabled = 0;
|
|
382
|
-
let total = 0;
|
|
383
|
-
const settings = getSettings();
|
|
384
|
-
|
|
385
|
-
if (settings?.hooks) {
|
|
386
|
-
for (const category of Object.keys(settings.hooks)) {
|
|
387
|
-
const matchers = settings.hooks[category];
|
|
388
|
-
if (!Array.isArray(matchers)) continue;
|
|
389
|
-
for (const matcher of matchers) {
|
|
390
|
-
const hooks = matcher?.hooks;
|
|
391
|
-
if (Array.isArray(hooks)) {
|
|
392
|
-
total += hooks.length;
|
|
393
|
-
enabled += hooks.length;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
331
|
|
|
399
332
|
try {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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;
|
|
405
340
|
}
|
|
406
|
-
} catch {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// AgentDB stats — count real entries, not file-size heuristics
|
|
412
|
-
function getAgentDBStats() {
|
|
413
|
-
let vectorCount = 0;
|
|
414
|
-
let dbSizeKB = 0;
|
|
415
|
-
let namespaces = 0;
|
|
416
|
-
let hasHnsw = false;
|
|
417
|
-
|
|
418
|
-
// 1. Count real entries from auto-memory-store.json
|
|
419
|
-
const storePath = path.join(CWD, '.kynjalflow', 'data', 'auto-memory-store.json');
|
|
420
|
-
const storeStat = safeStat(storePath);
|
|
421
|
-
if (storeStat) {
|
|
422
|
-
dbSizeKB += storeStat.size / 1024;
|
|
423
|
-
try {
|
|
424
|
-
const store = JSON.parse(fs.readFileSync(storePath, 'utf-8'));
|
|
425
|
-
if (Array.isArray(store)) vectorCount += store.length;
|
|
426
|
-
else if (store?.entries) vectorCount += store.entries.length;
|
|
427
|
-
} catch { /* fall back to size estimate */ }
|
|
341
|
+
} catch (e) {
|
|
342
|
+
// Fallback
|
|
343
|
+
memoryMB = Math.floor(process.memoryUsage().heapUsed / 1024 / 1024);
|
|
428
344
|
}
|
|
429
345
|
|
|
430
|
-
//
|
|
431
|
-
const
|
|
432
|
-
try {
|
|
433
|
-
const ranked = readJSON(rankedPath);
|
|
434
|
-
if (ranked?.entries?.length > vectorCount) vectorCount = ranked.entries.length;
|
|
435
|
-
} catch { /* ignore */ }
|
|
436
|
-
|
|
437
|
-
// 3. Add DB file sizes
|
|
438
|
-
const dbFiles = [
|
|
439
|
-
path.join(CWD, 'data', 'memory.db'),
|
|
440
|
-
path.join(CWD, '.kynjalflow', 'memory.db'),
|
|
441
|
-
path.join(CWD, '.swarm', 'memory.db'),
|
|
442
|
-
];
|
|
443
|
-
for (const f of dbFiles) {
|
|
444
|
-
const stat = safeStat(f);
|
|
445
|
-
if (stat) {
|
|
446
|
-
dbSizeKB += stat.size / 1024;
|
|
447
|
-
namespaces++;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// 4. Check for graph data
|
|
452
|
-
const graphPath = path.join(CWD, 'data', 'memory.graph');
|
|
453
|
-
const graphStat = safeStat(graphPath);
|
|
454
|
-
if (graphStat) dbSizeKB += graphStat.size / 1024;
|
|
455
|
-
|
|
456
|
-
// 5. HNSW index
|
|
457
|
-
const hnswPaths = [
|
|
458
|
-
path.join(CWD, '.swarm', 'hnsw.index'),
|
|
459
|
-
path.join(CWD, '.kynjalflow', 'hnsw.index'),
|
|
460
|
-
];
|
|
461
|
-
for (const p of hnswPaths) {
|
|
462
|
-
const stat = safeStat(p);
|
|
463
|
-
if (stat) {
|
|
464
|
-
hasHnsw = true;
|
|
465
|
-
break;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// HNSW is available if memory package is present
|
|
470
|
-
if (!hasHnsw) {
|
|
471
|
-
const memPkgPaths = [
|
|
472
|
-
path.join(CWD, 'v3', '@claude-flow', 'memory', 'dist'),
|
|
473
|
-
path.join(CWD, 'node_modules', '@claude-flow', 'memory'),
|
|
474
|
-
];
|
|
475
|
-
for (const p of memPkgPaths) {
|
|
476
|
-
if (fs.existsSync(p)) { hasHnsw = true; break; }
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces, hasHnsw };
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Test stats (count files only — NO reading file contents)
|
|
484
|
-
function getTestStats() {
|
|
485
|
-
let testFiles = 0;
|
|
346
|
+
// Get learning stats for intelligence %
|
|
347
|
+
const learning = getLearningStats();
|
|
486
348
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
const n = entry.name;
|
|
497
|
-
if (n.includes('.test.') || n.includes('.spec.') || n.includes('_test.') || n.includes('_spec.')) {
|
|
498
|
-
testFiles++;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
} 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);
|
|
503
358
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
countTestFiles(path.join(CWD, d));
|
|
359
|
+
// Fallback: legacy pattern count
|
|
360
|
+
if (intelligencePct === 0 && learning.patterns > 0) {
|
|
361
|
+
intelligencePct = Math.min(100, Math.floor(learning.patterns / 10));
|
|
508
362
|
}
|
|
509
363
|
|
|
510
|
-
//
|
|
511
|
-
|
|
512
|
-
}
|
|
364
|
+
// Context % based on session history
|
|
365
|
+
const contextPct = Math.min(100, Math.floor(learning.sessions * 5));
|
|
513
366
|
|
|
514
|
-
//
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
? settings.enabledMcpjsonServers.filter(s => servers.includes(s)).length
|
|
524
|
-
: servers.length;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Fallback: .mcp.json
|
|
528
|
-
if (mcpServers.total === 0) {
|
|
529
|
-
const mcpConfig = readJSON(path.join(CWD, '.mcp.json'))
|
|
530
|
-
|| readJSON(path.join(os.homedir(), '.claude', 'mcp.json'));
|
|
531
|
-
if (mcpConfig?.mcpServers) {
|
|
532
|
-
const s = Object.keys(mcpConfig.mcpServers);
|
|
533
|
-
mcpServers.total = s.length;
|
|
534
|
-
mcpServers.enabled = s.length;
|
|
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);
|
|
535
376
|
}
|
|
377
|
+
} catch (e) {
|
|
378
|
+
// Ignore - default to 0
|
|
536
379
|
}
|
|
537
380
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// Session stats (pure file reads)
|
|
546
|
-
function getSessionStats() {
|
|
547
|
-
for (const p of ['.kynjalflow/session.json', '.claude/session.json']) {
|
|
548
|
-
const data = readJSON(path.join(CWD, p));
|
|
549
|
-
if (data?.startTime) {
|
|
550
|
-
const diffMs = Date.now() - new Date(data.startTime).getTime();
|
|
551
|
-
const mins = Math.floor(diffMs / 60000);
|
|
552
|
-
const duration = mins < 60 ? `${mins}m` : `${Math.floor(mins / 60)}h${mins % 60}m`;
|
|
553
|
-
return { duration };
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
return { duration: '' };
|
|
381
|
+
return {
|
|
382
|
+
memoryMB,
|
|
383
|
+
contextPct,
|
|
384
|
+
intelligencePct,
|
|
385
|
+
subAgents,
|
|
386
|
+
};
|
|
557
387
|
}
|
|
558
388
|
|
|
559
|
-
//
|
|
560
|
-
|
|
389
|
+
// Generate progress bar
|
|
561
390
|
function progressBar(current, total) {
|
|
562
391
|
const width = 5;
|
|
563
392
|
const filled = Math.round((current / total) * width);
|
|
564
|
-
|
|
393
|
+
const empty = width - filled;
|
|
394
|
+
return '[' + '\u25CF'.repeat(filled) + '\u25CB'.repeat(empty) + ']';
|
|
565
395
|
}
|
|
566
396
|
|
|
567
|
-
//
|
|
397
|
+
// Generate full statusline
|
|
568
398
|
function generateStatusline() {
|
|
569
|
-
const
|
|
570
|
-
const
|
|
399
|
+
const user = getUserInfo();
|
|
400
|
+
const progress = getV3Progress();
|
|
401
|
+
const security = getSecurityStatus();
|
|
571
402
|
const swarm = getSwarmStatus();
|
|
572
403
|
const system = getSystemMetrics();
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
parts.push(`${c.bold}${c.brightPurple}\u258A KynjalFlow${c.reset}`);
|
|
581
|
-
|
|
582
|
-
// User + swarm indicator
|
|
583
|
-
const dot = swarm.coordinationActive ? `${c.brightGreen}\u25CF${c.reset}` : `${c.brightCyan}\u25CF${c.reset}`;
|
|
584
|
-
parts.push(`${dot} ${c.brightCyan}${git.name}${c.reset}`);
|
|
585
|
-
|
|
586
|
-
// Git branch + changes
|
|
587
|
-
if (git.gitBranch) {
|
|
588
|
-
let branchPart = `${c.brightBlue}\u23C7 ${git.gitBranch}${c.reset}`;
|
|
589
|
-
const changes = [];
|
|
590
|
-
if (git.staged > 0) changes.push(`${c.brightGreen}+${git.staged}${c.reset}`);
|
|
591
|
-
if (git.modified > 0) changes.push(`${c.brightYellow}~${git.modified}${c.reset}`);
|
|
592
|
-
if (git.untracked > 0) changes.push(`${c.dim}?${git.untracked}${c.reset}`);
|
|
593
|
-
if (changes.length > 0) branchPart += ` ${changes.join('')}`;
|
|
594
|
-
if (git.ahead > 0) branchPart += ` ${c.brightGreen}\u2191${git.ahead}${c.reset}`;
|
|
595
|
-
if (git.behind > 0) branchPart += ` ${c.brightRed}\u2193${git.behind}${c.reset}`;
|
|
596
|
-
parts.push(branchPart);
|
|
404
|
+
const lines = [];
|
|
405
|
+
|
|
406
|
+
// Header Line
|
|
407
|
+
let header = `${c.bold}${c.brightPurple}▊ RuFlo V3.5 ${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}`;
|
|
597
411
|
}
|
|
412
|
+
header += ` ${c.dim}│${c.reset} ${c.purple}${user.modelName}${c.reset}`;
|
|
413
|
+
lines.push(header);
|
|
598
414
|
|
|
599
|
-
//
|
|
600
|
-
|
|
415
|
+
// Separator
|
|
416
|
+
lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);
|
|
601
417
|
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
418
|
+
// Line 1: DDD Domain Progress
|
|
419
|
+
const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
|
|
420
|
+
lines.push(
|
|
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}`
|
|
424
|
+
);
|
|
606
425
|
|
|
607
|
-
// Intelligence
|
|
608
|
-
const
|
|
609
|
-
|
|
426
|
+
// Line 2: Swarm + CVE + Memory + Context + Intelligence
|
|
427
|
+
const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
|
|
428
|
+
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
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;
|
|
610
431
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
432
|
+
lines.push(
|
|
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}`
|
|
439
|
+
);
|
|
615
440
|
|
|
616
|
-
//
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
441
|
+
// Line 3: Architecture status
|
|
442
|
+
const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
|
|
443
|
+
lines.push(
|
|
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}`
|
|
449
|
+
);
|
|
620
450
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen : c.brightYellow;
|
|
624
|
-
parts.push(`${mcpCol}MCP${integration.mcpServers.enabled}${c.reset}`);
|
|
625
|
-
}
|
|
451
|
+
return lines.join('\n');
|
|
452
|
+
}
|
|
626
453
|
|
|
627
|
-
|
|
454
|
+
// Generate JSON data
|
|
455
|
+
function generateJSON() {
|
|
456
|
+
return {
|
|
457
|
+
user: getUserInfo(),
|
|
458
|
+
v3Progress: getV3Progress(),
|
|
459
|
+
security: getSecurityStatus(),
|
|
460
|
+
swarm: getSwarmStatus(),
|
|
461
|
+
system: getSystemMetrics(),
|
|
462
|
+
performance: {
|
|
463
|
+
flashAttentionTarget: '2.49x-7.47x',
|
|
464
|
+
searchImprovement: '150x-12,500x',
|
|
465
|
+
memoryReduction: '50-75%',
|
|
466
|
+
},
|
|
467
|
+
lastUpdated: new Date().toISOString(),
|
|
468
|
+
};
|
|
628
469
|
}
|
|
629
470
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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 '';
|
|
478
|
+
|
|
479
|
+
const user = getUserInfo();
|
|
480
|
+
const progress = getV3Progress();
|
|
481
|
+
const security = getSecurityStatus();
|
|
482
|
+
const swarm = getSwarmStatus();
|
|
483
|
+
const system = getSystemMetrics();
|
|
484
|
+
|
|
485
|
+
const swarmIndicator = swarm.coordinationActive ? '●' : '○';
|
|
486
|
+
const securityStatus = security.status === 'CLEAN' ? '✓' :
|
|
487
|
+
security.cvesFixed > 0 ? '~' : '✗';
|
|
488
|
+
|
|
489
|
+
return `${c.brightPurple}RuFlo${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}`;
|
|
494
|
+
}
|
|
495
|
+
|
|
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();
|
|
634
506
|
const progress = getV3Progress();
|
|
635
507
|
const security = getSecurityStatus();
|
|
636
508
|
const swarm = getSwarmStatus();
|
|
637
509
|
const system = getSystemMetrics();
|
|
638
|
-
const adrs = getADRStatus();
|
|
639
|
-
const hooks = getHooksStatus();
|
|
640
|
-
const agentdb = getAgentDBStats();
|
|
641
|
-
const tests = getTestStats();
|
|
642
|
-
const session = getSessionStats();
|
|
643
|
-
const integration = getIntegrationStatus();
|
|
644
510
|
const lines = [];
|
|
645
511
|
|
|
646
|
-
// Header
|
|
647
|
-
let header = `${c.bold}${c.brightPurple}
|
|
648
|
-
header += `${swarm.coordinationActive ? c.brightCyan : c.dim}
|
|
649
|
-
if (
|
|
650
|
-
header += ` ${c.dim}
|
|
651
|
-
const changes = git.modified + git.staged + git.untracked;
|
|
652
|
-
if (changes > 0) {
|
|
653
|
-
let ind = '';
|
|
654
|
-
if (git.staged > 0) ind += `${c.brightGreen}+${git.staged}${c.reset}`;
|
|
655
|
-
if (git.modified > 0) ind += `${c.brightYellow}~${git.modified}${c.reset}`;
|
|
656
|
-
if (git.untracked > 0) ind += `${c.dim}?${git.untracked}${c.reset}`;
|
|
657
|
-
header += ` ${ind}`;
|
|
658
|
-
}
|
|
659
|
-
if (git.ahead > 0) header += ` ${c.brightGreen}\u2191${git.ahead}${c.reset}`;
|
|
660
|
-
if (git.behind > 0) header += ` ${c.brightRed}\u2193${git.behind}${c.reset}`;
|
|
512
|
+
// Header Line
|
|
513
|
+
let header = `${c.bold}${c.brightPurple}▊ RuFlo V3.5 ${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}`;
|
|
661
517
|
}
|
|
662
|
-
header += ` ${c.dim}
|
|
663
|
-
if (session.duration) header += ` ${c.dim}\u2502${c.reset} ${c.cyan}\u23F1 ${session.duration}${c.reset}`;
|
|
518
|
+
header += ` ${c.dim}│${c.reset} ${c.purple}${user.modelName}${c.reset}`;
|
|
664
519
|
lines.push(header);
|
|
665
520
|
|
|
666
521
|
// Separator
|
|
667
|
-
lines.push(`${c.dim}
|
|
522
|
+
lines.push(`${c.dim}─────────────────────────────────────────────────────${c.reset}`);
|
|
668
523
|
|
|
669
|
-
// Line 1: DDD
|
|
524
|
+
// Line 1: DDD Domain Progress
|
|
670
525
|
const domainsColor = progress.domainsCompleted >= 3 ? c.brightGreen : progress.domainsCompleted > 0 ? c.yellow : c.red;
|
|
671
|
-
let perfIndicator;
|
|
672
|
-
if (agentdb.hasHnsw && agentdb.vectorCount > 0) {
|
|
673
|
-
const speedup = agentdb.vectorCount > 10000 ? '12500x' : agentdb.vectorCount > 1000 ? '150x' : '10x';
|
|
674
|
-
perfIndicator = `${c.brightGreen}\u26A1 HNSW ${speedup}${c.reset}`;
|
|
675
|
-
} else if (progress.patternsLearned > 0) {
|
|
676
|
-
const pk = progress.patternsLearned >= 1000 ? `${(progress.patternsLearned / 1000).toFixed(1)}k` : String(progress.patternsLearned);
|
|
677
|
-
perfIndicator = `${c.brightYellow}\uD83D\uDCDA ${pk} patterns${c.reset}`;
|
|
678
|
-
} else {
|
|
679
|
-
perfIndicator = `${c.dim}\u26A1 target: 150x-12500x${c.reset}`;
|
|
680
|
-
}
|
|
681
526
|
lines.push(
|
|
682
|
-
`${c.brightCyan}
|
|
683
|
-
`${domainsColor}${progress.domainsCompleted}${c.reset}/${c.brightWhite}${progress.totalDomains}${c.reset}
|
|
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}`
|
|
684
530
|
);
|
|
685
531
|
|
|
686
|
-
// Line 2: Swarm
|
|
687
|
-
|
|
532
|
+
// Line 2 (COLLISION LINE): Swarm status with padding after label
|
|
533
|
+
// The emoji+label is ~10 columns. Padding pushes content past collision zone (cols 15-25)
|
|
534
|
+
const swarmIndicator = swarm.coordinationActive ? `${c.brightGreen}◉${c.reset}` : `${c.dim}○${c.reset}`;
|
|
688
535
|
const agentsColor = swarm.activeAgents > 0 ? c.brightGreen : c.red;
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const hooksColor = hooks.enabled > 0 ? c.brightGreen : c.dim;
|
|
692
|
-
const intellColor = system.intelligencePct >= 80 ? c.brightGreen : system.intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
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;
|
|
693
538
|
|
|
539
|
+
// Padding after "🤖 Swarm" (emoji 2 cols + " Swarm" 6 cols = 8, pad 18 to reach col 26)
|
|
694
540
|
lines.push(
|
|
695
|
-
`${c.brightYellow}
|
|
696
|
-
`${c.
|
|
697
|
-
`${c.
|
|
698
|
-
`${
|
|
699
|
-
`${c.brightCyan}
|
|
700
|
-
`${
|
|
541
|
+
`${c.brightYellow}🤖 Swarm${c.reset} ` + // 18 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}`
|
|
701
547
|
);
|
|
702
548
|
|
|
703
|
-
// Line 3: Architecture
|
|
549
|
+
// Line 3: Architecture status (this is the last line, not in collision zone)
|
|
704
550
|
const dddColor = progress.dddProgress >= 50 ? c.brightGreen : progress.dddProgress > 0 ? c.yellow : c.red;
|
|
705
|
-
const adrColor = adrs.count > 0 ? (adrs.implemented === adrs.count ? c.brightGreen : c.yellow) : c.dim;
|
|
706
|
-
const adrDisplay = adrs.compliance > 0 ? `${adrColor}\u25CF${adrs.compliance}%${c.reset}` : `${adrColor}\u25CF${adrs.implemented}/${adrs.count}${c.reset}`;
|
|
707
|
-
|
|
708
|
-
lines.push(
|
|
709
|
-
`${c.brightPurple}\uD83D\uDD27 Architecture${c.reset} ` +
|
|
710
|
-
`${c.cyan}ADRs${c.reset} ${adrDisplay} ${c.dim}\u2502${c.reset} ` +
|
|
711
|
-
`${c.cyan}DDD${c.reset} ${dddColor}\u25CF${String(progress.dddProgress).padStart(3)}%${c.reset} ${c.dim}\u2502${c.reset} ` +
|
|
712
|
-
`${c.cyan}Security${c.reset} ${secColor}\u25CF${security.status}${c.reset}`
|
|
713
|
-
);
|
|
714
|
-
|
|
715
|
-
// Line 4: AgentDB, Tests, Integration
|
|
716
|
-
const hnswInd = agentdb.hasHnsw ? `${c.brightGreen}\u26A1${c.reset}` : '';
|
|
717
|
-
const sizeDisp = agentdb.dbSizeKB >= 1024 ? `${(agentdb.dbSizeKB / 1024).toFixed(1)}MB` : `${agentdb.dbSizeKB}KB`;
|
|
718
|
-
const vectorColor = agentdb.vectorCount > 0 ? c.brightGreen : c.dim;
|
|
719
|
-
const testColor = tests.testFiles > 0 ? c.brightGreen : c.dim;
|
|
720
|
-
|
|
721
|
-
let integStr = '';
|
|
722
|
-
if (integration.mcpServers.total > 0) {
|
|
723
|
-
const mcpCol = integration.mcpServers.enabled === integration.mcpServers.total ? c.brightGreen :
|
|
724
|
-
integration.mcpServers.enabled > 0 ? c.brightYellow : c.red;
|
|
725
|
-
integStr += `${c.cyan}MCP${c.reset} ${mcpCol}\u25CF${integration.mcpServers.enabled}/${integration.mcpServers.total}${c.reset}`;
|
|
726
|
-
}
|
|
727
|
-
if (integration.hasDatabase) integStr += (integStr ? ' ' : '') + `${c.brightGreen}\u25C6${c.reset}DB`;
|
|
728
|
-
if (integration.hasApi) integStr += (integStr ? ' ' : '') + `${c.brightGreen}\u25C6${c.reset}API`;
|
|
729
|
-
if (!integStr) integStr = `${c.dim}\u25CF none${c.reset}`;
|
|
730
|
-
|
|
731
551
|
lines.push(
|
|
732
|
-
`${c.
|
|
733
|
-
`${c.cyan}
|
|
734
|
-
`${c.cyan}
|
|
735
|
-
`${c.cyan}
|
|
736
|
-
|
|
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}`
|
|
737
557
|
);
|
|
738
558
|
|
|
739
559
|
return lines.join('\n');
|
|
740
560
|
}
|
|
741
561
|
|
|
742
|
-
//
|
|
743
|
-
function generateJSON() {
|
|
744
|
-
const git = getGitInfo();
|
|
745
|
-
return {
|
|
746
|
-
user: { name: git.name, gitBranch: git.gitBranch, modelName: getModelName() },
|
|
747
|
-
v3Progress: getV3Progress(),
|
|
748
|
-
security: getSecurityStatus(),
|
|
749
|
-
swarm: getSwarmStatus(),
|
|
750
|
-
system: getSystemMetrics(),
|
|
751
|
-
adrs: getADRStatus(),
|
|
752
|
-
hooks: getHooksStatus(),
|
|
753
|
-
agentdb: getAgentDBStats(),
|
|
754
|
-
tests: getTestStats(),
|
|
755
|
-
git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
|
|
756
|
-
lastUpdated: new Date().toISOString(),
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// ─── Main ───────────────────────────────────────────────────────
|
|
562
|
+
// Main
|
|
761
563
|
if (process.argv.includes('--json')) {
|
|
762
564
|
console.log(JSON.stringify(generateJSON(), null, 2));
|
|
763
565
|
} else if (process.argv.includes('--compact')) {
|
|
764
566
|
console.log(JSON.stringify(generateJSON()));
|
|
765
|
-
} else if (process.argv.includes('--single
|
|
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
|
|
766
572
|
console.log(generateStatusline());
|
|
767
573
|
} else {
|
|
768
|
-
// Default: multi-line
|
|
769
|
-
|
|
574
|
+
// Default: Safe multi-line mode with collision zone avoidance
|
|
575
|
+
// Use --unsafe or --legacy to get the original behavior
|
|
576
|
+
console.log(generateSafeStatusline());
|
|
770
577
|
}
|