@defai.digital/ax-cli 3.4.6 → 3.5.4

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.
Files changed (223) hide show
  1. package/LICENSE +2 -6
  2. package/README.md +109 -2
  3. package/dist/analyzers/ast/index.d.ts +9 -0
  4. package/dist/analyzers/ast/index.js +10 -0
  5. package/dist/analyzers/ast/index.js.map +1 -0
  6. package/dist/analyzers/ast/node-helpers.d.ts +81 -0
  7. package/dist/analyzers/ast/node-helpers.js +128 -0
  8. package/dist/analyzers/ast/node-helpers.js.map +1 -0
  9. package/dist/analyzers/ast/parser.d.ts +59 -0
  10. package/dist/analyzers/ast/parser.js +293 -0
  11. package/dist/analyzers/ast/parser.js.map +1 -0
  12. package/dist/analyzers/ast/traverser.d.ts +67 -0
  13. package/dist/analyzers/ast/traverser.js +156 -0
  14. package/dist/analyzers/ast/traverser.js.map +1 -0
  15. package/dist/analyzers/ast/types.d.ts +107 -0
  16. package/dist/analyzers/ast/types.js +7 -0
  17. package/dist/analyzers/ast/types.js.map +1 -0
  18. package/dist/analyzers/best-practices/index.d.ts +10 -0
  19. package/dist/analyzers/best-practices/index.js +11 -0
  20. package/dist/analyzers/best-practices/index.js.map +1 -0
  21. package/dist/analyzers/code-smells/base-smell-detector.d.ts +30 -0
  22. package/dist/analyzers/code-smells/base-smell-detector.js +44 -0
  23. package/dist/analyzers/code-smells/base-smell-detector.js.map +1 -0
  24. package/dist/analyzers/code-smells/code-smell-analyzer.d.ts +30 -0
  25. package/dist/analyzers/code-smells/code-smell-analyzer.js +167 -0
  26. package/dist/analyzers/code-smells/code-smell-analyzer.js.map +1 -0
  27. package/dist/analyzers/code-smells/detectors/data-clumps-detector.d.ts +11 -0
  28. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js +66 -0
  29. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js.map +1 -0
  30. package/dist/analyzers/code-smells/detectors/dead-code-detector.d.ts +11 -0
  31. package/dist/analyzers/code-smells/detectors/dead-code-detector.js +53 -0
  32. package/dist/analyzers/code-smells/detectors/dead-code-detector.js.map +1 -0
  33. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.d.ts +11 -0
  34. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js +51 -0
  35. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js.map +1 -0
  36. package/dist/analyzers/code-smells/detectors/feature-envy-detector.d.ts +11 -0
  37. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js +64 -0
  38. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js.map +1 -0
  39. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.d.ts +11 -0
  40. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js +56 -0
  41. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js.map +1 -0
  42. package/dist/analyzers/code-smells/detectors/large-class-detector.d.ts +13 -0
  43. package/dist/analyzers/code-smells/detectors/large-class-detector.js +58 -0
  44. package/dist/analyzers/code-smells/detectors/large-class-detector.js.map +1 -0
  45. package/dist/analyzers/code-smells/detectors/long-method-detector.d.ts +12 -0
  46. package/dist/analyzers/code-smells/detectors/long-method-detector.js +52 -0
  47. package/dist/analyzers/code-smells/detectors/long-method-detector.js.map +1 -0
  48. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.d.ts +12 -0
  49. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js +50 -0
  50. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js.map +1 -0
  51. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.d.ts +12 -0
  52. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js +54 -0
  53. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js.map +1 -0
  54. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.d.ts +13 -0
  55. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js +71 -0
  56. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js.map +1 -0
  57. package/dist/analyzers/code-smells/index.d.ts +16 -0
  58. package/dist/analyzers/code-smells/index.js +19 -0
  59. package/dist/analyzers/code-smells/index.js.map +1 -0
  60. package/dist/analyzers/code-smells/types.d.ts +82 -0
  61. package/dist/analyzers/code-smells/types.js +30 -0
  62. package/dist/analyzers/code-smells/types.js.map +1 -0
  63. package/dist/analyzers/dependency/circular-detector.d.ts +17 -0
  64. package/dist/analyzers/dependency/circular-detector.js +71 -0
  65. package/dist/analyzers/dependency/circular-detector.js.map +1 -0
  66. package/dist/analyzers/dependency/coupling-calculator.d.ts +24 -0
  67. package/dist/analyzers/dependency/coupling-calculator.js +86 -0
  68. package/dist/analyzers/dependency/coupling-calculator.js.map +1 -0
  69. package/dist/analyzers/dependency/dependency-analyzer.d.ts +40 -0
  70. package/dist/analyzers/dependency/dependency-analyzer.js +214 -0
  71. package/dist/analyzers/dependency/dependency-analyzer.js.map +1 -0
  72. package/dist/analyzers/dependency/dependency-graph.d.ts +57 -0
  73. package/dist/analyzers/dependency/dependency-graph.js +186 -0
  74. package/dist/analyzers/dependency/dependency-graph.js.map +1 -0
  75. package/dist/analyzers/dependency/index.d.ts +8 -0
  76. package/dist/analyzers/dependency/index.js +8 -0
  77. package/dist/analyzers/dependency/index.js.map +1 -0
  78. package/dist/analyzers/dependency/types.d.ts +105 -0
  79. package/dist/analyzers/dependency/types.js +5 -0
  80. package/dist/analyzers/dependency/types.js.map +1 -0
  81. package/dist/analyzers/git/churn-calculator.d.ts +34 -0
  82. package/dist/analyzers/git/churn-calculator.js +214 -0
  83. package/dist/analyzers/git/churn-calculator.js.map +1 -0
  84. package/dist/analyzers/git/git-analyzer.d.ts +19 -0
  85. package/dist/analyzers/git/git-analyzer.js +71 -0
  86. package/dist/analyzers/git/git-analyzer.js.map +1 -0
  87. package/dist/analyzers/git/hotspot-detector.d.ts +34 -0
  88. package/dist/analyzers/git/hotspot-detector.js +170 -0
  89. package/dist/analyzers/git/hotspot-detector.js.map +1 -0
  90. package/dist/analyzers/git/index.d.ts +7 -0
  91. package/dist/analyzers/git/index.js +7 -0
  92. package/dist/analyzers/git/index.js.map +1 -0
  93. package/dist/analyzers/git/types.d.ts +88 -0
  94. package/dist/analyzers/git/types.js +5 -0
  95. package/dist/analyzers/git/types.js.map +1 -0
  96. package/dist/analyzers/metrics/halstead-calculator.d.ts +30 -0
  97. package/dist/analyzers/metrics/halstead-calculator.js +150 -0
  98. package/dist/analyzers/metrics/halstead-calculator.js.map +1 -0
  99. package/dist/analyzers/metrics/index.d.ts +9 -0
  100. package/dist/analyzers/metrics/index.js +9 -0
  101. package/dist/analyzers/metrics/index.js.map +1 -0
  102. package/dist/analyzers/metrics/maintainability-calculator.d.ts +17 -0
  103. package/dist/analyzers/metrics/maintainability-calculator.js +46 -0
  104. package/dist/analyzers/metrics/maintainability-calculator.js.map +1 -0
  105. package/dist/analyzers/metrics/metrics-analyzer.d.ts +32 -0
  106. package/dist/analyzers/metrics/metrics-analyzer.js +140 -0
  107. package/dist/analyzers/metrics/metrics-analyzer.js.map +1 -0
  108. package/dist/analyzers/metrics/types.d.ts +67 -0
  109. package/dist/analyzers/metrics/types.js +5 -0
  110. package/dist/analyzers/metrics/types.js.map +1 -0
  111. package/dist/analyzers/security/base-detector.d.ts +58 -0
  112. package/dist/analyzers/security/base-detector.js +104 -0
  113. package/dist/analyzers/security/base-detector.js.map +1 -0
  114. package/dist/analyzers/security/detectors/command-injection-detector.d.ts +12 -0
  115. package/dist/analyzers/security/detectors/command-injection-detector.js +84 -0
  116. package/dist/analyzers/security/detectors/command-injection-detector.js.map +1 -0
  117. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.d.ts +16 -0
  118. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js +140 -0
  119. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js.map +1 -0
  120. package/dist/analyzers/security/detectors/insecure-deserialization-detector.d.ts +12 -0
  121. package/dist/analyzers/security/detectors/insecure-deserialization-detector.js +109 -0
  122. package/dist/analyzers/security/detectors/insecure-deserialization-detector.js.map +1 -0
  123. package/dist/analyzers/security/detectors/insecure-random-detector.d.ts +12 -0
  124. package/dist/analyzers/security/detectors/insecure-random-detector.js +61 -0
  125. package/dist/analyzers/security/detectors/insecure-random-detector.js.map +1 -0
  126. package/dist/analyzers/security/detectors/path-traversal-detector.d.ts +12 -0
  127. package/dist/analyzers/security/detectors/path-traversal-detector.js +82 -0
  128. package/dist/analyzers/security/detectors/path-traversal-detector.js.map +1 -0
  129. package/dist/analyzers/security/detectors/sql-injection-detector.d.ts +12 -0
  130. package/dist/analyzers/security/detectors/sql-injection-detector.js +88 -0
  131. package/dist/analyzers/security/detectors/sql-injection-detector.js.map +1 -0
  132. package/dist/analyzers/security/detectors/weak-crypto-detector.d.ts +12 -0
  133. package/dist/analyzers/security/detectors/weak-crypto-detector.js +104 -0
  134. package/dist/analyzers/security/detectors/weak-crypto-detector.js.map +1 -0
  135. package/dist/analyzers/security/detectors/xss-detector.d.ts +12 -0
  136. package/dist/analyzers/security/detectors/xss-detector.js +90 -0
  137. package/dist/analyzers/security/detectors/xss-detector.js.map +1 -0
  138. package/dist/analyzers/security/index.d.ts +16 -0
  139. package/dist/analyzers/security/index.js +18 -0
  140. package/dist/analyzers/security/index.js.map +1 -0
  141. package/dist/analyzers/security/security-analyzer.d.ts +38 -0
  142. package/dist/analyzers/security/security-analyzer.js +215 -0
  143. package/dist/analyzers/security/security-analyzer.js.map +1 -0
  144. package/dist/analyzers/security/types.d.ts +95 -0
  145. package/dist/analyzers/security/types.js +7 -0
  146. package/dist/analyzers/security/types.js.map +1 -0
  147. package/dist/hooks/use-enhanced-input.d.ts +0 -1
  148. package/dist/hooks/use-enhanced-input.js.map +1 -1
  149. package/dist/index.js +0 -0
  150. package/dist/mcp/validation.js +12 -6
  151. package/dist/mcp/validation.js.map +1 -1
  152. package/dist/tools/analysis-tools.d.ts +73 -0
  153. package/dist/tools/analysis-tools.js +422 -0
  154. package/dist/tools/analysis-tools.js.map +1 -0
  155. package/dist/tools/bash.js +2 -1
  156. package/dist/tools/bash.js.map +1 -1
  157. package/dist/ui/components/toast-notification.js +0 -1
  158. package/dist/ui/components/toast-notification.js.map +1 -1
  159. package/dist/ui/components/welcome-panel.js +1 -1
  160. package/dist/ui/components/welcome-panel.js.map +1 -1
  161. package/dist/ui/hooks/use-input-history.d.ts +9 -0
  162. package/dist/ui/hooks/use-input-history.js +117 -0
  163. package/dist/ui/hooks/use-input-history.js.map +1 -0
  164. package/dist/utils/parallel-analyzer.js +30 -17
  165. package/dist/utils/parallel-analyzer.js.map +1 -1
  166. package/eslint.config.js +3 -0
  167. package/package.json +5 -5
  168. package/vitest.config.ts +1 -0
  169. package/.ax-cli/checkpoints/2025-11-20/checkpoint-11e9e0ba-c39d-4fd2-aa77-bc818811c921.json +0 -69
  170. package/.ax-cli/checkpoints/2025-11-20/checkpoint-2b260b98-b418-4c7c-9694-e2b94967e662.json +0 -24
  171. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7e03601e-e8ab-4cd7-9841-a74b66adf78f.json +0 -69
  172. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7f9c6562-771f-4fd0-adcf-9e7e9ac34ae8.json +0 -44
  173. package/.ax-cli/checkpoints/2025-11-20/checkpoint-e1ebe666-4c3a-4367-ba5c-27fe512a9c70.json +0 -24
  174. package/.ax-cli/checkpoints/2025-11-21/checkpoint-15743e7d-430c-4d76-b6fc-955d7a5c250c.json +0 -44
  175. package/.ax-cli/checkpoints/2025-11-21/checkpoint-25cf7679-0b3f-4988-83d7-704548fbba91.json +0 -69
  176. package/.ax-cli/checkpoints/2025-11-21/checkpoint-54aedbac-6db0-464e-8ebb-dbb3979e6dca.json +0 -24
  177. package/.ax-cli/checkpoints/2025-11-21/checkpoint-7658aed8-fe5d-4222-903f-1a7c63717ea7.json +0 -24
  178. package/.ax-cli/checkpoints/2025-11-21/checkpoint-c9c13497-40dc-4294-a327-6a5fc854eaa1.json +0 -69
  179. package/automatosx.config.json +0 -333
  180. package/config/messages.yaml +0 -75
  181. package/config/models.yaml +0 -66
  182. package/config/prompts.yaml +0 -156
  183. package/config/settings.yaml +0 -86
  184. package/dist/commands/weather.d.ts +0 -8
  185. package/dist/commands/weather.js +0 -160
  186. package/dist/commands/weather.js.map +0 -1
  187. package/dist/grok/client.d.ts +0 -144
  188. package/dist/grok/client.js +0 -237
  189. package/dist/grok/client.js.map +0 -1
  190. package/dist/grok/tools.d.ts +0 -8
  191. package/dist/grok/tools.js +0 -318
  192. package/dist/grok/tools.js.map +0 -1
  193. package/dist/grok/types.d.ts +0 -291
  194. package/dist/grok/types.js +0 -127
  195. package/dist/grok/types.js.map +0 -1
  196. package/dist/tools/morph-editor.d.ts +0 -36
  197. package/dist/tools/morph-editor.js +0 -308
  198. package/dist/tools/morph-editor.js.map +0 -1
  199. package/dist/ui/components/session-recovery.d.ts +0 -12
  200. package/dist/ui/components/session-recovery.js +0 -93
  201. package/dist/ui/components/session-recovery.js.map +0 -1
  202. package/dist/utils/model-config.d.ts +0 -28
  203. package/dist/utils/model-config.js +0 -43
  204. package/dist/utils/model-config.js.map +0 -1
  205. package/dist/utils/tool-helpers.d.ts +0 -25
  206. package/dist/utils/tool-helpers.js +0 -79
  207. package/dist/utils/tool-helpers.js.map +0 -1
  208. package/packages/schemas/dist/index.d.ts +0 -14
  209. package/packages/schemas/dist/index.d.ts.map +0 -1
  210. package/packages/schemas/dist/index.js +0 -19
  211. package/packages/schemas/dist/index.js.map +0 -1
  212. package/packages/schemas/dist/public/core/brand-types.d.ts +0 -308
  213. package/packages/schemas/dist/public/core/brand-types.d.ts.map +0 -1
  214. package/packages/schemas/dist/public/core/brand-types.js +0 -243
  215. package/packages/schemas/dist/public/core/brand-types.js.map +0 -1
  216. package/packages/schemas/dist/public/core/enums.d.ts +0 -227
  217. package/packages/schemas/dist/public/core/enums.d.ts.map +0 -1
  218. package/packages/schemas/dist/public/core/enums.js +0 -222
  219. package/packages/schemas/dist/public/core/enums.js.map +0 -1
  220. package/packages/schemas/dist/public/core/id-types.d.ts +0 -286
  221. package/packages/schemas/dist/public/core/id-types.d.ts.map +0 -1
  222. package/packages/schemas/dist/public/core/id-types.js +0 -136
  223. package/packages/schemas/dist/public/core/id-types.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Circular Dependency Detector
3
+ *
4
+ * Uses Tarjan's Strongly Connected Components algorithm
5
+ */
6
+ export class CircularDependencyDetector {
7
+ /**
8
+ * Detect all circular dependencies
9
+ */
10
+ detectCycles(graph) {
11
+ const sccs = graph.getStronglyConnectedComponents();
12
+ const cycles = [];
13
+ for (const scc of sccs) {
14
+ if (scc.length > 1) {
15
+ cycles.push(this.createCircularDependency(scc, graph));
16
+ }
17
+ }
18
+ // Sort by severity and impact
19
+ return cycles.sort((a, b) => {
20
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
21
+ const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];
22
+ return severityDiff !== 0 ? severityDiff : b.impact - a.impact;
23
+ });
24
+ }
25
+ /**
26
+ * Create circular dependency object from SCC
27
+ */
28
+ createCircularDependency(cycle, graph) {
29
+ const length = cycle.length;
30
+ // Determine severity based on cycle length
31
+ let severity;
32
+ if (length === 2) {
33
+ severity = 'medium'; // Simple A->B->A cycle
34
+ }
35
+ else if (length <= 4) {
36
+ severity = 'high'; // Complex but manageable
37
+ }
38
+ else {
39
+ severity = 'critical'; // Very complex, hard to refactor
40
+ }
41
+ // Calculate impact based on:
42
+ // 1. Number of files in cycle
43
+ // 2. Total LOC in cycle
44
+ // 3. Coupling of files in cycle
45
+ let totalLOC = 0;
46
+ let totalCoupling = 0;
47
+ for (const file of cycle) {
48
+ const node = graph.getNode(file);
49
+ if (node) {
50
+ totalLOC += node.loc;
51
+ totalCoupling += node.imports.length + node.exports.length;
52
+ }
53
+ }
54
+ // Impact formula: weighted combination of factors
55
+ const impact = Math.min(100, Math.round((length / 10) * 30 + // Cycle length contribution (0-30)
56
+ (totalLOC / 500) * 40 + // LOC contribution (0-40)
57
+ (totalCoupling / 20) * 30 // Coupling contribution (0-30)
58
+ ));
59
+ // Generate description
60
+ const fileNames = cycle.map(f => f.split('/').pop() || f);
61
+ const description = `Circular dependency detected: ${fileNames.join(' → ')} → ${fileNames[0]}`;
62
+ return Object.freeze({
63
+ cycle: Object.freeze(cycle),
64
+ length,
65
+ severity,
66
+ impact,
67
+ description,
68
+ });
69
+ }
70
+ }
71
+ //# sourceMappingURL=circular-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circular-detector.js","sourceRoot":"","sources":["../../../src/analyzers/dependency/circular-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Coupling Metrics Calculator
3
+ *
4
+ * Calculates:
5
+ * - Afferent Coupling (Ca): How many files depend on this
6
+ * - Efferent Coupling (Ce): How many files this depends on
7
+ * - Instability (I): Ce / (Ce + Ca)
8
+ * - Abstractness (A): Abstract elements / Total elements
9
+ * - Distance from Main Sequence (D): |A + I - 1|
10
+ */
11
+ import type { DependencyGraph } from './dependency-graph.js';
12
+ import type { CouplingMetrics } from './types.js';
13
+ import type { FileASTInfo } from '../ast/types.js';
14
+ export declare class CouplingCalculator {
15
+ /**
16
+ * Calculate coupling metrics for all files
17
+ */
18
+ calculateMetrics(graph: DependencyGraph, astMap: Map<string, FileASTInfo>): CouplingMetrics[];
19
+ /**
20
+ * Calculate abstractness of a file
21
+ * A = abstract classes + interfaces / total classes + functions
22
+ */
23
+ private calculateAbstractness;
24
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Coupling Metrics Calculator
3
+ *
4
+ * Calculates:
5
+ * - Afferent Coupling (Ca): How many files depend on this
6
+ * - Efferent Coupling (Ce): How many files this depends on
7
+ * - Instability (I): Ce / (Ce + Ca)
8
+ * - Abstractness (A): Abstract elements / Total elements
9
+ * - Distance from Main Sequence (D): |A + I - 1|
10
+ */
11
+ export class CouplingCalculator {
12
+ /**
13
+ * Calculate coupling metrics for all files
14
+ */
15
+ calculateMetrics(graph, astMap) {
16
+ const metrics = [];
17
+ for (const node of graph.getNodes()) {
18
+ const file = node.filePath;
19
+ const ca = graph.getAfferentDependencies(file).length;
20
+ const ce = graph.getEfferentDependencies(file).length;
21
+ // Instability: I = Ce / (Ce + Ca)
22
+ // I = 0: Maximally stable (many dependents, few dependencies)
23
+ // I = 1: Maximally unstable (few dependents, many dependencies)
24
+ const instability = (ce + ca) === 0 ? 0 : ce / (ce + ca);
25
+ // Abstractness: A = abstract elements / total elements
26
+ const ast = astMap.get(file);
27
+ const abstractness = ast ? this.calculateAbstractness(ast) : 0;
28
+ // Distance from Main Sequence: D = |A + I - 1|
29
+ // D = 0: On the main sequence (ideal)
30
+ // D > 0.5: In "zone of pain" (concrete + unstable) or "zone of uselessness" (abstract + stable)
31
+ const distance = Math.abs(abstractness + instability - 1);
32
+ // Determine zone
33
+ let zone;
34
+ if (abstractness > 0.7 && instability < 0.3) {
35
+ zone = 'useless'; // Abstract but no dependents
36
+ }
37
+ else if (abstractness < 0.3 && instability > 0.7) {
38
+ zone = 'painful'; // Concrete and many dependencies
39
+ }
40
+ else {
41
+ zone = 'balanced';
42
+ }
43
+ metrics.push(Object.freeze({
44
+ file,
45
+ afferentCoupling: ca,
46
+ efferentCoupling: ce,
47
+ instability,
48
+ abstractness,
49
+ distanceFromMainSequence: distance,
50
+ zone,
51
+ }));
52
+ }
53
+ return metrics;
54
+ }
55
+ /**
56
+ * Calculate abstractness of a file
57
+ * A = abstract classes + interfaces / total classes + functions
58
+ */
59
+ calculateAbstractness(ast) {
60
+ let abstractCount = 0;
61
+ let totalCount = 0;
62
+ // Count classes
63
+ for (const cls of ast.classes) {
64
+ totalCount++;
65
+ // Heuristic: Consider class abstract if:
66
+ // 1. Name starts with 'Abstract' or 'Base' or 'I'
67
+ // 2. Implements interfaces (likely an abstraction)
68
+ const isAbstract = cls.name.startsWith('Abstract') ||
69
+ cls.name.startsWith('Base') ||
70
+ cls.name.startsWith('I') ||
71
+ cls.implementsInterfaces.length > 0;
72
+ if (isAbstract) {
73
+ abstractCount++;
74
+ }
75
+ }
76
+ // Count type exports as abstract
77
+ // (interfaces, type aliases)
78
+ const typeExports = ast.exports.filter(exp => exp.type === 'type');
79
+ abstractCount += typeExports.length;
80
+ totalCount += typeExports.length;
81
+ // Functions are always concrete
82
+ totalCount += ast.functions.length;
83
+ return totalCount === 0 ? 0 : abstractCount / totalCount;
84
+ }
85
+ }
86
+ //# sourceMappingURL=coupling-calculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coupling-calculator.js","sourceRoot":"","sources":["../../../src/analyzers/dependency/coupling-calculator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Dependency Analyzer
3
+ *
4
+ * Main orchestrator for dependency analysis
5
+ */
6
+ import type { DependencyAnalysisResult, DependencyAnalysisOptions } from './types.js';
7
+ export declare class DependencyAnalyzer {
8
+ private astParser;
9
+ private circularDetector;
10
+ private couplingCalculator;
11
+ constructor();
12
+ /**
13
+ * Analyze dependencies in a directory
14
+ */
15
+ analyzeDependencies(directory: string, pattern?: string, options?: DependencyAnalysisOptions): Promise<DependencyAnalysisResult>;
16
+ /**
17
+ * Create import edges from AST imports
18
+ */
19
+ private createImportEdges;
20
+ /**
21
+ * Create export edges from AST exports
22
+ */
23
+ private createExportEdges;
24
+ /**
25
+ * Resolve import specifier to absolute file path
26
+ */
27
+ private resolveImportPath;
28
+ /**
29
+ * Find orphaned files (no dependencies)
30
+ */
31
+ private findOrphanedFiles;
32
+ /**
33
+ * Find hub files (high coupling)
34
+ */
35
+ private findHubFiles;
36
+ /**
37
+ * Calculate summary statistics
38
+ */
39
+ private calculateSummary;
40
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Dependency Analyzer
3
+ *
4
+ * Main orchestrator for dependency analysis
5
+ */
6
+ import { DependencyGraph } from './dependency-graph.js';
7
+ import { CircularDependencyDetector } from './circular-detector.js';
8
+ import { CouplingCalculator } from './coupling-calculator.js';
9
+ import { ASTParser } from '../ast/parser.js';
10
+ import { existsSync, promises as fs } from 'fs';
11
+ import { glob } from 'glob';
12
+ import path from 'path';
13
+ export class DependencyAnalyzer {
14
+ astParser;
15
+ circularDetector;
16
+ couplingCalculator;
17
+ constructor() {
18
+ this.astParser = new ASTParser();
19
+ this.circularDetector = new CircularDependencyDetector();
20
+ this.couplingCalculator = new CouplingCalculator();
21
+ }
22
+ /**
23
+ * Analyze dependencies in a directory
24
+ */
25
+ async analyzeDependencies(directory, pattern = '**/*.{ts,tsx,js,jsx}', options = {}) {
26
+ const timestamp = new Date();
27
+ // Find all files
28
+ const ignorePatterns = [
29
+ '**/node_modules/**',
30
+ '**/dist/**',
31
+ '**/build/**',
32
+ '**/.git/**',
33
+ ...(options.ignorePatterns || []),
34
+ ];
35
+ const files = await glob(pattern, {
36
+ cwd: directory,
37
+ absolute: true,
38
+ nodir: true,
39
+ ignore: ignorePatterns,
40
+ });
41
+ // Build dependency graph
42
+ const graph = new DependencyGraph();
43
+ const astMap = new Map();
44
+ // Parse all files
45
+ for (const file of files) {
46
+ try {
47
+ const ast = this.astParser.parseFile(file);
48
+ astMap.set(file, ast);
49
+ // Get file stats
50
+ const stats = await fs.stat(file);
51
+ // Create dependency node
52
+ const node = {
53
+ filePath: file,
54
+ imports: this.createImportEdges(file, ast.imports, directory),
55
+ exports: this.createExportEdges(file, ast.exports),
56
+ size: stats.size,
57
+ loc: ast.totalLines,
58
+ };
59
+ graph.addNode(node);
60
+ // Add edges for internal imports
61
+ for (const imp of node.imports) {
62
+ if (!options.includeNodeModules && imp.to.includes('node_modules')) {
63
+ continue;
64
+ }
65
+ graph.addEdge(imp.from, imp.to);
66
+ }
67
+ }
68
+ catch (error) {
69
+ // Skip files that can't be parsed
70
+ console.error(`Error parsing ${file}:`, error);
71
+ }
72
+ }
73
+ // Detect circular dependencies
74
+ const circularDependencies = this.circularDetector.detectCycles(graph);
75
+ // Calculate coupling metrics
76
+ const couplingMetrics = this.couplingCalculator.calculateMetrics(graph, astMap);
77
+ // Find orphaned files (no imports/exports or isolated)
78
+ const orphanedFiles = this.findOrphanedFiles(graph);
79
+ // Find hub files (high coupling)
80
+ const hubFiles = this.findHubFiles(couplingMetrics);
81
+ // Calculate summary
82
+ const summary = this.calculateSummary(graph, circularDependencies, couplingMetrics);
83
+ return Object.freeze({
84
+ graph,
85
+ circularDependencies: Object.freeze(circularDependencies),
86
+ couplingMetrics: Object.freeze(couplingMetrics),
87
+ orphanedFiles: Object.freeze(orphanedFiles),
88
+ hubFiles: Object.freeze(hubFiles),
89
+ summary: Object.freeze(summary),
90
+ timestamp,
91
+ });
92
+ }
93
+ /**
94
+ * Create import edges from AST imports
95
+ */
96
+ createImportEdges(file, imports, baseDir) {
97
+ return imports.map(imp => {
98
+ const resolvedPath = this.resolveImportPath(file, imp.moduleSpecifier, baseDir);
99
+ return Object.freeze({
100
+ from: file,
101
+ to: resolvedPath,
102
+ importedSymbols: Object.freeze([
103
+ ...imp.namedImports,
104
+ ...(imp.defaultImport ? [imp.defaultImport] : []),
105
+ ...(imp.namespaceImport ? [imp.namespaceImport] : []),
106
+ ]),
107
+ isDynamic: false,
108
+ isTypeOnly: imp.isTypeOnly || false,
109
+ });
110
+ });
111
+ }
112
+ /**
113
+ * Create export edges from AST exports
114
+ */
115
+ createExportEdges(file, exports) {
116
+ return exports.map(exp => Object.freeze({
117
+ from: file,
118
+ symbols: Object.freeze([exp.name]),
119
+ isDefault: exp.isDefault,
120
+ isReExport: false, // Simplified for now
121
+ }));
122
+ }
123
+ /**
124
+ * Resolve import specifier to absolute file path
125
+ */
126
+ resolveImportPath(fromFile, specifier, baseDir) {
127
+ if (specifier.startsWith('.')) {
128
+ // Relative import
129
+ const fromDir = path.dirname(fromFile);
130
+ let resolved = path.resolve(fromDir, specifier);
131
+ // Remove .js extension if present (TypeScript uses .js in imports)
132
+ if (resolved.endsWith('.js')) {
133
+ resolved = resolved.slice(0, -3);
134
+ }
135
+ // Try extensions
136
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];
137
+ for (const ext of extensions) {
138
+ const testPath = resolved.endsWith('.ts') || resolved.endsWith('.tsx')
139
+ ? resolved
140
+ : resolved + ext;
141
+ try {
142
+ if (existsSync(testPath)) {
143
+ return testPath;
144
+ }
145
+ }
146
+ catch {
147
+ // Continue to next extension
148
+ }
149
+ }
150
+ // Return resolved path even if file doesn't exist
151
+ return resolved + '.ts'; // Default to .ts
152
+ }
153
+ // External module
154
+ return path.join(baseDir, 'node_modules', specifier);
155
+ }
156
+ /**
157
+ * Find orphaned files (no dependencies)
158
+ */
159
+ findOrphanedFiles(graph) {
160
+ const orphaned = [];
161
+ for (const node of graph.getNodes()) {
162
+ const afferent = graph.getAfferentDependencies(node.filePath);
163
+ const efferent = graph.getEfferentDependencies(node.filePath);
164
+ if (afferent.length === 0 && efferent.length === 0) {
165
+ orphaned.push(node.filePath);
166
+ }
167
+ }
168
+ return orphaned;
169
+ }
170
+ /**
171
+ * Find hub files (high coupling)
172
+ */
173
+ findHubFiles(metrics) {
174
+ if (metrics.length === 0)
175
+ return [];
176
+ // Hub = high afferent OR efferent coupling (top 10%)
177
+ const sorted = [...metrics].sort((a, b) => (b.afferentCoupling + b.efferentCoupling) -
178
+ (a.afferentCoupling + a.efferentCoupling));
179
+ const threshold = Math.max(1, Math.ceil(sorted.length * 0.1));
180
+ return sorted.slice(0, threshold).map(m => m.file);
181
+ }
182
+ /**
183
+ * Calculate summary statistics
184
+ */
185
+ calculateSummary(graph, circularDeps, metrics) {
186
+ const totalFiles = graph.getNodes().length;
187
+ const totalDependencies = graph.getTotalEdges();
188
+ const avgCa = totalFiles > 0
189
+ ? metrics.reduce((sum, m) => sum + m.afferentCoupling, 0) / totalFiles
190
+ : 0;
191
+ const avgCe = totalFiles > 0
192
+ ? metrics.reduce((sum, m) => sum + m.efferentCoupling, 0) / totalFiles
193
+ : 0;
194
+ const avgInstability = totalFiles > 0
195
+ ? metrics.reduce((sum, m) => sum + m.instability, 0) / totalFiles
196
+ : 0;
197
+ const maxCycleLength = circularDeps.reduce((max, dep) => Math.max(max, dep.length), 0);
198
+ // Health score (0-100)
199
+ const circularPenalty = Math.min(50, circularDeps.length * 5);
200
+ const instabilityPenalty = avgInstability * 20;
201
+ const healthScore = Math.max(0, 100 - circularPenalty - instabilityPenalty);
202
+ return Object.freeze({
203
+ totalFiles,
204
+ totalDependencies,
205
+ averageAfferentCoupling: avgCa,
206
+ averageEfferentCoupling: avgCe,
207
+ averageInstability: avgInstability,
208
+ circularDependencyCount: circularDeps.length,
209
+ maxCycleLength,
210
+ healthScore: Math.round(healthScore),
211
+ });
212
+ }
213
+ }
214
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../../src/analyzers/dependency/dependency-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Dependency Graph Implementation
3
+ *
4
+ * Adjacency list-based directed graph for file dependencies
5
+ */
6
+ import type { DependencyNode, DependencyGraph as IDependencyGraph } from './types.js';
7
+ export declare class DependencyGraph implements IDependencyGraph {
8
+ private nodes;
9
+ private adjacencyList;
10
+ private reverseAdjacencyList;
11
+ constructor();
12
+ /**
13
+ * Add node to graph
14
+ */
15
+ addNode(node: DependencyNode): void;
16
+ /**
17
+ * Add directed edge from -> to
18
+ */
19
+ addEdge(from: string, to: string): void;
20
+ /**
21
+ * Get node by file path
22
+ */
23
+ getNode(file: string): DependencyNode | undefined;
24
+ /**
25
+ * Get all nodes
26
+ */
27
+ getNodes(): DependencyNode[];
28
+ /**
29
+ * Get afferent dependencies (files that depend on this file)
30
+ */
31
+ getAfferentDependencies(file: string): string[];
32
+ /**
33
+ * Get efferent dependencies (files this file depends on)
34
+ */
35
+ getEfferentDependencies(file: string): string[];
36
+ /**
37
+ * Get total number of edges
38
+ */
39
+ getTotalEdges(): number;
40
+ /**
41
+ * Check if path exists from -> to using BFS
42
+ */
43
+ hasPath(from: string, to: string): boolean;
44
+ /**
45
+ * Topological sort using DFS
46
+ * Returns sorted list and whether cycle was detected
47
+ */
48
+ topologicalSort(): {
49
+ sorted: string[];
50
+ hasCycle: boolean;
51
+ };
52
+ /**
53
+ * Get strongly connected components using Tarjan's algorithm
54
+ * (Used for circular dependency detection)
55
+ */
56
+ getStronglyConnectedComponents(): string[][];
57
+ }