agentic-qe 2.6.5 → 2.6.6
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/CHANGELOG.md +52 -0
- package/README.md +1 -1
- package/dist/agents/CoverageAnalyzerAgent.d.ts +31 -0
- package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.js +159 -0
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
- package/dist/agents/FleetCommanderAgent.d.ts +36 -0
- package/dist/agents/FleetCommanderAgent.d.ts.map +1 -1
- package/dist/agents/FleetCommanderAgent.js +226 -0
- package/dist/agents/FleetCommanderAgent.js.map +1 -1
- package/dist/cli/commands/kg/mincut.d.ts +50 -0
- package/dist/cli/commands/kg/mincut.d.ts.map +1 -0
- package/dist/cli/commands/kg/mincut.js +372 -0
- package/dist/cli/commands/kg/mincut.js.map +1 -0
- package/dist/cli/index.js +91 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/claude-config.js +2 -2
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.d.ts +148 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.js +393 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.d.ts +169 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.js +335 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.d.ts +55 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.js +265 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.d.ts +92 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.js +200 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.d.ts +157 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.js +434 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/index.d.ts +12 -0
- package/dist/code-intelligence/analysis/mincut/index.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/index.js +20 -0
- package/dist/code-intelligence/analysis/mincut/index.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/types.d.ts +145 -0
- package/dist/code-intelligence/analysis/mincut/types.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/types.js +16 -0
- package/dist/code-intelligence/analysis/mincut/types.js.map +1 -0
- package/dist/code-intelligence/chunking/ASTChunker.d.ts +1 -1
- package/dist/code-intelligence/chunking/ASTChunker.d.ts.map +1 -1
- package/dist/code-intelligence/chunking/ASTChunker.js +4 -4
- package/dist/code-intelligence/chunking/ASTChunker.js.map +1 -1
- package/dist/code-intelligence/graph/GraphBuilder.d.ts +120 -0
- package/dist/code-intelligence/graph/GraphBuilder.d.ts.map +1 -1
- package/dist/code-intelligence/graph/GraphBuilder.js +517 -0
- package/dist/code-intelligence/graph/GraphBuilder.js.map +1 -1
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.d.ts.map +1 -1
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.js +3 -3
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.js.map +1 -1
- package/dist/code-intelligence/parser/{TreeSitterParser.d.ts → WebTreeSitterParser.d.ts} +45 -10
- package/dist/code-intelligence/parser/WebTreeSitterParser.d.ts.map +1 -0
- package/dist/code-intelligence/parser/{TreeSitterParser.js → WebTreeSitterParser.js} +147 -54
- package/dist/code-intelligence/parser/WebTreeSitterParser.js.map +1 -0
- package/dist/code-intelligence/parser/extractors/BaseExtractor.d.ts +12 -10
- package/dist/code-intelligence/parser/extractors/BaseExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/BaseExtractor.js +7 -3
- package/dist/code-intelligence/parser/extractors/BaseExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/GoExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/GoExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/GoExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/GoExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/PythonExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/PythonExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/PythonExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/PythonExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/RustExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/RustExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/RustExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/RustExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/index.d.ts +7 -1
- package/dist/code-intelligence/parser/index.d.ts.map +1 -1
- package/dist/code-intelligence/parser/index.js +11 -3
- package/dist/code-intelligence/parser/index.js.map +1 -1
- package/dist/code-intelligence/service/CodeIntelligenceService.d.ts.map +1 -1
- package/dist/code-intelligence/service/CodeIntelligenceService.js +7 -5
- package/dist/code-intelligence/service/CodeIntelligenceService.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/coverage/CriticalPathDetector.d.ts +240 -0
- package/dist/coverage/CriticalPathDetector.d.ts.map +1 -0
- package/dist/coverage/CriticalPathDetector.js +388 -0
- package/dist/coverage/CriticalPathDetector.js.map +1 -0
- package/dist/coverage/index.d.ts +13 -0
- package/dist/coverage/index.d.ts.map +1 -0
- package/dist/coverage/index.js +16 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/fleet/topology/SPOFMonitor.d.ts +181 -0
- package/dist/fleet/topology/SPOFMonitor.d.ts.map +1 -0
- package/dist/fleet/topology/SPOFMonitor.js +286 -0
- package/dist/fleet/topology/SPOFMonitor.js.map +1 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.d.ts +87 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.d.ts.map +1 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.js +472 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.js.map +1 -0
- package/dist/fleet/topology/index.d.ts +13 -0
- package/dist/fleet/topology/index.d.ts.map +1 -0
- package/dist/fleet/topology/index.js +20 -0
- package/dist/fleet/topology/index.js.map +1 -0
- package/dist/fleet/topology/types.d.ts +139 -0
- package/dist/fleet/topology/types.d.ts.map +1 -0
- package/dist/fleet/topology/types.js +19 -0
- package/dist/fleet/topology/types.js.map +1 -0
- package/dist/mcp/handlers/test/test-execute-parallel.d.ts +34 -3
- package/dist/mcp/handlers/test/test-execute-parallel.d.ts.map +1 -1
- package/dist/mcp/handlers/test/test-execute-parallel.js +120 -5
- package/dist/mcp/handlers/test/test-execute-parallel.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +2 -2
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +2 -2
- package/dist/test/partition/MinCutPartitioner.d.ts +97 -0
- package/dist/test/partition/MinCutPartitioner.d.ts.map +1 -0
- package/dist/test/partition/MinCutPartitioner.js +459 -0
- package/dist/test/partition/MinCutPartitioner.js.map +1 -0
- package/dist/test/partition/RealTestExecutor.d.ts +86 -0
- package/dist/test/partition/RealTestExecutor.d.ts.map +1 -0
- package/dist/test/partition/RealTestExecutor.js +279 -0
- package/dist/test/partition/RealTestExecutor.js.map +1 -0
- package/dist/test/partition/TestDependencyAnalyzer.d.ts +75 -0
- package/dist/test/partition/TestDependencyAnalyzer.d.ts.map +1 -0
- package/dist/test/partition/TestDependencyAnalyzer.js +297 -0
- package/dist/test/partition/TestDependencyAnalyzer.js.map +1 -0
- package/dist/test/partition/index.d.ts +10 -0
- package/dist/test/partition/index.d.ts.map +1 -0
- package/dist/test/partition/index.js +26 -0
- package/dist/test/partition/index.js.map +1 -0
- package/dist/test/partition/types.d.ts +120 -0
- package/dist/test/partition/types.d.ts.map +1 -0
- package/dist/test/partition/types.js +21 -0
- package/dist/test/partition/types.js.map +1 -0
- package/package.json +4 -7
- package/dist/code-intelligence/parser/TreeSitterParser.d.ts.map +0 -1
- package/dist/code-intelligence/parser/TreeSitterParser.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeIntelligenceService.js","sourceRoot":"","sources":["../../../src/code-intelligence/service/CodeIntelligenceService.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"CodeIntelligenceService.js","sourceRoot":"","sources":["../../../src/code-intelligence/service/CodeIntelligenceService.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuXH,gEAEC;AAED,gEAIC;AAED,gFAEC;AAjYD,qGAA+F;AAI/F,2CAA6B;AA+C7B,qBAAqB;AACrB,IAAI,QAAQ,GAAmC,IAAI,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAa,uBAAuB;IAOlC,YAAoB,SAAwC,EAAE;QANtD,iBAAY,GAAwC,IAAI,CAAC;QAEzD,gBAAW,GAAY,KAAK,CAAC;QAC7B,iBAAY,GAAyB,IAAI,CAAC;QAIhD,0CAA0C;QAC1C,MAAM,UAAU,GAAG,MAAM,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG;YACZ,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE;YAC5C,YAAY,EAAE,UAAU,CAAC,YAAY,IAAI,KAAK;YAC9C,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,IAAI;YACzC,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB;YACrF,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI;gBAC/B,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,WAAW;gBAC9C,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC;gBACnD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,aAAa;gBACxD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;gBAC7C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU;aACtD;SACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,MAAsC;QACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,kBAAkB;QAO7B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,eAAe;QACf,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB,CAAC;YACrE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7F,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,MAAM,GAAG,IAAI,CAAC;gBACd,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA0C,CAAC;gBAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;gBACjC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;gBACxF,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,QAAQ,CAAC,IAAI,CAAC,wFAAwF,CAAC,CAAC;gBAC1G,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAClE,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,GAAG,wDAAa,IAAI,GAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;gBACpB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,WAAW;gBAC9C,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC;gBACnD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,aAAa;gBACxD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;gBAC7C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU;gBACrD,uBAAuB,EAAE,IAAI;aAC9B,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7B,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;QACzF,CAAC;QAED,OAAO;YACL,MAAM;YACN,WAAW;YACX,QAAQ;YACR,QAAQ,EAAE,MAAM,IAAI,WAAW,IAAI,QAAQ;YAC3C,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,MAAM,IAAI,CAAC,YAAY,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,sBAAsB;QACtB,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,6CAA6C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,2CAA2C;QAC3C,MAAM,kBAAkB,GAAgC;YACtD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE;YAC7C,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,KAAK;YAC/C,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI;YAC1C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,wBAAwB;YAC5D,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;SAC/B,CAAC;QAEF,0BAA0B;QAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,8DAA4B,CAAC,kBAAkB,CAAC,CAAC;QACzE,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC;IAED;;;;;OAKG;IACH,aAAa;QACX,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;QAED,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;YACjD,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;YACjD,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,cAAc;QAKZ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;YACjD,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;SAClD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,OAAO;gBACL,WAAW,EAAE,KAAK;gBAClB,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,CAAC;gBACb,UAAU,EAAE,CAAC;gBACb,KAAK,EAAE,yBAAyB;aACjC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3C,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW;gBACxC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBACjC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBACjC,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,CAAC;gBACb,UAAU,EAAE,CAAC;gBACb,KAAK,EAAG,KAAe,CAAC,OAAO;aAChC,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAClB,SAAiB,EACjB,UAAsG;QAStG,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAC7C,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAQ,EAAE,SAAS,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC9E,IAAI,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,CAAC;QAEhC,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,UAII,EAAE;QAEN,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;YAC7B,KAAK;YACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;YACxB,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,IAAI;YACxD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;SACpC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;CACF;AApTD,0DAoTC;AAED,+BAA+B;AAC/B,SAAgB,0BAA0B,CAAC,MAAsC;IAC/E,OAAO,uBAAuB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC;AAEM,KAAK,UAAU,0BAA0B,CAAC,MAAsC;IACrF,MAAM,OAAO,GAAG,uBAAuB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAEM,KAAK,UAAU,kCAAkC;IACtD,OAAO,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CriticalPathDetector - Identify critical execution paths using MinCut analysis
|
|
3
|
+
*
|
|
4
|
+
* This component uses graph-theoretic minimum cut algorithms to identify:
|
|
5
|
+
* - Bottleneck code paths that many execution flows depend on
|
|
6
|
+
* - Critical edges in the dependency graph
|
|
7
|
+
* - High-priority coverage gaps based on structural importance
|
|
8
|
+
*
|
|
9
|
+
* @module coverage/CriticalPathDetector
|
|
10
|
+
* @version 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
import { CutEdge } from '../code-intelligence/analysis/mincut/types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Represents a node in the coverage dependency graph
|
|
15
|
+
*/
|
|
16
|
+
export interface CoverageNode {
|
|
17
|
+
/** Unique identifier (typically file path or function ID) */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Human-readable label */
|
|
20
|
+
label: string;
|
|
21
|
+
/** Type of code entity */
|
|
22
|
+
type: 'file' | 'function' | 'class' | 'method' | 'module';
|
|
23
|
+
/** Current coverage percentage (0-100) */
|
|
24
|
+
coverage: number;
|
|
25
|
+
/** Number of lines in this entity */
|
|
26
|
+
lines: number;
|
|
27
|
+
/** Cyclomatic complexity (if available) */
|
|
28
|
+
complexity?: number;
|
|
29
|
+
/** Whether this node is an entry point */
|
|
30
|
+
isEntryPoint?: boolean;
|
|
31
|
+
/** Whether this node is an exit point (e.g., API endpoint) */
|
|
32
|
+
isExitPoint?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Represents an edge in the coverage dependency graph
|
|
36
|
+
*/
|
|
37
|
+
export interface CoverageEdge {
|
|
38
|
+
/** Source node ID */
|
|
39
|
+
source: string;
|
|
40
|
+
/** Target node ID */
|
|
41
|
+
target: string;
|
|
42
|
+
/** Edge weight (call frequency, dependency strength, etc.) */
|
|
43
|
+
weight: number;
|
|
44
|
+
/** Type of dependency */
|
|
45
|
+
type: 'calls' | 'imports' | 'extends' | 'implements' | 'uses';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Input for critical path detection
|
|
49
|
+
*/
|
|
50
|
+
export interface CriticalPathInput {
|
|
51
|
+
/** Nodes in the coverage graph */
|
|
52
|
+
nodes: CoverageNode[];
|
|
53
|
+
/** Edges representing dependencies */
|
|
54
|
+
edges: CoverageEdge[];
|
|
55
|
+
/** Optional: Specific entry points to analyze from */
|
|
56
|
+
entryPoints?: string[];
|
|
57
|
+
/** Optional: Specific exit points to analyze to */
|
|
58
|
+
exitPoints?: string[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A critical path identified by the detector
|
|
62
|
+
*/
|
|
63
|
+
export interface CriticalPath {
|
|
64
|
+
/** Unique path identifier */
|
|
65
|
+
id: string;
|
|
66
|
+
/** Nodes in this critical path (ordered) */
|
|
67
|
+
nodes: string[];
|
|
68
|
+
/** Edges in this critical path */
|
|
69
|
+
edges: CutEdge[];
|
|
70
|
+
/** Criticality score (0-1, higher = more critical) */
|
|
71
|
+
criticality: number;
|
|
72
|
+
/** Total weight of dependencies flowing through this path */
|
|
73
|
+
flowWeight: number;
|
|
74
|
+
/** Average coverage of nodes in this path */
|
|
75
|
+
averageCoverage: number;
|
|
76
|
+
/** Reason why this path is critical */
|
|
77
|
+
reason: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A coverage gap with priority ranking
|
|
81
|
+
*/
|
|
82
|
+
export interface PrioritizedCoverageGap {
|
|
83
|
+
/** Node ID with the coverage gap */
|
|
84
|
+
nodeId: string;
|
|
85
|
+
/** Node label */
|
|
86
|
+
label: string;
|
|
87
|
+
/** Current coverage percentage */
|
|
88
|
+
currentCoverage: number;
|
|
89
|
+
/** Priority rank (1 = highest priority) */
|
|
90
|
+
priority: number;
|
|
91
|
+
/** Criticality score based on MinCut analysis */
|
|
92
|
+
criticality: number;
|
|
93
|
+
/** Impact score if this gap is filled */
|
|
94
|
+
impactScore: number;
|
|
95
|
+
/** Which critical paths this node belongs to */
|
|
96
|
+
criticalPaths: string[];
|
|
97
|
+
/** Suggested test focus areas */
|
|
98
|
+
testSuggestions: string[];
|
|
99
|
+
/** Estimated effort to achieve coverage */
|
|
100
|
+
estimatedEffort: 'low' | 'medium' | 'high';
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Result of critical path detection
|
|
104
|
+
*/
|
|
105
|
+
export interface CriticalPathResult {
|
|
106
|
+
/** Identified critical paths */
|
|
107
|
+
criticalPaths: CriticalPath[];
|
|
108
|
+
/** Prioritized coverage gaps */
|
|
109
|
+
prioritizedGaps: PrioritizedCoverageGap[];
|
|
110
|
+
/** Bottleneck nodes (appear in multiple critical paths) */
|
|
111
|
+
bottlenecks: BottleneckNode[];
|
|
112
|
+
/** Overall graph metrics */
|
|
113
|
+
metrics: GraphMetrics;
|
|
114
|
+
/** Computation time in milliseconds */
|
|
115
|
+
computationTimeMs: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A bottleneck node in the dependency graph
|
|
119
|
+
*/
|
|
120
|
+
export interface BottleneckNode {
|
|
121
|
+
/** Node ID */
|
|
122
|
+
nodeId: string;
|
|
123
|
+
/** Node label */
|
|
124
|
+
label: string;
|
|
125
|
+
/** Number of critical paths this node appears in */
|
|
126
|
+
pathCount: number;
|
|
127
|
+
/** Total flow weight through this node */
|
|
128
|
+
totalFlowWeight: number;
|
|
129
|
+
/** Current coverage */
|
|
130
|
+
coverage: number;
|
|
131
|
+
/** Risk level if this bottleneck is not covered */
|
|
132
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Metrics about the analyzed graph
|
|
136
|
+
*/
|
|
137
|
+
export interface GraphMetrics {
|
|
138
|
+
/** Total number of nodes */
|
|
139
|
+
totalNodes: number;
|
|
140
|
+
/** Total number of edges */
|
|
141
|
+
totalEdges: number;
|
|
142
|
+
/** Number of critical paths identified */
|
|
143
|
+
criticalPathCount: number;
|
|
144
|
+
/** Average coverage across all nodes */
|
|
145
|
+
averageCoverage: number;
|
|
146
|
+
/** Graph connectivity score (0-1) */
|
|
147
|
+
connectivityScore: number;
|
|
148
|
+
/** Minimum cut value of the graph */
|
|
149
|
+
minCutValue: number;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Configuration for the CriticalPathDetector
|
|
153
|
+
*/
|
|
154
|
+
export interface CriticalPathConfig {
|
|
155
|
+
/** Minimum criticality threshold for paths (0-1) */
|
|
156
|
+
criticalityThreshold?: number;
|
|
157
|
+
/** Maximum number of critical paths to return */
|
|
158
|
+
maxCriticalPaths?: number;
|
|
159
|
+
/** Coverage threshold below which a node is considered a gap */
|
|
160
|
+
coverageGapThreshold?: number;
|
|
161
|
+
/** Timeout for MinCut computation in milliseconds */
|
|
162
|
+
timeout?: number;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* CriticalPathDetector uses MinCut algorithms to identify critical execution paths
|
|
166
|
+
* and prioritize coverage gaps based on their structural importance in the codebase.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const detector = new CriticalPathDetector();
|
|
171
|
+
* const result = await detector.detectCriticalPaths({
|
|
172
|
+
* nodes: [
|
|
173
|
+
* { id: 'auth.ts', label: 'AuthService', type: 'file', coverage: 45, lines: 200 },
|
|
174
|
+
* { id: 'user.ts', label: 'UserService', type: 'file', coverage: 80, lines: 150 },
|
|
175
|
+
* ],
|
|
176
|
+
* edges: [
|
|
177
|
+
* { source: 'user.ts', target: 'auth.ts', weight: 5, type: 'calls' },
|
|
178
|
+
* ],
|
|
179
|
+
* });
|
|
180
|
+
* console.log('Critical paths:', result.criticalPaths);
|
|
181
|
+
* console.log('Priority gaps:', result.prioritizedGaps);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export declare class CriticalPathDetector {
|
|
185
|
+
private config;
|
|
186
|
+
private minCutAnalyzer;
|
|
187
|
+
constructor(config?: CriticalPathConfig);
|
|
188
|
+
/**
|
|
189
|
+
* Detect critical paths and prioritize coverage gaps
|
|
190
|
+
*
|
|
191
|
+
* @param input - Coverage graph with nodes and edges
|
|
192
|
+
* @returns Promise resolving to CriticalPathResult
|
|
193
|
+
*/
|
|
194
|
+
detectCriticalPaths(input: CriticalPathInput): Promise<CriticalPathResult>;
|
|
195
|
+
/**
|
|
196
|
+
* Get prioritized coverage gaps only (simpler API)
|
|
197
|
+
*/
|
|
198
|
+
getPrioritizedGaps(input: CriticalPathInput): Promise<PrioritizedCoverageGap[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Validate input data
|
|
201
|
+
*/
|
|
202
|
+
private validateInput;
|
|
203
|
+
/**
|
|
204
|
+
* Convert coverage graph to MinCut input format
|
|
205
|
+
*/
|
|
206
|
+
private toMinCutGraph;
|
|
207
|
+
/**
|
|
208
|
+
* Build critical paths from MinCut results
|
|
209
|
+
*/
|
|
210
|
+
private buildCriticalPaths;
|
|
211
|
+
/**
|
|
212
|
+
* Generate human-readable reason for why a path is critical
|
|
213
|
+
*/
|
|
214
|
+
private generateCriticalPathReason;
|
|
215
|
+
/**
|
|
216
|
+
* Identify bottleneck nodes that appear in multiple critical paths
|
|
217
|
+
*/
|
|
218
|
+
private identifyBottlenecks;
|
|
219
|
+
/**
|
|
220
|
+
* Calculate risk level for a bottleneck node
|
|
221
|
+
*/
|
|
222
|
+
private calculateRiskLevel;
|
|
223
|
+
/**
|
|
224
|
+
* Prioritize coverage gaps based on critical path analysis
|
|
225
|
+
*/
|
|
226
|
+
private prioritizeCoverageGaps;
|
|
227
|
+
/**
|
|
228
|
+
* Generate test suggestions for a coverage gap
|
|
229
|
+
*/
|
|
230
|
+
private generateTestSuggestions;
|
|
231
|
+
/**
|
|
232
|
+
* Estimate effort to achieve coverage
|
|
233
|
+
*/
|
|
234
|
+
private estimateEffort;
|
|
235
|
+
/**
|
|
236
|
+
* Calculate overall graph metrics
|
|
237
|
+
*/
|
|
238
|
+
private calculateMetrics;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=CriticalPathDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CriticalPathDetector.d.ts","sourceRoot":"","sources":["../../src/coverage/CriticalPathDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CriticalPathDetector - Identify critical execution paths using MinCut analysis
|
|
4
|
+
*
|
|
5
|
+
* This component uses graph-theoretic minimum cut algorithms to identify:
|
|
6
|
+
* - Bottleneck code paths that many execution flows depend on
|
|
7
|
+
* - Critical edges in the dependency graph
|
|
8
|
+
* - High-priority coverage gaps based on structural importance
|
|
9
|
+
*
|
|
10
|
+
* @module coverage/CriticalPathDetector
|
|
11
|
+
* @version 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.CriticalPathDetector = void 0;
|
|
15
|
+
const MinCutAnalyzer_js_1 = require("../code-intelligence/analysis/mincut/MinCutAnalyzer.js");
|
|
16
|
+
const Logger_js_1 = require("../utils/Logger.js");
|
|
17
|
+
const logger = Logger_js_1.Logger.getInstance();
|
|
18
|
+
const DEFAULT_CONFIG = {
|
|
19
|
+
criticalityThreshold: 0.3,
|
|
20
|
+
maxCriticalPaths: 10,
|
|
21
|
+
coverageGapThreshold: 80,
|
|
22
|
+
timeout: 10000,
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* CriticalPathDetector uses MinCut algorithms to identify critical execution paths
|
|
26
|
+
* and prioritize coverage gaps based on their structural importance in the codebase.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const detector = new CriticalPathDetector();
|
|
31
|
+
* const result = await detector.detectCriticalPaths({
|
|
32
|
+
* nodes: [
|
|
33
|
+
* { id: 'auth.ts', label: 'AuthService', type: 'file', coverage: 45, lines: 200 },
|
|
34
|
+
* { id: 'user.ts', label: 'UserService', type: 'file', coverage: 80, lines: 150 },
|
|
35
|
+
* ],
|
|
36
|
+
* edges: [
|
|
37
|
+
* { source: 'user.ts', target: 'auth.ts', weight: 5, type: 'calls' },
|
|
38
|
+
* ],
|
|
39
|
+
* });
|
|
40
|
+
* console.log('Critical paths:', result.criticalPaths);
|
|
41
|
+
* console.log('Priority gaps:', result.prioritizedGaps);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
class CriticalPathDetector {
|
|
45
|
+
constructor(config = {}) {
|
|
46
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
47
|
+
this.minCutAnalyzer = new MinCutAnalyzer_js_1.MinCutAnalyzer({
|
|
48
|
+
timeout: this.config.timeout,
|
|
49
|
+
maxNodes: 5000,
|
|
50
|
+
});
|
|
51
|
+
logger.debug('CriticalPathDetector initialized', { config: this.config });
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Detect critical paths and prioritize coverage gaps
|
|
55
|
+
*
|
|
56
|
+
* @param input - Coverage graph with nodes and edges
|
|
57
|
+
* @returns Promise resolving to CriticalPathResult
|
|
58
|
+
*/
|
|
59
|
+
async detectCriticalPaths(input) {
|
|
60
|
+
const startTime = Date.now();
|
|
61
|
+
try {
|
|
62
|
+
// Validate input
|
|
63
|
+
this.validateInput(input);
|
|
64
|
+
// Convert to MinCut graph format
|
|
65
|
+
const minCutGraph = this.toMinCutGraph(input);
|
|
66
|
+
// Find minimum cuts (identifies critical edges)
|
|
67
|
+
const minCutResults = await this.minCutAnalyzer.findAllMinCuts(minCutGraph, this.config.maxCriticalPaths);
|
|
68
|
+
// Build critical paths from cut results
|
|
69
|
+
const criticalPaths = this.buildCriticalPaths(input, minCutResults);
|
|
70
|
+
// Identify bottleneck nodes
|
|
71
|
+
const bottlenecks = this.identifyBottlenecks(input, criticalPaths);
|
|
72
|
+
// Prioritize coverage gaps
|
|
73
|
+
const prioritizedGaps = this.prioritizeCoverageGaps(input, criticalPaths, bottlenecks);
|
|
74
|
+
// Calculate graph metrics
|
|
75
|
+
const metrics = this.calculateMetrics(input, minCutResults, criticalPaths);
|
|
76
|
+
const computationTimeMs = Date.now() - startTime;
|
|
77
|
+
logger.info('Critical path detection completed', {
|
|
78
|
+
criticalPathCount: criticalPaths.length,
|
|
79
|
+
bottleneckCount: bottlenecks.length,
|
|
80
|
+
gapCount: prioritizedGaps.length,
|
|
81
|
+
computationTimeMs,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
criticalPaths,
|
|
85
|
+
prioritizedGaps,
|
|
86
|
+
bottlenecks,
|
|
87
|
+
metrics,
|
|
88
|
+
computationTimeMs,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.error('Critical path detection failed', { error });
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get prioritized coverage gaps only (simpler API)
|
|
98
|
+
*/
|
|
99
|
+
async getPrioritizedGaps(input) {
|
|
100
|
+
const result = await this.detectCriticalPaths(input);
|
|
101
|
+
return result.prioritizedGaps;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate input data
|
|
105
|
+
*/
|
|
106
|
+
validateInput(input) {
|
|
107
|
+
if (!input.nodes || input.nodes.length === 0) {
|
|
108
|
+
throw new Error('Input must have at least one node');
|
|
109
|
+
}
|
|
110
|
+
if (!input.edges) {
|
|
111
|
+
throw new Error('Input must have edges array (can be empty)');
|
|
112
|
+
}
|
|
113
|
+
const nodeIds = new Set(input.nodes.map(n => n.id));
|
|
114
|
+
for (const edge of input.edges) {
|
|
115
|
+
if (!nodeIds.has(edge.source)) {
|
|
116
|
+
throw new Error(`Edge source '${edge.source}' not found in nodes`);
|
|
117
|
+
}
|
|
118
|
+
if (!nodeIds.has(edge.target)) {
|
|
119
|
+
throw new Error(`Edge target '${edge.target}' not found in nodes`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Convert coverage graph to MinCut input format
|
|
125
|
+
*/
|
|
126
|
+
toMinCutGraph(input) {
|
|
127
|
+
return {
|
|
128
|
+
nodes: input.nodes.map(n => ({
|
|
129
|
+
id: n.id,
|
|
130
|
+
label: n.label,
|
|
131
|
+
properties: {
|
|
132
|
+
type: n.type,
|
|
133
|
+
coverage: n.coverage,
|
|
134
|
+
lines: n.lines,
|
|
135
|
+
complexity: n.complexity,
|
|
136
|
+
isEntryPoint: n.isEntryPoint,
|
|
137
|
+
isExitPoint: n.isExitPoint,
|
|
138
|
+
},
|
|
139
|
+
})),
|
|
140
|
+
edges: input.edges.map(e => ({
|
|
141
|
+
source: e.source,
|
|
142
|
+
target: e.target,
|
|
143
|
+
weight: e.weight,
|
|
144
|
+
edgeType: e.type,
|
|
145
|
+
})),
|
|
146
|
+
directed: false, // MinCut works on undirected graphs
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Build critical paths from MinCut results
|
|
151
|
+
*/
|
|
152
|
+
buildCriticalPaths(input, minCutResults) {
|
|
153
|
+
const nodeMap = new Map(input.nodes.map(n => [n.id, n]));
|
|
154
|
+
const criticalPaths = [];
|
|
155
|
+
for (let i = 0; i < minCutResults.length; i++) {
|
|
156
|
+
const result = minCutResults[i];
|
|
157
|
+
if (result.cutValue === 0 || result.cutEdges.length === 0) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Calculate average coverage for nodes in this cut
|
|
161
|
+
const cutNodeIds = new Set([
|
|
162
|
+
...result.cutEdges.map(e => e.source),
|
|
163
|
+
...result.cutEdges.map(e => e.target),
|
|
164
|
+
]);
|
|
165
|
+
const cutNodes = Array.from(cutNodeIds)
|
|
166
|
+
.map(id => nodeMap.get(id))
|
|
167
|
+
.filter((n) => n !== undefined);
|
|
168
|
+
const averageCoverage = cutNodes.length > 0
|
|
169
|
+
? cutNodes.reduce((sum, n) => sum + n.coverage, 0) / cutNodes.length
|
|
170
|
+
: 0;
|
|
171
|
+
// Calculate criticality based on cut value and position
|
|
172
|
+
const maxWeight = Math.max(...input.edges.map(e => e.weight), 1);
|
|
173
|
+
const normalizedCutValue = result.cutValue / maxWeight;
|
|
174
|
+
const criticality = Math.min(1, normalizedCutValue * (1 / (i + 1)));
|
|
175
|
+
if (criticality < this.config.criticalityThreshold) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
criticalPaths.push({
|
|
179
|
+
id: `critical-path-${i + 1}`,
|
|
180
|
+
nodes: Array.from(cutNodeIds),
|
|
181
|
+
edges: result.cutEdges,
|
|
182
|
+
criticality,
|
|
183
|
+
flowWeight: result.cutValue,
|
|
184
|
+
averageCoverage,
|
|
185
|
+
reason: this.generateCriticalPathReason(result, cutNodes, criticality),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return criticalPaths.slice(0, this.config.maxCriticalPaths);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Generate human-readable reason for why a path is critical
|
|
192
|
+
*/
|
|
193
|
+
generateCriticalPathReason(result, nodes, criticality) {
|
|
194
|
+
const lowCoverageNodes = nodes.filter(n => n.coverage < this.config.coverageGapThreshold);
|
|
195
|
+
const avgCoverage = nodes.length > 0
|
|
196
|
+
? nodes.reduce((sum, n) => sum + n.coverage, 0) / nodes.length
|
|
197
|
+
: 0;
|
|
198
|
+
if (lowCoverageNodes.length > 0) {
|
|
199
|
+
return `Contains ${lowCoverageNodes.length} low-coverage node(s) with ${result.cutEdges.length} critical edge(s). Average coverage: ${avgCoverage.toFixed(1)}%`;
|
|
200
|
+
}
|
|
201
|
+
if (criticality > 0.7) {
|
|
202
|
+
return `High-traffic path with ${result.cutEdges.length} edge(s) carrying ${result.cutValue.toFixed(2)} total weight`;
|
|
203
|
+
}
|
|
204
|
+
return `Structural bottleneck connecting ${result.partition1.length} and ${result.partition2.length} components`;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Identify bottleneck nodes that appear in multiple critical paths
|
|
208
|
+
*/
|
|
209
|
+
identifyBottlenecks(input, criticalPaths) {
|
|
210
|
+
const nodeMap = new Map(input.nodes.map(n => [n.id, n]));
|
|
211
|
+
const nodePathCount = new Map();
|
|
212
|
+
const nodeFlowWeight = new Map();
|
|
213
|
+
// Count appearances in critical paths
|
|
214
|
+
for (const path of criticalPaths) {
|
|
215
|
+
for (const nodeId of path.nodes) {
|
|
216
|
+
nodePathCount.set(nodeId, (nodePathCount.get(nodeId) || 0) + 1);
|
|
217
|
+
nodeFlowWeight.set(nodeId, (nodeFlowWeight.get(nodeId) || 0) + path.flowWeight);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Build bottleneck list
|
|
221
|
+
const bottlenecks = [];
|
|
222
|
+
for (const [nodeId, pathCount] of nodePathCount.entries()) {
|
|
223
|
+
if (pathCount >= 2 || (pathCount >= 1 && criticalPaths.length <= 2)) {
|
|
224
|
+
const node = nodeMap.get(nodeId);
|
|
225
|
+
if (!node)
|
|
226
|
+
continue;
|
|
227
|
+
const flowWeight = nodeFlowWeight.get(nodeId) || 0;
|
|
228
|
+
const riskLevel = this.calculateRiskLevel(node, pathCount, flowWeight);
|
|
229
|
+
bottlenecks.push({
|
|
230
|
+
nodeId,
|
|
231
|
+
label: node.label,
|
|
232
|
+
pathCount,
|
|
233
|
+
totalFlowWeight: flowWeight,
|
|
234
|
+
coverage: node.coverage,
|
|
235
|
+
riskLevel,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Sort by risk (critical first) then by path count
|
|
240
|
+
return bottlenecks.sort((a, b) => {
|
|
241
|
+
const riskOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
242
|
+
const riskDiff = riskOrder[a.riskLevel] - riskOrder[b.riskLevel];
|
|
243
|
+
if (riskDiff !== 0)
|
|
244
|
+
return riskDiff;
|
|
245
|
+
return b.pathCount - a.pathCount;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Calculate risk level for a bottleneck node
|
|
250
|
+
*/
|
|
251
|
+
calculateRiskLevel(node, pathCount, flowWeight) {
|
|
252
|
+
const coverageWeight = (100 - node.coverage) / 100;
|
|
253
|
+
const pathWeight = Math.min(pathCount / 5, 1);
|
|
254
|
+
const complexityWeight = node.complexity ? Math.min(node.complexity / 20, 1) : 0.5;
|
|
255
|
+
const riskScore = (coverageWeight * 0.4) + (pathWeight * 0.35) + (complexityWeight * 0.25);
|
|
256
|
+
if (riskScore >= 0.75)
|
|
257
|
+
return 'critical';
|
|
258
|
+
if (riskScore >= 0.5)
|
|
259
|
+
return 'high';
|
|
260
|
+
if (riskScore >= 0.25)
|
|
261
|
+
return 'medium';
|
|
262
|
+
return 'low';
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Prioritize coverage gaps based on critical path analysis
|
|
266
|
+
*/
|
|
267
|
+
prioritizeCoverageGaps(input, criticalPaths, bottlenecks) {
|
|
268
|
+
const gaps = [];
|
|
269
|
+
const bottleneckSet = new Set(bottlenecks.map(b => b.nodeId));
|
|
270
|
+
// Create node-to-paths mapping
|
|
271
|
+
const nodeToPathsMap = new Map();
|
|
272
|
+
for (const path of criticalPaths) {
|
|
273
|
+
for (const nodeId of path.nodes) {
|
|
274
|
+
const paths = nodeToPathsMap.get(nodeId) || [];
|
|
275
|
+
paths.push(path.id);
|
|
276
|
+
nodeToPathsMap.set(nodeId, paths);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Find all nodes below coverage threshold
|
|
280
|
+
for (const node of input.nodes) {
|
|
281
|
+
if (node.coverage >= this.config.coverageGapThreshold) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const criticalPathIds = nodeToPathsMap.get(node.id) || [];
|
|
285
|
+
const isBottleneck = bottleneckSet.has(node.id);
|
|
286
|
+
// Calculate criticality score
|
|
287
|
+
const pathCriticality = criticalPathIds.length > 0
|
|
288
|
+
? criticalPaths
|
|
289
|
+
.filter(p => criticalPathIds.includes(p.id))
|
|
290
|
+
.reduce((sum, p) => sum + p.criticality, 0) / criticalPathIds.length
|
|
291
|
+
: 0;
|
|
292
|
+
const criticality = isBottleneck ? Math.min(1, pathCriticality + 0.3) : pathCriticality;
|
|
293
|
+
// Calculate impact score
|
|
294
|
+
const coverageGap = this.config.coverageGapThreshold - node.coverage;
|
|
295
|
+
const impactScore = (coverageGap / 100) * (1 + criticality) * (node.lines / 100);
|
|
296
|
+
// Generate test suggestions
|
|
297
|
+
const testSuggestions = this.generateTestSuggestions(node, criticalPathIds.length);
|
|
298
|
+
// Estimate effort
|
|
299
|
+
const estimatedEffort = this.estimateEffort(node, coverageGap);
|
|
300
|
+
gaps.push({
|
|
301
|
+
nodeId: node.id,
|
|
302
|
+
label: node.label,
|
|
303
|
+
currentCoverage: node.coverage,
|
|
304
|
+
priority: 0, // Will be set after sorting
|
|
305
|
+
criticality,
|
|
306
|
+
impactScore,
|
|
307
|
+
criticalPaths: criticalPathIds,
|
|
308
|
+
testSuggestions,
|
|
309
|
+
estimatedEffort,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
// Sort by criticality (descending), then by impact score (descending)
|
|
313
|
+
gaps.sort((a, b) => {
|
|
314
|
+
const critDiff = b.criticality - a.criticality;
|
|
315
|
+
if (Math.abs(critDiff) > 0.1)
|
|
316
|
+
return critDiff;
|
|
317
|
+
return b.impactScore - a.impactScore;
|
|
318
|
+
});
|
|
319
|
+
// Assign priority ranks
|
|
320
|
+
gaps.forEach((gap, index) => {
|
|
321
|
+
gap.priority = index + 1;
|
|
322
|
+
});
|
|
323
|
+
return gaps;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Generate test suggestions for a coverage gap
|
|
327
|
+
*/
|
|
328
|
+
generateTestSuggestions(node, criticalPathCount) {
|
|
329
|
+
const suggestions = [];
|
|
330
|
+
if (node.type === 'function' || node.type === 'method') {
|
|
331
|
+
suggestions.push(`Add unit tests for ${node.label}`);
|
|
332
|
+
if (node.complexity && node.complexity > 10) {
|
|
333
|
+
suggestions.push(`Test edge cases for complex logic (complexity: ${node.complexity})`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (node.type === 'class') {
|
|
337
|
+
suggestions.push(`Add integration tests for ${node.label}`);
|
|
338
|
+
suggestions.push(`Test class instantiation and public methods`);
|
|
339
|
+
}
|
|
340
|
+
if (node.isEntryPoint) {
|
|
341
|
+
suggestions.push(`Add API/endpoint tests for ${node.label}`);
|
|
342
|
+
}
|
|
343
|
+
if (criticalPathCount > 0) {
|
|
344
|
+
suggestions.push(`Priority: On ${criticalPathCount} critical path(s) - test thoroughly`);
|
|
345
|
+
}
|
|
346
|
+
if (node.coverage < 20) {
|
|
347
|
+
suggestions.push(`Low coverage (${node.coverage}%) - start with basic happy path tests`);
|
|
348
|
+
}
|
|
349
|
+
return suggestions;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Estimate effort to achieve coverage
|
|
353
|
+
*/
|
|
354
|
+
estimateEffort(node, coverageGap) {
|
|
355
|
+
const complexity = node.complexity || 5;
|
|
356
|
+
const lines = node.lines;
|
|
357
|
+
// Factor in complexity, lines, and coverage gap
|
|
358
|
+
const effortScore = (complexity / 10) * (lines / 200) * (coverageGap / 50);
|
|
359
|
+
if (effortScore < 0.5)
|
|
360
|
+
return 'low';
|
|
361
|
+
if (effortScore < 1.5)
|
|
362
|
+
return 'medium';
|
|
363
|
+
return 'high';
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Calculate overall graph metrics
|
|
367
|
+
*/
|
|
368
|
+
calculateMetrics(input, minCutResults, criticalPaths) {
|
|
369
|
+
const totalCoverage = input.nodes.reduce((sum, n) => sum + n.coverage, 0);
|
|
370
|
+
const averageCoverage = input.nodes.length > 0 ? totalCoverage / input.nodes.length : 0;
|
|
371
|
+
// Calculate connectivity score based on edge density
|
|
372
|
+
const maxPossibleEdges = (input.nodes.length * (input.nodes.length - 1)) / 2;
|
|
373
|
+
const connectivityScore = maxPossibleEdges > 0
|
|
374
|
+
? Math.min(1, input.edges.length / maxPossibleEdges * 2) // *2 because sparse graphs are typical
|
|
375
|
+
: 0;
|
|
376
|
+
const minCutValue = minCutResults.length > 0 ? minCutResults[0].cutValue : 0;
|
|
377
|
+
return {
|
|
378
|
+
totalNodes: input.nodes.length,
|
|
379
|
+
totalEdges: input.edges.length,
|
|
380
|
+
criticalPathCount: criticalPaths.length,
|
|
381
|
+
averageCoverage,
|
|
382
|
+
connectivityScore,
|
|
383
|
+
minCutValue,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
exports.CriticalPathDetector = CriticalPathDetector;
|
|
388
|
+
//# sourceMappingURL=CriticalPathDetector.js.map
|