kynjal-cli 3.1.3 → 4.0.0
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 +14 -33
- 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.js +664 -0
- package/dist/src/appliance/gguf-engine.js.map +1 -0
- package/dist/src/appliance/ruvllm-bridge.js +492 -0
- package/dist/src/appliance/ruvllm-bridge.js.map +1 -0
- package/dist/src/appliance/rvfa-builder.js +383 -0
- package/dist/src/appliance/rvfa-builder.js.map +1 -0
- package/dist/src/appliance/rvfa-distribution.js +533 -0
- package/dist/src/appliance/rvfa-distribution.js.map +1 -0
- package/dist/src/appliance/rvfa-format.js +465 -0
- package/dist/src/appliance/rvfa-format.js.map +1 -0
- package/dist/src/appliance/rvfa-runner.js +373 -0
- package/dist/src/appliance/rvfa-runner.js.map +1 -0
- package/dist/src/appliance/rvfa-signing.js +469 -0
- package/dist/src/appliance/rvfa-signing.js.map +1 -0
- package/dist/src/benchmarks/pretrain/index.js +542 -331
- package/dist/src/benchmarks/pretrain/index.js.map +1 -1
- package/dist/src/commands/agent.d.ts.map +1 -1
- package/dist/src/commands/agent.js +725 -502
- package/dist/src/commands/agent.js.map +1 -1
- package/dist/src/commands/analyze.js +1548 -1218
- package/dist/src/commands/analyze.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 +324 -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 +581 -0
- package/dist/src/commands/appliance.js.map +1 -0
- package/dist/src/commands/benchmark.js +523 -372
- package/dist/src/commands/benchmark.js.map +1 -1
- package/dist/src/commands/claims.js +364 -274
- 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 +262 -0
- package/dist/src/commands/cleanup.js.map +1 -0
- package/dist/src/commands/completions.js +118 -477
- package/dist/src/commands/completions.js.map +1 -1
- package/dist/src/commands/config.js +303 -237
- 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 +597 -425
- package/dist/src/commands/daemon.js.map +1 -1
- package/dist/src/commands/deployment.js +275 -194
- 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 +690 -460
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/embeddings.js +1543 -1293
- package/dist/src/commands/embeddings.js.map +1 -1
- package/dist/src/commands/guidance.js +596 -449
- package/dist/src/commands/guidance.js.map +1 -1
- package/dist/src/commands/hive-mind.js +938 -854
- 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 +3677 -2570
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/index.js +322 -122
- 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 +943 -787
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/issues.js +558 -383
- package/dist/src/commands/issues.js.map +1 -1
- package/dist/src/commands/mcp.d.ts.map +1 -1
- package/dist/src/commands/mcp.js +605 -475
- 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 +1031 -814
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/migrate.js +347 -282
- package/dist/src/commands/migrate.js.map +1 -1
- package/dist/src/commands/neural.d.ts.map +1 -1
- package/dist/src/commands/neural.js +1563 -1283
- package/dist/src/commands/neural.js.map +1 -1
- package/dist/src/commands/performance.js +643 -497
- package/dist/src/commands/performance.js.map +1 -1
- package/dist/src/commands/plugins.js +841 -668
- package/dist/src/commands/plugins.js.map +1 -1
- package/dist/src/commands/process.js +447 -392
- package/dist/src/commands/process.js.map +1 -1
- package/dist/src/commands/progress.js +256 -162
- package/dist/src/commands/progress.js.map +1 -1
- package/dist/src/commands/providers.js +220 -150
- package/dist/src/commands/providers.js.map +1 -1
- package/dist/src/commands/route.js +665 -520
- package/dist/src/commands/route.js.map +1 -1
- package/dist/src/commands/ruvector/backup.js +651 -505
- package/dist/src/commands/ruvector/backup.js.map +1 -1
- package/dist/src/commands/ruvector/benchmark.js +401 -349
- package/dist/src/commands/ruvector/benchmark.js.map +1 -1
- package/dist/src/commands/ruvector/import.js +267 -225
- package/dist/src/commands/ruvector/import.js.map +1 -1
- package/dist/src/commands/ruvector/index.js +75 -37
- package/dist/src/commands/ruvector/index.js.map +1 -1
- package/dist/src/commands/ruvector/init.js +359 -336
- package/dist/src/commands/ruvector/init.js.map +1 -1
- package/dist/src/commands/ruvector/migrate.js +322 -335
- package/dist/src/commands/ruvector/migrate.js.map +1 -1
- package/dist/src/commands/ruvector/optimize.js +431 -375
- package/dist/src/commands/ruvector/optimize.js.map +1 -1
- package/dist/src/commands/ruvector/setup.js +117 -703
- package/dist/src/commands/ruvector/setup.js.map +1 -1
- package/dist/src/commands/ruvector/status.js +419 -364
- package/dist/src/commands/ruvector/status.js.map +1 -1
- package/dist/src/commands/security.d.ts.map +1 -1
- package/dist/src/commands/security.js +610 -456
- package/dist/src/commands/security.js.map +1 -1
- package/dist/src/commands/session.d.ts +1 -1
- package/dist/src/commands/session.js +627 -505
- package/dist/src/commands/session.js.map +1 -1
- package/dist/src/commands/start.d.ts +1 -1
- package/dist/src/commands/start.js +368 -271
- 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 +492 -379
- package/dist/src/commands/status.js.map +1 -1
- package/dist/src/commands/swarm.js +488 -408
- package/dist/src/commands/swarm.js.map +1 -1
- package/dist/src/commands/task.d.ts +1 -1
- package/dist/src/commands/task.js +539 -424
- package/dist/src/commands/task.js.map +1 -1
- package/dist/src/commands/transfer-store.js +412 -322
- package/dist/src/commands/transfer-store.js.map +1 -1
- package/dist/src/commands/update.js +291 -196
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/workflow.js +486 -386
- package/dist/src/commands/workflow.js.map +1 -1
- package/dist/src/config-adapter.js +40 -39
- package/dist/src/config-adapter.js.map +1 -1
- package/dist/src/index.js +416 -312
- package/dist/src/index.js.map +1 -1
- package/dist/src/infrastructure/in-memory-repositories.js +507 -246
- package/dist/src/infrastructure/in-memory-repositories.js.map +1 -1
- package/dist/src/init/claudemd-generator.js +78 -368
- package/dist/src/init/claudemd-generator.js.map +1 -1
- package/dist/src/init/executor.js +1019 -1345
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/helpers-generator.js +60 -635
- package/dist/src/init/helpers-generator.js.map +1 -1
- package/dist/src/init/index.d.ts +1 -1
- package/dist/src/init/index.d.ts.map +1 -1
- package/dist/src/init/index.js +1 -1
- package/dist/src/init/index.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 +62 -42
- 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 +167 -100
- 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 +20 -1300
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/init/types.d.ts +15 -5
- package/dist/src/init/types.d.ts.map +1 -1
- package/dist/src/init/types.js +66 -76
- package/dist/src/init/types.js.map +1 -1
- package/dist/src/mcp-client.js +130 -76
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-server.js +758 -445
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp-tools/agent-tools.js +492 -391
- package/dist/src/mcp-tools/agent-tools.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 +758 -0
- package/dist/src/mcp-tools/agentdb-tools.js.map +1 -0
- package/dist/src/mcp-tools/analyze-tools.js +236 -172
- package/dist/src/mcp-tools/analyze-tools.js.map +1 -1
- package/dist/src/mcp-tools/auto-install.js +142 -80
- package/dist/src/mcp-tools/auto-install.js.map +1 -1
- package/dist/src/mcp-tools/browser-tools.js +375 -252
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/claims-tools.js +565 -473
- package/dist/src/mcp-tools/claims-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 +284 -190
- 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 +600 -349
- package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
- package/dist/src/mcp-tools/daa-tools.js +367 -289
- package/dist/src/mcp-tools/daa-tools.js.map +1 -1
- package/dist/src/mcp-tools/embeddings-tools.js +693 -582
- package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
- package/dist/src/mcp-tools/github-tools.js +312 -261
- 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 +718 -423
- 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 +2726 -1978
- 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 +514 -329
- 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 +428 -326
- package/dist/src/mcp-tools/neural-tools.js.map +1 -1
- package/dist/src/mcp-tools/performance-tools.js +480 -420
- package/dist/src/mcp-tools/performance-tools.js.map +1 -1
- package/dist/src/mcp-tools/progress-tools.js +278 -204
- package/dist/src/mcp-tools/progress-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 +399 -0
- package/dist/src/mcp-tools/ruvllm-tools.js.map +1 -0
- package/dist/src/mcp-tools/security-tools.js +429 -297
- package/dist/src/mcp-tools/security-tools.js.map +1 -1
- package/dist/src/mcp-tools/session-tools.js +234 -185
- package/dist/src/mcp-tools/session-tools.js.map +1 -1
- 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 +303 -64
- 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 +352 -200
- 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 +357 -189
- package/dist/src/mcp-tools/task-tools.js.map +1 -1
- package/dist/src/mcp-tools/terminal-tools.js +196 -148
- package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
- package/dist/src/mcp-tools/transfer-tools.js +333 -186
- package/dist/src/mcp-tools/transfer-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 +377 -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 +471 -335
- package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
- package/dist/src/memory/ewc-consolidation.js +345 -173
- package/dist/src/memory/ewc-consolidation.js.map +1 -1
- package/dist/src/memory/intelligence.js +841 -359
- package/dist/src/memory/intelligence.js.map +1 -1
- package/dist/src/memory/memory-bridge.js +1964 -0
- package/dist/src/memory/memory-bridge.js.map +1 -0
- package/dist/src/memory/memory-initializer.js +1895 -1602
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/memory/sona-optimizer.js +329 -199
- package/dist/src/memory/sona-optimizer.js.map +1 -1
- package/dist/src/output.d.ts +2 -2
- package/dist/src/output.d.ts.map +1 -1
- package/dist/src/output.js +273 -242
- package/dist/src/output.js.map +1 -1
- package/dist/src/parser.js +217 -124
- package/dist/src/parser.js.map +1 -1
- package/dist/src/plugins/manager.js +531 -278
- package/dist/src/plugins/manager.js.map +1 -1
- package/dist/src/plugins/store/discovery.js +362 -275
- package/dist/src/plugins/store/discovery.js.map +1 -1
- package/dist/src/plugins/store/index.js +105 -48
- package/dist/src/plugins/store/index.js.map +1 -1
- package/dist/src/plugins/store/search.js +107 -69
- package/dist/src/plugins/store/search.js.map +1 -1
- package/dist/src/plugins/tests/demo-plugin-store.js +160 -113
- package/dist/src/plugins/tests/demo-plugin-store.js.map +1 -1
- package/dist/src/plugins/tests/standalone-test.js +223 -172
- package/dist/src/plugins/tests/standalone-test.js.map +1 -1
- package/dist/src/plugins/tests/test-plugin-store.js +228 -190
- package/dist/src/plugins/tests/test-plugin-store.js.map +1 -1
- package/dist/src/production/circuit-breaker.js +126 -62
- package/dist/src/production/circuit-breaker.js.map +1 -1
- package/dist/src/production/error-handler.js +156 -86
- package/dist/src/production/error-handler.js.map +1 -1
- package/dist/src/production/monitoring.js +220 -139
- package/dist/src/production/monitoring.js.map +1 -1
- package/dist/src/production/rate-limiter.js +93 -74
- package/dist/src/production/rate-limiter.js.map +1 -1
- package/dist/src/production/retry.js +167 -75
- package/dist/src/production/retry.js.map +1 -1
- package/dist/src/prompt.js +560 -436
- package/dist/src/prompt.js.map +1 -1
- package/dist/src/runtime/headless.js +289 -200
- package/dist/src/runtime/headless.js.map +1 -1
- package/dist/src/ruvector/agent-wasm.js +511 -0
- package/dist/src/ruvector/agent-wasm.js.map +1 -0
- package/dist/src/ruvector/ast-analyzer.js +232 -145
- package/dist/src/ruvector/ast-analyzer.js.map +1 -1
- package/dist/src/ruvector/coverage-router.js +419 -287
- package/dist/src/ruvector/coverage-router.js.map +1 -1
- package/dist/src/ruvector/coverage-tools.js +101 -56
- package/dist/src/ruvector/coverage-tools.js.map +1 -1
- package/dist/src/ruvector/diff-classifier.js +451 -324
- package/dist/src/ruvector/diff-classifier.js.map +1 -1
- package/dist/src/ruvector/enhanced-model-router.js +337 -251
- package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
- package/dist/src/ruvector/flash-attention.js +254 -223
- package/dist/src/ruvector/flash-attention.js.map +1 -1
- package/dist/src/ruvector/graph-analyzer.js +680 -486
- package/dist/src/ruvector/graph-analyzer.js.map +1 -1
- package/dist/src/ruvector/index.js +113 -27
- package/dist/src/ruvector/index.js.map +1 -1
- package/dist/src/ruvector/lora-adapter.js +248 -155
- package/dist/src/ruvector/lora-adapter.js.map +1 -1
- package/dist/src/ruvector/model-router.js +248 -175
- package/dist/src/ruvector/model-router.js.map +1 -1
- package/dist/src/ruvector/moe-router.js +286 -228
- package/dist/src/ruvector/moe-router.js.map +1 -1
- package/dist/src/ruvector/q-learning-router.js +338 -257
- package/dist/src/ruvector/q-learning-router.js.map +1 -1
- package/dist/src/ruvector/ruvllm-wasm.js +527 -0
- package/dist/src/ruvector/ruvllm-wasm.js.map +1 -0
- package/dist/src/ruvector/semantic-router.js +67 -60
- package/dist/src/ruvector/semantic-router.js.map +1 -1
- package/dist/src/ruvector/vector-db.js +205 -119
- package/dist/src/ruvector/vector-db.js.map +1 -1
- package/dist/src/services/agentic-flow-bridge.js +168 -0
- package/dist/src/services/agentic-flow-bridge.js.map +1 -0
- package/dist/src/services/claim-service.js +940 -615
- package/dist/src/services/claim-service.js.map +1 -1
- package/dist/src/services/container-worker-pool.js +669 -399
- package/dist/src/services/container-worker-pool.js.map +1 -1
- package/dist/src/services/headless-worker-executor.js +467 -441
- package/dist/src/services/headless-worker-executor.js.map +1 -1
- package/dist/src/services/index.d.ts +5 -5
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/index.js +4 -4
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/services/registry-api.js +201 -93
- package/dist/src/services/registry-api.js.map +1 -1
- package/dist/src/services/ruvector-training.js +414 -144
- package/dist/src/services/ruvector-training.js.map +1 -1
- package/dist/src/services/worker-daemon.js +928 -531
- package/dist/src/services/worker-daemon.js.map +1 -1
- package/dist/src/services/worker-queue.js +550 -331
- package/dist/src/services/worker-queue.js.map +1 -1
- package/dist/src/suggest.js +55 -45
- package/dist/src/suggest.js.map +1 -1
- package/dist/src/transfer/anonymization/index.js +37 -29
- package/dist/src/transfer/anonymization/index.js.map +1 -1
- package/dist/src/transfer/deploy-seraphine.d.ts +1 -1
- package/dist/src/transfer/deploy-seraphine.js +156 -129
- package/dist/src/transfer/deploy-seraphine.js.map +1 -1
- package/dist/src/transfer/export.js +142 -84
- package/dist/src/transfer/export.js.map +1 -1
- package/dist/src/transfer/index.d.ts +1 -1
- package/dist/src/transfer/index.d.ts.map +1 -1
- package/dist/src/transfer/index.js +2 -0
- package/dist/src/transfer/index.js.map +1 -1
- package/dist/src/transfer/ipfs/client.js +337 -179
- package/dist/src/transfer/ipfs/client.js.map +1 -1
- package/dist/src/transfer/ipfs/upload.js +434 -290
- package/dist/src/transfer/ipfs/upload.js.map +1 -1
- package/dist/src/transfer/models/seraphine.js +58 -58
- package/dist/src/transfer/models/seraphine.js.map +1 -1
- package/dist/src/transfer/serialization/cfp.js +37 -33
- package/dist/src/transfer/serialization/cfp.js.map +1 -1
- package/dist/src/transfer/storage/gcs.js +248 -139
- package/dist/src/transfer/storage/gcs.js.map +1 -1
- package/dist/src/transfer/store/discovery.js +353 -243
- package/dist/src/transfer/store/discovery.js.map +1 -1
- package/dist/src/transfer/store/download.js +365 -243
- package/dist/src/transfer/store/download.js.map +1 -1
- package/dist/src/transfer/store/index.js +130 -63
- package/dist/src/transfer/store/index.js.map +1 -1
- package/dist/src/transfer/store/publish.js +258 -184
- package/dist/src/transfer/store/publish.js.map +1 -1
- package/dist/src/transfer/store/registry.js +73 -51
- package/dist/src/transfer/store/registry.js.map +1 -1
- package/dist/src/transfer/store/search.js +96 -64
- package/dist/src/transfer/store/search.js.map +1 -1
- package/dist/src/transfer/store/tests/standalone-test.js +231 -174
- package/dist/src/transfer/store/tests/standalone-test.js.map +1 -1
- package/dist/src/transfer/test-seraphine.js +130 -95
- package/dist/src/transfer/test-seraphine.js.map +1 -1
- package/dist/src/transfer/tests/test-store.js +239 -194
- package/dist/src/transfer/tests/test-store.js.map +1 -1
- package/dist/src/types.js +56 -27
- package/dist/src/types.js.map +1 -1
- package/dist/src/update/checker.js +183 -106
- package/dist/src/update/checker.js.map +1 -1
- package/dist/src/update/executor.js +198 -135
- package/dist/src/update/executor.js.map +1 -1
- package/dist/src/update/index.js +85 -38
- package/dist/src/update/index.js.map +1 -1
- package/dist/src/update/rate-limiter.js +31 -19
- package/dist/src/update/rate-limiter.js.map +1 -1
- package/dist/src/update/validator.js +64 -38
- 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
- package/dist/src/benchmarks/pretrain/index.d.ts +0 -58
- package/dist/src/benchmarks/pretrain/index.d.ts.map +0 -1
- package/dist/src/commands/index.d.ts +0 -108
- package/dist/src/commands/index.d.ts.map +0 -1
- package/dist/src/config-adapter.d.ts +0 -15
- package/dist/src/config-adapter.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -76
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/infrastructure/in-memory-repositories.d.ts +0 -68
- package/dist/src/infrastructure/in-memory-repositories.d.ts.map +0 -1
- package/dist/src/init/claudemd-generator.d.ts +0 -25
- package/dist/src/init/claudemd-generator.d.ts.map +0 -1
- package/dist/src/init/executor.d.ts +0 -41
- package/dist/src/init/executor.d.ts.map +0 -1
- package/dist/src/init/helpers-generator.d.ts +0 -60
- package/dist/src/init/helpers-generator.d.ts.map +0 -1
- package/dist/src/mcp-client.d.ts +0 -92
- package/dist/src/mcp-client.d.ts.map +0 -1
- package/dist/src/mcp-server.d.ts +0 -161
- package/dist/src/mcp-server.d.ts.map +0 -1
- package/dist/src/mcp-tools/auto-install.d.ts +0 -83
- package/dist/src/mcp-tools/auto-install.d.ts.map +0 -1
- package/dist/src/mcp-tools/types.d.ts +0 -31
- package/dist/src/mcp-tools/types.d.ts.map +0 -1
- package/dist/src/memory/ewc-consolidation.d.ts +0 -271
- package/dist/src/memory/ewc-consolidation.d.ts.map +0 -1
- package/dist/src/memory/intelligence.d.ts +0 -285
- package/dist/src/memory/intelligence.d.ts.map +0 -1
- package/dist/src/memory/memory-initializer.d.ts +0 -396
- package/dist/src/memory/memory-initializer.d.ts.map +0 -1
- package/dist/src/memory/sona-optimizer.d.ts +0 -227
- package/dist/src/memory/sona-optimizer.d.ts.map +0 -1
- package/dist/src/parser.d.ts +0 -41
- package/dist/src/parser.d.ts.map +0 -1
- package/dist/src/plugins/manager.d.ts +0 -133
- package/dist/src/plugins/manager.d.ts.map +0 -1
- package/dist/src/plugins/store/discovery.d.ts +0 -88
- package/dist/src/plugins/store/discovery.d.ts.map +0 -1
- package/dist/src/plugins/store/index.d.ts +0 -76
- package/dist/src/plugins/store/index.d.ts.map +0 -1
- package/dist/src/plugins/store/search.d.ts +0 -46
- package/dist/src/plugins/store/search.d.ts.map +0 -1
- package/dist/src/plugins/store/types.d.ts +0 -274
- package/dist/src/plugins/store/types.d.ts.map +0 -1
- package/dist/src/production/circuit-breaker.d.ts +0 -101
- package/dist/src/production/circuit-breaker.d.ts.map +0 -1
- package/dist/src/production/error-handler.d.ts +0 -92
- package/dist/src/production/error-handler.d.ts.map +0 -1
- package/dist/src/production/monitoring.d.ts +0 -161
- package/dist/src/production/monitoring.d.ts.map +0 -1
- package/dist/src/production/rate-limiter.d.ts +0 -80
- package/dist/src/production/rate-limiter.d.ts.map +0 -1
- package/dist/src/production/retry.d.ts +0 -48
- package/dist/src/production/retry.d.ts.map +0 -1
- package/dist/src/prompt.d.ts +0 -44
- package/dist/src/prompt.d.ts.map +0 -1
- package/dist/src/runtime/headless.d.ts +0 -60
- package/dist/src/runtime/headless.d.ts.map +0 -1
- package/dist/src/ruvector/ast-analyzer.d.ts +0 -67
- package/dist/src/ruvector/ast-analyzer.d.ts.map +0 -1
- package/dist/src/ruvector/coverage-router.d.ts +0 -160
- package/dist/src/ruvector/coverage-router.d.ts.map +0 -1
- package/dist/src/ruvector/diff-classifier.d.ts +0 -175
- package/dist/src/ruvector/diff-classifier.d.ts.map +0 -1
- package/dist/src/ruvector/enhanced-model-router.d.ts +0 -146
- package/dist/src/ruvector/enhanced-model-router.d.ts.map +0 -1
- package/dist/src/ruvector/flash-attention.d.ts +0 -195
- package/dist/src/ruvector/flash-attention.d.ts.map +0 -1
- package/dist/src/ruvector/graph-analyzer.d.ts +0 -187
- package/dist/src/ruvector/graph-analyzer.d.ts.map +0 -1
- package/dist/src/ruvector/index.d.ts +0 -34
- package/dist/src/ruvector/index.d.ts.map +0 -1
- package/dist/src/ruvector/lora-adapter.d.ts +0 -218
- package/dist/src/ruvector/lora-adapter.d.ts.map +0 -1
- package/dist/src/ruvector/model-router.d.ts +0 -220
- package/dist/src/ruvector/model-router.d.ts.map +0 -1
- package/dist/src/ruvector/moe-router.d.ts +0 -206
- package/dist/src/ruvector/moe-router.d.ts.map +0 -1
- package/dist/src/ruvector/q-learning-router.d.ts +0 -211
- package/dist/src/ruvector/q-learning-router.d.ts.map +0 -1
- package/dist/src/ruvector/semantic-router.d.ts +0 -77
- package/dist/src/ruvector/semantic-router.d.ts.map +0 -1
- package/dist/src/ruvector/vector-db.d.ts +0 -69
- package/dist/src/ruvector/vector-db.d.ts.map +0 -1
- package/dist/src/services/claim-service.d.ts +0 -204
- package/dist/src/services/claim-service.d.ts.map +0 -1
- package/dist/src/services/container-worker-pool.d.ts +0 -197
- package/dist/src/services/container-worker-pool.d.ts.map +0 -1
- package/dist/src/services/headless-worker-executor.d.ts +0 -304
- package/dist/src/services/headless-worker-executor.d.ts.map +0 -1
- package/dist/src/services/registry-api.d.ts +0 -58
- package/dist/src/services/registry-api.d.ts.map +0 -1
- package/dist/src/services/ruvector-training.d.ts +0 -213
- package/dist/src/services/ruvector-training.d.ts.map +0 -1
- package/dist/src/services/worker-daemon.d.ts +0 -203
- package/dist/src/services/worker-daemon.d.ts.map +0 -1
- package/dist/src/services/worker-queue.d.ts +0 -194
- package/dist/src/services/worker-queue.d.ts.map +0 -1
- package/dist/src/suggest.d.ts +0 -53
- package/dist/src/suggest.d.ts.map +0 -1
- package/dist/src/transfer/export.d.ts +0 -25
- package/dist/src/transfer/export.d.ts.map +0 -1
- package/dist/src/transfer/ipfs/client.d.ts +0 -109
- package/dist/src/transfer/ipfs/client.d.ts.map +0 -1
- package/dist/src/transfer/ipfs/upload.d.ts +0 -95
- package/dist/src/transfer/ipfs/upload.d.ts.map +0 -1
- package/dist/src/transfer/models/seraphine.d.ts +0 -72
- package/dist/src/transfer/models/seraphine.d.ts.map +0 -1
- package/dist/src/transfer/serialization/cfp.d.ts +0 -49
- package/dist/src/transfer/serialization/cfp.d.ts.map +0 -1
- package/dist/src/transfer/storage/gcs.d.ts +0 -82
- package/dist/src/transfer/storage/gcs.d.ts.map +0 -1
- package/dist/src/transfer/store/discovery.d.ts +0 -84
- package/dist/src/transfer/store/discovery.d.ts.map +0 -1
- package/dist/src/transfer/store/download.d.ts +0 -70
- package/dist/src/transfer/store/download.d.ts.map +0 -1
- package/dist/src/transfer/store/index.d.ts +0 -84
- package/dist/src/transfer/store/index.d.ts.map +0 -1
- package/dist/src/transfer/store/publish.d.ts +0 -76
- package/dist/src/transfer/store/publish.d.ts.map +0 -1
- package/dist/src/transfer/store/search.d.ts +0 -54
- package/dist/src/transfer/store/search.d.ts.map +0 -1
- package/dist/src/transfer/types.d.ts +0 -245
- package/dist/src/transfer/types.d.ts.map +0 -1
- package/dist/src/types.d.ts +0 -198
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/update/checker.d.ts +0 -34
- package/dist/src/update/checker.d.ts.map +0 -1
- package/dist/src/update/executor.d.ts +0 -32
- package/dist/src/update/executor.d.ts.map +0 -1
- package/dist/src/update/index.d.ts +0 -33
- package/dist/src/update/index.d.ts.map +0 -1
- package/dist/src/update/rate-limiter.d.ts +0 -20
- package/dist/src/update/rate-limiter.d.ts.map +0 -1
- package/dist/src/update/validator.d.ts +0 -17
- package/dist/src/update/validator.d.ts.map +0 -1
|
@@ -13,6 +13,53 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Created with ruv.io
|
|
15
15
|
*/
|
|
16
|
+
var __assign = (this && this.__assign) || function () {
|
|
17
|
+
__assign = Object.assign || function(t) {
|
|
18
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
19
|
+
s = arguments[i];
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
21
|
+
t[p] = s[p];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
return __assign.apply(this, arguments);
|
|
26
|
+
};
|
|
27
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
28
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
29
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
30
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
31
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
32
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
33
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
37
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
38
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
39
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
40
|
+
function step(op) {
|
|
41
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
42
|
+
while (_) try {
|
|
43
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
44
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
45
|
+
switch (op[0]) {
|
|
46
|
+
case 0: case 1: t = op; break;
|
|
47
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
48
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
49
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
50
|
+
default:
|
|
51
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
52
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
53
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
54
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
55
|
+
if (t[2]) _.ops.pop();
|
|
56
|
+
_.trys.pop(); continue;
|
|
57
|
+
}
|
|
58
|
+
op = body.call(thisArg, _);
|
|
59
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
60
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
61
|
+
}
|
|
62
|
+
};
|
|
16
63
|
import { output } from '../output.js';
|
|
17
64
|
import { callMCPTool, MCPClientError } from '../mcp-client.js';
|
|
18
65
|
import * as path from 'path';
|
|
@@ -20,25 +67,43 @@ import * as fs from 'fs/promises';
|
|
|
20
67
|
import { writeFile } from 'fs/promises';
|
|
21
68
|
import { resolve } from 'path';
|
|
22
69
|
// Dynamic import for AST analyzer
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
70
|
+
function getASTAnalyzer() {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
72
|
+
var _a;
|
|
73
|
+
return __generator(this, function (_b) {
|
|
74
|
+
switch (_b.label) {
|
|
75
|
+
case 0:
|
|
76
|
+
_b.trys.push([0, 2, , 3]);
|
|
77
|
+
return [4 /*yield*/, import('../ruvector/ast-analyzer.js')];
|
|
78
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
79
|
+
case 2:
|
|
80
|
+
_a = _b.sent();
|
|
81
|
+
return [2 /*return*/, null];
|
|
82
|
+
case 3: return [2 /*return*/];
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
30
86
|
}
|
|
31
87
|
// Dynamic import for graph analyzer
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
88
|
+
function getGraphAnalyzer() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
90
|
+
var _a;
|
|
91
|
+
return __generator(this, function (_b) {
|
|
92
|
+
switch (_b.label) {
|
|
93
|
+
case 0:
|
|
94
|
+
_b.trys.push([0, 2, , 3]);
|
|
95
|
+
return [4 /*yield*/, import('../ruvector/graph-analyzer.js')];
|
|
96
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
97
|
+
case 2:
|
|
98
|
+
_a = _b.sent();
|
|
99
|
+
return [2 /*return*/, null];
|
|
100
|
+
case 3: return [2 /*return*/];
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
39
104
|
}
|
|
40
105
|
// Diff subcommand
|
|
41
|
-
|
|
106
|
+
var diffCommand = {
|
|
42
107
|
name: 'diff',
|
|
43
108
|
description: 'Analyze git diff for change risk assessment and classification',
|
|
44
109
|
options: [
|
|
@@ -47,35 +112,35 @@ const diffCommand = {
|
|
|
47
112
|
short: 'r',
|
|
48
113
|
description: 'Show risk assessment',
|
|
49
114
|
type: 'boolean',
|
|
50
|
-
default: false
|
|
115
|
+
"default": false
|
|
51
116
|
},
|
|
52
117
|
{
|
|
53
118
|
name: 'classify',
|
|
54
119
|
short: 'c',
|
|
55
120
|
description: 'Classify change type',
|
|
56
121
|
type: 'boolean',
|
|
57
|
-
default: false
|
|
122
|
+
"default": false
|
|
58
123
|
},
|
|
59
124
|
{
|
|
60
125
|
name: 'reviewers',
|
|
61
126
|
description: 'Show recommended reviewers',
|
|
62
127
|
type: 'boolean',
|
|
63
|
-
default: false
|
|
128
|
+
"default": false
|
|
64
129
|
},
|
|
65
130
|
{
|
|
66
131
|
name: 'format',
|
|
67
132
|
short: 'f',
|
|
68
133
|
description: 'Output format: text, json, table',
|
|
69
134
|
type: 'string',
|
|
70
|
-
default: 'text',
|
|
71
|
-
choices: ['text', 'json', 'table']
|
|
135
|
+
"default": 'text',
|
|
136
|
+
choices: ['text', 'json', 'table']
|
|
72
137
|
},
|
|
73
138
|
{
|
|
74
139
|
name: 'verbose',
|
|
75
140
|
short: 'v',
|
|
76
141
|
description: 'Show detailed file-level analysis',
|
|
77
142
|
type: 'boolean',
|
|
78
|
-
default: false
|
|
143
|
+
"default": false
|
|
79
144
|
},
|
|
80
145
|
],
|
|
81
146
|
examples: [
|
|
@@ -84,191 +149,201 @@ const diffCommand = {
|
|
|
84
149
|
{ command: 'claude-flow analyze diff main..feature --format json', description: 'Compare branches with JSON output' },
|
|
85
150
|
{ command: 'claude-flow analyze diff --reviewers', description: 'Get recommended reviewers for changes' },
|
|
86
151
|
],
|
|
87
|
-
action:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`Ref: ${result.ref || 'HEAD'}`,
|
|
116
|
-
`Files: ${files.length}`,
|
|
117
|
-
`Risk: ${getRiskDisplay(risk.overall)} (${risk.score}/100)`,
|
|
118
|
-
`Type: ${classification.category}${classification.subcategory ? ` (${classification.subcategory})` : ''}`,
|
|
119
|
-
``,
|
|
120
|
-
result.summary || 'No summary available',
|
|
121
|
-
].join('\n'), 'Diff Analysis');
|
|
122
|
-
// Risk assessment
|
|
123
|
-
if (showRisk || showAll) {
|
|
124
|
-
output.writeln();
|
|
125
|
-
output.writeln(output.bold('Risk Assessment'));
|
|
126
|
-
output.writeln(output.dim('-'.repeat(50)));
|
|
127
|
-
output.printTable({
|
|
128
|
-
columns: [
|
|
129
|
-
{ key: 'metric', header: 'Metric', width: 25 },
|
|
130
|
-
{ key: 'value', header: 'Value', width: 30 },
|
|
131
|
-
],
|
|
132
|
-
data: [
|
|
133
|
-
{ metric: 'Overall Risk', value: getRiskDisplay(risk.overall) },
|
|
134
|
-
{ metric: 'Risk Score', value: `${risk.score}/100` },
|
|
135
|
-
{ metric: 'Files Changed', value: risk.breakdown.fileCount },
|
|
136
|
-
{ metric: 'Total Lines Changed', value: risk.breakdown.totalChanges },
|
|
137
|
-
{ metric: 'Test Coverage', value: risk.breakdown.testCoverage },
|
|
138
|
-
],
|
|
139
|
-
});
|
|
140
|
-
// Security concerns
|
|
141
|
-
if (risk.breakdown.securityConcerns.length > 0) {
|
|
142
|
-
output.writeln();
|
|
143
|
-
output.writeln(output.bold(output.warning('Security Concerns')));
|
|
144
|
-
output.printList(risk.breakdown.securityConcerns.map(c => output.warning(c)));
|
|
145
|
-
}
|
|
146
|
-
// Breaking changes
|
|
147
|
-
if (risk.breakdown.breakingChanges.length > 0) {
|
|
148
|
-
output.writeln();
|
|
149
|
-
output.writeln(output.bold(output.error('Potential Breaking Changes')));
|
|
150
|
-
output.printList(risk.breakdown.breakingChanges.map(c => output.error(c)));
|
|
151
|
-
}
|
|
152
|
-
// High risk files
|
|
153
|
-
if (risk.breakdown.highRiskFiles.length > 0) {
|
|
152
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
153
|
+
var ref, showRisk, showClassify, showReviewers, formatType, verbose, showAll, result, files, risk, classification, reviewers, error_1;
|
|
154
|
+
return __generator(this, function (_a) {
|
|
155
|
+
switch (_a.label) {
|
|
156
|
+
case 0:
|
|
157
|
+
ref = ctx.args[0] || 'HEAD';
|
|
158
|
+
showRisk = ctx.flags.risk;
|
|
159
|
+
showClassify = ctx.flags.classify;
|
|
160
|
+
showReviewers = ctx.flags.reviewers;
|
|
161
|
+
formatType = ctx.flags.format || 'text';
|
|
162
|
+
verbose = ctx.flags.verbose;
|
|
163
|
+
showAll = !showRisk && !showClassify && !showReviewers;
|
|
164
|
+
output.printInfo("Analyzing diff: " + output.highlight(ref));
|
|
165
|
+
_a.label = 1;
|
|
166
|
+
case 1:
|
|
167
|
+
_a.trys.push([1, 3, , 4]);
|
|
168
|
+
return [4 /*yield*/, callMCPTool('analyze_diff', {
|
|
169
|
+
ref: ref,
|
|
170
|
+
includeFileRisks: verbose,
|
|
171
|
+
includeReviewers: showReviewers || showAll
|
|
172
|
+
})];
|
|
173
|
+
case 2:
|
|
174
|
+
result = _a.sent();
|
|
175
|
+
// JSON output
|
|
176
|
+
if (formatType === 'json') {
|
|
177
|
+
output.printJson(result);
|
|
178
|
+
return [2 /*return*/, { success: true, data: result }];
|
|
179
|
+
}
|
|
154
180
|
output.writeln();
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
181
|
+
files = result.files || [];
|
|
182
|
+
risk = result.risk || { overall: 'unknown', score: 0, breakdown: { fileCount: 0, totalChanges: 0, highRiskFiles: [], securityConcerns: [], breakingChanges: [], testCoverage: 'unknown' } };
|
|
183
|
+
classification = result.classification || { category: 'unknown', confidence: 0, reasoning: '' };
|
|
184
|
+
output.printBox([
|
|
185
|
+
"Ref: " + (result.ref || 'HEAD'),
|
|
186
|
+
"Files: " + files.length,
|
|
187
|
+
"Risk: " + getRiskDisplay(risk.overall) + " (" + risk.score + "/100)",
|
|
188
|
+
"Type: " + classification.category + (classification.subcategory ? " (" + classification.subcategory + ")" : ''),
|
|
189
|
+
"",
|
|
190
|
+
result.summary || 'No summary available',
|
|
191
|
+
].join('\n'), 'Diff Analysis');
|
|
192
|
+
// Risk assessment
|
|
193
|
+
if (showRisk || showAll) {
|
|
194
|
+
output.writeln();
|
|
195
|
+
output.writeln(output.bold('Risk Assessment'));
|
|
196
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
197
|
+
output.printTable({
|
|
198
|
+
columns: [
|
|
199
|
+
{ key: 'metric', header: 'Metric', width: 25 },
|
|
200
|
+
{ key: 'value', header: 'Value', width: 30 },
|
|
201
|
+
],
|
|
202
|
+
data: [
|
|
203
|
+
{ metric: 'Overall Risk', value: getRiskDisplay(risk.overall) },
|
|
204
|
+
{ metric: 'Risk Score', value: risk.score + "/100" },
|
|
205
|
+
{ metric: 'Files Changed', value: risk.breakdown.fileCount },
|
|
206
|
+
{ metric: 'Total Lines Changed', value: risk.breakdown.totalChanges },
|
|
207
|
+
{ metric: 'Test Coverage', value: risk.breakdown.testCoverage },
|
|
208
|
+
]
|
|
209
|
+
});
|
|
210
|
+
// Security concerns
|
|
211
|
+
if (risk.breakdown.securityConcerns.length > 0) {
|
|
212
|
+
output.writeln();
|
|
213
|
+
output.writeln(output.bold(output.warning('Security Concerns')));
|
|
214
|
+
output.printList(risk.breakdown.securityConcerns.map(function (c) { return output.warning(c); }));
|
|
215
|
+
}
|
|
216
|
+
// Breaking changes
|
|
217
|
+
if (risk.breakdown.breakingChanges.length > 0) {
|
|
218
|
+
output.writeln();
|
|
219
|
+
output.writeln(output.bold(output.error('Potential Breaking Changes')));
|
|
220
|
+
output.printList(risk.breakdown.breakingChanges.map(function (c) { return output.error(c); }));
|
|
221
|
+
}
|
|
222
|
+
// High risk files
|
|
223
|
+
if (risk.breakdown.highRiskFiles.length > 0) {
|
|
224
|
+
output.writeln();
|
|
225
|
+
output.writeln(output.bold('High Risk Files'));
|
|
226
|
+
output.printList(risk.breakdown.highRiskFiles.map(function (f) { return output.warning(f); }));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Classification
|
|
230
|
+
if (showClassify || showAll) {
|
|
231
|
+
output.writeln();
|
|
232
|
+
output.writeln(output.bold('Classification'));
|
|
233
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
234
|
+
output.printTable({
|
|
235
|
+
columns: [
|
|
236
|
+
{ key: 'field', header: 'Field', width: 15 },
|
|
237
|
+
{ key: 'value', header: 'Value', width: 40 },
|
|
238
|
+
],
|
|
239
|
+
data: [
|
|
240
|
+
{ field: 'Category', value: classification.category },
|
|
241
|
+
{ field: 'Subcategory', value: classification.subcategory || '-' },
|
|
242
|
+
{ field: 'Confidence', value: (classification.confidence * 100).toFixed(0) + "%" },
|
|
243
|
+
]
|
|
244
|
+
});
|
|
245
|
+
output.writeln();
|
|
246
|
+
output.writeln(output.dim("Reasoning: " + classification.reasoning));
|
|
247
|
+
}
|
|
248
|
+
// Reviewers
|
|
249
|
+
if (showReviewers || showAll) {
|
|
250
|
+
output.writeln();
|
|
251
|
+
output.writeln(output.bold('Recommended Reviewers'));
|
|
252
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
253
|
+
reviewers = result.recommendedReviewers || [];
|
|
254
|
+
if (reviewers.length > 0) {
|
|
255
|
+
output.printNumberedList(reviewers.map(function (r) { return output.highlight(r); }));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
output.writeln(output.dim('No specific reviewers recommended'));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Verbose file-level details
|
|
262
|
+
if (verbose && result.fileRisks) {
|
|
263
|
+
output.writeln();
|
|
264
|
+
output.writeln(output.bold('File-Level Analysis'));
|
|
265
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
266
|
+
output.printTable({
|
|
267
|
+
columns: [
|
|
268
|
+
{ key: 'path', header: 'File', width: 40 },
|
|
269
|
+
{ key: 'risk', header: 'Risk', width: 12, format: function (v) { return getRiskDisplay(String(v)); } },
|
|
270
|
+
{ key: 'score', header: 'Score', width: 8, align: 'right' },
|
|
271
|
+
{ key: 'reasons', header: 'Reasons', width: 30, format: function (v) {
|
|
272
|
+
var reasons = v;
|
|
273
|
+
return reasons.slice(0, 2).join('; ');
|
|
274
|
+
} },
|
|
275
|
+
],
|
|
276
|
+
data: result.fileRisks
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// Files changed table
|
|
280
|
+
if (formatType === 'table' || showAll) {
|
|
281
|
+
output.writeln();
|
|
282
|
+
output.writeln(output.bold('Files Changed'));
|
|
283
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
284
|
+
output.printTable({
|
|
285
|
+
columns: [
|
|
286
|
+
{ key: 'status', header: 'Status', width: 10, format: function (v) { return getStatusDisplay(String(v)); } },
|
|
287
|
+
{ key: 'path', header: 'File', width: 45 },
|
|
288
|
+
{ key: 'additions', header: '+', width: 8, align: 'right', format: function (v) { return output.success("+" + v); } },
|
|
289
|
+
{ key: 'deletions', header: '-', width: 8, align: 'right', format: function (v) { return output.error("-" + v); } },
|
|
290
|
+
],
|
|
291
|
+
data: files.slice(0, 20)
|
|
292
|
+
});
|
|
293
|
+
if (files.length > 20) {
|
|
294
|
+
output.writeln(output.dim(" ... and " + (files.length - 20) + " more files"));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return [2 /*return*/, { success: true, data: result }];
|
|
298
|
+
case 3:
|
|
299
|
+
error_1 = _a.sent();
|
|
300
|
+
if (error_1 instanceof MCPClientError) {
|
|
301
|
+
output.printError("Diff analysis failed: " + error_1.message);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
output.printError("Unexpected error: " + String(error_1));
|
|
305
|
+
}
|
|
306
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
307
|
+
case 4: return [2 /*return*/];
|
|
235
308
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
},
|
|
309
|
+
});
|
|
310
|
+
}); }
|
|
239
311
|
};
|
|
240
312
|
// Code subcommand (placeholder for future code analysis)
|
|
241
|
-
|
|
313
|
+
var codeCommand = {
|
|
242
314
|
name: 'code',
|
|
243
315
|
description: 'Static code analysis and quality assessment',
|
|
244
316
|
options: [
|
|
245
|
-
{ name: 'path', short: 'p', type: 'string', description: 'Path to analyze', default: '.' },
|
|
246
|
-
{ name: 'type', short: 't', type: 'string', description: 'Analysis type: quality, complexity, security', default: 'quality' },
|
|
247
|
-
{ name: 'format', short: 'f', type: 'string', description: 'Output format: text, json', default: 'text' },
|
|
317
|
+
{ name: 'path', short: 'p', type: 'string', description: 'Path to analyze', "default": '.' },
|
|
318
|
+
{ name: 'type', short: 't', type: 'string', description: 'Analysis type: quality, complexity, security', "default": 'quality' },
|
|
319
|
+
{ name: 'format', short: 'f', type: 'string', description: 'Output format: text, json', "default": 'text' },
|
|
248
320
|
],
|
|
249
321
|
examples: [
|
|
250
322
|
{ command: 'claude-flow analyze code -p ./src', description: 'Analyze source directory' },
|
|
251
323
|
{ command: 'claude-flow analyze code --type complexity', description: 'Run complexity analysis' },
|
|
252
324
|
],
|
|
253
|
-
action:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
325
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
326
|
+
var path, analysisType;
|
|
327
|
+
return __generator(this, function (_a) {
|
|
328
|
+
path = ctx.flags.path || '.';
|
|
329
|
+
analysisType = ctx.flags.type || 'quality';
|
|
330
|
+
output.writeln();
|
|
331
|
+
output.writeln(output.bold('Code Analysis'));
|
|
332
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
333
|
+
output.printInfo("Analyzing " + path + " for " + analysisType + "...");
|
|
334
|
+
output.writeln();
|
|
335
|
+
// Placeholder - would integrate with actual code analysis tools
|
|
336
|
+
output.printBox([
|
|
337
|
+
"Path: " + path,
|
|
338
|
+
"Type: " + analysisType,
|
|
339
|
+
"Status: Feature in development",
|
|
340
|
+
"",
|
|
341
|
+
"Code analysis capabilities coming soon.",
|
|
342
|
+
"Use 'analyze diff' for change analysis.",
|
|
343
|
+
].join('\n'), 'Code Analysis');
|
|
344
|
+
return [2 /*return*/, { success: true }];
|
|
345
|
+
});
|
|
346
|
+
}); }
|
|
272
347
|
};
|
|
273
348
|
// ============================================================================
|
|
274
349
|
// AST Analysis Subcommands (using ruvector tree-sitter with fallback)
|
|
@@ -276,7 +351,8 @@ const codeCommand = {
|
|
|
276
351
|
/**
|
|
277
352
|
* Helper: Truncate file path for display
|
|
278
353
|
*/
|
|
279
|
-
function truncatePathAst(filePath, maxLen
|
|
354
|
+
function truncatePathAst(filePath, maxLen) {
|
|
355
|
+
if (maxLen === void 0) { maxLen = 45; }
|
|
280
356
|
if (filePath.length <= maxLen)
|
|
281
357
|
return filePath;
|
|
282
358
|
return '...' + filePath.slice(-(maxLen - 3));
|
|
@@ -319,7 +395,7 @@ function getComplexityRatingAst(value) {
|
|
|
319
395
|
/**
|
|
320
396
|
* AST analysis subcommand
|
|
321
397
|
*/
|
|
322
|
-
|
|
398
|
+
var astCommand = {
|
|
323
399
|
name: 'ast',
|
|
324
400
|
description: 'Analyze code using AST parsing (tree-sitter via ruvector)',
|
|
325
401
|
options: [
|
|
@@ -328,35 +404,35 @@ const astCommand = {
|
|
|
328
404
|
short: 'c',
|
|
329
405
|
description: 'Include complexity metrics',
|
|
330
406
|
type: 'boolean',
|
|
331
|
-
default: false
|
|
407
|
+
"default": false
|
|
332
408
|
},
|
|
333
409
|
{
|
|
334
410
|
name: 'symbols',
|
|
335
411
|
short: 's',
|
|
336
412
|
description: 'Include symbol extraction',
|
|
337
413
|
type: 'boolean',
|
|
338
|
-
default: false
|
|
414
|
+
"default": false
|
|
339
415
|
},
|
|
340
416
|
{
|
|
341
417
|
name: 'format',
|
|
342
418
|
short: 'f',
|
|
343
419
|
description: 'Output format (text, json, table)',
|
|
344
420
|
type: 'string',
|
|
345
|
-
default: 'text',
|
|
346
|
-
choices: ['text', 'json', 'table']
|
|
421
|
+
"default": 'text',
|
|
422
|
+
choices: ['text', 'json', 'table']
|
|
347
423
|
},
|
|
348
424
|
{
|
|
349
425
|
name: 'output',
|
|
350
426
|
short: 'o',
|
|
351
427
|
description: 'Output file path',
|
|
352
|
-
type: 'string'
|
|
428
|
+
type: 'string'
|
|
353
429
|
},
|
|
354
430
|
{
|
|
355
431
|
name: 'verbose',
|
|
356
432
|
short: 'v',
|
|
357
433
|
description: 'Show detailed analysis',
|
|
358
434
|
type: 'boolean',
|
|
359
|
-
default: false
|
|
435
|
+
"default": false
|
|
360
436
|
},
|
|
361
437
|
],
|
|
362
438
|
examples: [
|
|
@@ -365,193 +441,223 @@ const astCommand = {
|
|
|
365
441
|
{ command: 'claude-flow analyze ast . --format json', description: 'JSON output' },
|
|
366
442
|
{ command: 'claude-flow analyze ast src/ --symbols', description: 'Extract symbols' },
|
|
367
443
|
],
|
|
368
|
-
action:
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
// Scan directory for source files
|
|
394
|
-
const files = await scanSourceFiles(resolvedPath);
|
|
395
|
-
spinner.stop();
|
|
396
|
-
output.printInfo(`Found ${files.length} source files`);
|
|
397
|
-
spinner.start();
|
|
398
|
-
for (const file of files.slice(0, 100)) {
|
|
399
|
-
try {
|
|
400
|
-
const content = await fs.readFile(file, 'utf-8');
|
|
401
|
-
if (astModule) {
|
|
402
|
-
const analyzer = astModule.createASTAnalyzer();
|
|
403
|
-
const analysis = analyzer.analyze(content, file);
|
|
404
|
-
results.push(analysis);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
// Fallback analysis
|
|
408
|
-
results.push(fallbackAnalyze(content, file));
|
|
409
|
-
}
|
|
444
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
445
|
+
var targetPath, showComplexity, showSymbols, formatType, outputFile, verbose, showAll, spinner, astModule, resolvedPath, stat, isDirectory, results, files, _i, _a, file, content, analyzer, analysis, _b, content, analyzer, analysis, totals, jsonOutput, complexityData, allSymbols, _c, results_1, r, _d, _e, fn, _f, _g, cls, displaySymbols, importCounts, _h, results_2, r, _j, _k, imp, topImports, _l, topImports_1, _m, imp, count, error_2, message;
|
|
446
|
+
return __generator(this, function (_o) {
|
|
447
|
+
switch (_o.label) {
|
|
448
|
+
case 0:
|
|
449
|
+
targetPath = ctx.args[0] || ctx.cwd;
|
|
450
|
+
showComplexity = ctx.flags.complexity;
|
|
451
|
+
showSymbols = ctx.flags.symbols;
|
|
452
|
+
formatType = ctx.flags.format || 'text';
|
|
453
|
+
outputFile = ctx.flags.output;
|
|
454
|
+
verbose = ctx.flags.verbose;
|
|
455
|
+
showAll = !showComplexity && !showSymbols;
|
|
456
|
+
output.printInfo("Analyzing: " + output.highlight(targetPath));
|
|
457
|
+
output.writeln();
|
|
458
|
+
spinner = output.createSpinner({ text: 'Parsing AST...', spinner: 'dots' });
|
|
459
|
+
spinner.start();
|
|
460
|
+
_o.label = 1;
|
|
461
|
+
case 1:
|
|
462
|
+
_o.trys.push([1, 20, , 21]);
|
|
463
|
+
return [4 /*yield*/, getASTAnalyzer()];
|
|
464
|
+
case 2:
|
|
465
|
+
astModule = _o.sent();
|
|
466
|
+
if (!astModule) {
|
|
467
|
+
spinner.stop();
|
|
468
|
+
output.printWarning('AST analyzer not available, using regex fallback');
|
|
410
469
|
}
|
|
411
|
-
|
|
412
|
-
|
|
470
|
+
resolvedPath = resolve(targetPath);
|
|
471
|
+
return [4 /*yield*/, fs.stat(resolvedPath)];
|
|
472
|
+
case 3:
|
|
473
|
+
stat = _o.sent();
|
|
474
|
+
isDirectory = stat.isDirectory();
|
|
475
|
+
results = [];
|
|
476
|
+
if (!isDirectory) return [3 /*break*/, 11];
|
|
477
|
+
return [4 /*yield*/, scanSourceFiles(resolvedPath)];
|
|
478
|
+
case 4:
|
|
479
|
+
files = _o.sent();
|
|
480
|
+
spinner.stop();
|
|
481
|
+
output.printInfo("Found " + files.length + " source files");
|
|
482
|
+
spinner.start();
|
|
483
|
+
_i = 0, _a = files.slice(0, 100);
|
|
484
|
+
_o.label = 5;
|
|
485
|
+
case 5:
|
|
486
|
+
if (!(_i < _a.length)) return [3 /*break*/, 10];
|
|
487
|
+
file = _a[_i];
|
|
488
|
+
_o.label = 6;
|
|
489
|
+
case 6:
|
|
490
|
+
_o.trys.push([6, 8, , 9]);
|
|
491
|
+
return [4 /*yield*/, fs.readFile(file, 'utf-8')];
|
|
492
|
+
case 7:
|
|
493
|
+
content = _o.sent();
|
|
494
|
+
if (astModule) {
|
|
495
|
+
analyzer = astModule.createASTAnalyzer();
|
|
496
|
+
analysis = analyzer.analyze(content, file);
|
|
497
|
+
results.push(analysis);
|
|
413
498
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
499
|
+
else {
|
|
500
|
+
// Fallback analysis
|
|
501
|
+
results.push(fallbackAnalyze(content, file));
|
|
502
|
+
}
|
|
503
|
+
return [3 /*break*/, 9];
|
|
504
|
+
case 8:
|
|
505
|
+
_b = _o.sent();
|
|
506
|
+
return [3 /*break*/, 9];
|
|
507
|
+
case 9:
|
|
508
|
+
_i++;
|
|
509
|
+
return [3 /*break*/, 5];
|
|
510
|
+
case 10: return [3 /*break*/, 13];
|
|
511
|
+
case 11: return [4 /*yield*/, fs.readFile(resolvedPath, 'utf-8')];
|
|
512
|
+
case 12:
|
|
513
|
+
content = _o.sent();
|
|
514
|
+
if (astModule) {
|
|
515
|
+
analyzer = astModule.createASTAnalyzer();
|
|
516
|
+
analysis = analyzer.analyze(content, resolvedPath);
|
|
517
|
+
results.push(analysis);
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
results.push(fallbackAnalyze(content, resolvedPath));
|
|
521
|
+
}
|
|
522
|
+
_o.label = 13;
|
|
523
|
+
case 13:
|
|
524
|
+
spinner.stop();
|
|
525
|
+
if (results.length === 0) {
|
|
526
|
+
output.printWarning('No files analyzed');
|
|
527
|
+
return [2 /*return*/, { success: true }];
|
|
528
|
+
}
|
|
529
|
+
totals = {
|
|
530
|
+
files: results.length,
|
|
531
|
+
functions: results.reduce(function (sum, r) { return sum + r.functions.length; }, 0),
|
|
532
|
+
classes: results.reduce(function (sum, r) { return sum + r.classes.length; }, 0),
|
|
533
|
+
imports: results.reduce(function (sum, r) { return sum + r.imports.length; }, 0),
|
|
534
|
+
avgComplexity: results.reduce(function (sum, r) { return sum + r.complexity.cyclomatic; }, 0) / results.length,
|
|
535
|
+
totalLoc: results.reduce(function (sum, r) { return sum + r.complexity.loc; }, 0)
|
|
536
|
+
};
|
|
537
|
+
if (!(formatType === 'json')) return [3 /*break*/, 17];
|
|
538
|
+
jsonOutput = { files: results, totals: totals };
|
|
539
|
+
if (!outputFile) return [3 /*break*/, 15];
|
|
540
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
541
|
+
case 14:
|
|
542
|
+
_o.sent();
|
|
543
|
+
output.printSuccess("Results written to " + outputFile);
|
|
544
|
+
return [3 /*break*/, 16];
|
|
545
|
+
case 15:
|
|
450
546
|
output.printJson(jsonOutput);
|
|
451
|
-
|
|
452
|
-
return { success: true, data: jsonOutput };
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
491
|
-
// Symbols view
|
|
492
|
-
if (showSymbols || showAll) {
|
|
493
|
-
output.writeln();
|
|
494
|
-
output.writeln(output.bold('Extracted Symbols'));
|
|
495
|
-
output.writeln(output.dim('-'.repeat(60)));
|
|
496
|
-
const allSymbols = [];
|
|
497
|
-
for (const r of results) {
|
|
498
|
-
for (const fn of r.functions) {
|
|
499
|
-
allSymbols.push({ name: fn.name, type: 'function', file: truncatePathAst(r.filePath, 30), line: fn.startLine });
|
|
547
|
+
_o.label = 16;
|
|
548
|
+
case 16: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
549
|
+
case 17:
|
|
550
|
+
// Summary box
|
|
551
|
+
output.printBox([
|
|
552
|
+
"Files analyzed: " + totals.files,
|
|
553
|
+
"Functions: " + totals.functions,
|
|
554
|
+
"Classes: " + totals.classes,
|
|
555
|
+
"Total LOC: " + totals.totalLoc,
|
|
556
|
+
"Avg Complexity: " + formatComplexityValueAst(Math.round(totals.avgComplexity)),
|
|
557
|
+
].join('\n'), 'AST Analysis Summary');
|
|
558
|
+
// Complexity view
|
|
559
|
+
if (showComplexity || showAll) {
|
|
560
|
+
output.writeln();
|
|
561
|
+
output.writeln(output.bold('Complexity by File'));
|
|
562
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
563
|
+
complexityData = results
|
|
564
|
+
.map(function (r) { return ({
|
|
565
|
+
file: truncatePathAst(r.filePath),
|
|
566
|
+
cyclomatic: r.complexity.cyclomatic,
|
|
567
|
+
cognitive: r.complexity.cognitive,
|
|
568
|
+
loc: r.complexity.loc,
|
|
569
|
+
rating: getComplexityRatingAst(r.complexity.cyclomatic)
|
|
570
|
+
}); })
|
|
571
|
+
.sort(function (a, b) { return b.cyclomatic - a.cyclomatic; })
|
|
572
|
+
.slice(0, 15);
|
|
573
|
+
output.printTable({
|
|
574
|
+
columns: [
|
|
575
|
+
{ key: 'file', header: 'File', width: 40 },
|
|
576
|
+
{ key: 'cyclomatic', header: 'Cyclo', width: 8, align: 'right', format: function (v) { return formatComplexityValueAst(v); } },
|
|
577
|
+
{ key: 'cognitive', header: 'Cogni', width: 8, align: 'right' },
|
|
578
|
+
{ key: 'loc', header: 'LOC', width: 8, align: 'right' },
|
|
579
|
+
{ key: 'rating', header: 'Rating', width: 15 },
|
|
580
|
+
],
|
|
581
|
+
data: complexityData
|
|
582
|
+
});
|
|
583
|
+
if (results.length > 15) {
|
|
584
|
+
output.writeln(output.dim(" ... and " + (results.length - 15) + " more files"));
|
|
585
|
+
}
|
|
500
586
|
}
|
|
501
|
-
|
|
502
|
-
|
|
587
|
+
// Symbols view
|
|
588
|
+
if (showSymbols || showAll) {
|
|
589
|
+
output.writeln();
|
|
590
|
+
output.writeln(output.bold('Extracted Symbols'));
|
|
591
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
592
|
+
allSymbols = [];
|
|
593
|
+
for (_c = 0, results_1 = results; _c < results_1.length; _c++) {
|
|
594
|
+
r = results_1[_c];
|
|
595
|
+
for (_d = 0, _e = r.functions; _d < _e.length; _d++) {
|
|
596
|
+
fn = _e[_d];
|
|
597
|
+
allSymbols.push({ name: fn.name, type: 'function', file: truncatePathAst(r.filePath, 30), line: fn.startLine });
|
|
598
|
+
}
|
|
599
|
+
for (_f = 0, _g = r.classes; _f < _g.length; _f++) {
|
|
600
|
+
cls = _g[_f];
|
|
601
|
+
allSymbols.push({ name: cls.name, type: 'class', file: truncatePathAst(r.filePath, 30), line: cls.startLine });
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
displaySymbols = allSymbols.slice(0, 20);
|
|
605
|
+
output.printTable({
|
|
606
|
+
columns: [
|
|
607
|
+
{ key: 'type', header: 'Type', width: 8, format: function (v) { return getTypeMarkerAst(v); } },
|
|
608
|
+
{ key: 'name', header: 'Symbol', width: 30 },
|
|
609
|
+
{ key: 'file', header: 'File', width: 35 },
|
|
610
|
+
{ key: 'line', header: 'Line', width: 8, align: 'right' },
|
|
611
|
+
],
|
|
612
|
+
data: displaySymbols
|
|
613
|
+
});
|
|
614
|
+
if (allSymbols.length > 20) {
|
|
615
|
+
output.writeln(output.dim(" ... and " + (allSymbols.length - 20) + " more symbols"));
|
|
616
|
+
}
|
|
503
617
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const importCounts = new Map();
|
|
525
|
-
for (const r of results) {
|
|
526
|
-
for (const imp of r.imports) {
|
|
527
|
-
importCounts.set(imp, (importCounts.get(imp) || 0) + 1);
|
|
618
|
+
// Verbose output
|
|
619
|
+
if (verbose) {
|
|
620
|
+
output.writeln();
|
|
621
|
+
output.writeln(output.bold('Import Analysis'));
|
|
622
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
623
|
+
importCounts = new Map();
|
|
624
|
+
for (_h = 0, results_2 = results; _h < results_2.length; _h++) {
|
|
625
|
+
r = results_2[_h];
|
|
626
|
+
for (_j = 0, _k = r.imports; _j < _k.length; _j++) {
|
|
627
|
+
imp = _k[_j];
|
|
628
|
+
importCounts.set(imp, (importCounts.get(imp) || 0) + 1);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
topImports = Array.from(importCounts.entries())
|
|
632
|
+
.sort(function (a, b) { return b[1] - a[1]; })
|
|
633
|
+
.slice(0, 10);
|
|
634
|
+
for (_l = 0, topImports_1 = topImports; _l < topImports_1.length; _l++) {
|
|
635
|
+
_m = topImports_1[_l], imp = _m[0], count = _m[1];
|
|
636
|
+
output.writeln(" " + output.highlight(count.toString().padStart(3)) + " " + imp);
|
|
637
|
+
}
|
|
528
638
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
.
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
639
|
+
if (!outputFile) return [3 /*break*/, 19];
|
|
640
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify({ files: results, totals: totals }, null, 2))];
|
|
641
|
+
case 18:
|
|
642
|
+
_o.sent();
|
|
643
|
+
output.printSuccess("Results written to " + outputFile);
|
|
644
|
+
_o.label = 19;
|
|
645
|
+
case 19: return [2 /*return*/, { success: true, data: { files: results, totals: totals } }];
|
|
646
|
+
case 20:
|
|
647
|
+
error_2 = _o.sent();
|
|
648
|
+
spinner.stop();
|
|
649
|
+
message = error_2 instanceof Error ? error_2.message : String(error_2);
|
|
650
|
+
output.printError("AST analysis failed: " + message);
|
|
651
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
652
|
+
case 21: return [2 /*return*/];
|
|
540
653
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
catch (error) {
|
|
544
|
-
spinner.stop();
|
|
545
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
546
|
-
output.printError(`AST analysis failed: ${message}`);
|
|
547
|
-
return { success: false, exitCode: 1 };
|
|
548
|
-
}
|
|
549
|
-
},
|
|
654
|
+
});
|
|
655
|
+
}); }
|
|
550
656
|
};
|
|
551
657
|
/**
|
|
552
658
|
* Complexity analysis subcommand
|
|
553
659
|
*/
|
|
554
|
-
|
|
660
|
+
var complexityAstCommand = {
|
|
555
661
|
name: 'complexity',
|
|
556
662
|
aliases: ['cx'],
|
|
557
663
|
description: 'Analyze code complexity metrics',
|
|
@@ -561,55 +667,82 @@ const complexityAstCommand = {
|
|
|
561
667
|
short: 't',
|
|
562
668
|
description: 'Complexity threshold to flag (default: 10)',
|
|
563
669
|
type: 'number',
|
|
564
|
-
default: 10
|
|
670
|
+
"default": 10
|
|
565
671
|
},
|
|
566
672
|
{
|
|
567
673
|
name: 'format',
|
|
568
674
|
short: 'f',
|
|
569
675
|
description: 'Output format (text, json)',
|
|
570
676
|
type: 'string',
|
|
571
|
-
default: 'text',
|
|
572
|
-
choices: ['text', 'json']
|
|
677
|
+
"default": 'text',
|
|
678
|
+
choices: ['text', 'json']
|
|
573
679
|
},
|
|
574
680
|
{
|
|
575
681
|
name: 'output',
|
|
576
682
|
short: 'o',
|
|
577
683
|
description: 'Output file path',
|
|
578
|
-
type: 'string'
|
|
684
|
+
type: 'string'
|
|
579
685
|
},
|
|
580
686
|
],
|
|
581
687
|
examples: [
|
|
582
688
|
{ command: 'claude-flow analyze complexity src/', description: 'Analyze complexity' },
|
|
583
689
|
{ command: 'claude-flow analyze complexity src/ --threshold 15', description: 'Flag high complexity' },
|
|
584
690
|
],
|
|
585
|
-
action:
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
691
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
692
|
+
var targetPath, threshold, formatType, outputFile, spinner, astModule, resolvedPath, stat, files, _a, results, _i, _b, file, content, analysis, analyzer, flagged, rating, _c, flaggedCount, avgComplexity, jsonOutput, flaggedFiles, displayFiles, error_3, message;
|
|
693
|
+
return __generator(this, function (_d) {
|
|
694
|
+
switch (_d.label) {
|
|
695
|
+
case 0:
|
|
696
|
+
targetPath = ctx.args[0] || ctx.cwd;
|
|
697
|
+
threshold = ctx.flags.threshold || 10;
|
|
698
|
+
formatType = ctx.flags.format || 'text';
|
|
699
|
+
outputFile = ctx.flags.output;
|
|
700
|
+
output.printInfo("Analyzing complexity: " + output.highlight(targetPath));
|
|
701
|
+
output.writeln();
|
|
702
|
+
spinner = output.createSpinner({ text: 'Calculating complexity...', spinner: 'dots' });
|
|
703
|
+
spinner.start();
|
|
704
|
+
_d.label = 1;
|
|
705
|
+
case 1:
|
|
706
|
+
_d.trys.push([1, 19, , 20]);
|
|
707
|
+
return [4 /*yield*/, getASTAnalyzer()];
|
|
708
|
+
case 2:
|
|
709
|
+
astModule = _d.sent();
|
|
710
|
+
resolvedPath = resolve(targetPath);
|
|
711
|
+
return [4 /*yield*/, fs.stat(resolvedPath)];
|
|
712
|
+
case 3:
|
|
713
|
+
stat = _d.sent();
|
|
714
|
+
if (!stat.isDirectory()) return [3 /*break*/, 5];
|
|
715
|
+
return [4 /*yield*/, scanSourceFiles(resolvedPath)];
|
|
716
|
+
case 4:
|
|
717
|
+
_a = _d.sent();
|
|
718
|
+
return [3 /*break*/, 6];
|
|
719
|
+
case 5:
|
|
720
|
+
_a = [resolvedPath];
|
|
721
|
+
_d.label = 6;
|
|
722
|
+
case 6:
|
|
723
|
+
files = _a;
|
|
724
|
+
results = [];
|
|
725
|
+
_i = 0, _b = files.slice(0, 100);
|
|
726
|
+
_d.label = 7;
|
|
727
|
+
case 7:
|
|
728
|
+
if (!(_i < _b.length)) return [3 /*break*/, 12];
|
|
729
|
+
file = _b[_i];
|
|
730
|
+
_d.label = 8;
|
|
731
|
+
case 8:
|
|
732
|
+
_d.trys.push([8, 10, , 11]);
|
|
733
|
+
return [4 /*yield*/, fs.readFile(file, 'utf-8')];
|
|
734
|
+
case 9:
|
|
735
|
+
content = _d.sent();
|
|
736
|
+
analysis = void 0;
|
|
604
737
|
if (astModule) {
|
|
605
|
-
|
|
738
|
+
analyzer = astModule.createASTAnalyzer();
|
|
606
739
|
analysis = analyzer.analyze(content, file);
|
|
607
740
|
}
|
|
608
741
|
else {
|
|
609
742
|
analysis = fallbackAnalyze(content, file);
|
|
610
743
|
}
|
|
611
|
-
|
|
612
|
-
|
|
744
|
+
flagged = analysis.complexity.cyclomatic > threshold;
|
|
745
|
+
rating = analysis.complexity.cyclomatic <= 5 ? 'Simple' :
|
|
613
746
|
analysis.complexity.cyclomatic <= 10 ? 'Moderate' :
|
|
614
747
|
analysis.complexity.cyclomatic <= 20 ? 'Complex' : 'Very Complex';
|
|
615
748
|
results.push({
|
|
@@ -618,91 +751,100 @@ const complexityAstCommand = {
|
|
|
618
751
|
cognitive: analysis.complexity.cognitive,
|
|
619
752
|
loc: analysis.complexity.loc,
|
|
620
753
|
commentDensity: analysis.complexity.commentDensity,
|
|
621
|
-
rating,
|
|
622
|
-
flagged
|
|
754
|
+
rating: rating,
|
|
755
|
+
flagged: flagged
|
|
623
756
|
});
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
757
|
+
return [3 /*break*/, 11];
|
|
758
|
+
case 10:
|
|
759
|
+
_c = _d.sent();
|
|
760
|
+
return [3 /*break*/, 11];
|
|
761
|
+
case 11:
|
|
762
|
+
_i++;
|
|
763
|
+
return [3 /*break*/, 7];
|
|
764
|
+
case 12:
|
|
765
|
+
spinner.stop();
|
|
766
|
+
// Sort by complexity descending
|
|
767
|
+
results.sort(function (a, b) { return b.cyclomatic - a.cyclomatic; });
|
|
768
|
+
flaggedCount = results.filter(function (r) { return r.flagged; }).length;
|
|
769
|
+
avgComplexity = results.length > 0
|
|
770
|
+
? results.reduce(function (sum, r) { return sum + r.cyclomatic; }, 0) / results.length
|
|
771
|
+
: 0;
|
|
772
|
+
if (!(formatType === 'json')) return [3 /*break*/, 16];
|
|
773
|
+
jsonOutput = { files: results, summary: { total: results.length, flagged: flaggedCount, avgComplexity: avgComplexity, threshold: threshold } };
|
|
774
|
+
if (!outputFile) return [3 /*break*/, 14];
|
|
775
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
776
|
+
case 13:
|
|
777
|
+
_d.sent();
|
|
778
|
+
output.printSuccess("Results written to " + outputFile);
|
|
779
|
+
return [3 /*break*/, 15];
|
|
780
|
+
case 14:
|
|
643
781
|
output.printJson(jsonOutput);
|
|
644
|
-
|
|
645
|
-
return { success: true, data: jsonOutput };
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
782
|
+
_d.label = 15;
|
|
783
|
+
case 15: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
784
|
+
case 16:
|
|
785
|
+
// Summary
|
|
786
|
+
output.printBox([
|
|
787
|
+
"Files analyzed: " + results.length,
|
|
788
|
+
"Threshold: " + threshold,
|
|
789
|
+
"Flagged files: " + (flaggedCount > 0 ? output.error(String(flaggedCount)) : output.success('0')),
|
|
790
|
+
"Average complexity: " + formatComplexityValueAst(Math.round(avgComplexity)),
|
|
791
|
+
].join('\n'), 'Complexity Analysis');
|
|
792
|
+
// Show flagged files first
|
|
793
|
+
if (flaggedCount > 0) {
|
|
794
|
+
output.writeln();
|
|
795
|
+
output.writeln(output.bold(output.warning("High Complexity Files (>" + threshold + ")")));
|
|
796
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
797
|
+
flaggedFiles = results.filter(function (r) { return r.flagged; }).slice(0, 10);
|
|
798
|
+
output.printTable({
|
|
799
|
+
columns: [
|
|
800
|
+
{ key: 'file', header: 'File', width: 40, format: function (v) { return truncatePathAst(v); } },
|
|
801
|
+
{ key: 'cyclomatic', header: 'Cyclo', width: 8, align: 'right', format: function (v) { return output.error(String(v)); } },
|
|
802
|
+
{ key: 'cognitive', header: 'Cogni', width: 8, align: 'right' },
|
|
803
|
+
{ key: 'loc', header: 'LOC', width: 8, align: 'right' },
|
|
804
|
+
{ key: 'rating', header: 'Rating', width: 15 },
|
|
805
|
+
],
|
|
806
|
+
data: flaggedFiles
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
// Show all files in table format
|
|
810
|
+
output.writeln();
|
|
811
|
+
output.writeln(output.bold('All Files'));
|
|
812
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
813
|
+
displayFiles = results.slice(0, 15);
|
|
814
|
+
output.printTable({
|
|
815
|
+
columns: [
|
|
816
|
+
{ key: 'file', header: 'File', width: 40, format: function (v) { return truncatePathAst(v); } },
|
|
817
|
+
{ key: 'cyclomatic', header: 'Cyclo', width: 8, align: 'right', format: function (v) { return formatComplexityValueAst(v); } },
|
|
818
|
+
{ key: 'cognitive', header: 'Cogni', width: 8, align: 'right' },
|
|
819
|
+
{ key: 'loc', header: 'LOC', width: 8, align: 'right' },
|
|
820
|
+
],
|
|
821
|
+
data: displayFiles
|
|
822
|
+
});
|
|
823
|
+
if (results.length > 15) {
|
|
824
|
+
output.writeln(output.dim(" ... and " + (results.length - 15) + " more files"));
|
|
825
|
+
}
|
|
826
|
+
if (!outputFile) return [3 /*break*/, 18];
|
|
827
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify({ files: results, summary: { total: results.length, flagged: flaggedCount, avgComplexity: avgComplexity, threshold: threshold } }, null, 2))];
|
|
828
|
+
case 17:
|
|
829
|
+
_d.sent();
|
|
830
|
+
output.printSuccess("Results written to " + outputFile);
|
|
831
|
+
_d.label = 18;
|
|
832
|
+
case 18: return [2 /*return*/, { success: true, data: { files: results, flaggedCount: flaggedCount } }];
|
|
833
|
+
case 19:
|
|
834
|
+
error_3 = _d.sent();
|
|
835
|
+
spinner.stop();
|
|
836
|
+
message = error_3 instanceof Error ? error_3.message : String(error_3);
|
|
837
|
+
output.printError("Complexity analysis failed: " + message);
|
|
838
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
839
|
+
case 20: return [2 /*return*/];
|
|
691
840
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
catch (error) {
|
|
695
|
-
spinner.stop();
|
|
696
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
697
|
-
output.printError(`Complexity analysis failed: ${message}`);
|
|
698
|
-
return { success: false, exitCode: 1 };
|
|
699
|
-
}
|
|
700
|
-
},
|
|
841
|
+
});
|
|
842
|
+
}); }
|
|
701
843
|
};
|
|
702
844
|
/**
|
|
703
845
|
* Symbol extraction subcommand
|
|
704
846
|
*/
|
|
705
|
-
|
|
847
|
+
var symbolsCommand = {
|
|
706
848
|
name: 'symbols',
|
|
707
849
|
aliases: ['sym'],
|
|
708
850
|
description: 'Extract and list code symbols (functions, classes, types)',
|
|
@@ -712,22 +854,22 @@ const symbolsCommand = {
|
|
|
712
854
|
short: 't',
|
|
713
855
|
description: 'Filter by symbol type (function, class, all)',
|
|
714
856
|
type: 'string',
|
|
715
|
-
default: 'all',
|
|
716
|
-
choices: ['function', 'class', 'all']
|
|
857
|
+
"default": 'all',
|
|
858
|
+
choices: ['function', 'class', 'all']
|
|
717
859
|
},
|
|
718
860
|
{
|
|
719
861
|
name: 'format',
|
|
720
862
|
short: 'f',
|
|
721
863
|
description: 'Output format (text, json)',
|
|
722
864
|
type: 'string',
|
|
723
|
-
default: 'text',
|
|
724
|
-
choices: ['text', 'json']
|
|
865
|
+
"default": 'text',
|
|
866
|
+
choices: ['text', 'json']
|
|
725
867
|
},
|
|
726
868
|
{
|
|
727
869
|
name: 'output',
|
|
728
870
|
short: 'o',
|
|
729
871
|
description: 'Output file path',
|
|
730
|
-
type: 'string'
|
|
872
|
+
type: 'string'
|
|
731
873
|
},
|
|
732
874
|
],
|
|
733
875
|
examples: [
|
|
@@ -735,115 +877,152 @@ const symbolsCommand = {
|
|
|
735
877
|
{ command: 'claude-flow analyze symbols src/ --type function', description: 'Only functions' },
|
|
736
878
|
{ command: 'claude-flow analyze symbols src/ --format json', description: 'JSON output' },
|
|
737
879
|
],
|
|
738
|
-
action:
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
880
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
881
|
+
var targetPath, symbolType, formatType, outputFile, spinner, astModule, resolvedPath, stat, files, _a, symbols, _i, _b, file, content, analysis, analyzer, _c, _d, fn, _e, _f, cls, _g, functionCount, classCount, displaySymbols, error_4, message;
|
|
882
|
+
return __generator(this, function (_h) {
|
|
883
|
+
switch (_h.label) {
|
|
884
|
+
case 0:
|
|
885
|
+
targetPath = ctx.args[0] || ctx.cwd;
|
|
886
|
+
symbolType = ctx.flags.type || 'all';
|
|
887
|
+
formatType = ctx.flags.format || 'text';
|
|
888
|
+
outputFile = ctx.flags.output;
|
|
889
|
+
output.printInfo("Extracting symbols: " + output.highlight(targetPath));
|
|
890
|
+
output.writeln();
|
|
891
|
+
spinner = output.createSpinner({ text: 'Parsing code...', spinner: 'dots' });
|
|
892
|
+
spinner.start();
|
|
893
|
+
_h.label = 1;
|
|
894
|
+
case 1:
|
|
895
|
+
_h.trys.push([1, 19, , 20]);
|
|
896
|
+
return [4 /*yield*/, getASTAnalyzer()];
|
|
897
|
+
case 2:
|
|
898
|
+
astModule = _h.sent();
|
|
899
|
+
resolvedPath = resolve(targetPath);
|
|
900
|
+
return [4 /*yield*/, fs.stat(resolvedPath)];
|
|
901
|
+
case 3:
|
|
902
|
+
stat = _h.sent();
|
|
903
|
+
if (!stat.isDirectory()) return [3 /*break*/, 5];
|
|
904
|
+
return [4 /*yield*/, scanSourceFiles(resolvedPath)];
|
|
905
|
+
case 4:
|
|
906
|
+
_a = _h.sent();
|
|
907
|
+
return [3 /*break*/, 6];
|
|
908
|
+
case 5:
|
|
909
|
+
_a = [resolvedPath];
|
|
910
|
+
_h.label = 6;
|
|
911
|
+
case 6:
|
|
912
|
+
files = _a;
|
|
913
|
+
symbols = [];
|
|
914
|
+
_i = 0, _b = files.slice(0, 100);
|
|
915
|
+
_h.label = 7;
|
|
916
|
+
case 7:
|
|
917
|
+
if (!(_i < _b.length)) return [3 /*break*/, 12];
|
|
918
|
+
file = _b[_i];
|
|
919
|
+
_h.label = 8;
|
|
920
|
+
case 8:
|
|
921
|
+
_h.trys.push([8, 10, , 11]);
|
|
922
|
+
return [4 /*yield*/, fs.readFile(file, 'utf-8')];
|
|
923
|
+
case 9:
|
|
924
|
+
content = _h.sent();
|
|
925
|
+
analysis = void 0;
|
|
757
926
|
if (astModule) {
|
|
758
|
-
|
|
927
|
+
analyzer = astModule.createASTAnalyzer();
|
|
759
928
|
analysis = analyzer.analyze(content, file);
|
|
760
929
|
}
|
|
761
930
|
else {
|
|
762
931
|
analysis = fallbackAnalyze(content, file);
|
|
763
932
|
}
|
|
764
933
|
if (symbolType === 'all' || symbolType === 'function') {
|
|
765
|
-
for (
|
|
934
|
+
for (_c = 0, _d = analysis.functions; _c < _d.length; _c++) {
|
|
935
|
+
fn = _d[_c];
|
|
766
936
|
symbols.push({
|
|
767
937
|
name: fn.name,
|
|
768
938
|
type: 'function',
|
|
769
|
-
file,
|
|
939
|
+
file: file,
|
|
770
940
|
startLine: fn.startLine,
|
|
771
|
-
endLine: fn.endLine
|
|
941
|
+
endLine: fn.endLine
|
|
772
942
|
});
|
|
773
943
|
}
|
|
774
944
|
}
|
|
775
945
|
if (symbolType === 'all' || symbolType === 'class') {
|
|
776
|
-
for (
|
|
946
|
+
for (_e = 0, _f = analysis.classes; _e < _f.length; _e++) {
|
|
947
|
+
cls = _f[_e];
|
|
777
948
|
symbols.push({
|
|
778
949
|
name: cls.name,
|
|
779
950
|
type: 'class',
|
|
780
|
-
file,
|
|
951
|
+
file: file,
|
|
781
952
|
startLine: cls.startLine,
|
|
782
|
-
endLine: cls.endLine
|
|
953
|
+
endLine: cls.endLine
|
|
783
954
|
});
|
|
784
955
|
}
|
|
785
956
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
957
|
+
return [3 /*break*/, 11];
|
|
958
|
+
case 10:
|
|
959
|
+
_g = _h.sent();
|
|
960
|
+
return [3 /*break*/, 11];
|
|
961
|
+
case 11:
|
|
962
|
+
_i++;
|
|
963
|
+
return [3 /*break*/, 7];
|
|
964
|
+
case 12:
|
|
965
|
+
spinner.stop();
|
|
966
|
+
// Sort by file then name
|
|
967
|
+
symbols.sort(function (a, b) { return a.file.localeCompare(b.file) || a.name.localeCompare(b.name); });
|
|
968
|
+
if (!(formatType === 'json')) return [3 /*break*/, 16];
|
|
969
|
+
if (!outputFile) return [3 /*break*/, 14];
|
|
970
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(symbols, null, 2))];
|
|
971
|
+
case 13:
|
|
972
|
+
_h.sent();
|
|
973
|
+
output.printSuccess("Results written to " + outputFile);
|
|
974
|
+
return [3 /*break*/, 15];
|
|
975
|
+
case 14:
|
|
800
976
|
output.printJson(symbols);
|
|
801
|
-
|
|
802
|
-
return { success: true, data: symbols };
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
977
|
+
_h.label = 15;
|
|
978
|
+
case 15: return [2 /*return*/, { success: true, data: symbols }];
|
|
979
|
+
case 16:
|
|
980
|
+
functionCount = symbols.filter(function (s) { return s.type === 'function'; }).length;
|
|
981
|
+
classCount = symbols.filter(function (s) { return s.type === 'class'; }).length;
|
|
982
|
+
output.printBox([
|
|
983
|
+
"Total symbols: " + symbols.length,
|
|
984
|
+
"Functions: " + functionCount,
|
|
985
|
+
"Classes: " + classCount,
|
|
986
|
+
"Files: " + files.length,
|
|
987
|
+
].join('\n'), 'Symbol Extraction');
|
|
988
|
+
output.writeln();
|
|
989
|
+
output.writeln(output.bold('Symbols'));
|
|
990
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
991
|
+
displaySymbols = symbols.slice(0, 30);
|
|
992
|
+
output.printTable({
|
|
993
|
+
columns: [
|
|
994
|
+
{ key: 'type', header: 'Type', width: 10, format: function (v) { return getTypeMarkerAst(v); } },
|
|
995
|
+
{ key: 'name', header: 'Name', width: 30 },
|
|
996
|
+
{ key: 'file', header: 'File', width: 35, format: function (v) { return truncatePathAst(v, 33); } },
|
|
997
|
+
{ key: 'startLine', header: 'Line', width: 8, align: 'right' },
|
|
998
|
+
],
|
|
999
|
+
data: displaySymbols
|
|
1000
|
+
});
|
|
1001
|
+
if (symbols.length > 30) {
|
|
1002
|
+
output.writeln(output.dim(" ... and " + (symbols.length - 30) + " more symbols"));
|
|
1003
|
+
}
|
|
1004
|
+
if (!outputFile) return [3 /*break*/, 18];
|
|
1005
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(symbols, null, 2))];
|
|
1006
|
+
case 17:
|
|
1007
|
+
_h.sent();
|
|
1008
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1009
|
+
_h.label = 18;
|
|
1010
|
+
case 18: return [2 /*return*/, { success: true, data: symbols }];
|
|
1011
|
+
case 19:
|
|
1012
|
+
error_4 = _h.sent();
|
|
1013
|
+
spinner.stop();
|
|
1014
|
+
message = error_4 instanceof Error ? error_4.message : String(error_4);
|
|
1015
|
+
output.printError("Symbol extraction failed: " + message);
|
|
1016
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1017
|
+
case 20: return [2 /*return*/];
|
|
832
1018
|
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
catch (error) {
|
|
836
|
-
spinner.stop();
|
|
837
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
838
|
-
output.printError(`Symbol extraction failed: ${message}`);
|
|
839
|
-
return { success: false, exitCode: 1 };
|
|
840
|
-
}
|
|
841
|
-
},
|
|
1019
|
+
});
|
|
1020
|
+
}); }
|
|
842
1021
|
};
|
|
843
1022
|
/**
|
|
844
1023
|
* Imports analysis subcommand
|
|
845
1024
|
*/
|
|
846
|
-
|
|
1025
|
+
var importsCommand = {
|
|
847
1026
|
name: 'imports',
|
|
848
1027
|
aliases: ['imp'],
|
|
849
1028
|
description: 'Analyze import dependencies across files',
|
|
@@ -853,275 +1032,357 @@ const importsCommand = {
|
|
|
853
1032
|
short: 'f',
|
|
854
1033
|
description: 'Output format (text, json)',
|
|
855
1034
|
type: 'string',
|
|
856
|
-
default: 'text',
|
|
857
|
-
choices: ['text', 'json']
|
|
1035
|
+
"default": 'text',
|
|
1036
|
+
choices: ['text', 'json']
|
|
858
1037
|
},
|
|
859
1038
|
{
|
|
860
1039
|
name: 'output',
|
|
861
1040
|
short: 'o',
|
|
862
1041
|
description: 'Output file path',
|
|
863
|
-
type: 'string'
|
|
1042
|
+
type: 'string'
|
|
864
1043
|
},
|
|
865
1044
|
{
|
|
866
1045
|
name: 'external',
|
|
867
1046
|
short: 'e',
|
|
868
1047
|
description: 'Show only external (npm) imports',
|
|
869
1048
|
type: 'boolean',
|
|
870
|
-
default: false
|
|
1049
|
+
"default": false
|
|
871
1050
|
},
|
|
872
1051
|
],
|
|
873
1052
|
examples: [
|
|
874
1053
|
{ command: 'claude-flow analyze imports src/', description: 'Analyze all imports' },
|
|
875
1054
|
{ command: 'claude-flow analyze imports src/ --external', description: 'Only npm packages' },
|
|
876
1055
|
],
|
|
877
|
-
action:
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1056
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1057
|
+
var targetPath, formatType, outputFile, externalOnly, spinner, astModule, resolvedPath, stat, files, _a, importCounts, fileImports, _i, _b, file, content, analysis, analyzer, imports, _c, imports_1, imp, existing, _d, sortedImports, jsonOutput, externalImports, localImports, topImports, error_5, message;
|
|
1058
|
+
return __generator(this, function (_e) {
|
|
1059
|
+
switch (_e.label) {
|
|
1060
|
+
case 0:
|
|
1061
|
+
targetPath = ctx.args[0] || ctx.cwd;
|
|
1062
|
+
formatType = ctx.flags.format || 'text';
|
|
1063
|
+
outputFile = ctx.flags.output;
|
|
1064
|
+
externalOnly = ctx.flags.external;
|
|
1065
|
+
output.printInfo("Analyzing imports: " + output.highlight(targetPath));
|
|
1066
|
+
output.writeln();
|
|
1067
|
+
spinner = output.createSpinner({ text: 'Scanning imports...', spinner: 'dots' });
|
|
1068
|
+
spinner.start();
|
|
1069
|
+
_e.label = 1;
|
|
1070
|
+
case 1:
|
|
1071
|
+
_e.trys.push([1, 19, , 20]);
|
|
1072
|
+
return [4 /*yield*/, getASTAnalyzer()];
|
|
1073
|
+
case 2:
|
|
1074
|
+
astModule = _e.sent();
|
|
1075
|
+
resolvedPath = resolve(targetPath);
|
|
1076
|
+
return [4 /*yield*/, fs.stat(resolvedPath)];
|
|
1077
|
+
case 3:
|
|
1078
|
+
stat = _e.sent();
|
|
1079
|
+
if (!stat.isDirectory()) return [3 /*break*/, 5];
|
|
1080
|
+
return [4 /*yield*/, scanSourceFiles(resolvedPath)];
|
|
1081
|
+
case 4:
|
|
1082
|
+
_a = _e.sent();
|
|
1083
|
+
return [3 /*break*/, 6];
|
|
1084
|
+
case 5:
|
|
1085
|
+
_a = [resolvedPath];
|
|
1086
|
+
_e.label = 6;
|
|
1087
|
+
case 6:
|
|
1088
|
+
files = _a;
|
|
1089
|
+
importCounts = new Map();
|
|
1090
|
+
fileImports = new Map();
|
|
1091
|
+
_i = 0, _b = files.slice(0, 100);
|
|
1092
|
+
_e.label = 7;
|
|
1093
|
+
case 7:
|
|
1094
|
+
if (!(_i < _b.length)) return [3 /*break*/, 12];
|
|
1095
|
+
file = _b[_i];
|
|
1096
|
+
_e.label = 8;
|
|
1097
|
+
case 8:
|
|
1098
|
+
_e.trys.push([8, 10, , 11]);
|
|
1099
|
+
return [4 /*yield*/, fs.readFile(file, 'utf-8')];
|
|
1100
|
+
case 9:
|
|
1101
|
+
content = _e.sent();
|
|
1102
|
+
analysis = void 0;
|
|
897
1103
|
if (astModule) {
|
|
898
|
-
|
|
1104
|
+
analyzer = astModule.createASTAnalyzer();
|
|
899
1105
|
analysis = analyzer.analyze(content, file);
|
|
900
1106
|
}
|
|
901
1107
|
else {
|
|
902
1108
|
analysis = fallbackAnalyze(content, file);
|
|
903
1109
|
}
|
|
904
|
-
|
|
1110
|
+
imports = analysis.imports.filter(function (imp) {
|
|
905
1111
|
if (externalOnly) {
|
|
906
1112
|
return !imp.startsWith('.') && !imp.startsWith('/');
|
|
907
1113
|
}
|
|
908
1114
|
return true;
|
|
909
1115
|
});
|
|
910
1116
|
fileImports.set(file, imports);
|
|
911
|
-
for (
|
|
912
|
-
|
|
1117
|
+
for (_c = 0, imports_1 = imports; _c < imports_1.length; _c++) {
|
|
1118
|
+
imp = imports_1[_c];
|
|
1119
|
+
existing = importCounts.get(imp) || { count: 0, files: [] };
|
|
913
1120
|
existing.count++;
|
|
914
1121
|
existing.files.push(file);
|
|
915
1122
|
importCounts.set(imp, existing);
|
|
916
1123
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1124
|
+
return [3 /*break*/, 11];
|
|
1125
|
+
case 10:
|
|
1126
|
+
_d = _e.sent();
|
|
1127
|
+
return [3 /*break*/, 11];
|
|
1128
|
+
case 11:
|
|
1129
|
+
_i++;
|
|
1130
|
+
return [3 /*break*/, 7];
|
|
1131
|
+
case 12:
|
|
1132
|
+
spinner.stop();
|
|
1133
|
+
sortedImports = Array.from(importCounts.entries())
|
|
1134
|
+
.sort(function (a, b) { return b[1].count - a[1].count; });
|
|
1135
|
+
if (!(formatType === 'json')) return [3 /*break*/, 16];
|
|
1136
|
+
jsonOutput = {
|
|
1137
|
+
imports: Object.fromEntries(sortedImports),
|
|
1138
|
+
fileImports: Object.fromEntries(fileImports)
|
|
1139
|
+
};
|
|
1140
|
+
if (!outputFile) return [3 /*break*/, 14];
|
|
1141
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
1142
|
+
case 13:
|
|
1143
|
+
_e.sent();
|
|
1144
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1145
|
+
return [3 /*break*/, 15];
|
|
1146
|
+
case 14:
|
|
936
1147
|
output.printJson(jsonOutput);
|
|
937
|
-
|
|
938
|
-
return { success: true, data: jsonOutput };
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1148
|
+
_e.label = 15;
|
|
1149
|
+
case 15: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
1150
|
+
case 16:
|
|
1151
|
+
externalImports = sortedImports.filter(function (_a) {
|
|
1152
|
+
var imp = _a[0];
|
|
1153
|
+
return !imp.startsWith('.') && !imp.startsWith('/');
|
|
1154
|
+
});
|
|
1155
|
+
localImports = sortedImports.filter(function (_a) {
|
|
1156
|
+
var imp = _a[0];
|
|
1157
|
+
return imp.startsWith('.') || imp.startsWith('/');
|
|
1158
|
+
});
|
|
1159
|
+
output.printBox([
|
|
1160
|
+
"Total unique imports: " + sortedImports.length,
|
|
1161
|
+
"External (npm): " + externalImports.length,
|
|
1162
|
+
"Local (relative): " + localImports.length,
|
|
1163
|
+
"Files scanned: " + files.length,
|
|
1164
|
+
].join('\n'), 'Import Analysis');
|
|
1165
|
+
// Most used imports
|
|
1166
|
+
output.writeln();
|
|
1167
|
+
output.writeln(output.bold('Most Used Imports'));
|
|
1168
|
+
output.writeln(output.dim('-'.repeat(60)));
|
|
1169
|
+
topImports = sortedImports.slice(0, 20);
|
|
1170
|
+
output.printTable({
|
|
1171
|
+
columns: [
|
|
1172
|
+
{ key: 'count', header: 'Uses', width: 8, align: 'right' },
|
|
1173
|
+
{ key: 'import', header: 'Import', width: 50 },
|
|
1174
|
+
{ key: 'type', header: 'Type', width: 10 },
|
|
1175
|
+
],
|
|
1176
|
+
data: topImports.map(function (_a) {
|
|
1177
|
+
var imp = _a[0], data = _a[1];
|
|
1178
|
+
return ({
|
|
1179
|
+
count: data.count,
|
|
1180
|
+
"import": imp,
|
|
1181
|
+
type: imp.startsWith('.') || imp.startsWith('/') ? output.dim('local') : output.highlight('npm')
|
|
1182
|
+
});
|
|
1183
|
+
})
|
|
1184
|
+
});
|
|
1185
|
+
if (sortedImports.length > 20) {
|
|
1186
|
+
output.writeln(output.dim(" ... and " + (sortedImports.length - 20) + " more imports"));
|
|
1187
|
+
}
|
|
1188
|
+
if (!outputFile) return [3 /*break*/, 18];
|
|
1189
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify({
|
|
1190
|
+
imports: Object.fromEntries(sortedImports),
|
|
1191
|
+
fileImports: Object.fromEntries(fileImports)
|
|
1192
|
+
}, null, 2))];
|
|
1193
|
+
case 17:
|
|
1194
|
+
_e.sent();
|
|
1195
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1196
|
+
_e.label = 18;
|
|
1197
|
+
case 18: return [2 /*return*/, { success: true, data: { imports: sortedImports } }];
|
|
1198
|
+
case 19:
|
|
1199
|
+
error_5 = _e.sent();
|
|
1200
|
+
spinner.stop();
|
|
1201
|
+
message = error_5 instanceof Error ? error_5.message : String(error_5);
|
|
1202
|
+
output.printError("Import analysis failed: " + message);
|
|
1203
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1204
|
+
case 20: return [2 /*return*/];
|
|
975
1205
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
catch (error) {
|
|
979
|
-
spinner.stop();
|
|
980
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
981
|
-
output.printError(`Import analysis failed: ${message}`);
|
|
982
|
-
return { success: false, exitCode: 1 };
|
|
983
|
-
}
|
|
984
|
-
},
|
|
1206
|
+
});
|
|
1207
|
+
}); }
|
|
985
1208
|
};
|
|
986
1209
|
/**
|
|
987
1210
|
* Helper: Scan directory for source files
|
|
988
1211
|
*/
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1212
|
+
function scanSourceFiles(dir, maxDepth) {
|
|
1213
|
+
if (maxDepth === void 0) { maxDepth = 10; }
|
|
1214
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1215
|
+
function scan(currentDir, depth) {
|
|
1216
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1217
|
+
var entries, _i, entries_1, entry, fullPath, ext, _a;
|
|
1218
|
+
return __generator(this, function (_b) {
|
|
1219
|
+
switch (_b.label) {
|
|
1220
|
+
case 0:
|
|
1221
|
+
if (depth > maxDepth)
|
|
1222
|
+
return [2 /*return*/];
|
|
1223
|
+
_b.label = 1;
|
|
1224
|
+
case 1:
|
|
1225
|
+
_b.trys.push([1, 9, , 10]);
|
|
1226
|
+
return [4 /*yield*/, fs.readdir(currentDir, { withFileTypes: true })];
|
|
1227
|
+
case 2:
|
|
1228
|
+
entries = _b.sent();
|
|
1229
|
+
_i = 0, entries_1 = entries;
|
|
1230
|
+
_b.label = 3;
|
|
1231
|
+
case 3:
|
|
1232
|
+
if (!(_i < entries_1.length)) return [3 /*break*/, 8];
|
|
1233
|
+
entry = entries_1[_i];
|
|
1234
|
+
fullPath = path.join(currentDir, entry.name);
|
|
1235
|
+
if (!entry.isDirectory()) return [3 /*break*/, 6];
|
|
1236
|
+
if (!!excludeDirs.includes(entry.name)) return [3 /*break*/, 5];
|
|
1237
|
+
return [4 /*yield*/, scan(fullPath, depth + 1)];
|
|
1238
|
+
case 4:
|
|
1239
|
+
_b.sent();
|
|
1240
|
+
_b.label = 5;
|
|
1241
|
+
case 5: return [3 /*break*/, 7];
|
|
1242
|
+
case 6:
|
|
1243
|
+
if (entry.isFile()) {
|
|
1244
|
+
ext = path.extname(entry.name);
|
|
1245
|
+
if (extensions.includes(ext)) {
|
|
1246
|
+
files.push(fullPath);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
_b.label = 7;
|
|
1250
|
+
case 7:
|
|
1251
|
+
_i++;
|
|
1252
|
+
return [3 /*break*/, 3];
|
|
1253
|
+
case 8: return [3 /*break*/, 10];
|
|
1254
|
+
case 9:
|
|
1255
|
+
_a = _b.sent();
|
|
1256
|
+
return [3 /*break*/, 10];
|
|
1257
|
+
case 10: return [2 /*return*/];
|
|
1009
1258
|
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
catch {
|
|
1014
|
-
// Skip directories we can't read
|
|
1259
|
+
});
|
|
1260
|
+
});
|
|
1015
1261
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1262
|
+
var files, extensions, excludeDirs;
|
|
1263
|
+
return __generator(this, function (_a) {
|
|
1264
|
+
switch (_a.label) {
|
|
1265
|
+
case 0:
|
|
1266
|
+
files = [];
|
|
1267
|
+
extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
|
|
1268
|
+
excludeDirs = ['node_modules', 'dist', 'build', '.git', 'coverage', '__pycache__'];
|
|
1269
|
+
return [4 /*yield*/, scan(dir, 0)];
|
|
1270
|
+
case 1:
|
|
1271
|
+
_a.sent();
|
|
1272
|
+
return [2 /*return*/, files];
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
});
|
|
1019
1276
|
}
|
|
1020
1277
|
/**
|
|
1021
1278
|
* Fallback analysis when ruvector is not available
|
|
1022
1279
|
*/
|
|
1023
1280
|
function fallbackAnalyze(code, filePath) {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1281
|
+
var lines = code.split('\n');
|
|
1282
|
+
var functions = [];
|
|
1283
|
+
var classes = [];
|
|
1284
|
+
var imports = [];
|
|
1285
|
+
var exports = [];
|
|
1029
1286
|
// Extract functions
|
|
1030
|
-
|
|
1031
|
-
|
|
1287
|
+
var funcPattern = /(?:export\s+)?(?:async\s+)?function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>|^\s*(?:async\s+)?(\w+)\s*\([^)]*\)\s*(?::\s*\w+)?\s*\{/gm;
|
|
1288
|
+
var match;
|
|
1032
1289
|
while ((match = funcPattern.exec(code)) !== null) {
|
|
1033
|
-
|
|
1290
|
+
var name = match[1] || match[2] || match[3];
|
|
1034
1291
|
if (name && !['if', 'while', 'for', 'switch'].includes(name)) {
|
|
1035
|
-
|
|
1036
|
-
functions.push({ name, startLine: lineNum, endLine: lineNum + 10 });
|
|
1292
|
+
var lineNum = code.substring(0, match.index).split('\n').length;
|
|
1293
|
+
functions.push({ name: name, startLine: lineNum, endLine: lineNum + 10 });
|
|
1037
1294
|
}
|
|
1038
1295
|
}
|
|
1039
1296
|
// Extract classes
|
|
1040
|
-
|
|
1297
|
+
var classPattern = /(?:export\s+)?class\s+(\w+)/gm;
|
|
1041
1298
|
while ((match = classPattern.exec(code)) !== null) {
|
|
1042
|
-
|
|
1299
|
+
var lineNum = code.substring(0, match.index).split('\n').length;
|
|
1043
1300
|
classes.push({ name: match[1], startLine: lineNum, endLine: lineNum + 20 });
|
|
1044
1301
|
}
|
|
1045
1302
|
// Extract imports
|
|
1046
|
-
|
|
1303
|
+
var importPattern = /import\s+(?:.*\s+from\s+)?['"]([^'"]+)['"]/gm;
|
|
1047
1304
|
while ((match = importPattern.exec(code)) !== null) {
|
|
1048
1305
|
imports.push(match[1]);
|
|
1049
1306
|
}
|
|
1050
|
-
|
|
1307
|
+
var requirePattern = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/gm;
|
|
1051
1308
|
while ((match = requirePattern.exec(code)) !== null) {
|
|
1052
1309
|
imports.push(match[1]);
|
|
1053
1310
|
}
|
|
1054
1311
|
// Extract exports
|
|
1055
|
-
|
|
1312
|
+
var exportPattern = /export\s+(?:default\s+)?(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/gm;
|
|
1056
1313
|
while ((match = exportPattern.exec(code)) !== null) {
|
|
1057
1314
|
exports.push(match[1]);
|
|
1058
1315
|
}
|
|
1059
1316
|
// Calculate complexity
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
for (
|
|
1066
|
-
|
|
1067
|
-
|
|
1317
|
+
var nonEmptyLines = lines.filter(function (l) { return l.trim().length > 0; }).length;
|
|
1318
|
+
var commentLines = lines.filter(function (l) { return /^\s*(\/\/|\/\*|\*|#)/.test(l); }).length;
|
|
1319
|
+
var decisionPoints = (code.match(/\b(if|else|for|while|switch|case|catch|&&|\|\||\?)\b/g) || []).length;
|
|
1320
|
+
var cognitive = 0;
|
|
1321
|
+
var nestingLevel = 0;
|
|
1322
|
+
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
|
|
1323
|
+
var line = lines_1[_i];
|
|
1324
|
+
var opens = (line.match(/\{/g) || []).length;
|
|
1325
|
+
var closes = (line.match(/\}/g) || []).length;
|
|
1068
1326
|
if (/\b(if|for|while|switch)\b/.test(line)) {
|
|
1069
1327
|
cognitive += 1 + nestingLevel;
|
|
1070
1328
|
}
|
|
1071
1329
|
nestingLevel = Math.max(0, nestingLevel + opens - closes);
|
|
1072
1330
|
}
|
|
1073
1331
|
// Detect language
|
|
1074
|
-
|
|
1075
|
-
|
|
1332
|
+
var ext = path.extname(filePath).toLowerCase();
|
|
1333
|
+
var language = ext === '.ts' || ext === '.tsx' ? 'typescript' :
|
|
1076
1334
|
ext === '.js' || ext === '.jsx' || ext === '.mjs' || ext === '.cjs' ? 'javascript' :
|
|
1077
1335
|
ext === '.py' ? 'python' : 'unknown';
|
|
1078
1336
|
return {
|
|
1079
|
-
filePath,
|
|
1080
|
-
language,
|
|
1081
|
-
functions,
|
|
1082
|
-
classes,
|
|
1083
|
-
imports,
|
|
1084
|
-
exports,
|
|
1337
|
+
filePath: filePath,
|
|
1338
|
+
language: language,
|
|
1339
|
+
functions: functions,
|
|
1340
|
+
classes: classes,
|
|
1341
|
+
imports: imports,
|
|
1342
|
+
exports: exports,
|
|
1085
1343
|
complexity: {
|
|
1086
1344
|
cyclomatic: decisionPoints + 1,
|
|
1087
|
-
cognitive,
|
|
1345
|
+
cognitive: cognitive,
|
|
1088
1346
|
loc: nonEmptyLines,
|
|
1089
|
-
commentDensity: lines.length > 0 ? commentLines / lines.length : 0
|
|
1090
|
-
}
|
|
1347
|
+
commentDensity: lines.length > 0 ? commentLines / lines.length : 0
|
|
1348
|
+
}
|
|
1091
1349
|
};
|
|
1092
1350
|
}
|
|
1093
1351
|
// Dependencies subcommand
|
|
1094
|
-
|
|
1352
|
+
var depsCommand = {
|
|
1095
1353
|
name: 'deps',
|
|
1096
1354
|
description: 'Analyze project dependencies',
|
|
1097
1355
|
options: [
|
|
1098
1356
|
{ name: 'outdated', short: 'o', type: 'boolean', description: 'Show only outdated dependencies' },
|
|
1099
1357
|
{ name: 'security', short: 's', type: 'boolean', description: 'Check for security vulnerabilities' },
|
|
1100
|
-
{ name: 'format', short: 'f', type: 'string', description: 'Output format: text, json', default: 'text' },
|
|
1358
|
+
{ name: 'format', short: 'f', type: 'string', description: 'Output format: text, json', "default": 'text' },
|
|
1101
1359
|
],
|
|
1102
1360
|
examples: [
|
|
1103
1361
|
{ command: 'claude-flow analyze deps --outdated', description: 'Show outdated dependencies' },
|
|
1104
1362
|
{ command: 'claude-flow analyze deps --security', description: 'Check for vulnerabilities' },
|
|
1105
1363
|
],
|
|
1106
|
-
action:
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1364
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1365
|
+
var showOutdated, checkSecurity;
|
|
1366
|
+
return __generator(this, function (_a) {
|
|
1367
|
+
showOutdated = ctx.flags.outdated;
|
|
1368
|
+
checkSecurity = ctx.flags.security;
|
|
1369
|
+
output.writeln();
|
|
1370
|
+
output.writeln(output.bold('Dependency Analysis'));
|
|
1371
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
1372
|
+
output.printInfo('Analyzing dependencies...');
|
|
1373
|
+
output.writeln();
|
|
1374
|
+
// Placeholder - would integrate with npm/yarn audit
|
|
1375
|
+
output.printBox([
|
|
1376
|
+
"Outdated Check: " + (showOutdated ? 'Enabled' : 'Disabled'),
|
|
1377
|
+
"Security Check: " + (checkSecurity ? 'Enabled' : 'Disabled'),
|
|
1378
|
+
"Status: Feature in development",
|
|
1379
|
+
"",
|
|
1380
|
+
"Dependency analysis capabilities coming soon.",
|
|
1381
|
+
"Use 'security scan --type deps' for security scanning.",
|
|
1382
|
+
].join('\n'), 'Dependency Analysis');
|
|
1383
|
+
return [2 /*return*/, { success: true }];
|
|
1384
|
+
});
|
|
1385
|
+
}); }
|
|
1125
1386
|
};
|
|
1126
1387
|
// ============================================================================
|
|
1127
1388
|
// Graph Analysis Subcommands (MinCut, Louvain, Circular Dependencies)
|
|
@@ -1129,7 +1390,7 @@ const depsCommand = {
|
|
|
1129
1390
|
/**
|
|
1130
1391
|
* Analyze code boundaries using MinCut algorithm
|
|
1131
1392
|
*/
|
|
1132
|
-
|
|
1393
|
+
var boundariesCommand = {
|
|
1133
1394
|
name: 'boundaries',
|
|
1134
1395
|
aliases: ['boundary', 'mincut'],
|
|
1135
1396
|
description: 'Find natural code boundaries using MinCut algorithm',
|
|
@@ -1139,21 +1400,21 @@ const boundariesCommand = {
|
|
|
1139
1400
|
short: 'p',
|
|
1140
1401
|
description: 'Number of partitions to find',
|
|
1141
1402
|
type: 'number',
|
|
1142
|
-
default: 2
|
|
1403
|
+
"default": 2
|
|
1143
1404
|
},
|
|
1144
1405
|
{
|
|
1145
1406
|
name: 'output',
|
|
1146
1407
|
short: 'o',
|
|
1147
1408
|
description: 'Output file path',
|
|
1148
|
-
type: 'string'
|
|
1409
|
+
type: 'string'
|
|
1149
1410
|
},
|
|
1150
1411
|
{
|
|
1151
1412
|
name: 'format',
|
|
1152
1413
|
short: 'f',
|
|
1153
1414
|
description: 'Output format (text, json, dot)',
|
|
1154
1415
|
type: 'string',
|
|
1155
|
-
default: 'text',
|
|
1156
|
-
choices: ['text', 'json', 'dot']
|
|
1416
|
+
"default": 'text',
|
|
1417
|
+
choices: ['text', 'json', 'dot']
|
|
1157
1418
|
},
|
|
1158
1419
|
],
|
|
1159
1420
|
examples: [
|
|
@@ -1161,127 +1422,145 @@ const boundariesCommand = {
|
|
|
1161
1422
|
{ command: 'claude-flow analyze boundaries -p 3 src/', description: 'Find 3 partitions' },
|
|
1162
1423
|
{ command: 'claude-flow analyze boundaries -f dot -o graph.dot src/', description: 'Export to DOT format' },
|
|
1163
1424
|
],
|
|
1164
|
-
action:
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1425
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1426
|
+
var targetDir, numPartitions, outputFile, format, spinner, analyzer, result, jsonOutput, dotOutput, i, boundary, p1Display, p2Display, _i, _a, cycle, severityColor, error_6, message;
|
|
1427
|
+
return __generator(this, function (_b) {
|
|
1428
|
+
switch (_b.label) {
|
|
1429
|
+
case 0:
|
|
1430
|
+
targetDir = ctx.args[0] || ctx.cwd;
|
|
1431
|
+
numPartitions = ctx.flags.partitions || 2;
|
|
1432
|
+
outputFile = ctx.flags.output;
|
|
1433
|
+
format = ctx.flags.format || 'text';
|
|
1434
|
+
output.printInfo("Analyzing code boundaries in: " + output.highlight(targetDir));
|
|
1435
|
+
output.writeln();
|
|
1436
|
+
spinner = output.createSpinner({ text: 'Building dependency graph...', spinner: 'dots' });
|
|
1437
|
+
spinner.start();
|
|
1438
|
+
_b.label = 1;
|
|
1439
|
+
case 1:
|
|
1440
|
+
_b.trys.push([1, 14, , 15]);
|
|
1441
|
+
return [4 /*yield*/, getGraphAnalyzer()];
|
|
1442
|
+
case 2:
|
|
1443
|
+
analyzer = _b.sent();
|
|
1444
|
+
if (!analyzer) {
|
|
1445
|
+
spinner.stop();
|
|
1446
|
+
output.printError('Graph analyzer module not available');
|
|
1447
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1448
|
+
}
|
|
1449
|
+
return [4 /*yield*/, analyzer.analyzeGraph(resolve(targetDir), {
|
|
1450
|
+
includeBoundaries: true,
|
|
1451
|
+
includeModules: false,
|
|
1452
|
+
numPartitions: numPartitions
|
|
1453
|
+
})];
|
|
1454
|
+
case 3:
|
|
1455
|
+
result = _b.sent();
|
|
1456
|
+
spinner.stop();
|
|
1457
|
+
if (!(format === 'json')) return [3 /*break*/, 7];
|
|
1458
|
+
jsonOutput = {
|
|
1459
|
+
boundaries: result.boundaries,
|
|
1460
|
+
statistics: result.statistics,
|
|
1461
|
+
circularDependencies: result.circularDependencies
|
|
1462
|
+
};
|
|
1463
|
+
if (!outputFile) return [3 /*break*/, 5];
|
|
1464
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
1465
|
+
case 4:
|
|
1466
|
+
_b.sent();
|
|
1467
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1468
|
+
return [3 /*break*/, 6];
|
|
1469
|
+
case 5:
|
|
1198
1470
|
output.printJson(jsonOutput);
|
|
1199
|
-
|
|
1200
|
-
return { success: true, data: jsonOutput };
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1471
|
+
_b.label = 6;
|
|
1472
|
+
case 6: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
1473
|
+
case 7:
|
|
1474
|
+
if (!(format === 'dot')) return [3 /*break*/, 11];
|
|
1475
|
+
dotOutput = analyzer.exportToDot(result, {
|
|
1476
|
+
includeLabels: true,
|
|
1477
|
+
highlightCycles: true
|
|
1478
|
+
});
|
|
1479
|
+
if (!outputFile) return [3 /*break*/, 9];
|
|
1480
|
+
return [4 /*yield*/, writeFile(outputFile, dotOutput)];
|
|
1481
|
+
case 8:
|
|
1482
|
+
_b.sent();
|
|
1483
|
+
output.printSuccess("DOT graph written to " + outputFile);
|
|
1210
1484
|
output.writeln(output.dim('Visualize with: dot -Tpng -o graph.png ' + outputFile));
|
|
1211
|
-
|
|
1212
|
-
|
|
1485
|
+
return [3 /*break*/, 10];
|
|
1486
|
+
case 9:
|
|
1213
1487
|
output.writeln(dotOutput);
|
|
1214
|
-
|
|
1215
|
-
return { success: true };
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1488
|
+
_b.label = 10;
|
|
1489
|
+
case 10: return [2 /*return*/, { success: true }];
|
|
1490
|
+
case 11:
|
|
1491
|
+
// Text format (default)
|
|
1492
|
+
output.printBox([
|
|
1493
|
+
"Files analyzed: " + result.statistics.nodeCount,
|
|
1494
|
+
"Dependencies: " + result.statistics.edgeCount,
|
|
1495
|
+
"Avg degree: " + result.statistics.avgDegree.toFixed(2),
|
|
1496
|
+
"Density: " + (result.statistics.density * 100).toFixed(2) + "%",
|
|
1497
|
+
"Components: " + result.statistics.componentCount,
|
|
1498
|
+
].join('\n'), 'Graph Statistics');
|
|
1499
|
+
if (result.boundaries && result.boundaries.length > 0) {
|
|
1500
|
+
output.writeln();
|
|
1501
|
+
output.writeln(output.bold('MinCut Boundaries'));
|
|
1502
|
+
output.writeln();
|
|
1503
|
+
for (i = 0; i < result.boundaries.length; i++) {
|
|
1504
|
+
boundary = result.boundaries[i];
|
|
1505
|
+
output.writeln(output.bold("Boundary " + (i + 1) + " (cut value: " + boundary.cutValue + ")"));
|
|
1506
|
+
output.writeln();
|
|
1507
|
+
output.writeln(output.dim('Partition 1:'));
|
|
1508
|
+
p1Display = boundary.partition1.slice(0, 10);
|
|
1509
|
+
output.printList(p1Display);
|
|
1510
|
+
if (boundary.partition1.length > 10) {
|
|
1511
|
+
output.writeln(output.dim(" ... and " + (boundary.partition1.length - 10) + " more files"));
|
|
1512
|
+
}
|
|
1513
|
+
output.writeln();
|
|
1514
|
+
output.writeln(output.dim('Partition 2:'));
|
|
1515
|
+
p2Display = boundary.partition2.slice(0, 10);
|
|
1516
|
+
output.printList(p2Display);
|
|
1517
|
+
if (boundary.partition2.length > 10) {
|
|
1518
|
+
output.writeln(output.dim(" ... and " + (boundary.partition2.length - 10) + " more files"));
|
|
1519
|
+
}
|
|
1520
|
+
output.writeln();
|
|
1521
|
+
output.writeln(output.success('Suggestion:'));
|
|
1522
|
+
output.writeln(" " + boundary.suggestion);
|
|
1523
|
+
output.writeln();
|
|
1524
|
+
}
|
|
1238
1525
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1526
|
+
// Show circular dependencies
|
|
1527
|
+
if (result.circularDependencies.length > 0) {
|
|
1528
|
+
output.writeln();
|
|
1529
|
+
output.writeln(output.bold(output.warning('Circular Dependencies Detected')));
|
|
1530
|
+
output.writeln();
|
|
1531
|
+
for (_i = 0, _a = result.circularDependencies.slice(0, 5); _i < _a.length; _i++) {
|
|
1532
|
+
cycle = _a[_i];
|
|
1533
|
+
severityColor = cycle.severity === 'high' ? output.error : cycle.severity === 'medium' ? output.warning : output.dim;
|
|
1534
|
+
output.writeln(severityColor("[" + cycle.severity.toUpperCase() + "]") + " " + cycle.cycle.join(' -> '));
|
|
1535
|
+
output.writeln(output.dim(" " + cycle.suggestion));
|
|
1536
|
+
output.writeln();
|
|
1537
|
+
}
|
|
1538
|
+
if (result.circularDependencies.length > 5) {
|
|
1539
|
+
output.writeln(output.dim("... and " + (result.circularDependencies.length - 5) + " more cycles"));
|
|
1540
|
+
}
|
|
1245
1541
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1542
|
+
if (!outputFile) return [3 /*break*/, 13];
|
|
1543
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(result, null, 2))];
|
|
1544
|
+
case 12:
|
|
1545
|
+
_b.sent();
|
|
1546
|
+
output.printSuccess("Full results written to " + outputFile);
|
|
1547
|
+
_b.label = 13;
|
|
1548
|
+
case 13: return [2 /*return*/, { success: true, data: result }];
|
|
1549
|
+
case 14:
|
|
1550
|
+
error_6 = _b.sent();
|
|
1551
|
+
spinner.stop();
|
|
1552
|
+
message = error_6 instanceof Error ? error_6.message : String(error_6);
|
|
1553
|
+
output.printError("Analysis failed: " + message);
|
|
1554
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1555
|
+
case 15: return [2 /*return*/];
|
|
1251
1556
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
output.writeln();
|
|
1255
|
-
output.writeln(output.bold(output.warning('Circular Dependencies Detected')));
|
|
1256
|
-
output.writeln();
|
|
1257
|
-
for (const cycle of result.circularDependencies.slice(0, 5)) {
|
|
1258
|
-
const severityColor = cycle.severity === 'high' ? output.error : cycle.severity === 'medium' ? output.warning : output.dim;
|
|
1259
|
-
output.writeln(`${severityColor(`[${cycle.severity.toUpperCase()}]`)} ${cycle.cycle.join(' -> ')}`);
|
|
1260
|
-
output.writeln(output.dim(` ${cycle.suggestion}`));
|
|
1261
|
-
output.writeln();
|
|
1262
|
-
}
|
|
1263
|
-
if (result.circularDependencies.length > 5) {
|
|
1264
|
-
output.writeln(output.dim(`... and ${result.circularDependencies.length - 5} more cycles`));
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
if (outputFile) {
|
|
1268
|
-
await writeFile(outputFile, JSON.stringify(result, null, 2));
|
|
1269
|
-
output.printSuccess(`Full results written to ${outputFile}`);
|
|
1270
|
-
}
|
|
1271
|
-
return { success: true, data: result };
|
|
1272
|
-
}
|
|
1273
|
-
catch (error) {
|
|
1274
|
-
spinner.stop();
|
|
1275
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1276
|
-
output.printError(`Analysis failed: ${message}`);
|
|
1277
|
-
return { success: false, exitCode: 1 };
|
|
1278
|
-
}
|
|
1279
|
-
},
|
|
1557
|
+
});
|
|
1558
|
+
}); }
|
|
1280
1559
|
};
|
|
1281
1560
|
/**
|
|
1282
1561
|
* Analyze modules/communities using Louvain algorithm
|
|
1283
1562
|
*/
|
|
1284
|
-
|
|
1563
|
+
var modulesCommand = {
|
|
1285
1564
|
name: 'modules',
|
|
1286
1565
|
aliases: ['communities', 'louvain'],
|
|
1287
1566
|
description: 'Detect module communities using Louvain algorithm',
|
|
@@ -1290,22 +1569,22 @@ const modulesCommand = {
|
|
|
1290
1569
|
name: 'output',
|
|
1291
1570
|
short: 'o',
|
|
1292
1571
|
description: 'Output file path',
|
|
1293
|
-
type: 'string'
|
|
1572
|
+
type: 'string'
|
|
1294
1573
|
},
|
|
1295
1574
|
{
|
|
1296
1575
|
name: 'format',
|
|
1297
1576
|
short: 'f',
|
|
1298
1577
|
description: 'Output format (text, json, dot)',
|
|
1299
1578
|
type: 'string',
|
|
1300
|
-
default: 'text',
|
|
1301
|
-
choices: ['text', 'json', 'dot']
|
|
1579
|
+
"default": 'text',
|
|
1580
|
+
choices: ['text', 'json', 'dot']
|
|
1302
1581
|
},
|
|
1303
1582
|
{
|
|
1304
1583
|
name: 'min-size',
|
|
1305
1584
|
short: 'm',
|
|
1306
1585
|
description: 'Minimum community size to display',
|
|
1307
1586
|
type: 'number',
|
|
1308
|
-
default: 2
|
|
1587
|
+
"default": 2
|
|
1309
1588
|
},
|
|
1310
1589
|
],
|
|
1311
1590
|
examples: [
|
|
@@ -1313,109 +1592,128 @@ const modulesCommand = {
|
|
|
1313
1592
|
{ command: 'claude-flow analyze modules -f dot -o modules.dot src/', description: 'Export colored DOT graph' },
|
|
1314
1593
|
{ command: 'claude-flow analyze modules -m 3 src/', description: 'Only show communities with 3+ files' },
|
|
1315
1594
|
],
|
|
1316
|
-
action:
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1595
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1596
|
+
var targetDir, outputFile, format, minSize, spinner, analyzer, result, communities, jsonOutput, dotOutput, _i, _a, community, cohesionIndicator, displayMembers, _b, displayMembers_1, member, error_7, message;
|
|
1597
|
+
var _c, _d;
|
|
1598
|
+
return __generator(this, function (_e) {
|
|
1599
|
+
switch (_e.label) {
|
|
1600
|
+
case 0:
|
|
1601
|
+
targetDir = ctx.args[0] || ctx.cwd;
|
|
1602
|
+
outputFile = ctx.flags.output;
|
|
1603
|
+
format = ctx.flags.format || 'text';
|
|
1604
|
+
minSize = ctx.flags['min-size'] || 2;
|
|
1605
|
+
output.printInfo("Detecting module communities in: " + output.highlight(targetDir));
|
|
1606
|
+
output.writeln();
|
|
1607
|
+
spinner = output.createSpinner({ text: 'Building dependency graph...', spinner: 'dots' });
|
|
1608
|
+
spinner.start();
|
|
1609
|
+
_e.label = 1;
|
|
1610
|
+
case 1:
|
|
1611
|
+
_e.trys.push([1, 14, , 15]);
|
|
1612
|
+
return [4 /*yield*/, getGraphAnalyzer()];
|
|
1613
|
+
case 2:
|
|
1614
|
+
analyzer = _e.sent();
|
|
1615
|
+
if (!analyzer) {
|
|
1616
|
+
spinner.stop();
|
|
1617
|
+
output.printError('Graph analyzer module not available');
|
|
1618
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1619
|
+
}
|
|
1620
|
+
return [4 /*yield*/, analyzer.analyzeGraph(resolve(targetDir), {
|
|
1621
|
+
includeBoundaries: false,
|
|
1622
|
+
includeModules: true
|
|
1623
|
+
})];
|
|
1624
|
+
case 3:
|
|
1625
|
+
result = _e.sent();
|
|
1626
|
+
spinner.stop();
|
|
1627
|
+
communities = ((_c = result.communities) === null || _c === void 0 ? void 0 : _c.filter(function (c) { return c.members.length >= minSize; })) || [];
|
|
1628
|
+
if (!(format === 'json')) return [3 /*break*/, 7];
|
|
1629
|
+
jsonOutput = {
|
|
1630
|
+
communities: communities,
|
|
1631
|
+
statistics: result.statistics
|
|
1632
|
+
};
|
|
1633
|
+
if (!outputFile) return [3 /*break*/, 5];
|
|
1634
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
1635
|
+
case 4:
|
|
1636
|
+
_e.sent();
|
|
1637
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1638
|
+
return [3 /*break*/, 6];
|
|
1639
|
+
case 5:
|
|
1350
1640
|
output.printJson(jsonOutput);
|
|
1351
|
-
|
|
1352
|
-
return { success: true, data: jsonOutput };
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1641
|
+
_e.label = 6;
|
|
1642
|
+
case 6: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
1643
|
+
case 7:
|
|
1644
|
+
if (!(format === 'dot')) return [3 /*break*/, 11];
|
|
1645
|
+
dotOutput = analyzer.exportToDot(result, {
|
|
1646
|
+
includeLabels: true,
|
|
1647
|
+
colorByCommunity: true,
|
|
1648
|
+
highlightCycles: true
|
|
1649
|
+
});
|
|
1650
|
+
if (!outputFile) return [3 /*break*/, 9];
|
|
1651
|
+
return [4 /*yield*/, writeFile(outputFile, dotOutput)];
|
|
1652
|
+
case 8:
|
|
1653
|
+
_e.sent();
|
|
1654
|
+
output.printSuccess("DOT graph written to " + outputFile);
|
|
1363
1655
|
output.writeln(output.dim('Visualize with: dot -Tpng -o modules.png ' + outputFile));
|
|
1364
|
-
|
|
1365
|
-
|
|
1656
|
+
return [3 /*break*/, 10];
|
|
1657
|
+
case 9:
|
|
1366
1658
|
output.writeln(dotOutput);
|
|
1367
|
-
|
|
1368
|
-
return { success: true };
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1659
|
+
_e.label = 10;
|
|
1660
|
+
case 10: return [2 /*return*/, { success: true }];
|
|
1661
|
+
case 11:
|
|
1662
|
+
// Text format (default)
|
|
1663
|
+
output.printBox([
|
|
1664
|
+
"Files analyzed: " + result.statistics.nodeCount,
|
|
1665
|
+
"Dependencies: " + result.statistics.edgeCount,
|
|
1666
|
+
"Communities found: " + (((_d = result.communities) === null || _d === void 0 ? void 0 : _d.length) || 0),
|
|
1667
|
+
"Showing: " + communities.length + " (min size: " + minSize + ")",
|
|
1668
|
+
].join('\n'), 'Module Detection Results');
|
|
1669
|
+
if (communities.length > 0) {
|
|
1670
|
+
output.writeln();
|
|
1671
|
+
output.writeln(output.bold('Detected Communities'));
|
|
1672
|
+
output.writeln();
|
|
1673
|
+
for (_i = 0, _a = communities.slice(0, 10); _i < _a.length; _i++) {
|
|
1674
|
+
community = _a[_i];
|
|
1675
|
+
cohesionIndicator = community.cohesion > 0.5 ? output.success('High') :
|
|
1676
|
+
community.cohesion > 0.2 ? output.warning('Medium') : output.dim('Low');
|
|
1677
|
+
output.writeln(output.bold("Community " + community.id + ": " + (community.suggestedName || 'unnamed')));
|
|
1678
|
+
output.writeln(" " + output.dim('Cohesion:') + " " + cohesionIndicator + " (" + (community.cohesion * 100).toFixed(1) + "%)");
|
|
1679
|
+
output.writeln(" " + output.dim('Central node:') + " " + (community.centralNode || 'none'));
|
|
1680
|
+
output.writeln(" " + output.dim('Members:') + " " + community.members.length + " files");
|
|
1681
|
+
displayMembers = community.members.slice(0, 5);
|
|
1682
|
+
for (_b = 0, displayMembers_1 = displayMembers; _b < displayMembers_1.length; _b++) {
|
|
1683
|
+
member = displayMembers_1[_b];
|
|
1684
|
+
output.writeln(" - " + member);
|
|
1685
|
+
}
|
|
1686
|
+
if (community.members.length > 5) {
|
|
1687
|
+
output.writeln(output.dim(" ... and " + (community.members.length - 5) + " more"));
|
|
1688
|
+
}
|
|
1689
|
+
output.writeln();
|
|
1690
|
+
}
|
|
1691
|
+
if (communities.length > 10) {
|
|
1692
|
+
output.writeln(output.dim("... and " + (communities.length - 10) + " more communities"));
|
|
1693
|
+
}
|
|
1394
1694
|
}
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1695
|
+
if (!outputFile) return [3 /*break*/, 13];
|
|
1696
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(result, null, 2))];
|
|
1697
|
+
case 12:
|
|
1698
|
+
_e.sent();
|
|
1699
|
+
output.printSuccess("Full results written to " + outputFile);
|
|
1700
|
+
_e.label = 13;
|
|
1701
|
+
case 13: return [2 /*return*/, { success: true, data: result }];
|
|
1702
|
+
case 14:
|
|
1703
|
+
error_7 = _e.sent();
|
|
1704
|
+
spinner.stop();
|
|
1705
|
+
message = error_7 instanceof Error ? error_7.message : String(error_7);
|
|
1706
|
+
output.printError("Analysis failed: " + message);
|
|
1707
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1708
|
+
case 15: return [2 /*return*/];
|
|
1404
1709
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
catch (error) {
|
|
1408
|
-
spinner.stop();
|
|
1409
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1410
|
-
output.printError(`Analysis failed: ${message}`);
|
|
1411
|
-
return { success: false, exitCode: 1 };
|
|
1412
|
-
}
|
|
1413
|
-
},
|
|
1710
|
+
});
|
|
1711
|
+
}); }
|
|
1414
1712
|
};
|
|
1415
1713
|
/**
|
|
1416
1714
|
* Build and export dependency graph
|
|
1417
1715
|
*/
|
|
1418
|
-
|
|
1716
|
+
var dependenciesCommand = {
|
|
1419
1717
|
name: 'dependencies',
|
|
1420
1718
|
aliases: ['graph'],
|
|
1421
1719
|
description: 'Build and export full dependency graph',
|
|
@@ -1424,36 +1722,36 @@ const dependenciesCommand = {
|
|
|
1424
1722
|
name: 'output',
|
|
1425
1723
|
short: 'o',
|
|
1426
1724
|
description: 'Output file path',
|
|
1427
|
-
type: 'string'
|
|
1725
|
+
type: 'string'
|
|
1428
1726
|
},
|
|
1429
1727
|
{
|
|
1430
1728
|
name: 'format',
|
|
1431
1729
|
short: 'f',
|
|
1432
1730
|
description: 'Output format (text, json, dot)',
|
|
1433
1731
|
type: 'string',
|
|
1434
|
-
default: 'text',
|
|
1435
|
-
choices: ['text', 'json', 'dot']
|
|
1732
|
+
"default": 'text',
|
|
1733
|
+
choices: ['text', 'json', 'dot']
|
|
1436
1734
|
},
|
|
1437
1735
|
{
|
|
1438
1736
|
name: 'include',
|
|
1439
1737
|
short: 'i',
|
|
1440
1738
|
description: 'File extensions to include (comma-separated)',
|
|
1441
1739
|
type: 'string',
|
|
1442
|
-
default: '.ts,.tsx,.js,.jsx,.mjs,.cjs'
|
|
1740
|
+
"default": '.ts,.tsx,.js,.jsx,.mjs,.cjs'
|
|
1443
1741
|
},
|
|
1444
1742
|
{
|
|
1445
1743
|
name: 'exclude',
|
|
1446
1744
|
short: 'e',
|
|
1447
1745
|
description: 'Patterns to exclude (comma-separated)',
|
|
1448
1746
|
type: 'string',
|
|
1449
|
-
default: 'node_modules,dist,build,.git'
|
|
1747
|
+
"default": 'node_modules,dist,build,.git'
|
|
1450
1748
|
},
|
|
1451
1749
|
{
|
|
1452
1750
|
name: 'depth',
|
|
1453
1751
|
short: 'd',
|
|
1454
1752
|
description: 'Maximum directory depth',
|
|
1455
1753
|
type: 'number',
|
|
1456
|
-
default: 10
|
|
1754
|
+
"default": 10
|
|
1457
1755
|
},
|
|
1458
1756
|
],
|
|
1459
1757
|
examples: [
|
|
@@ -1461,138 +1759,152 @@ const dependenciesCommand = {
|
|
|
1461
1759
|
{ command: 'claude-flow analyze dependencies -f dot -o deps.dot src/', description: 'Export to DOT' },
|
|
1462
1760
|
{ command: 'claude-flow analyze dependencies -i .ts,.tsx src/', description: 'Only TypeScript files' },
|
|
1463
1761
|
],
|
|
1464
|
-
action:
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1762
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1763
|
+
var targetDir, outputFile, format, include, exclude, maxDepth, spinner, analyzer, graph_1, circularDeps, jsonOutput, result, dotOutput, nodesByDegree, _i, _a, cycle, fullOutput, error_8, message;
|
|
1764
|
+
return __generator(this, function (_b) {
|
|
1765
|
+
switch (_b.label) {
|
|
1766
|
+
case 0:
|
|
1767
|
+
targetDir = ctx.args[0] || ctx.cwd;
|
|
1768
|
+
outputFile = ctx.flags.output;
|
|
1769
|
+
format = ctx.flags.format || 'text';
|
|
1770
|
+
include = (ctx.flags.include || '.ts,.tsx,.js,.jsx,.mjs,.cjs').split(',');
|
|
1771
|
+
exclude = (ctx.flags.exclude || 'node_modules,dist,build,.git').split(',');
|
|
1772
|
+
maxDepth = ctx.flags.depth || 10;
|
|
1773
|
+
output.printInfo("Building dependency graph for: " + output.highlight(targetDir));
|
|
1774
|
+
output.writeln();
|
|
1775
|
+
spinner = output.createSpinner({ text: 'Scanning files...', spinner: 'dots' });
|
|
1776
|
+
spinner.start();
|
|
1777
|
+
_b.label = 1;
|
|
1778
|
+
case 1:
|
|
1779
|
+
_b.trys.push([1, 14, , 15]);
|
|
1780
|
+
return [4 /*yield*/, getGraphAnalyzer()];
|
|
1781
|
+
case 2:
|
|
1782
|
+
analyzer = _b.sent();
|
|
1783
|
+
if (!analyzer) {
|
|
1784
|
+
spinner.stop();
|
|
1785
|
+
output.printError('Graph analyzer module not available');
|
|
1786
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1787
|
+
}
|
|
1788
|
+
return [4 /*yield*/, analyzer.buildDependencyGraph(resolve(targetDir), {
|
|
1789
|
+
include: include,
|
|
1790
|
+
exclude: exclude,
|
|
1791
|
+
maxDepth: maxDepth
|
|
1792
|
+
})];
|
|
1793
|
+
case 3:
|
|
1794
|
+
graph_1 = _b.sent();
|
|
1795
|
+
spinner.stop();
|
|
1796
|
+
circularDeps = analyzer.detectCircularDependencies(graph_1);
|
|
1797
|
+
if (!(format === 'json')) return [3 /*break*/, 7];
|
|
1798
|
+
jsonOutput = {
|
|
1799
|
+
nodes: Array.from(graph_1.nodes.values()),
|
|
1800
|
+
edges: graph_1.edges,
|
|
1801
|
+
metadata: graph_1.metadata,
|
|
1802
|
+
circularDependencies: circularDeps
|
|
1803
|
+
};
|
|
1804
|
+
if (!outputFile) return [3 /*break*/, 5];
|
|
1805
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
1806
|
+
case 4:
|
|
1807
|
+
_b.sent();
|
|
1808
|
+
output.printSuccess("Graph written to " + outputFile);
|
|
1809
|
+
return [3 /*break*/, 6];
|
|
1810
|
+
case 5:
|
|
1503
1811
|
output.printJson(jsonOutput);
|
|
1504
|
-
|
|
1505
|
-
return { success: true, data: jsonOutput };
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1812
|
+
_b.label = 6;
|
|
1813
|
+
case 6: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
1814
|
+
case 7:
|
|
1815
|
+
if (!(format === 'dot')) return [3 /*break*/, 11];
|
|
1816
|
+
result = { graph: graph_1, circularDependencies: circularDeps, statistics: {
|
|
1817
|
+
nodeCount: graph_1.nodes.size,
|
|
1818
|
+
edgeCount: graph_1.edges.length,
|
|
1819
|
+
avgDegree: 0,
|
|
1820
|
+
maxDegree: 0,
|
|
1821
|
+
density: 0,
|
|
1822
|
+
componentCount: 0
|
|
1823
|
+
} };
|
|
1824
|
+
dotOutput = analyzer.exportToDot(result, {
|
|
1825
|
+
includeLabels: true,
|
|
1826
|
+
highlightCycles: true
|
|
1827
|
+
});
|
|
1828
|
+
if (!outputFile) return [3 /*break*/, 9];
|
|
1829
|
+
return [4 /*yield*/, writeFile(outputFile, dotOutput)];
|
|
1830
|
+
case 8:
|
|
1831
|
+
_b.sent();
|
|
1832
|
+
output.printSuccess("DOT graph written to " + outputFile);
|
|
1523
1833
|
output.writeln(output.dim('Visualize with: dot -Tpng -o deps.png ' + outputFile));
|
|
1524
|
-
|
|
1525
|
-
|
|
1834
|
+
return [3 /*break*/, 10];
|
|
1835
|
+
case 9:
|
|
1526
1836
|
output.writeln(dotOutput);
|
|
1527
|
-
|
|
1528
|
-
return { success: true };
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1837
|
+
_b.label = 10;
|
|
1838
|
+
case 10: return [2 /*return*/, { success: true }];
|
|
1839
|
+
case 11:
|
|
1840
|
+
// Text format (default)
|
|
1841
|
+
output.printBox([
|
|
1842
|
+
"Files: " + graph_1.metadata.totalFiles,
|
|
1843
|
+
"Dependencies: " + graph_1.metadata.totalEdges,
|
|
1844
|
+
"Build time: " + graph_1.metadata.buildTime + "ms",
|
|
1845
|
+
"Root: " + graph_1.metadata.rootDir,
|
|
1846
|
+
].join('\n'), 'Dependency Graph');
|
|
1847
|
+
// Show top files by imports
|
|
1848
|
+
output.writeln();
|
|
1849
|
+
output.writeln(output.bold('Most Connected Files'));
|
|
1850
|
+
output.writeln();
|
|
1851
|
+
nodesByDegree = Array.from(graph_1.nodes.values())
|
|
1852
|
+
.map(function (n) { return (__assign(__assign({}, n), { degree: graph_1.edges.filter(function (e) { return e.source === n.id || e.target === n.id; }).length })); })
|
|
1853
|
+
.sort(function (a, b) { return b.degree - a.degree; })
|
|
1854
|
+
.slice(0, 10);
|
|
1855
|
+
output.printTable({
|
|
1856
|
+
columns: [
|
|
1857
|
+
{ key: 'path', header: 'File', width: 50 },
|
|
1858
|
+
{ key: 'degree', header: 'Connections', width: 12, align: 'right' },
|
|
1859
|
+
{ key: 'complexity', header: 'Complexity', width: 12, align: 'right' },
|
|
1860
|
+
],
|
|
1861
|
+
data: nodesByDegree.map(function (n) { return ({
|
|
1862
|
+
path: n.path.length > 48 ? '...' + n.path.slice(-45) : n.path,
|
|
1863
|
+
degree: n.degree,
|
|
1864
|
+
complexity: n.complexity || 0
|
|
1865
|
+
}); })
|
|
1866
|
+
});
|
|
1867
|
+
// Show circular dependencies
|
|
1868
|
+
if (circularDeps.length > 0) {
|
|
1869
|
+
output.writeln();
|
|
1870
|
+
output.writeln(output.bold(output.warning("Circular Dependencies: " + circularDeps.length)));
|
|
1871
|
+
output.writeln();
|
|
1872
|
+
for (_i = 0, _a = circularDeps.slice(0, 3); _i < _a.length; _i++) {
|
|
1873
|
+
cycle = _a[_i];
|
|
1874
|
+
output.writeln(" " + cycle.cycle.join(' -> '));
|
|
1875
|
+
}
|
|
1876
|
+
if (circularDeps.length > 3) {
|
|
1877
|
+
output.writeln(output.dim(" ... and " + (circularDeps.length - 3) + " more"));
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
if (!outputFile) return [3 /*break*/, 13];
|
|
1881
|
+
fullOutput = {
|
|
1882
|
+
nodes: Array.from(graph_1.nodes.values()),
|
|
1883
|
+
edges: graph_1.edges,
|
|
1884
|
+
metadata: graph_1.metadata,
|
|
1885
|
+
circularDependencies: circularDeps
|
|
1886
|
+
};
|
|
1887
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(fullOutput, null, 2))];
|
|
1888
|
+
case 12:
|
|
1889
|
+
_b.sent();
|
|
1890
|
+
output.printSuccess("Full results written to " + outputFile);
|
|
1891
|
+
_b.label = 13;
|
|
1892
|
+
case 13: return [2 /*return*/, { success: true }];
|
|
1893
|
+
case 14:
|
|
1894
|
+
error_8 = _b.sent();
|
|
1895
|
+
spinner.stop();
|
|
1896
|
+
message = error_8 instanceof Error ? error_8.message : String(error_8);
|
|
1897
|
+
output.printError("Analysis failed: " + message);
|
|
1898
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1899
|
+
case 15: return [2 /*return*/];
|
|
1581
1900
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
catch (error) {
|
|
1585
|
-
spinner.stop();
|
|
1586
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1587
|
-
output.printError(`Analysis failed: ${message}`);
|
|
1588
|
-
return { success: false, exitCode: 1 };
|
|
1589
|
-
}
|
|
1590
|
-
},
|
|
1901
|
+
});
|
|
1902
|
+
}); }
|
|
1591
1903
|
};
|
|
1592
1904
|
/**
|
|
1593
1905
|
* Detect circular dependencies
|
|
1594
1906
|
*/
|
|
1595
|
-
|
|
1907
|
+
var circularCommand = {
|
|
1596
1908
|
name: 'circular',
|
|
1597
1909
|
aliases: ['cycles'],
|
|
1598
1910
|
description: 'Detect circular dependencies in codebase',
|
|
@@ -1601,111 +1913,127 @@ const circularCommand = {
|
|
|
1601
1913
|
name: 'output',
|
|
1602
1914
|
short: 'o',
|
|
1603
1915
|
description: 'Output file path',
|
|
1604
|
-
type: 'string'
|
|
1916
|
+
type: 'string'
|
|
1605
1917
|
},
|
|
1606
1918
|
{
|
|
1607
1919
|
name: 'format',
|
|
1608
1920
|
short: 'f',
|
|
1609
1921
|
description: 'Output format (text, json)',
|
|
1610
1922
|
type: 'string',
|
|
1611
|
-
default: 'text',
|
|
1612
|
-
choices: ['text', 'json']
|
|
1923
|
+
"default": 'text',
|
|
1924
|
+
choices: ['text', 'json']
|
|
1613
1925
|
},
|
|
1614
1926
|
{
|
|
1615
1927
|
name: 'severity',
|
|
1616
1928
|
short: 's',
|
|
1617
1929
|
description: 'Minimum severity to show (low, medium, high)',
|
|
1618
1930
|
type: 'string',
|
|
1619
|
-
default: 'low',
|
|
1620
|
-
choices: ['low', 'medium', 'high']
|
|
1931
|
+
"default": 'low',
|
|
1932
|
+
choices: ['low', 'medium', 'high']
|
|
1621
1933
|
},
|
|
1622
1934
|
],
|
|
1623
1935
|
examples: [
|
|
1624
1936
|
{ command: 'claude-flow analyze circular src/', description: 'Find circular dependencies' },
|
|
1625
1937
|
{ command: 'claude-flow analyze circular -s high src/', description: 'Only high severity cycles' },
|
|
1626
1938
|
],
|
|
1627
|
-
action:
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
const analyzer = await getGraphAnalyzer();
|
|
1638
|
-
if (!analyzer) {
|
|
1639
|
-
spinner.stop();
|
|
1640
|
-
output.printError('Graph analyzer module not available');
|
|
1641
|
-
return { success: false, exitCode: 1 };
|
|
1642
|
-
}
|
|
1643
|
-
const graph = await analyzer.buildDependencyGraph(resolve(targetDir));
|
|
1644
|
-
const cycles = analyzer.detectCircularDependencies(graph);
|
|
1645
|
-
spinner.stop();
|
|
1646
|
-
// Filter by severity
|
|
1647
|
-
const severityOrder = { low: 0, medium: 1, high: 2 };
|
|
1648
|
-
const minLevel = severityOrder[minSeverity] || 0;
|
|
1649
|
-
const filtered = cycles.filter(c => severityOrder[c.severity] >= minLevel);
|
|
1650
|
-
if (format === 'json') {
|
|
1651
|
-
const jsonOutput = { cycles: filtered, total: cycles.length, filtered: filtered.length };
|
|
1652
|
-
if (outputFile) {
|
|
1653
|
-
await writeFile(outputFile, JSON.stringify(jsonOutput, null, 2));
|
|
1654
|
-
output.printSuccess(`Results written to ${outputFile}`);
|
|
1655
|
-
}
|
|
1656
|
-
else {
|
|
1657
|
-
output.printJson(jsonOutput);
|
|
1658
|
-
}
|
|
1659
|
-
return { success: true, data: jsonOutput };
|
|
1660
|
-
}
|
|
1661
|
-
// Text format
|
|
1662
|
-
if (filtered.length === 0) {
|
|
1663
|
-
output.printSuccess('No circular dependencies found!');
|
|
1664
|
-
return { success: true };
|
|
1665
|
-
}
|
|
1666
|
-
output.printBox([
|
|
1667
|
-
`Total cycles: ${cycles.length}`,
|
|
1668
|
-
`Shown (${minSeverity}+): ${filtered.length}`,
|
|
1669
|
-
`High severity: ${cycles.filter(c => c.severity === 'high').length}`,
|
|
1670
|
-
`Medium severity: ${cycles.filter(c => c.severity === 'medium').length}`,
|
|
1671
|
-
`Low severity: ${cycles.filter(c => c.severity === 'low').length}`,
|
|
1672
|
-
].join('\n'), 'Circular Dependencies');
|
|
1673
|
-
output.writeln();
|
|
1674
|
-
// Group by severity
|
|
1675
|
-
const grouped = {
|
|
1676
|
-
high: filtered.filter(c => c.severity === 'high'),
|
|
1677
|
-
medium: filtered.filter(c => c.severity === 'medium'),
|
|
1678
|
-
low: filtered.filter(c => c.severity === 'low'),
|
|
1679
|
-
};
|
|
1680
|
-
for (const [severity, items] of Object.entries(grouped)) {
|
|
1681
|
-
if (items.length === 0)
|
|
1682
|
-
continue;
|
|
1683
|
-
const color = severity === 'high' ? output.error : severity === 'medium' ? output.warning : output.dim;
|
|
1684
|
-
output.writeln(color(output.bold(`${severity.toUpperCase()} SEVERITY (${items.length})`)));
|
|
1685
|
-
output.writeln();
|
|
1686
|
-
for (const cycle of items.slice(0, 5)) {
|
|
1687
|
-
output.writeln(` ${cycle.cycle.join(' -> ')}`);
|
|
1688
|
-
output.writeln(output.dim(` Fix: ${cycle.suggestion}`));
|
|
1939
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
1940
|
+
var targetDir, outputFile, format, minSeverity, spinner, analyzer, graph, cycles, severityOrder_1, minLevel_1, filtered, jsonOutput, grouped, _i, _a, _b, severity, items, color, _c, _d, cycle, error_9, message;
|
|
1941
|
+
return __generator(this, function (_e) {
|
|
1942
|
+
switch (_e.label) {
|
|
1943
|
+
case 0:
|
|
1944
|
+
targetDir = ctx.args[0] || ctx.cwd;
|
|
1945
|
+
outputFile = ctx.flags.output;
|
|
1946
|
+
format = ctx.flags.format || 'text';
|
|
1947
|
+
minSeverity = ctx.flags.severity || 'low';
|
|
1948
|
+
output.printInfo("Detecting circular dependencies in: " + output.highlight(targetDir));
|
|
1689
1949
|
output.writeln();
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1950
|
+
spinner = output.createSpinner({ text: 'Analyzing dependencies...', spinner: 'dots' });
|
|
1951
|
+
spinner.start();
|
|
1952
|
+
_e.label = 1;
|
|
1953
|
+
case 1:
|
|
1954
|
+
_e.trys.push([1, 10, , 11]);
|
|
1955
|
+
return [4 /*yield*/, getGraphAnalyzer()];
|
|
1956
|
+
case 2:
|
|
1957
|
+
analyzer = _e.sent();
|
|
1958
|
+
if (!analyzer) {
|
|
1959
|
+
spinner.stop();
|
|
1960
|
+
output.printError('Graph analyzer module not available');
|
|
1961
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
1962
|
+
}
|
|
1963
|
+
return [4 /*yield*/, analyzer.buildDependencyGraph(resolve(targetDir))];
|
|
1964
|
+
case 3:
|
|
1965
|
+
graph = _e.sent();
|
|
1966
|
+
cycles = analyzer.detectCircularDependencies(graph);
|
|
1967
|
+
spinner.stop();
|
|
1968
|
+
severityOrder_1 = { low: 0, medium: 1, high: 2 };
|
|
1969
|
+
minLevel_1 = severityOrder_1[minSeverity] || 0;
|
|
1970
|
+
filtered = cycles.filter(function (c) { return severityOrder_1[c.severity] >= minLevel_1; });
|
|
1971
|
+
if (!(format === 'json')) return [3 /*break*/, 7];
|
|
1972
|
+
jsonOutput = { cycles: filtered, total: cycles.length, filtered: filtered.length };
|
|
1973
|
+
if (!outputFile) return [3 /*break*/, 5];
|
|
1974
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify(jsonOutput, null, 2))];
|
|
1975
|
+
case 4:
|
|
1976
|
+
_e.sent();
|
|
1977
|
+
output.printSuccess("Results written to " + outputFile);
|
|
1978
|
+
return [3 /*break*/, 6];
|
|
1979
|
+
case 5:
|
|
1980
|
+
output.printJson(jsonOutput);
|
|
1981
|
+
_e.label = 6;
|
|
1982
|
+
case 6: return [2 /*return*/, { success: true, data: jsonOutput }];
|
|
1983
|
+
case 7:
|
|
1984
|
+
// Text format
|
|
1985
|
+
if (filtered.length === 0) {
|
|
1986
|
+
output.printSuccess('No circular dependencies found!');
|
|
1987
|
+
return [2 /*return*/, { success: true }];
|
|
1988
|
+
}
|
|
1989
|
+
output.printBox([
|
|
1990
|
+
"Total cycles: " + cycles.length,
|
|
1991
|
+
"Shown (" + minSeverity + "+): " + filtered.length,
|
|
1992
|
+
"High severity: " + cycles.filter(function (c) { return c.severity === 'high'; }).length,
|
|
1993
|
+
"Medium severity: " + cycles.filter(function (c) { return c.severity === 'medium'; }).length,
|
|
1994
|
+
"Low severity: " + cycles.filter(function (c) { return c.severity === 'low'; }).length,
|
|
1995
|
+
].join('\n'), 'Circular Dependencies');
|
|
1693
1996
|
output.writeln();
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1997
|
+
grouped = {
|
|
1998
|
+
high: filtered.filter(function (c) { return c.severity === 'high'; }),
|
|
1999
|
+
medium: filtered.filter(function (c) { return c.severity === 'medium'; }),
|
|
2000
|
+
low: filtered.filter(function (c) { return c.severity === 'low'; })
|
|
2001
|
+
};
|
|
2002
|
+
for (_i = 0, _a = Object.entries(grouped); _i < _a.length; _i++) {
|
|
2003
|
+
_b = _a[_i], severity = _b[0], items = _b[1];
|
|
2004
|
+
if (items.length === 0)
|
|
2005
|
+
continue;
|
|
2006
|
+
color = severity === 'high' ? output.error : severity === 'medium' ? output.warning : output.dim;
|
|
2007
|
+
output.writeln(color(output.bold(severity.toUpperCase() + " SEVERITY (" + items.length + ")")));
|
|
2008
|
+
output.writeln();
|
|
2009
|
+
for (_c = 0, _d = items.slice(0, 5); _c < _d.length; _c++) {
|
|
2010
|
+
cycle = _d[_c];
|
|
2011
|
+
output.writeln(" " + cycle.cycle.join(' -> '));
|
|
2012
|
+
output.writeln(output.dim(" Fix: " + cycle.suggestion));
|
|
2013
|
+
output.writeln();
|
|
2014
|
+
}
|
|
2015
|
+
if (items.length > 5) {
|
|
2016
|
+
output.writeln(output.dim(" ... and " + (items.length - 5) + " more " + severity + " cycles"));
|
|
2017
|
+
output.writeln();
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
if (!outputFile) return [3 /*break*/, 9];
|
|
2021
|
+
return [4 /*yield*/, writeFile(outputFile, JSON.stringify({ cycles: filtered }, null, 2))];
|
|
2022
|
+
case 8:
|
|
2023
|
+
_e.sent();
|
|
2024
|
+
output.printSuccess("Results written to " + outputFile);
|
|
2025
|
+
_e.label = 9;
|
|
2026
|
+
case 9: return [2 /*return*/, { success: true, data: { cycles: filtered } }];
|
|
2027
|
+
case 10:
|
|
2028
|
+
error_9 = _e.sent();
|
|
2029
|
+
spinner.stop();
|
|
2030
|
+
message = error_9 instanceof Error ? error_9.message : String(error_9);
|
|
2031
|
+
output.printError("Analysis failed: " + message);
|
|
2032
|
+
return [2 /*return*/, { success: false, exitCode: 1 }];
|
|
2033
|
+
case 11: return [2 /*return*/];
|
|
1699
2034
|
}
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
catch (error) {
|
|
1703
|
-
spinner.stop();
|
|
1704
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1705
|
-
output.printError(`Analysis failed: ${message}`);
|
|
1706
|
-
return { success: false, exitCode: 1 };
|
|
1707
|
-
}
|
|
1708
|
-
},
|
|
2035
|
+
});
|
|
2036
|
+
}); }
|
|
1709
2037
|
};
|
|
1710
2038
|
// Helper functions
|
|
1711
2039
|
function getRiskDisplay(risk) {
|
|
@@ -1737,7 +2065,7 @@ function getStatusDisplay(status) {
|
|
|
1737
2065
|
}
|
|
1738
2066
|
}
|
|
1739
2067
|
// Main analyze command
|
|
1740
|
-
export
|
|
2068
|
+
export var analyzeCommand = {
|
|
1741
2069
|
name: 'analyze',
|
|
1742
2070
|
description: 'Code analysis, diff classification, graph boundaries, and change risk assessment',
|
|
1743
2071
|
aliases: ['an'],
|
|
@@ -1760,7 +2088,7 @@ export const analyzeCommand = {
|
|
|
1760
2088
|
short: 'f',
|
|
1761
2089
|
description: 'Output format: text, json, table',
|
|
1762
2090
|
type: 'string',
|
|
1763
|
-
default: 'text'
|
|
2091
|
+
"default": 'text'
|
|
1764
2092
|
},
|
|
1765
2093
|
],
|
|
1766
2094
|
examples: [
|
|
@@ -1775,49 +2103,51 @@ export const analyzeCommand = {
|
|
|
1775
2103
|
{ command: 'claude-flow analyze circular src/', description: 'Find circular dependencies' },
|
|
1776
2104
|
{ command: 'claude-flow analyze deps --security', description: 'Check dependency vulnerabilities' },
|
|
1777
2105
|
],
|
|
1778
|
-
action:
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
2106
|
+
action: function (ctx) { return __awaiter(void 0, void 0, Promise, function () {
|
|
2107
|
+
return __generator(this, function (_a) {
|
|
2108
|
+
// If no subcommand, show help
|
|
2109
|
+
output.writeln();
|
|
2110
|
+
output.writeln(output.bold('Analyze Commands'));
|
|
2111
|
+
output.writeln(output.dim('-'.repeat(50)));
|
|
2112
|
+
output.writeln();
|
|
2113
|
+
output.writeln(output.bold('Available subcommands:'));
|
|
2114
|
+
output.writeln();
|
|
2115
|
+
output.writeln(" " + output.highlight('diff') + " Analyze git diff for change risk and classification");
|
|
2116
|
+
output.writeln(" " + output.highlight('code') + " Static code analysis and quality assessment");
|
|
2117
|
+
output.writeln(" " + output.highlight('deps') + " Analyze project dependencies");
|
|
2118
|
+
output.writeln(" " + output.highlight('ast') + " AST analysis with symbol extraction and complexity");
|
|
2119
|
+
output.writeln(" " + output.highlight('complexity') + " Analyze cyclomatic and cognitive complexity");
|
|
2120
|
+
output.writeln(" " + output.highlight('symbols') + " Extract functions, classes, and types");
|
|
2121
|
+
output.writeln(" " + output.highlight('imports') + " Analyze import dependencies");
|
|
2122
|
+
output.writeln(" " + output.highlight('boundaries') + " Find code boundaries using MinCut algorithm");
|
|
2123
|
+
output.writeln(" " + output.highlight('modules') + " Detect module communities using Louvain algorithm");
|
|
2124
|
+
output.writeln(" " + output.highlight('dependencies') + " Build and export full dependency graph");
|
|
2125
|
+
output.writeln(" " + output.highlight('circular') + " Detect circular dependencies in codebase");
|
|
2126
|
+
output.writeln();
|
|
2127
|
+
output.writeln(output.bold('AST Analysis Examples:'));
|
|
2128
|
+
output.writeln();
|
|
2129
|
+
output.writeln(" " + output.dim('claude-flow analyze ast src/') + " # Full AST analysis");
|
|
2130
|
+
output.writeln(" " + output.dim('claude-flow analyze ast src/index.ts -c') + " # Include complexity");
|
|
2131
|
+
output.writeln(" " + output.dim('claude-flow analyze complexity src/ -t 15') + " # Flag high complexity");
|
|
2132
|
+
output.writeln(" " + output.dim('claude-flow analyze symbols src/ --type fn') + " # Extract functions");
|
|
2133
|
+
output.writeln(" " + output.dim('claude-flow analyze imports src/ --external') + " # Only npm imports");
|
|
2134
|
+
output.writeln();
|
|
2135
|
+
output.writeln(output.bold('Graph Analysis Examples:'));
|
|
2136
|
+
output.writeln();
|
|
2137
|
+
output.writeln(" " + output.dim('claude-flow analyze boundaries src/') + " # Find natural code boundaries");
|
|
2138
|
+
output.writeln(" " + output.dim('claude-flow analyze modules src/') + " # Detect module communities");
|
|
2139
|
+
output.writeln(" " + output.dim('claude-flow analyze dependencies -f dot src/') + " # Export to DOT format");
|
|
2140
|
+
output.writeln(" " + output.dim('claude-flow analyze circular src/') + " # Find circular deps");
|
|
2141
|
+
output.writeln();
|
|
2142
|
+
output.writeln(output.bold('Diff Analysis Examples:'));
|
|
2143
|
+
output.writeln();
|
|
2144
|
+
output.writeln(" " + output.dim('claude-flow analyze diff --risk') + " # Risk assessment");
|
|
2145
|
+
output.writeln(" " + output.dim('claude-flow analyze diff HEAD~1 --classify') + " # Classify changes");
|
|
2146
|
+
output.writeln(" " + output.dim('claude-flow analyze diff main..feature') + " # Compare branches");
|
|
2147
|
+
output.writeln();
|
|
2148
|
+
return [2 /*return*/, { success: true }];
|
|
2149
|
+
});
|
|
2150
|
+
}); }
|
|
1821
2151
|
};
|
|
1822
2152
|
export default analyzeCommand;
|
|
1823
2153
|
//# sourceMappingURL=analyze.js.map
|