@aiready/context-analyzer 0.9.4 → 0.9.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.
Files changed (75) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/.turbo/turbo-test.log +21 -9
  3. package/README.md +8 -0
  4. package/dist/__tests__/analyzer.test.d.ts +2 -0
  5. package/dist/__tests__/analyzer.test.d.ts.map +1 -0
  6. package/dist/__tests__/analyzer.test.js +157 -0
  7. package/dist/__tests__/analyzer.test.js.map +1 -0
  8. package/dist/__tests__/auto-detection.test.d.ts +2 -0
  9. package/dist/__tests__/auto-detection.test.d.ts.map +1 -0
  10. package/dist/__tests__/auto-detection.test.js +132 -0
  11. package/dist/__tests__/auto-detection.test.js.map +1 -0
  12. package/dist/__tests__/enhanced-cohesion.test.d.ts +2 -0
  13. package/dist/__tests__/enhanced-cohesion.test.d.ts.map +1 -0
  14. package/dist/__tests__/enhanced-cohesion.test.js +109 -0
  15. package/dist/__tests__/enhanced-cohesion.test.js.map +1 -0
  16. package/dist/__tests__/fragmentation-advanced.test.d.ts +2 -0
  17. package/dist/__tests__/fragmentation-advanced.test.d.ts.map +1 -0
  18. package/dist/__tests__/fragmentation-advanced.test.js +50 -0
  19. package/dist/__tests__/fragmentation-advanced.test.js.map +1 -0
  20. package/dist/__tests__/fragmentation-coupling.test.d.ts +2 -0
  21. package/dist/__tests__/fragmentation-coupling.test.d.ts.map +1 -0
  22. package/dist/__tests__/fragmentation-coupling.test.js +52 -0
  23. package/dist/__tests__/fragmentation-coupling.test.js.map +1 -0
  24. package/dist/__tests__/fragmentation-log.test.d.ts +2 -0
  25. package/dist/__tests__/fragmentation-log.test.d.ts.map +1 -0
  26. package/dist/__tests__/fragmentation-log.test.js +33 -0
  27. package/dist/__tests__/fragmentation-log.test.js.map +1 -0
  28. package/dist/__tests__/scoring.test.d.ts +2 -0
  29. package/dist/__tests__/scoring.test.d.ts.map +1 -0
  30. package/dist/__tests__/scoring.test.js +118 -0
  31. package/dist/__tests__/scoring.test.js.map +1 -0
  32. package/dist/__tests__/structural-cohesion.test.d.ts +2 -0
  33. package/dist/__tests__/structural-cohesion.test.d.ts.map +1 -0
  34. package/dist/__tests__/structural-cohesion.test.js +29 -0
  35. package/dist/__tests__/structural-cohesion.test.js.map +1 -0
  36. package/dist/analyzer.d.ts +100 -0
  37. package/dist/analyzer.d.ts.map +1 -0
  38. package/dist/analyzer.js +701 -0
  39. package/dist/analyzer.js.map +1 -0
  40. package/dist/analyzers/python-context.d.ts +38 -0
  41. package/dist/analyzers/python-context.d.ts.map +1 -0
  42. package/dist/analyzers/python-context.js +232 -0
  43. package/dist/analyzers/python-context.js.map +1 -0
  44. package/dist/chunk-BD4NWUVG.mjs +1242 -0
  45. package/dist/cli.d.ts.map +1 -0
  46. package/dist/cli.js +139 -13
  47. package/dist/cli.js.map +1 -0
  48. package/dist/cli.mjs +1 -1
  49. package/dist/index.d.mts +3 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +139 -13
  53. package/dist/index.js.map +1 -0
  54. package/dist/index.mjs +1 -1
  55. package/dist/scoring.d.ts +13 -0
  56. package/dist/scoring.d.ts.map +1 -0
  57. package/dist/scoring.js +133 -0
  58. package/dist/scoring.js.map +1 -0
  59. package/dist/semantic-analysis.d.ts +44 -0
  60. package/dist/semantic-analysis.d.ts.map +1 -0
  61. package/dist/semantic-analysis.js +241 -0
  62. package/dist/semantic-analysis.js.map +1 -0
  63. package/dist/types.d.ts +117 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +2 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +2 -2
  68. package/src/__tests__/fragmentation-advanced.test.ts +60 -0
  69. package/src/__tests__/fragmentation-coupling.test.ts +62 -0
  70. package/src/__tests__/fragmentation-log.test.ts +38 -0
  71. package/src/__tests__/structural-cohesion.test.ts +32 -0
  72. package/src/analyzer.ts +193 -18
  73. package/src/index.ts +34 -2
  74. package/src/types.ts +3 -0
  75. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Calculate AI Readiness Score for context efficiency (0-100)
3
+ *
4
+ * Based on:
5
+ * - Average context budget (tokens needed to understand files)
6
+ * - Import depth (dependency chain length)
7
+ * - Fragmentation score (code organization)
8
+ * - Critical/major issues
9
+ */
10
+ export function calculateContextScore(summary) {
11
+ const { avgContextBudget, maxContextBudget, avgImportDepth, maxImportDepth, avgFragmentation, criticalIssues, majorIssues, } = summary;
12
+ // Context budget scoring (40% weight in final score)
13
+ // Ideal: <5000 tokens avg = 100
14
+ // Acceptable: 5000-10000 = 90-70
15
+ // High: 10000-20000 = 70-40
16
+ // Critical: >20000 = <40
17
+ const budgetScore = avgContextBudget < 5000
18
+ ? 100
19
+ : Math.max(0, 100 - (avgContextBudget - 5000) / 150);
20
+ // Import depth scoring (30% weight)
21
+ // Ideal: <5 avg = 100
22
+ // Acceptable: 5-8 = 80-60
23
+ // Deep: >8 = <60
24
+ const depthScore = avgImportDepth < 5
25
+ ? 100
26
+ : Math.max(0, 100 - (avgImportDepth - 5) * 10);
27
+ // Fragmentation scoring (30% weight)
28
+ // Well-organized: <0.3 = 100
29
+ // Moderate: 0.3-0.5 = 80-60
30
+ // Fragmented: >0.5 = <60
31
+ const fragmentationScore = avgFragmentation < 0.3
32
+ ? 100
33
+ : Math.max(0, 100 - (avgFragmentation - 0.3) * 200);
34
+ // Issue penalties
35
+ const criticalPenalty = criticalIssues * 10;
36
+ const majorPenalty = majorIssues * 3;
37
+ // Max budget penalty (if any single file is extreme)
38
+ const maxBudgetPenalty = maxContextBudget > 15000
39
+ ? Math.min(20, (maxContextBudget - 15000) / 500)
40
+ : 0;
41
+ // Weighted average of subscores
42
+ const rawScore = (budgetScore * 0.4) + (depthScore * 0.3) + (fragmentationScore * 0.3);
43
+ const finalScore = rawScore - criticalPenalty - majorPenalty - maxBudgetPenalty;
44
+ const score = Math.max(0, Math.min(100, Math.round(finalScore)));
45
+ // Build factors array
46
+ const factors = [
47
+ {
48
+ name: 'Context Budget',
49
+ impact: Math.round((budgetScore * 0.4) - 40),
50
+ description: `Avg ${Math.round(avgContextBudget)} tokens per file ${avgContextBudget < 5000 ? '(excellent)' : avgContextBudget < 10000 ? '(acceptable)' : '(high)'}`,
51
+ },
52
+ {
53
+ name: 'Import Depth',
54
+ impact: Math.round((depthScore * 0.3) - 30),
55
+ description: `Avg ${avgImportDepth.toFixed(1)} levels ${avgImportDepth < 5 ? '(excellent)' : avgImportDepth < 8 ? '(acceptable)' : '(deep)'}`,
56
+ },
57
+ {
58
+ name: 'Fragmentation',
59
+ impact: Math.round((fragmentationScore * 0.3) - 30),
60
+ description: `${(avgFragmentation * 100).toFixed(0)}% fragmentation ${avgFragmentation < 0.3 ? '(well-organized)' : avgFragmentation < 0.5 ? '(moderate)' : '(high)'}`,
61
+ },
62
+ ];
63
+ if (criticalIssues > 0) {
64
+ factors.push({
65
+ name: 'Critical Issues',
66
+ impact: -criticalPenalty,
67
+ description: `${criticalIssues} critical context issue${criticalIssues > 1 ? 's' : ''}`,
68
+ });
69
+ }
70
+ if (majorIssues > 0) {
71
+ factors.push({
72
+ name: 'Major Issues',
73
+ impact: -majorPenalty,
74
+ description: `${majorIssues} major context issue${majorIssues > 1 ? 's' : ''}`,
75
+ });
76
+ }
77
+ if (maxBudgetPenalty > 0) {
78
+ factors.push({
79
+ name: 'Extreme File Detected',
80
+ impact: -Math.round(maxBudgetPenalty),
81
+ description: `One file requires ${Math.round(maxContextBudget)} tokens (very high)`,
82
+ });
83
+ }
84
+ // Generate recommendations
85
+ const recommendations = [];
86
+ if (avgContextBudget > 10000) {
87
+ const estimatedImpact = Math.min(15, Math.round((avgContextBudget - 10000) / 1000));
88
+ recommendations.push({
89
+ action: 'Reduce file dependencies to lower context requirements',
90
+ estimatedImpact,
91
+ priority: 'high',
92
+ });
93
+ }
94
+ if (avgImportDepth > 8) {
95
+ const estimatedImpact = Math.min(10, Math.round((avgImportDepth - 8) * 2));
96
+ recommendations.push({
97
+ action: 'Flatten import chains to reduce depth',
98
+ estimatedImpact,
99
+ priority: avgImportDepth > 10 ? 'high' : 'medium',
100
+ });
101
+ }
102
+ if (avgFragmentation > 0.5) {
103
+ const estimatedImpact = Math.min(12, Math.round((avgFragmentation - 0.5) * 40));
104
+ recommendations.push({
105
+ action: 'Consolidate related code into cohesive modules',
106
+ estimatedImpact,
107
+ priority: 'medium',
108
+ });
109
+ }
110
+ if (maxContextBudget > 20000) {
111
+ recommendations.push({
112
+ action: `Split large file (${Math.round(maxContextBudget)} tokens) into smaller modules`,
113
+ estimatedImpact: 8,
114
+ priority: 'high',
115
+ });
116
+ }
117
+ return {
118
+ toolName: 'context-analyzer',
119
+ score,
120
+ rawMetrics: {
121
+ avgContextBudget: Math.round(avgContextBudget),
122
+ maxContextBudget: Math.round(maxContextBudget),
123
+ avgImportDepth: Math.round(avgImportDepth * 10) / 10,
124
+ maxImportDepth,
125
+ avgFragmentation: Math.round(avgFragmentation * 100) / 100,
126
+ criticalIssues,
127
+ majorIssues,
128
+ },
129
+ factors,
130
+ recommendations,
131
+ };
132
+ }
133
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { DependencyGraph, CoUsageData, DomainAssignment, DomainSignals } from './types';
2
+ /**
3
+ * Build co-usage matrix: track which files are imported together
4
+ *
5
+ * Files frequently imported together likely belong to the same semantic domain
6
+ */
7
+ export declare function buildCoUsageMatrix(graph: DependencyGraph): Map<string, Map<string, number>>;
8
+ /**
9
+ * Extract type dependencies from AST exports
10
+ *
11
+ * Files that share types are semantically related
12
+ */
13
+ export declare function buildTypeGraph(graph: DependencyGraph): Map<string, Set<string>>;
14
+ /**
15
+ * Find semantic clusters using co-usage patterns
16
+ *
17
+ * Files with high co-usage counts belong in the same cluster
18
+ */
19
+ export declare function findSemanticClusters(coUsageMatrix: Map<string, Map<string, number>>, minCoUsage?: number): Map<string, string[]>;
20
+ /**
21
+ * Calculate confidence score for domain assignment based on multiple signals
22
+ */
23
+ export declare function calculateDomainConfidence(signals: DomainSignals): number;
24
+ /**
25
+ * Infer domain from semantic analysis (co-usage + types)
26
+ *
27
+ * This replaces the folder-based heuristic with actual code relationships
28
+ */
29
+ export declare function inferDomainFromSemantics(file: string, exportName: string, graph: DependencyGraph, coUsageMatrix: Map<string, Map<string, number>>, typeGraph: Map<string, Set<string>>, exportTypeRefs?: string[]): DomainAssignment[];
30
+ /**
31
+ * Get co-usage data for a specific file
32
+ */
33
+ export declare function getCoUsageData(file: string, coUsageMatrix: Map<string, Map<string, number>>): CoUsageData;
34
+ /**
35
+ * Find files that should be consolidated based on semantic similarity
36
+ *
37
+ * High co-usage + shared types = strong consolidation candidate
38
+ */
39
+ export declare function findConsolidationCandidates(graph: DependencyGraph, coUsageMatrix: Map<string, Map<string, number>>, typeGraph: Map<string, Set<string>>, minCoUsage?: number, minSharedTypes?: number): Array<{
40
+ files: string[];
41
+ reason: string;
42
+ strength: number;
43
+ }>;
44
+ //# sourceMappingURL=semantic-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-analysis.d.ts","sourceRoot":"","sources":["../src/semantic-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAkB,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgC3F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAiB/E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC/C,UAAU,GAAE,MAAU,GACrB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA0BvB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAiBxE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC/C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACnC,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,gBAAgB,EAAE,CA2EpB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC9C,WAAW,CAYb;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC/C,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACnC,UAAU,GAAE,MAAU,EACtB,cAAc,GAAE,MAAU,GACzB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA2C9D"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Build co-usage matrix: track which files are imported together
3
+ *
4
+ * Files frequently imported together likely belong to the same semantic domain
5
+ */
6
+ export function buildCoUsageMatrix(graph) {
7
+ const coUsageMatrix = new Map();
8
+ // For each file, track which other files are imported alongside it
9
+ for (const [sourceFile, node] of graph.nodes) {
10
+ const imports = node.imports;
11
+ // For each pair of imports in this file, increment their co-usage count
12
+ for (let i = 0; i < imports.length; i++) {
13
+ const fileA = imports[i];
14
+ if (!coUsageMatrix.has(fileA)) {
15
+ coUsageMatrix.set(fileA, new Map());
16
+ }
17
+ for (let j = i + 1; j < imports.length; j++) {
18
+ const fileB = imports[j];
19
+ // Increment bidirectional co-usage count
20
+ const fileAUsage = coUsageMatrix.get(fileA);
21
+ fileAUsage.set(fileB, (fileAUsage.get(fileB) || 0) + 1);
22
+ if (!coUsageMatrix.has(fileB)) {
23
+ coUsageMatrix.set(fileB, new Map());
24
+ }
25
+ const fileBUsage = coUsageMatrix.get(fileB);
26
+ fileBUsage.set(fileA, (fileBUsage.get(fileA) || 0) + 1);
27
+ }
28
+ }
29
+ }
30
+ return coUsageMatrix;
31
+ }
32
+ /**
33
+ * Extract type dependencies from AST exports
34
+ *
35
+ * Files that share types are semantically related
36
+ */
37
+ export function buildTypeGraph(graph) {
38
+ const typeGraph = new Map();
39
+ for (const [file, node] of graph.nodes) {
40
+ for (const exp of node.exports) {
41
+ if (exp.typeReferences) {
42
+ for (const typeRef of exp.typeReferences) {
43
+ if (!typeGraph.has(typeRef)) {
44
+ typeGraph.set(typeRef, new Set());
45
+ }
46
+ typeGraph.get(typeRef).add(file);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return typeGraph;
52
+ }
53
+ /**
54
+ * Find semantic clusters using co-usage patterns
55
+ *
56
+ * Files with high co-usage counts belong in the same cluster
57
+ */
58
+ export function findSemanticClusters(coUsageMatrix, minCoUsage = 3) {
59
+ const clusters = new Map();
60
+ const visited = new Set();
61
+ // Simple clustering: group files with high co-usage
62
+ for (const [file, coUsages] of coUsageMatrix) {
63
+ if (visited.has(file))
64
+ continue;
65
+ const cluster = [file];
66
+ visited.add(file);
67
+ // Find strongly related files (co-imported >= minCoUsage times)
68
+ for (const [relatedFile, count] of coUsages) {
69
+ if (count >= minCoUsage && !visited.has(relatedFile)) {
70
+ cluster.push(relatedFile);
71
+ visited.add(relatedFile);
72
+ }
73
+ }
74
+ if (cluster.length > 1) {
75
+ // Use first file as cluster ID
76
+ clusters.set(file, cluster);
77
+ }
78
+ }
79
+ return clusters;
80
+ }
81
+ /**
82
+ * Calculate confidence score for domain assignment based on multiple signals
83
+ */
84
+ export function calculateDomainConfidence(signals) {
85
+ const weights = {
86
+ coUsage: 0.35, // Strongest signal: actual usage patterns
87
+ typeReference: 0.30, // Strong signal: shared types
88
+ exportName: 0.15, // Medium signal: identifier semantics
89
+ importPath: 0.10, // Weaker signal: path structure
90
+ folderStructure: 0.10 // Weakest signal: organization convention
91
+ };
92
+ let confidence = 0;
93
+ if (signals.coUsage)
94
+ confidence += weights.coUsage;
95
+ if (signals.typeReference)
96
+ confidence += weights.typeReference;
97
+ if (signals.exportName)
98
+ confidence += weights.exportName;
99
+ if (signals.importPath)
100
+ confidence += weights.importPath;
101
+ if (signals.folderStructure)
102
+ confidence += weights.folderStructure;
103
+ return confidence;
104
+ }
105
+ /**
106
+ * Infer domain from semantic analysis (co-usage + types)
107
+ *
108
+ * This replaces the folder-based heuristic with actual code relationships
109
+ */
110
+ export function inferDomainFromSemantics(file, exportName, graph, coUsageMatrix, typeGraph, exportTypeRefs) {
111
+ const assignments = [];
112
+ const domainSignals = new Map();
113
+ // 1. Check co-usage patterns
114
+ const coUsages = coUsageMatrix.get(file) || new Map();
115
+ const strongCoUsages = Array.from(coUsages.entries())
116
+ .filter(([_, count]) => count >= 3)
117
+ .map(([coFile]) => coFile);
118
+ // Extract domains from frequently co-imported files
119
+ for (const coFile of strongCoUsages) {
120
+ const coNode = graph.nodes.get(coFile);
121
+ if (coNode) {
122
+ for (const exp of coNode.exports) {
123
+ if (exp.inferredDomain && exp.inferredDomain !== 'unknown') {
124
+ const domain = exp.inferredDomain;
125
+ if (!domainSignals.has(domain)) {
126
+ domainSignals.set(domain, {
127
+ coUsage: false,
128
+ typeReference: false,
129
+ exportName: false,
130
+ importPath: false,
131
+ folderStructure: false
132
+ });
133
+ }
134
+ domainSignals.get(domain).coUsage = true;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ // 2. Check type references
140
+ if (exportTypeRefs) {
141
+ for (const typeRef of exportTypeRefs) {
142
+ const filesWithType = typeGraph.get(typeRef);
143
+ if (filesWithType) {
144
+ for (const typeFile of filesWithType) {
145
+ if (typeFile !== file) {
146
+ const typeNode = graph.nodes.get(typeFile);
147
+ if (typeNode) {
148
+ for (const exp of typeNode.exports) {
149
+ if (exp.inferredDomain && exp.inferredDomain !== 'unknown') {
150
+ const domain = exp.inferredDomain;
151
+ if (!domainSignals.has(domain)) {
152
+ domainSignals.set(domain, {
153
+ coUsage: false,
154
+ typeReference: false,
155
+ exportName: false,
156
+ importPath: false,
157
+ folderStructure: false
158
+ });
159
+ }
160
+ domainSignals.get(domain).typeReference = true;
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ // 3. Build domain assignments with confidence scores
170
+ for (const [domain, signals] of domainSignals) {
171
+ const confidence = calculateDomainConfidence(signals);
172
+ if (confidence >= 0.3) { // Minimum confidence threshold
173
+ assignments.push({ domain, confidence, signals });
174
+ }
175
+ }
176
+ // Sort by confidence (highest first)
177
+ assignments.sort((a, b) => b.confidence - a.confidence);
178
+ return assignments;
179
+ }
180
+ /**
181
+ * Get co-usage data for a specific file
182
+ */
183
+ export function getCoUsageData(file, coUsageMatrix) {
184
+ const coImportedWith = coUsageMatrix.get(file) || new Map();
185
+ // Find files that import both this file and others
186
+ const sharedImporters = [];
187
+ // This would require inverse mapping from imports, simplified for now
188
+ return {
189
+ file,
190
+ coImportedWith,
191
+ sharedImporters
192
+ };
193
+ }
194
+ /**
195
+ * Find files that should be consolidated based on semantic similarity
196
+ *
197
+ * High co-usage + shared types = strong consolidation candidate
198
+ */
199
+ export function findConsolidationCandidates(graph, coUsageMatrix, typeGraph, minCoUsage = 5, minSharedTypes = 2) {
200
+ const candidates = [];
201
+ // Find file pairs with both high co-usage AND shared types
202
+ for (const [fileA, coUsages] of coUsageMatrix) {
203
+ const nodeA = graph.nodes.get(fileA);
204
+ if (!nodeA)
205
+ continue;
206
+ for (const [fileB, coUsageCount] of coUsages) {
207
+ if (fileB <= fileA)
208
+ continue; // Avoid duplicates
209
+ if (coUsageCount < minCoUsage)
210
+ continue;
211
+ const nodeB = graph.nodes.get(fileB);
212
+ if (!nodeB)
213
+ continue;
214
+ // Count shared types
215
+ const typesA = new Set(nodeA.exports.flatMap(e => e.typeReferences || []));
216
+ const typesB = new Set(nodeB.exports.flatMap(e => e.typeReferences || []));
217
+ const sharedTypes = Array.from(typesA).filter(t => typesB.has(t));
218
+ if (sharedTypes.length >= minSharedTypes) {
219
+ const strength = (coUsageCount / 10) + (sharedTypes.length / 5);
220
+ candidates.push({
221
+ files: [fileA, fileB],
222
+ reason: `High co-usage (${coUsageCount}x) and ${sharedTypes.length} shared types`,
223
+ strength
224
+ });
225
+ }
226
+ else if (coUsageCount >= minCoUsage * 2) {
227
+ // Very high co-usage alone is enough
228
+ const strength = coUsageCount / 10;
229
+ candidates.push({
230
+ files: [fileA, fileB],
231
+ reason: `Very high co-usage (${coUsageCount}x)`,
232
+ strength
233
+ });
234
+ }
235
+ }
236
+ }
237
+ // Sort by strength (highest first)
238
+ candidates.sort((a, b) => b.strength - a.strength);
239
+ return candidates;
240
+ }
241
+ //# sourceMappingURL=semantic-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-analysis.js","sourceRoot":"","sources":["../src/semantic-analysis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import type { ScanOptions } from '@aiready/core';
2
+ export interface ContextAnalyzerOptions extends ScanOptions {
3
+ maxDepth?: number;
4
+ maxContextBudget?: number;
5
+ minCohesion?: number;
6
+ maxFragmentation?: number;
7
+ focus?: 'fragmentation' | 'cohesion' | 'depth' | 'all';
8
+ includeNodeModules?: boolean;
9
+ }
10
+ export interface ContextAnalysisResult {
11
+ file: string;
12
+ tokenCost: number;
13
+ linesOfCode: number;
14
+ importDepth: number;
15
+ dependencyCount: number;
16
+ dependencyList: string[];
17
+ circularDeps: string[][];
18
+ cohesionScore: number;
19
+ domains: string[];
20
+ exportCount: number;
21
+ contextBudget: number;
22
+ fragmentationScore: number;
23
+ relatedFiles: string[];
24
+ severity: 'critical' | 'major' | 'minor' | 'info';
25
+ issues: string[];
26
+ recommendations: string[];
27
+ potentialSavings: number;
28
+ }
29
+ export interface ModuleCluster {
30
+ domain: string;
31
+ files: string[];
32
+ totalTokens: number;
33
+ fragmentationScore: number;
34
+ pathEntropy?: number;
35
+ directoryDistance?: number;
36
+ importCohesion?: number;
37
+ avgCohesion: number;
38
+ suggestedStructure: {
39
+ targetFiles: number;
40
+ consolidationPlan: string[];
41
+ };
42
+ }
43
+ export interface ContextSummary {
44
+ totalFiles: number;
45
+ totalTokens: number;
46
+ avgContextBudget: number;
47
+ maxContextBudget: number;
48
+ avgImportDepth: number;
49
+ maxImportDepth: number;
50
+ deepFiles: Array<{
51
+ file: string;
52
+ depth: number;
53
+ }>;
54
+ avgFragmentation: number;
55
+ fragmentedModules: ModuleCluster[];
56
+ avgCohesion: number;
57
+ lowCohesionFiles: Array<{
58
+ file: string;
59
+ score: number;
60
+ }>;
61
+ criticalIssues: number;
62
+ majorIssues: number;
63
+ minorIssues: number;
64
+ totalPotentialSavings: number;
65
+ topExpensiveFiles: Array<{
66
+ file: string;
67
+ contextBudget: number;
68
+ severity: string;
69
+ }>;
70
+ }
71
+ export interface DependencyGraph {
72
+ nodes: Map<string, DependencyNode>;
73
+ edges: Map<string, Set<string>>;
74
+ coUsageMatrix?: Map<string, Map<string, number>>;
75
+ typeGraph?: Map<string, Set<string>>;
76
+ }
77
+ export interface DependencyNode {
78
+ file: string;
79
+ imports: string[];
80
+ exports: ExportInfo[];
81
+ tokenCost: number;
82
+ linesOfCode: number;
83
+ exportedBy?: string[];
84
+ sharedTypes?: string[];
85
+ }
86
+ export interface ExportInfo {
87
+ name: string;
88
+ type: 'function' | 'class' | 'const' | 'type' | 'interface' | 'default';
89
+ inferredDomain?: string;
90
+ domains?: DomainAssignment[];
91
+ imports?: string[];
92
+ dependencies?: string[];
93
+ typeReferences?: string[];
94
+ }
95
+ export interface DomainAssignment {
96
+ domain: string;
97
+ confidence: number;
98
+ signals: DomainSignals;
99
+ }
100
+ export interface DomainSignals {
101
+ folderStructure: boolean;
102
+ importPath: boolean;
103
+ typeReference: boolean;
104
+ coUsage: boolean;
105
+ exportName: boolean;
106
+ }
107
+ export interface CoUsageData {
108
+ file: string;
109
+ coImportedWith: Map<string, number>;
110
+ sharedImporters: string[];
111
+ }
112
+ export interface TypeDependency {
113
+ typeName: string;
114
+ definedIn: string;
115
+ usedBy: string[];
116
+ }
117
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACvD,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IAGb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;IAGzB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IAGpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IAGvB,QAAQ,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IAClD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IAGzB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAGlD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,aAAa,EAAE,CAAC;IAGnC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAGzD,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAG9B,iBAAiB,EAAE,KAAK,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/context-analyzer",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "description": "AI context window cost analysis - detect fragmented code, deep import chains, and expensive context budgets",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -49,7 +49,7 @@
49
49
  "commander": "^14.0.0",
50
50
  "chalk": "^5.3.0",
51
51
  "prompts": "^2.4.2",
52
- "@aiready/core": "0.9.4"
52
+ "@aiready/core": "0.9.6"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/node": "^24.0.0",
@@ -0,0 +1,60 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ calculatePathEntropy,
4
+ calculateDirectoryDistance,
5
+ } from '../analyzer';
6
+
7
+ describe('advanced fragmentation heuristics', () => {
8
+ it('path entropy is low when most files are in one directory', () => {
9
+ const files = [
10
+ 'src/billing/a.ts',
11
+ 'src/billing/b.ts',
12
+ 'src/billing/c.ts',
13
+ 'src/billing/d.ts',
14
+ 'src/billing/e.ts',
15
+ 'src/billing/f.ts',
16
+ 'src/billing/g.ts',
17
+ 'src/billing/h.ts',
18
+ 'src/billing/i.ts',
19
+ 'src/other/x.ts',
20
+ ];
21
+
22
+ const entropy = calculatePathEntropy(files);
23
+ // 9 in one folder and 1 in another should yield low entropy (< 0.5)
24
+ expect(entropy).toBeLessThan(0.5);
25
+ });
26
+
27
+ it('path entropy is high when files are evenly distributed', () => {
28
+ const files = [
29
+ 'a/f1.ts',
30
+ 'b/f2.ts',
31
+ 'c/f3.ts',
32
+ 'd/f4.ts',
33
+ 'e/f5.ts',
34
+ ];
35
+
36
+ const entropy = calculatePathEntropy(files);
37
+ expect(entropy).toBeGreaterThan(0.8);
38
+ });
39
+
40
+ it('directory distance is low for sibling files and high for scattered files', () => {
41
+ const siblings = [
42
+ 'src/auth/ui/button.ts',
43
+ 'src/auth/ui/input.ts',
44
+ 'src/auth/ui/modal.ts',
45
+ ];
46
+
47
+ const scattered = [
48
+ 'src/auth/ui/button.ts',
49
+ 'src/payments/api/charge.ts',
50
+ 'lib/analytics/track.ts',
51
+ ];
52
+
53
+ const distSiblings = calculateDirectoryDistance(siblings);
54
+ const distScattered = calculateDirectoryDistance(scattered);
55
+
56
+ expect(distSiblings).toBeLessThan(distScattered);
57
+ expect(distSiblings).toBeLessThan(0.5);
58
+ expect(distScattered).toBeGreaterThan(0.6);
59
+ });
60
+ });