phantom-pr 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +0 -0
- package/README.md +143 -0
- package/dist/adapters/git.d.ts +28 -0
- package/dist/adapters/git.js +112 -0
- package/dist/adapters/git.js.map +1 -0
- package/dist/adapters/github.d.ts +71 -0
- package/dist/adapters/github.js +194 -0
- package/dist/adapters/github.js.map +1 -0
- package/dist/cli.d.ts +47 -0
- package/dist/cli.js +201 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/context.d.ts +2 -0
- package/dist/commands/context.js +275 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/full.d.ts +13 -0
- package/dist/commands/full.js +590 -0
- package/dist/commands/full.js.map +1 -0
- package/dist/commands/gen_test.d.ts +2 -0
- package/dist/commands/gen_test.js +94 -0
- package/dist/commands/gen_test.js.map +1 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +62 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.js +107 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/pr.d.ts +9 -0
- package/dist/commands/pr.js +400 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/pr_list.d.ts +2 -0
- package/dist/commands/pr_list.js +158 -0
- package/dist/commands/pr_list.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.js +132 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.js +143 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/testability.d.ts +10 -0
- package/dist/commands/testability.js +406 -0
- package/dist/commands/testability.js.map +1 -0
- package/dist/commands/tests.d.ts +9 -0
- package/dist/commands/tests.js +801 -0
- package/dist/commands/tests.js.map +1 -0
- package/dist/core/code/exports.d.ts +5 -0
- package/dist/core/code/exports.js +68 -0
- package/dist/core/code/exports.js.map +1 -0
- package/dist/core/config/forkPolicy.d.ts +25 -0
- package/dist/core/config/forkPolicy.js +35 -0
- package/dist/core/config/forkPolicy.js.map +1 -0
- package/dist/core/config/load.d.ts +13 -0
- package/dist/core/config/load.js +35 -0
- package/dist/core/config/load.js.map +1 -0
- package/dist/core/config/types.d.ts +87 -0
- package/dist/core/config/types.js +2 -0
- package/dist/core/config/types.js.map +1 -0
- package/dist/core/config/validate.d.ts +4 -0
- package/dist/core/config/validate.js +246 -0
- package/dist/core/config/validate.js.map +1 -0
- package/dist/core/context/packer.d.ts +31 -0
- package/dist/core/context/packer.js +345 -0
- package/dist/core/context/packer.js.map +1 -0
- package/dist/core/context/types.d.ts +41 -0
- package/dist/core/context/types.js +2 -0
- package/dist/core/context/types.js.map +1 -0
- package/dist/core/converge/loop.d.ts +13 -0
- package/dist/core/converge/loop.js +35 -0
- package/dist/core/converge/loop.js.map +1 -0
- package/dist/core/converge/types.d.ts +15 -0
- package/dist/core/converge/types.js +2 -0
- package/dist/core/converge/types.js.map +1 -0
- package/dist/core/generator/llm/diffApply.d.ts +26 -0
- package/dist/core/generator/llm/diffApply.js +276 -0
- package/dist/core/generator/llm/diffApply.js.map +1 -0
- package/dist/core/generator/llm/qualityGate.d.ts +34 -0
- package/dist/core/generator/llm/qualityGate.js +324 -0
- package/dist/core/generator/llm/qualityGate.js.map +1 -0
- package/dist/core/generator/llmGenerator.d.ts +34 -0
- package/dist/core/generator/llmGenerator.js +245 -0
- package/dist/core/generator/llmGenerator.js.map +1 -0
- package/dist/core/generator/quality.d.ts +17 -0
- package/dist/core/generator/quality.js +31 -0
- package/dist/core/generator/quality.js.map +1 -0
- package/dist/core/generator/registry.d.ts +26 -0
- package/dist/core/generator/registry.js +29 -0
- package/dist/core/generator/registry.js.map +1 -0
- package/dist/core/generator/smokeGenerator.d.ts +11 -0
- package/dist/core/generator/smokeGenerator.js +27 -0
- package/dist/core/generator/smokeGenerator.js.map +1 -0
- package/dist/core/generator/types.d.ts +48 -0
- package/dist/core/generator/types.js +2 -0
- package/dist/core/generator/types.js.map +1 -0
- package/dist/core/index/indexer.d.ts +29 -0
- package/dist/core/index/indexer.js +167 -0
- package/dist/core/index/indexer.js.map +1 -0
- package/dist/core/jest/parser.d.ts +17 -0
- package/dist/core/jest/parser.js +90 -0
- package/dist/core/jest/parser.js.map +1 -0
- package/dist/core/llm/provider.d.ts +55 -0
- package/dist/core/llm/provider.js +105 -0
- package/dist/core/llm/provider.js.map +1 -0
- package/dist/core/logger.d.ts +19 -0
- package/dist/core/logger.js +44 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/plan/planner.d.ts +16 -0
- package/dist/core/plan/planner.js +91 -0
- package/dist/core/plan/planner.js.map +1 -0
- package/dist/core/process/exec.d.ts +22 -0
- package/dist/core/process/exec.js +83 -0
- package/dist/core/process/exec.js.map +1 -0
- package/dist/core/redact.d.ts +6 -0
- package/dist/core/redact.js +49 -0
- package/dist/core/redact.js.map +1 -0
- package/dist/core/repo/boundary.d.ts +10 -0
- package/dist/core/repo/boundary.js +58 -0
- package/dist/core/repo/boundary.js.map +1 -0
- package/dist/core/stableJson.d.ts +1 -0
- package/dist/core/stableJson.js +32 -0
- package/dist/core/stableJson.js.map +1 -0
- package/dist/core/state/policy.d.ts +20 -0
- package/dist/core/state/policy.js +51 -0
- package/dist/core/state/policy.js.map +1 -0
- package/dist/core/state/state.d.ts +67 -0
- package/dist/core/state/state.js +142 -0
- package/dist/core/state/state.js.map +1 -0
- package/dist/core/state/storage.d.ts +9 -0
- package/dist/core/state/storage.js +25 -0
- package/dist/core/state/storage.js.map +1 -0
- package/dist/core/targets/resolve.d.ts +28 -0
- package/dist/core/targets/resolve.js +96 -0
- package/dist/core/targets/resolve.js.map +1 -0
- package/dist/core/testGenerator/conventions.d.ts +7 -0
- package/dist/core/testGenerator/conventions.js +29 -0
- package/dist/core/testGenerator/conventions.js.map +1 -0
- package/dist/core/testGenerator/generate.d.ts +35 -0
- package/dist/core/testGenerator/generate.js +127 -0
- package/dist/core/testGenerator/generate.js.map +1 -0
- package/dist/core/testRunner/hints.d.ts +12 -0
- package/dist/core/testRunner/hints.js +133 -0
- package/dist/core/testRunner/hints.js.map +1 -0
- package/dist/core/testRunner/infer.d.ts +24 -0
- package/dist/core/testRunner/infer.js +65 -0
- package/dist/core/testRunner/infer.js.map +1 -0
- package/dist/core/testRunner/resolve.d.ts +12 -0
- package/dist/core/testRunner/resolve.js +31 -0
- package/dist/core/testRunner/resolve.js.map +1 -0
- package/dist/core/testRunner/runner.d.ts +24 -0
- package/dist/core/testRunner/runner.js +145 -0
- package/dist/core/testRunner/runner.js.map +1 -0
- package/dist/core/testability/heuristics.d.ts +7 -0
- package/dist/core/testability/heuristics.js +35 -0
- package/dist/core/testability/heuristics.js.map +1 -0
- package/dist/core/tests/fixers.d.ts +14 -0
- package/dist/core/tests/fixers.js +59 -0
- package/dist/core/tests/fixers.js.map +1 -0
- package/dist/core/tests/types.d.ts +98 -0
- package/dist/core/tests/types.js +2 -0
- package/dist/core/tests/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ContextBudgets, ContextPack } from './types.js';
|
|
2
|
+
type Boundary = {
|
|
3
|
+
kind: 'js' | 'py' | 'unknown';
|
|
4
|
+
rootPathPosix: string | null;
|
|
5
|
+
boundaryFileRel: string | null;
|
|
6
|
+
};
|
|
7
|
+
export declare function buildContextPack(input: {
|
|
8
|
+
rootAbs: string;
|
|
9
|
+
targetId: string;
|
|
10
|
+
targetPathPosix: string;
|
|
11
|
+
boundary: Boundary;
|
|
12
|
+
inferred: {
|
|
13
|
+
runner: string;
|
|
14
|
+
command: string | null;
|
|
15
|
+
source: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
};
|
|
18
|
+
observed: {
|
|
19
|
+
runner: string;
|
|
20
|
+
hints: {
|
|
21
|
+
failingFiles: string[];
|
|
22
|
+
failingTests: string[];
|
|
23
|
+
};
|
|
24
|
+
} | null;
|
|
25
|
+
budgets: ContextBudgets;
|
|
26
|
+
nowMs: () => number;
|
|
27
|
+
readFileText: (absPath: string) => Promise<string>;
|
|
28
|
+
listIndexFiles?: () => Promise<string[]>;
|
|
29
|
+
redact: (s: string) => string;
|
|
30
|
+
}): Promise<ContextPack>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
function toPosix(p) {
|
|
4
|
+
return p.replace(/\\/g, '/');
|
|
5
|
+
}
|
|
6
|
+
function normalizeRelPosix(p) {
|
|
7
|
+
let x = toPosix(p).trim();
|
|
8
|
+
if (x.startsWith('./'))
|
|
9
|
+
x = x.slice(2);
|
|
10
|
+
x = path.posix.normalize(x);
|
|
11
|
+
if (x === '.')
|
|
12
|
+
x = '';
|
|
13
|
+
return x;
|
|
14
|
+
}
|
|
15
|
+
function uniqSorted(xs) {
|
|
16
|
+
return [...new Set(xs.map((x) => x.trim()).filter(Boolean))].sort((a, b) => a.localeCompare(b));
|
|
17
|
+
}
|
|
18
|
+
function sha256_8(text) {
|
|
19
|
+
return crypto.createHash('sha256').update(text).digest('hex').slice(0, 8);
|
|
20
|
+
}
|
|
21
|
+
function sanitizeText(text) {
|
|
22
|
+
// Replace null bytes and other control chars with spaces (deterministic).
|
|
23
|
+
return text.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, ' ');
|
|
24
|
+
}
|
|
25
|
+
function isInsideRoot(rootAbs, absPath) {
|
|
26
|
+
const rel = path.relative(rootAbs, absPath);
|
|
27
|
+
if (!rel)
|
|
28
|
+
return true;
|
|
29
|
+
const norm = rel.replace(/\\/g, '/');
|
|
30
|
+
return !norm.startsWith('../') && norm !== '..';
|
|
31
|
+
}
|
|
32
|
+
function absFromMaybePath(rootAbs, p) {
|
|
33
|
+
const looksAbs = path.isAbsolute(p) || /^[A-Za-z]:[\\/]/.test(p);
|
|
34
|
+
return looksAbs ? path.resolve(p) : path.resolve(rootAbs, p);
|
|
35
|
+
}
|
|
36
|
+
function isSensitivePath(pathPosix) {
|
|
37
|
+
const p = pathPosix.replace(/\\/g, '/');
|
|
38
|
+
const lower = p.toLowerCase();
|
|
39
|
+
const base = path.posix.basename(lower);
|
|
40
|
+
if (base === '.env')
|
|
41
|
+
return true;
|
|
42
|
+
if (base === '.npmrc')
|
|
43
|
+
return true;
|
|
44
|
+
if (base === 'id_rsa')
|
|
45
|
+
return true;
|
|
46
|
+
if (base.endsWith('.pem'))
|
|
47
|
+
return true;
|
|
48
|
+
if (base.endsWith('.key'))
|
|
49
|
+
return true;
|
|
50
|
+
if (lower.includes('secrets'))
|
|
51
|
+
return true;
|
|
52
|
+
if (lower === '.git/config' || lower.endsWith('/.git/config'))
|
|
53
|
+
return true;
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
function kindOrder(k) {
|
|
57
|
+
switch (k) {
|
|
58
|
+
case 'target':
|
|
59
|
+
return 0;
|
|
60
|
+
case 'test':
|
|
61
|
+
return 1;
|
|
62
|
+
case 'neighbor':
|
|
63
|
+
return 2;
|
|
64
|
+
case 'config':
|
|
65
|
+
return 3;
|
|
66
|
+
case 'readme':
|
|
67
|
+
return 4;
|
|
68
|
+
default:
|
|
69
|
+
return 5;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function extractRelativeImportsJsTs(source) {
|
|
73
|
+
const out = [];
|
|
74
|
+
// import ... from '...'
|
|
75
|
+
for (const m of source.matchAll(/\bimport\s+[^;]*?\s+from\s+['"]([^'"]+)['"]/g)) {
|
|
76
|
+
const spec = m[1] ?? '';
|
|
77
|
+
if (spec.startsWith('.'))
|
|
78
|
+
out.push(spec);
|
|
79
|
+
}
|
|
80
|
+
// require('...')
|
|
81
|
+
for (const m of source.matchAll(/\brequire\(\s*['"]([^'"]+)['"]\s*\)/g)) {
|
|
82
|
+
const spec = m[1] ?? '';
|
|
83
|
+
if (spec.startsWith('.'))
|
|
84
|
+
out.push(spec);
|
|
85
|
+
}
|
|
86
|
+
return uniqSorted(out);
|
|
87
|
+
}
|
|
88
|
+
const RESOLVE_EXTS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json'];
|
|
89
|
+
async function resolveRelativeImport(opts) {
|
|
90
|
+
const fromDir = path.posix.dirname(opts.fromFilePosix);
|
|
91
|
+
const specPosix = toPosix(opts.spec);
|
|
92
|
+
const joined = normalizeRelPosix(path.posix.join(fromDir, specPosix));
|
|
93
|
+
if (!joined)
|
|
94
|
+
return null;
|
|
95
|
+
const hasExt = path.posix.extname(joined) !== '';
|
|
96
|
+
const candidates = [];
|
|
97
|
+
if (hasExt)
|
|
98
|
+
candidates.push(joined);
|
|
99
|
+
else
|
|
100
|
+
for (const ext of RESOLVE_EXTS)
|
|
101
|
+
candidates.push(`${joined}${ext}`);
|
|
102
|
+
for (const rel of candidates) {
|
|
103
|
+
// Never traverse node_modules (defensive; relative paths shouldn’t hit it, but keep safe).
|
|
104
|
+
if (rel.split('/').includes('node_modules'))
|
|
105
|
+
continue;
|
|
106
|
+
const abs = path.resolve(opts.rootAbs, ...rel.split('/'));
|
|
107
|
+
if (!isInsideRoot(opts.rootAbs, abs))
|
|
108
|
+
continue;
|
|
109
|
+
const text = await opts.readTextCached(abs);
|
|
110
|
+
if (text != null)
|
|
111
|
+
return rel;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function pickNearestTestsFromIndex(opts) {
|
|
116
|
+
const targetDir = path.posix.dirname(opts.targetPathPosix);
|
|
117
|
+
const prefix = targetDir === '.' ? '' : `${targetDir.replace(/\/+$/, '')}/`;
|
|
118
|
+
const isTest = (p) => p.includes('__tests__/') || /\.[Tt]est\./.test(p);
|
|
119
|
+
const candidates = opts.indexPaths
|
|
120
|
+
.map((p) => normalizeRelPosix(p))
|
|
121
|
+
.filter((p) => (prefix ? p.startsWith(prefix) : true))
|
|
122
|
+
.filter(isTest);
|
|
123
|
+
const depth = (p) => p.split('/').filter(Boolean).length;
|
|
124
|
+
const baseDepth = prefix ? depth(prefix) : 0;
|
|
125
|
+
candidates.sort((a, b) => {
|
|
126
|
+
const da = Math.max(0, depth(a) - baseDepth);
|
|
127
|
+
const db = Math.max(0, depth(b) - baseDepth);
|
|
128
|
+
if (da !== db)
|
|
129
|
+
return da - db;
|
|
130
|
+
return a.localeCompare(b);
|
|
131
|
+
});
|
|
132
|
+
return candidates.slice(0, Math.max(0, opts.max));
|
|
133
|
+
}
|
|
134
|
+
export async function buildContextPack(input) {
|
|
135
|
+
const rootAbs = path.resolve(input.rootAbs);
|
|
136
|
+
const budgets = {
|
|
137
|
+
maxFiles: Math.max(1, Math.trunc(input.budgets.maxFiles)),
|
|
138
|
+
maxChars: Math.max(1, Math.trunc(input.budgets.maxChars)),
|
|
139
|
+
maxDepth: Math.max(0, Math.trunc(input.budgets.maxDepth)),
|
|
140
|
+
maxFileChars: Math.max(1, Math.trunc(input.budgets.maxFileChars)),
|
|
141
|
+
};
|
|
142
|
+
const warnings = [];
|
|
143
|
+
let charsUsed = 0;
|
|
144
|
+
let hitMaxFiles = false;
|
|
145
|
+
let hitMaxChars = false;
|
|
146
|
+
// Cache reads to avoid double I/O and keep deterministic behavior.
|
|
147
|
+
const readCache = new Map();
|
|
148
|
+
const readTextCached = async (abs) => {
|
|
149
|
+
const key = path.resolve(abs);
|
|
150
|
+
const existing = readCache.get(key);
|
|
151
|
+
if (existing)
|
|
152
|
+
return existing;
|
|
153
|
+
const p = (async () => {
|
|
154
|
+
try {
|
|
155
|
+
const t = await input.readFileText(key);
|
|
156
|
+
return t;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
})();
|
|
162
|
+
readCache.set(key, p);
|
|
163
|
+
return p;
|
|
164
|
+
};
|
|
165
|
+
const included = new Map(); // pathPosix -> file
|
|
166
|
+
const includeFile = async (pathPosixRaw, kind) => {
|
|
167
|
+
const pathPosix = normalizeRelPosix(pathPosixRaw);
|
|
168
|
+
if (!pathPosix)
|
|
169
|
+
return;
|
|
170
|
+
if (included.has(pathPosix))
|
|
171
|
+
return;
|
|
172
|
+
if (isSensitivePath(pathPosix)) {
|
|
173
|
+
warnings.push(`deny_sensitive:${pathPosix}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (included.size >= budgets.maxFiles) {
|
|
177
|
+
hitMaxFiles = true;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const abs = path.resolve(rootAbs, ...pathPosix.split('/'));
|
|
181
|
+
if (!isInsideRoot(rootAbs, abs))
|
|
182
|
+
return;
|
|
183
|
+
const raw = await readTextCached(abs);
|
|
184
|
+
if (raw == null)
|
|
185
|
+
return;
|
|
186
|
+
let content = input.redact(sanitizeText(raw));
|
|
187
|
+
let truncated = false;
|
|
188
|
+
if (content.length > budgets.maxFileChars) {
|
|
189
|
+
content = content.slice(0, budgets.maxFileChars);
|
|
190
|
+
truncated = true;
|
|
191
|
+
warnings.push(`file_truncated:${pathPosix}`);
|
|
192
|
+
}
|
|
193
|
+
const remaining = budgets.maxChars - charsUsed;
|
|
194
|
+
if (remaining <= 0) {
|
|
195
|
+
hitMaxChars = true;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (content.length > remaining) {
|
|
199
|
+
content = content.slice(0, remaining);
|
|
200
|
+
truncated = true;
|
|
201
|
+
hitMaxChars = true;
|
|
202
|
+
warnings.push(`file_truncated:${pathPosix}`);
|
|
203
|
+
}
|
|
204
|
+
charsUsed += content.length;
|
|
205
|
+
included.set(pathPosix, {
|
|
206
|
+
pathPosix,
|
|
207
|
+
kind,
|
|
208
|
+
sha256_8: sha256_8(content),
|
|
209
|
+
truncated,
|
|
210
|
+
content,
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
// 1) Always include target
|
|
214
|
+
await includeFile(input.targetPathPosix, 'target');
|
|
215
|
+
// 2) Related tests
|
|
216
|
+
const observedHints = input.observed?.hints ?? null;
|
|
217
|
+
if (observedHints && observedHints.failingFiles.length > 0) {
|
|
218
|
+
const candidates = uniqSorted(observedHints.failingFiles);
|
|
219
|
+
for (const p of candidates) {
|
|
220
|
+
const abs = absFromMaybePath(rootAbs, p);
|
|
221
|
+
if (!isInsideRoot(rootAbs, abs))
|
|
222
|
+
continue;
|
|
223
|
+
const rel = normalizeRelPosix(toPosix(path.relative(rootAbs, abs)));
|
|
224
|
+
if (!rel)
|
|
225
|
+
continue;
|
|
226
|
+
await includeFile(rel, 'test');
|
|
227
|
+
if (included.size >= budgets.maxFiles)
|
|
228
|
+
break;
|
|
229
|
+
if (charsUsed >= budgets.maxChars)
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (input.listIndexFiles) {
|
|
234
|
+
try {
|
|
235
|
+
const indexFiles = await input.listIndexFiles();
|
|
236
|
+
const nearest = pickNearestTestsFromIndex({ targetPathPosix: input.targetPathPosix, indexPaths: indexFiles, max: 3 });
|
|
237
|
+
for (const p of nearest) {
|
|
238
|
+
await includeFile(p, 'test');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// ignore: optional signal
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// 3) Minimal repo config files
|
|
246
|
+
const boundaryRootPosix = input.boundary.rootPathPosix ? normalizeRelPosix(input.boundary.rootPathPosix) : '';
|
|
247
|
+
const boundaryAbs = boundaryRootPosix ? path.resolve(rootAbs, ...boundaryRootPosix.split('/')) : rootAbs;
|
|
248
|
+
const configCandidates = [];
|
|
249
|
+
configCandidates.push('package.json', 'tsconfig.json');
|
|
250
|
+
configCandidates.push('jest.config.js', 'jest.config.ts', 'jest.config.cjs', 'jest.config.mjs');
|
|
251
|
+
configCandidates.push('vitest.config.js', 'vitest.config.ts', 'vitest.config.cjs', 'vitest.config.mjs');
|
|
252
|
+
if (input.boundary.kind === 'py')
|
|
253
|
+
configCandidates.push('pyproject.toml', 'pytest.ini', 'setup.cfg');
|
|
254
|
+
for (const name of configCandidates) {
|
|
255
|
+
const abs = path.resolve(boundaryAbs, name);
|
|
256
|
+
if (!isInsideRoot(rootAbs, abs))
|
|
257
|
+
continue;
|
|
258
|
+
const rel = normalizeRelPosix(toPosix(path.relative(rootAbs, abs)));
|
|
259
|
+
await includeFile(rel, 'config');
|
|
260
|
+
}
|
|
261
|
+
// 4) README at boundary root
|
|
262
|
+
{
|
|
263
|
+
const abs = path.resolve(boundaryAbs, 'README.md');
|
|
264
|
+
const rel = normalizeRelPosix(toPosix(path.relative(rootAbs, abs)));
|
|
265
|
+
await includeFile(rel, 'readme');
|
|
266
|
+
}
|
|
267
|
+
// 5) Neighbor imports (JS/TS only), BFS up to maxDepth
|
|
268
|
+
const targetExt = path.posix.extname(normalizeRelPosix(input.targetPathPosix)).toLowerCase();
|
|
269
|
+
const canTraverse = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'].includes(targetExt);
|
|
270
|
+
if (canTraverse && budgets.maxDepth > 0) {
|
|
271
|
+
const seen = new Set();
|
|
272
|
+
let frontier = [normalizeRelPosix(input.targetPathPosix)];
|
|
273
|
+
seen.add(frontier[0] ?? '');
|
|
274
|
+
for (let depth = 1; depth <= budgets.maxDepth; depth++) {
|
|
275
|
+
const next = [];
|
|
276
|
+
frontier.sort((a, b) => a.localeCompare(b));
|
|
277
|
+
for (const filePosix of frontier) {
|
|
278
|
+
const abs = path.resolve(rootAbs, ...filePosix.split('/'));
|
|
279
|
+
const raw = await readTextCached(abs);
|
|
280
|
+
if (raw == null)
|
|
281
|
+
continue;
|
|
282
|
+
const textForParse = input.redact(sanitizeText(raw)).slice(0, budgets.maxFileChars);
|
|
283
|
+
const relImports = extractRelativeImportsJsTs(textForParse);
|
|
284
|
+
for (const spec of relImports) {
|
|
285
|
+
const resolved = await resolveRelativeImport({
|
|
286
|
+
fromFilePosix: filePosix,
|
|
287
|
+
spec,
|
|
288
|
+
rootAbs,
|
|
289
|
+
readTextCached,
|
|
290
|
+
});
|
|
291
|
+
if (!resolved)
|
|
292
|
+
continue;
|
|
293
|
+
if (seen.has(resolved))
|
|
294
|
+
continue;
|
|
295
|
+
seen.add(resolved);
|
|
296
|
+
next.push(resolved);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const uniqNext = uniqSorted(next);
|
|
300
|
+
for (const p of uniqNext) {
|
|
301
|
+
await includeFile(p, 'neighbor');
|
|
302
|
+
}
|
|
303
|
+
frontier = uniqNext;
|
|
304
|
+
if (included.size >= budgets.maxFiles)
|
|
305
|
+
break;
|
|
306
|
+
if (charsUsed >= budgets.maxChars)
|
|
307
|
+
break;
|
|
308
|
+
if (frontier.length === 0)
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (hitMaxFiles)
|
|
313
|
+
warnings.push('budget_hit_maxFiles');
|
|
314
|
+
if (hitMaxChars)
|
|
315
|
+
warnings.push('budget_hit_maxChars');
|
|
316
|
+
const files = [...included.values()].sort((a, b) => {
|
|
317
|
+
const ka = kindOrder(a.kind);
|
|
318
|
+
const kb = kindOrder(b.kind);
|
|
319
|
+
if (ka !== kb)
|
|
320
|
+
return ka - kb;
|
|
321
|
+
return a.pathPosix.localeCompare(b.pathPosix);
|
|
322
|
+
});
|
|
323
|
+
return {
|
|
324
|
+
schemaVersion: 1,
|
|
325
|
+
createdAtMs: Math.trunc(input.nowMs()),
|
|
326
|
+
rootPathPosix: input.boundary.rootPathPosix ? normalizeRelPosix(input.boundary.rootPathPosix) : null,
|
|
327
|
+
targetId: input.targetId,
|
|
328
|
+
targetPathPosix: normalizeRelPosix(input.targetPathPosix),
|
|
329
|
+
boundary: input.boundary,
|
|
330
|
+
runnerInferred: input.inferred.runner,
|
|
331
|
+
runnerObserved: input.observed?.runner ?? null,
|
|
332
|
+
testCommandUsed: input.inferred.command,
|
|
333
|
+
budgets,
|
|
334
|
+
usage: {
|
|
335
|
+
filesUsed: files.length,
|
|
336
|
+
charsUsed,
|
|
337
|
+
hitMaxFiles,
|
|
338
|
+
hitMaxChars,
|
|
339
|
+
},
|
|
340
|
+
hints: observedHints ? { failingFiles: uniqSorted(observedHints.failingFiles), failingTests: uniqSorted(observedHints.failingTests) } : null,
|
|
341
|
+
files,
|
|
342
|
+
warnings: uniqSorted(warnings),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=packer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packer.js","sourceRoot":"","sources":["../../../src/core/context/packer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type ContextBudgets = {
|
|
2
|
+
maxFiles: number;
|
|
3
|
+
maxChars: number;
|
|
4
|
+
maxDepth: number;
|
|
5
|
+
maxFileChars: number;
|
|
6
|
+
};
|
|
7
|
+
export type ContextFile = {
|
|
8
|
+
pathPosix: string;
|
|
9
|
+
kind: 'target' | 'test' | 'neighbor' | 'config' | 'readme' | 'other';
|
|
10
|
+
sha256_8: string;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
content: string;
|
|
13
|
+
};
|
|
14
|
+
export type ContextPack = {
|
|
15
|
+
schemaVersion: 1;
|
|
16
|
+
createdAtMs: number;
|
|
17
|
+
rootPathPosix: string | null;
|
|
18
|
+
targetId: string;
|
|
19
|
+
targetPathPosix: string;
|
|
20
|
+
boundary: {
|
|
21
|
+
kind: 'js' | 'py' | 'unknown';
|
|
22
|
+
rootPathPosix: string | null;
|
|
23
|
+
boundaryFileRel: string | null;
|
|
24
|
+
};
|
|
25
|
+
runnerInferred: string;
|
|
26
|
+
runnerObserved: string | null;
|
|
27
|
+
testCommandUsed: string | null;
|
|
28
|
+
budgets: ContextBudgets;
|
|
29
|
+
usage: {
|
|
30
|
+
filesUsed: number;
|
|
31
|
+
charsUsed: number;
|
|
32
|
+
hitMaxFiles: boolean;
|
|
33
|
+
hitMaxChars: boolean;
|
|
34
|
+
};
|
|
35
|
+
hints: {
|
|
36
|
+
failingFiles: string[];
|
|
37
|
+
failingTests: string[];
|
|
38
|
+
} | null;
|
|
39
|
+
files: ContextFile[];
|
|
40
|
+
warnings: string[];
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/context/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { JestFailure } from '../jest/parser.js';
|
|
2
|
+
import type { ConvergeReport } from './types.js';
|
|
3
|
+
export type ConvergeRunnerResult = {
|
|
4
|
+
exitCode: number | null;
|
|
5
|
+
timedOut: boolean;
|
|
6
|
+
durationMs: number;
|
|
7
|
+
output: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function runConvergeLoop(opts: {
|
|
10
|
+
maxIterations: number;
|
|
11
|
+
runOnce: (attempt: number) => Promise<ConvergeRunnerResult>;
|
|
12
|
+
parseFailures: (output: string) => JestFailure[];
|
|
13
|
+
}): Promise<ConvergeReport>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export async function runConvergeLoop(opts) {
|
|
2
|
+
const maxIterations = Math.max(1, Math.trunc(opts.maxIterations));
|
|
3
|
+
const attempts = [];
|
|
4
|
+
let stopReason = 'max_iterations';
|
|
5
|
+
for (let attempt = 1; attempt <= maxIterations; attempt++) {
|
|
6
|
+
const r = await opts.runOnce(attempt);
|
|
7
|
+
const failures = opts.parseFailures(r.output);
|
|
8
|
+
attempts.push({
|
|
9
|
+
attempt,
|
|
10
|
+
exitCode: r.exitCode,
|
|
11
|
+
timedOut: r.timedOut,
|
|
12
|
+
durationMs: r.durationMs,
|
|
13
|
+
failures,
|
|
14
|
+
});
|
|
15
|
+
if (r.exitCode === 0) {
|
|
16
|
+
stopReason = 'passed';
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
if (r.timedOut) {
|
|
20
|
+
stopReason = 'timeout';
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
if (r.exitCode === null) {
|
|
24
|
+
stopReason = 'runner_error';
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (attempt === maxIterations) {
|
|
28
|
+
stopReason = 'max_iterations';
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
// MVP: no codegen or plan changes; just framework + reporting.
|
|
32
|
+
}
|
|
33
|
+
return { schemaVersion: 1, maxIterations, stopReason, attempts };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/converge/loop.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAIrC;IACC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAsB,EAAE,CAAC;IAEvC,IAAI,UAAU,GAAuB,gBAAgB,CAAC;IAEtD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC;QAC1D,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE9C,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO;YACP,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,QAAQ;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACrB,UAAU,GAAG,QAAQ,CAAC;YACtB,MAAM;QACR,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACf,UAAU,GAAG,SAAS,CAAC;YACvB,MAAM;QACR,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACxB,UAAU,GAAG,cAAc,CAAC;YAC5B,MAAM;QACR,CAAC;QACD,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC9B,UAAU,GAAG,gBAAgB,CAAC;YAC9B,MAAM;QACR,CAAC;QACD,+DAA+D;IACjE,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JestFailure } from '../jest/parser.js';
|
|
2
|
+
export type ConvergeStopReason = 'passed' | 'max_iterations' | 'timeout' | 'runner_error';
|
|
3
|
+
export type ConvergeAttempt = {
|
|
4
|
+
attempt: number;
|
|
5
|
+
exitCode: number | null;
|
|
6
|
+
timedOut: boolean;
|
|
7
|
+
durationMs: number;
|
|
8
|
+
failures: JestFailure[];
|
|
9
|
+
};
|
|
10
|
+
export type ConvergeReport = {
|
|
11
|
+
schemaVersion: 1;
|
|
12
|
+
maxIterations: number;
|
|
13
|
+
stopReason: ConvergeStopReason;
|
|
14
|
+
attempts: ConvergeAttempt[];
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/converge/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified diff parsing and application for LLM-generated test patches.
|
|
3
|
+
* Deterministic, fail-closed: rejects invalid, unsafe, or out-of-scope patches.
|
|
4
|
+
*/
|
|
5
|
+
export declare function toPosix(p: string): string;
|
|
6
|
+
export declare function isAllowedTestPathForRunner(runner: string, pathPosix: string): boolean;
|
|
7
|
+
export declare function isAllowedFixturePath(pathPosix: string): boolean;
|
|
8
|
+
export declare function applyUnifiedDiffToTestFiles(opts: {
|
|
9
|
+
rootAbs: string;
|
|
10
|
+
boundaryRootPosix: string | null;
|
|
11
|
+
runner: string;
|
|
12
|
+
diffText: string;
|
|
13
|
+
tuning: {
|
|
14
|
+
minTestCases: number;
|
|
15
|
+
maxTestCases: number;
|
|
16
|
+
minExpectCalls: number;
|
|
17
|
+
};
|
|
18
|
+
targetExportNames: readonly string[];
|
|
19
|
+
targetModuleStem: string;
|
|
20
|
+
targetSource?: string | null;
|
|
21
|
+
}): {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
warnings: string[];
|
|
24
|
+
pathsPosix: string[];
|
|
25
|
+
createdPathsPosix: string[];
|
|
26
|
+
};
|