phantom-pr 0.4.19 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -80
- package/dist/core/analysis/astExtractor.d.ts +15 -0
- package/dist/core/analysis/astExtractor.js +354 -0
- package/dist/core/analysis/astExtractor.js.map +1 -0
- package/dist/core/analysis/index.d.ts +3 -0
- package/dist/core/analysis/index.js +3 -0
- package/dist/core/analysis/index.js.map +1 -0
- package/dist/core/analysis/types.d.ts +50 -0
- package/dist/core/analysis/types.js +16 -0
- package/dist/core/analysis/types.js.map +1 -0
- package/dist/core/context/contextSelector.d.ts +29 -0
- package/dist/core/context/contextSelector.js +293 -0
- package/dist/core/context/contextSelector.js.map +1 -0
- package/dist/core/context/index.d.ts +4 -0
- package/dist/core/context/index.js +3 -0
- package/dist/core/context/index.js.map +1 -0
- package/dist/core/generator/enhancedContext.d.ts +34 -0
- package/dist/core/generator/enhancedContext.js +144 -0
- package/dist/core/generator/enhancedContext.js.map +1 -0
- package/dist/core/generator/llmGenerator.js +157 -15
- package/dist/core/generator/llmGenerator.js.map +1 -1
- package/dist/core/generator/postValidation.d.ts +24 -0
- package/dist/core/generator/postValidation.js +57 -0
- package/dist/core/generator/postValidation.js.map +1 -0
- package/dist/core/retry/errorParser.d.ts +12 -0
- package/dist/core/retry/errorParser.js +264 -0
- package/dist/core/retry/errorParser.js.map +1 -0
- package/dist/core/retry/feedbackGenerator.d.ts +12 -0
- package/dist/core/retry/feedbackGenerator.js +164 -0
- package/dist/core/retry/feedbackGenerator.js.map +1 -0
- package/dist/core/retry/index.d.ts +3 -0
- package/dist/core/retry/index.js +3 -0
- package/dist/core/retry/index.js.map +1 -0
- package/dist/core/retry/types.d.ts +40 -0
- package/dist/core/retry/types.js +5 -0
- package/dist/core/retry/types.js.map +1 -0
- package/dist/core/testRunner/retryEnhancer.d.ts +32 -0
- package/dist/core/testRunner/retryEnhancer.js +58 -0
- package/dist/core/testRunner/retryEnhancer.js.map +1 -0
- package/dist/core/validation/coverageVerifier.d.ts +16 -0
- package/dist/core/validation/coverageVerifier.js +226 -0
- package/dist/core/validation/coverageVerifier.js.map +1 -0
- package/dist/core/validation/index.d.ts +2 -0
- package/dist/core/validation/index.js +2 -0
- package/dist/core/validation/index.js.map +1 -0
- package/dist/core/validation/types.d.ts +24 -0
- package/dist/core/validation/types.js +6 -0
- package/dist/core/validation/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intelligent context selection using AST analysis.
|
|
3
|
+
* Minimizes token usage while maximizing test generation quality.
|
|
4
|
+
*
|
|
5
|
+
* Pure functions only - no file I/O (receives file contents as input).
|
|
6
|
+
*/
|
|
7
|
+
/** Known external packages that should never be included in context. */
|
|
8
|
+
const EXTERNAL_PACKAGES = new Set([
|
|
9
|
+
'react',
|
|
10
|
+
'react-dom',
|
|
11
|
+
'next',
|
|
12
|
+
'next/router',
|
|
13
|
+
'next/link',
|
|
14
|
+
'next/image',
|
|
15
|
+
'next/head',
|
|
16
|
+
'next/script',
|
|
17
|
+
'lodash',
|
|
18
|
+
'underscore',
|
|
19
|
+
'axios',
|
|
20
|
+
'moment',
|
|
21
|
+
'dayjs',
|
|
22
|
+
'date-fns',
|
|
23
|
+
'classnames',
|
|
24
|
+
'clsx',
|
|
25
|
+
'uuid',
|
|
26
|
+
'zod',
|
|
27
|
+
'yup',
|
|
28
|
+
'formik',
|
|
29
|
+
'react-hook-form',
|
|
30
|
+
'react-query',
|
|
31
|
+
'@tanstack/react-query',
|
|
32
|
+
'swr',
|
|
33
|
+
'redux',
|
|
34
|
+
'react-redux',
|
|
35
|
+
'@reduxjs/toolkit',
|
|
36
|
+
'zustand',
|
|
37
|
+
'jotai',
|
|
38
|
+
'recoil',
|
|
39
|
+
'framer-motion',
|
|
40
|
+
'styled-components',
|
|
41
|
+
'@emotion/react',
|
|
42
|
+
'@emotion/styled',
|
|
43
|
+
'tailwindcss',
|
|
44
|
+
'@mui/material',
|
|
45
|
+
'@chakra-ui/react',
|
|
46
|
+
'antd',
|
|
47
|
+
'prop-types',
|
|
48
|
+
]);
|
|
49
|
+
/**
|
|
50
|
+
* Estimate token count from content length.
|
|
51
|
+
* Rough approximation: ~4 chars per token for English/code.
|
|
52
|
+
*/
|
|
53
|
+
function estimateTokens(content) {
|
|
54
|
+
return Math.ceil(content.length / 4);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Extract mocked module paths from a test file.
|
|
58
|
+
* Looks for jest.mock('path') patterns.
|
|
59
|
+
*/
|
|
60
|
+
function extractMockedModules(testContent) {
|
|
61
|
+
const mocked = new Set();
|
|
62
|
+
// jest.mock('...')
|
|
63
|
+
const jestMockRe = /jest\.mock\(\s*['"]([^'"]+)['"]/g;
|
|
64
|
+
for (const match of testContent.matchAll(jestMockRe)) {
|
|
65
|
+
const modulePath = match[1];
|
|
66
|
+
if (modulePath)
|
|
67
|
+
mocked.add(modulePath);
|
|
68
|
+
}
|
|
69
|
+
// vi.mock('...')
|
|
70
|
+
const viMockRe = /vi\.mock\(\s*['"]([^'"]+)['"]/g;
|
|
71
|
+
for (const match of testContent.matchAll(viMockRe)) {
|
|
72
|
+
const modulePath = match[1];
|
|
73
|
+
if (modulePath)
|
|
74
|
+
mocked.add(modulePath);
|
|
75
|
+
}
|
|
76
|
+
return mocked;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a path is an external package (not a relative import).
|
|
80
|
+
*/
|
|
81
|
+
function isExternalPackage(importPath) {
|
|
82
|
+
// Relative imports start with . or /
|
|
83
|
+
if (importPath.startsWith('.') || importPath.startsWith('/')) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// Check against known external packages
|
|
87
|
+
if (EXTERNAL_PACKAGES.has(importPath)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// Scoped packages like @org/package
|
|
91
|
+
if (importPath.startsWith('@')) {
|
|
92
|
+
const parts = importPath.split('/');
|
|
93
|
+
const scopedName = parts.slice(0, 2).join('/');
|
|
94
|
+
if (EXTERNAL_PACKAGES.has(scopedName)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Non-relative, non-scoped package names are likely external
|
|
99
|
+
// But we can't be sure without checking node_modules, so be conservative
|
|
100
|
+
return !importPath.includes('/') && !importPath.startsWith('.');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve a relative import path to match against availableFiles.
|
|
104
|
+
* Handles extensions and index files.
|
|
105
|
+
*/
|
|
106
|
+
function resolveImportPath(fromPath, importPath) {
|
|
107
|
+
if (!importPath.startsWith('.')) {
|
|
108
|
+
return [importPath];
|
|
109
|
+
}
|
|
110
|
+
// Get directory of the source file
|
|
111
|
+
const fromDir = fromPath.replace(/\/[^/]+$/, '');
|
|
112
|
+
// Join paths
|
|
113
|
+
let resolved = importPath;
|
|
114
|
+
if (importPath.startsWith('./')) {
|
|
115
|
+
resolved = `${fromDir}/${importPath.slice(2)}`;
|
|
116
|
+
}
|
|
117
|
+
else if (importPath.startsWith('../')) {
|
|
118
|
+
const parts = fromDir.split('/');
|
|
119
|
+
let upCount = 0;
|
|
120
|
+
let remaining = importPath;
|
|
121
|
+
while (remaining.startsWith('../')) {
|
|
122
|
+
upCount++;
|
|
123
|
+
remaining = remaining.slice(3);
|
|
124
|
+
}
|
|
125
|
+
const baseParts = parts.slice(0, -upCount);
|
|
126
|
+
resolved = [...baseParts, remaining].join('/');
|
|
127
|
+
}
|
|
128
|
+
// Normalize
|
|
129
|
+
resolved = resolved.replace(/\/+/g, '/').replace(/^\//, '');
|
|
130
|
+
// Generate candidates with different extensions
|
|
131
|
+
const exts = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json'];
|
|
132
|
+
const candidates = [resolved];
|
|
133
|
+
// Add extension variants
|
|
134
|
+
if (!exts.some(ext => resolved.endsWith(ext))) {
|
|
135
|
+
for (const ext of exts) {
|
|
136
|
+
candidates.push(`${resolved}${ext}`);
|
|
137
|
+
candidates.push(`${resolved}/index${ext}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return candidates;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if a path looks like a type definition file.
|
|
144
|
+
*/
|
|
145
|
+
function isTypeDefinitionPath(path) {
|
|
146
|
+
const lower = path.toLowerCase();
|
|
147
|
+
return (lower.includes('/types') ||
|
|
148
|
+
lower.includes('.types.') ||
|
|
149
|
+
lower.includes('.d.ts') ||
|
|
150
|
+
lower.endsWith('types.ts') ||
|
|
151
|
+
lower.endsWith('types.tsx'));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check if a path looks like a constants file.
|
|
155
|
+
*/
|
|
156
|
+
function isConstantsPath(path) {
|
|
157
|
+
const lower = path.toLowerCase();
|
|
158
|
+
return (lower.includes('/constants') ||
|
|
159
|
+
lower.includes('.constants.') ||
|
|
160
|
+
lower.endsWith('constants.ts') ||
|
|
161
|
+
lower.endsWith('constants.js'));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Select context files based on analysis and heuristics.
|
|
165
|
+
* Returns files sorted by priority with reasons for selection.
|
|
166
|
+
*/
|
|
167
|
+
export function selectContext(input) {
|
|
168
|
+
const selected = [];
|
|
169
|
+
let tokenBudgetUsed = 0;
|
|
170
|
+
// Track what we've included
|
|
171
|
+
const includedPaths = new Set();
|
|
172
|
+
// Get mocked modules from existing test
|
|
173
|
+
const mockedModules = input.existingTestContent
|
|
174
|
+
? extractMockedModules(input.existingTestContent)
|
|
175
|
+
: new Set();
|
|
176
|
+
// Helper to add a file if within budget
|
|
177
|
+
const addFile = (path, priority, reason) => {
|
|
178
|
+
if (includedPaths.has(path))
|
|
179
|
+
return true;
|
|
180
|
+
const content = input.availableFiles.get(path);
|
|
181
|
+
if (!content)
|
|
182
|
+
return false;
|
|
183
|
+
const tokens = estimateTokens(content);
|
|
184
|
+
// Required files always included
|
|
185
|
+
if (priority !== 'required') {
|
|
186
|
+
if (tokenBudgetUsed + tokens > input.maxTokens) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
includedPaths.add(path);
|
|
191
|
+
tokenBudgetUsed += tokens;
|
|
192
|
+
selected.push({ path, content, priority, reason });
|
|
193
|
+
return true;
|
|
194
|
+
};
|
|
195
|
+
// 1. REQUIRED: Target file - always include
|
|
196
|
+
addFile(input.targetPath, 'required', 'Target file under test');
|
|
197
|
+
// 2. REQUIRED: Existing test file - if exists, include for pattern learning
|
|
198
|
+
if (input.existingTestPath && input.existingTestContent) {
|
|
199
|
+
addFile(input.existingTestPath, 'required', 'Existing test file for pattern learning');
|
|
200
|
+
}
|
|
201
|
+
// 3. Process child components - they should be mocked, not included
|
|
202
|
+
// But we note them as excluded for clarity
|
|
203
|
+
const childrenToMock = [];
|
|
204
|
+
for (const child of input.analysis.children) {
|
|
205
|
+
if (child.importPath && child.importPath !== 'unknown') {
|
|
206
|
+
childrenToMock.push(child.name);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// 4. Process external calls to find type definitions and constants
|
|
210
|
+
const typesNeeded = [];
|
|
211
|
+
const constantsNeeded = [];
|
|
212
|
+
for (const call of input.analysis.externalCalls) {
|
|
213
|
+
// Skip external packages
|
|
214
|
+
if (isExternalPackage(call.module))
|
|
215
|
+
continue;
|
|
216
|
+
// Skip mocked modules
|
|
217
|
+
if (mockedModules.has(call.module))
|
|
218
|
+
continue;
|
|
219
|
+
// Check if it's a type or constant
|
|
220
|
+
const candidates = resolveImportPath(input.targetPath, call.module);
|
|
221
|
+
for (const candidate of candidates) {
|
|
222
|
+
if (input.availableFiles.has(candidate)) {
|
|
223
|
+
if (isTypeDefinitionPath(candidate)) {
|
|
224
|
+
typesNeeded.push(candidate);
|
|
225
|
+
}
|
|
226
|
+
else if (isConstantsPath(candidate)) {
|
|
227
|
+
constantsNeeded.push(candidate);
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// 5. RECOMMENDED: Type definitions
|
|
234
|
+
const seenTypes = new Set();
|
|
235
|
+
for (const typePath of typesNeeded.sort()) {
|
|
236
|
+
if (seenTypes.has(typePath))
|
|
237
|
+
continue;
|
|
238
|
+
seenTypes.add(typePath);
|
|
239
|
+
addFile(typePath, 'recommended', 'Type definitions used by component');
|
|
240
|
+
}
|
|
241
|
+
// 6. RECOMMENDED: Constants
|
|
242
|
+
const seenConstants = new Set();
|
|
243
|
+
for (const constPath of constantsNeeded.sort()) {
|
|
244
|
+
if (seenConstants.has(constPath))
|
|
245
|
+
continue;
|
|
246
|
+
seenConstants.add(constPath);
|
|
247
|
+
addFile(constPath, 'recommended', 'Constants imported by component');
|
|
248
|
+
}
|
|
249
|
+
// 7. OPTIONAL: Other non-child, non-mocked, non-external imports
|
|
250
|
+
// Find all imports from target content
|
|
251
|
+
const importRe = /(?:import|from)\s+['"]([^'"]+)['"]/g;
|
|
252
|
+
const allImports = [];
|
|
253
|
+
for (const match of input.targetContent.matchAll(importRe)) {
|
|
254
|
+
const imp = match[1];
|
|
255
|
+
if (imp)
|
|
256
|
+
allImports.push(imp);
|
|
257
|
+
}
|
|
258
|
+
for (const imp of [...new Set(allImports)].sort()) {
|
|
259
|
+
// Skip external packages
|
|
260
|
+
if (isExternalPackage(imp))
|
|
261
|
+
continue;
|
|
262
|
+
// Skip mocked modules
|
|
263
|
+
if (mockedModules.has(imp))
|
|
264
|
+
continue;
|
|
265
|
+
// Skip child components (they should be mocked)
|
|
266
|
+
const isChildImport = input.analysis.children.some(c => c.importPath === imp || c.importPath.includes(imp));
|
|
267
|
+
if (isChildImport)
|
|
268
|
+
continue;
|
|
269
|
+
// Try to find the file
|
|
270
|
+
const candidates = resolveImportPath(input.targetPath, imp);
|
|
271
|
+
for (const candidate of candidates) {
|
|
272
|
+
if (input.availableFiles.has(candidate) && !includedPaths.has(candidate)) {
|
|
273
|
+
// Skip if already processed as type or constant
|
|
274
|
+
if (seenTypes.has(candidate) || seenConstants.has(candidate))
|
|
275
|
+
continue;
|
|
276
|
+
addFile(candidate, 'optional', `Imported module: ${imp}`);
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Sort by priority order: required → recommended → optional
|
|
282
|
+
// Then alphabetically within each priority
|
|
283
|
+
const priorityOrder = { required: 0, recommended: 1, optional: 2 };
|
|
284
|
+
selected.sort((a, b) => {
|
|
285
|
+
const pa = priorityOrder[a.priority];
|
|
286
|
+
const pb = priorityOrder[b.priority];
|
|
287
|
+
if (pa !== pb)
|
|
288
|
+
return pa - pb;
|
|
289
|
+
return a.path.localeCompare(b.path);
|
|
290
|
+
});
|
|
291
|
+
return selected;
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=contextSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextSelector.js","sourceRoot":"","sources":["../../../src/core/context/contextSelector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,OAAO;IACP,WAAW;IACX,MAAM;IACN,aAAa;IACb,WAAW;IACX,YAAY;IACZ,WAAW;IACX,aAAa;IACb,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;IACV,YAAY;IACZ,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,QAAQ;IACR,iBAAiB;IACjB,aAAa;IACb,uBAAuB;IACvB,KAAK;IACL,OAAO;IACP,aAAa;IACb,kBAAkB;IAClB,SAAS;IACT,OAAO;IACP,QAAQ;IACR,eAAe;IACf,mBAAmB;IACnB,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,MAAM;IACN,YAAY;CACb,CAAC,CAAC;AAEH;;;GAGG;AACH,SAAS,cAAc,CAAC,OAAe;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,WAAmB;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,mBAAmB;IACnB,MAAM,UAAU,GAAG,kCAAkC,CAAC;IACtD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,UAAU;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,iBAAiB;IACjB,MAAM,QAAQ,GAAG,gCAAgC,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,UAAU;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,qCAAqC;IACrC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,wCAAwC;IACxC,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oCAAoC;IACpC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,yEAAyE;IACzE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,QAAgB,EAAE,UAAkB;IAC7D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAED,mCAAmC;IACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAEjD,aAAa;IACb,IAAI,QAAQ,GAAG,UAAU,CAAC;IAC1B,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,QAAQ,GAAG,GAAG,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,CAAC;SAAM,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,SAAS,GAAG,UAAU,CAAC;QAC3B,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;YACV,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3C,QAAQ,GAAG,CAAC,GAAG,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,YAAY;IACZ,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAE5D,gDAAgD;IAChD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE9B,yBAAyB;IACzB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,UAAU,CAAC,IAAI,CAAC,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC,GAAG,QAAQ,SAAS,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACxB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QACvB,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC1B,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC7B,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAA4B;IACxD,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAC3C,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,4BAA4B;IAC5B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAExC,wCAAwC;IACxC,MAAM,aAAa,GAAG,KAAK,CAAC,mBAAmB;QAC7C,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,mBAAmB,CAAC;QACjD,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IAEtB,wCAAwC;IACxC,MAAM,OAAO,GAAG,CACd,IAAY,EACZ,QAAyC,EACzC,MAAc,EACL,EAAE;QACX,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAE3B,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvC,iCAAiC;QACjC,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,eAAe,GAAG,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC/C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,eAAe,IAAI,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,4CAA4C;IAC5C,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,wBAAwB,CAAC,CAAC;IAEhE,4EAA4E;IAC5E,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QACxD,OAAO,CACL,KAAK,CAAC,gBAAgB,EACtB,UAAU,EACV,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,2CAA2C;IAC3C,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC5C,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACvD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,eAAe,GAAa,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAChD,yBAAyB;QACzB,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,SAAS;QAE7C,sBAAsB;QACtB,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,SAAS;QAE7C,mCAAmC;QACnC,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;oBACpC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC9B,CAAC;qBAAM,IAAI,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;oBACtC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAClC,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACtC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,oCAAoC,CAAC,CAAC;IACzE,CAAC;IAED,4BAA4B;IAC5B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,KAAK,MAAM,SAAS,IAAI,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/C,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,SAAS;QAC3C,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7B,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,iCAAiC,CAAC,CAAC;IACvE,CAAC;IAED,iEAAiE;IACjE,uCAAuC;IACvC,MAAM,QAAQ,GAAG,qCAAqC,CAAC;IACvD,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,GAAG;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAClD,yBAAyB;QACzB,IAAI,iBAAiB,CAAC,GAAG,CAAC;YAAE,SAAS;QAErC,sBAAsB;QACtB,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAErC,gDAAgD;QAChD,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAChD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CACxD,CAAC;QACF,IAAI,aAAa;YAAE,SAAS;QAE5B,uBAAuB;QACvB,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC5D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzE,gDAAgD;gBAChD,IAAI,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;oBAAE,SAAS;gBAEvE,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,oBAAoB,GAAG,EAAE,CAAC,CAAC;gBAC1D,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,2CAA2C;IAC3C,MAAM,aAAa,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACnE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/context/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced context building that incorporates AST analysis.
|
|
3
|
+
* Wraps existing context packer with analysis-aware selection.
|
|
4
|
+
*
|
|
5
|
+
* Maintains backward compatibility - new features are additive.
|
|
6
|
+
*/
|
|
7
|
+
import { type ComponentAnalysis } from '../analysis/index.js';
|
|
8
|
+
import { type SelectedContextFile } from '../context/contextSelector.js';
|
|
9
|
+
export type EnhancedContextOptions = {
|
|
10
|
+
rootAbs: string;
|
|
11
|
+
targetPathPosix: string;
|
|
12
|
+
existingTestPathPosix?: string;
|
|
13
|
+
maxTokens?: number;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type EnhancedContextResult = {
|
|
17
|
+
analysis: ComponentAnalysis;
|
|
18
|
+
selectedFiles: SelectedContextFile[];
|
|
19
|
+
analysisJson: string;
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Build enhanced context using AST analysis.
|
|
24
|
+
* Returns analysis and selected files for inclusion in LLM prompt.
|
|
25
|
+
*
|
|
26
|
+
* @param opts - Context options
|
|
27
|
+
* @returns Enhanced context result with analysis and selected files
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildEnhancedContext(opts: EnhancedContextOptions): Promise<EnhancedContextResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Format analysis for inclusion in LLM prompt.
|
|
32
|
+
* Returns a prompt section with key insights from the analysis.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatAnalysisForPrompt(analysis: ComponentAnalysis): string;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced context building that incorporates AST analysis.
|
|
3
|
+
* Wraps existing context packer with analysis-aware selection.
|
|
4
|
+
*
|
|
5
|
+
* Maintains backward compatibility - new features are additive.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { extractComponentAnalysis, emptyAnalysis } from '../analysis/index.js';
|
|
10
|
+
import { selectContext } from '../context/contextSelector.js';
|
|
11
|
+
import { stableStringify } from '../stableJson.js';
|
|
12
|
+
/**
|
|
13
|
+
* Build enhanced context using AST analysis.
|
|
14
|
+
* Returns analysis and selected files for inclusion in LLM prompt.
|
|
15
|
+
*
|
|
16
|
+
* @param opts - Context options
|
|
17
|
+
* @returns Enhanced context result with analysis and selected files
|
|
18
|
+
*/
|
|
19
|
+
export async function buildEnhancedContext(opts) {
|
|
20
|
+
const enabled = opts.enabled ?? true;
|
|
21
|
+
if (!enabled) {
|
|
22
|
+
return {
|
|
23
|
+
analysis: emptyAnalysis(opts.targetPathPosix),
|
|
24
|
+
selectedFiles: [],
|
|
25
|
+
analysisJson: '{}',
|
|
26
|
+
enabled: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Read target file
|
|
30
|
+
let targetContent = '';
|
|
31
|
+
try {
|
|
32
|
+
const targetAbs = path.resolve(opts.rootAbs, ...opts.targetPathPosix.split('/'));
|
|
33
|
+
targetContent = await fs.promises.readFile(targetAbs, 'utf8');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// If we can't read the target, return empty analysis
|
|
37
|
+
return {
|
|
38
|
+
analysis: emptyAnalysis(opts.targetPathPosix),
|
|
39
|
+
selectedFiles: [],
|
|
40
|
+
analysisJson: '{}',
|
|
41
|
+
enabled: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Extract component analysis
|
|
45
|
+
const analysis = extractComponentAnalysis(opts.targetPathPosix, targetContent);
|
|
46
|
+
// Read existing test file if provided
|
|
47
|
+
let existingTestContent;
|
|
48
|
+
if (opts.existingTestPathPosix) {
|
|
49
|
+
try {
|
|
50
|
+
const testAbs = path.resolve(opts.rootAbs, ...opts.existingTestPathPosix.split('/'));
|
|
51
|
+
existingTestContent = await fs.promises.readFile(testAbs, 'utf8');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Test file doesn't exist yet - that's fine
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// For now, just use the target file in available files
|
|
58
|
+
// A full implementation would scan the directory, but we keep it simple
|
|
59
|
+
const availableFiles = new Map();
|
|
60
|
+
availableFiles.set(opts.targetPathPosix, targetContent);
|
|
61
|
+
if (existingTestContent && opts.existingTestPathPosix) {
|
|
62
|
+
availableFiles.set(opts.existingTestPathPosix, existingTestContent);
|
|
63
|
+
}
|
|
64
|
+
// Select context using analysis
|
|
65
|
+
const contextInput = {
|
|
66
|
+
targetPath: opts.targetPathPosix,
|
|
67
|
+
targetContent,
|
|
68
|
+
availableFiles,
|
|
69
|
+
analysis,
|
|
70
|
+
maxTokens: opts.maxTokens ?? 8000,
|
|
71
|
+
};
|
|
72
|
+
// Add optional properties only if defined
|
|
73
|
+
if (opts.existingTestPathPosix !== undefined) {
|
|
74
|
+
contextInput.existingTestPath = opts.existingTestPathPosix;
|
|
75
|
+
}
|
|
76
|
+
if (existingTestContent !== undefined) {
|
|
77
|
+
contextInput.existingTestContent = existingTestContent;
|
|
78
|
+
}
|
|
79
|
+
const selectedFiles = selectContext(contextInput);
|
|
80
|
+
// Create deterministic JSON representation
|
|
81
|
+
const analysisJson = stableStringify({
|
|
82
|
+
filePath: analysis.filePath,
|
|
83
|
+
branchCount: analysis.branches.length,
|
|
84
|
+
branches: analysis.branches.map(b => ({
|
|
85
|
+
line: b.line,
|
|
86
|
+
kind: b.kind,
|
|
87
|
+
condition: b.condition.slice(0, 50), // Truncate long conditions
|
|
88
|
+
})),
|
|
89
|
+
effectCount: analysis.effects.length,
|
|
90
|
+
effects: analysis.effects.map(e => ({
|
|
91
|
+
line: e.line,
|
|
92
|
+
kind: e.kind,
|
|
93
|
+
hasCleanup: e.hasCleanup,
|
|
94
|
+
depCount: e.dependencies.length,
|
|
95
|
+
})),
|
|
96
|
+
childCount: analysis.children.length,
|
|
97
|
+
children: analysis.children.map(c => ({
|
|
98
|
+
name: c.name,
|
|
99
|
+
importPath: c.importPath,
|
|
100
|
+
isConditional: c.isConditional,
|
|
101
|
+
})),
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
analysis,
|
|
105
|
+
selectedFiles,
|
|
106
|
+
analysisJson,
|
|
107
|
+
enabled: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Format analysis for inclusion in LLM prompt.
|
|
112
|
+
* Returns a prompt section with key insights from the analysis.
|
|
113
|
+
*/
|
|
114
|
+
export function formatAnalysisForPrompt(analysis) {
|
|
115
|
+
if (analysis.branches.length === 0 &&
|
|
116
|
+
analysis.effects.length === 0 &&
|
|
117
|
+
analysis.children.length === 0) {
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
const lines = [];
|
|
121
|
+
lines.push('## PRE-ANALYZED STRUCTURE (use this to guide test coverage)');
|
|
122
|
+
if (analysis.branches.length > 0) {
|
|
123
|
+
lines.push(`- BRANCHES (${analysis.branches.length}): Test BOTH paths for each`);
|
|
124
|
+
for (const b of analysis.branches.slice(0, 5)) {
|
|
125
|
+
lines.push(` - Line ${b.line}: ${b.kind} on \`${b.condition.slice(0, 40)}\``);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (analysis.effects.length > 0) {
|
|
129
|
+
lines.push(`- EFFECTS (${analysis.effects.length}):`);
|
|
130
|
+
for (const e of analysis.effects) {
|
|
131
|
+
const cleanup = e.hasCleanup ? ' [HAS CLEANUP - test unmount]' : '';
|
|
132
|
+
lines.push(` - Line ${e.line}: ${e.kind}${cleanup}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (analysis.children.length > 0) {
|
|
136
|
+
lines.push(`- CHILDREN TO MOCK (${analysis.children.length}):`);
|
|
137
|
+
for (const c of analysis.children.slice(0, 5)) {
|
|
138
|
+
lines.push(` - ${c.name} from '${c.importPath}'`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
lines.push('');
|
|
142
|
+
return lines.join('\n');
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=enhancedContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enhancedContext.js","sourceRoot":"","sources":["../../../src/core/generator/enhancedContext.ts"],"names":[],"mappings":"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"}
|