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.
Files changed (159) hide show
  1. package/LICENSE.md +0 -0
  2. package/README.md +143 -0
  3. package/dist/adapters/git.d.ts +28 -0
  4. package/dist/adapters/git.js +112 -0
  5. package/dist/adapters/git.js.map +1 -0
  6. package/dist/adapters/github.d.ts +71 -0
  7. package/dist/adapters/github.js +194 -0
  8. package/dist/adapters/github.js.map +1 -0
  9. package/dist/cli.d.ts +47 -0
  10. package/dist/cli.js +201 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/context.d.ts +2 -0
  13. package/dist/commands/context.js +275 -0
  14. package/dist/commands/context.js.map +1 -0
  15. package/dist/commands/full.d.ts +13 -0
  16. package/dist/commands/full.js +590 -0
  17. package/dist/commands/full.js.map +1 -0
  18. package/dist/commands/gen_test.d.ts +2 -0
  19. package/dist/commands/gen_test.js +94 -0
  20. package/dist/commands/gen_test.js.map +1 -0
  21. package/dist/commands/index.d.ts +2 -0
  22. package/dist/commands/index.js +62 -0
  23. package/dist/commands/index.js.map +1 -0
  24. package/dist/commands/plan.d.ts +2 -0
  25. package/dist/commands/plan.js +107 -0
  26. package/dist/commands/plan.js.map +1 -0
  27. package/dist/commands/pr.d.ts +9 -0
  28. package/dist/commands/pr.js +400 -0
  29. package/dist/commands/pr.js.map +1 -0
  30. package/dist/commands/pr_list.d.ts +2 -0
  31. package/dist/commands/pr_list.js +158 -0
  32. package/dist/commands/pr_list.js.map +1 -0
  33. package/dist/commands/status.d.ts +6 -0
  34. package/dist/commands/status.js +132 -0
  35. package/dist/commands/status.js.map +1 -0
  36. package/dist/commands/test.d.ts +2 -0
  37. package/dist/commands/test.js +143 -0
  38. package/dist/commands/test.js.map +1 -0
  39. package/dist/commands/testability.d.ts +10 -0
  40. package/dist/commands/testability.js +406 -0
  41. package/dist/commands/testability.js.map +1 -0
  42. package/dist/commands/tests.d.ts +9 -0
  43. package/dist/commands/tests.js +801 -0
  44. package/dist/commands/tests.js.map +1 -0
  45. package/dist/core/code/exports.d.ts +5 -0
  46. package/dist/core/code/exports.js +68 -0
  47. package/dist/core/code/exports.js.map +1 -0
  48. package/dist/core/config/forkPolicy.d.ts +25 -0
  49. package/dist/core/config/forkPolicy.js +35 -0
  50. package/dist/core/config/forkPolicy.js.map +1 -0
  51. package/dist/core/config/load.d.ts +13 -0
  52. package/dist/core/config/load.js +35 -0
  53. package/dist/core/config/load.js.map +1 -0
  54. package/dist/core/config/types.d.ts +87 -0
  55. package/dist/core/config/types.js +2 -0
  56. package/dist/core/config/types.js.map +1 -0
  57. package/dist/core/config/validate.d.ts +4 -0
  58. package/dist/core/config/validate.js +246 -0
  59. package/dist/core/config/validate.js.map +1 -0
  60. package/dist/core/context/packer.d.ts +31 -0
  61. package/dist/core/context/packer.js +345 -0
  62. package/dist/core/context/packer.js.map +1 -0
  63. package/dist/core/context/types.d.ts +41 -0
  64. package/dist/core/context/types.js +2 -0
  65. package/dist/core/context/types.js.map +1 -0
  66. package/dist/core/converge/loop.d.ts +13 -0
  67. package/dist/core/converge/loop.js +35 -0
  68. package/dist/core/converge/loop.js.map +1 -0
  69. package/dist/core/converge/types.d.ts +15 -0
  70. package/dist/core/converge/types.js +2 -0
  71. package/dist/core/converge/types.js.map +1 -0
  72. package/dist/core/generator/llm/diffApply.d.ts +26 -0
  73. package/dist/core/generator/llm/diffApply.js +276 -0
  74. package/dist/core/generator/llm/diffApply.js.map +1 -0
  75. package/dist/core/generator/llm/qualityGate.d.ts +34 -0
  76. package/dist/core/generator/llm/qualityGate.js +324 -0
  77. package/dist/core/generator/llm/qualityGate.js.map +1 -0
  78. package/dist/core/generator/llmGenerator.d.ts +34 -0
  79. package/dist/core/generator/llmGenerator.js +245 -0
  80. package/dist/core/generator/llmGenerator.js.map +1 -0
  81. package/dist/core/generator/quality.d.ts +17 -0
  82. package/dist/core/generator/quality.js +31 -0
  83. package/dist/core/generator/quality.js.map +1 -0
  84. package/dist/core/generator/registry.d.ts +26 -0
  85. package/dist/core/generator/registry.js +29 -0
  86. package/dist/core/generator/registry.js.map +1 -0
  87. package/dist/core/generator/smokeGenerator.d.ts +11 -0
  88. package/dist/core/generator/smokeGenerator.js +27 -0
  89. package/dist/core/generator/smokeGenerator.js.map +1 -0
  90. package/dist/core/generator/types.d.ts +48 -0
  91. package/dist/core/generator/types.js +2 -0
  92. package/dist/core/generator/types.js.map +1 -0
  93. package/dist/core/index/indexer.d.ts +29 -0
  94. package/dist/core/index/indexer.js +167 -0
  95. package/dist/core/index/indexer.js.map +1 -0
  96. package/dist/core/jest/parser.d.ts +17 -0
  97. package/dist/core/jest/parser.js +90 -0
  98. package/dist/core/jest/parser.js.map +1 -0
  99. package/dist/core/llm/provider.d.ts +55 -0
  100. package/dist/core/llm/provider.js +105 -0
  101. package/dist/core/llm/provider.js.map +1 -0
  102. package/dist/core/logger.d.ts +19 -0
  103. package/dist/core/logger.js +44 -0
  104. package/dist/core/logger.js.map +1 -0
  105. package/dist/core/plan/planner.d.ts +16 -0
  106. package/dist/core/plan/planner.js +91 -0
  107. package/dist/core/plan/planner.js.map +1 -0
  108. package/dist/core/process/exec.d.ts +22 -0
  109. package/dist/core/process/exec.js +83 -0
  110. package/dist/core/process/exec.js.map +1 -0
  111. package/dist/core/redact.d.ts +6 -0
  112. package/dist/core/redact.js +49 -0
  113. package/dist/core/redact.js.map +1 -0
  114. package/dist/core/repo/boundary.d.ts +10 -0
  115. package/dist/core/repo/boundary.js +58 -0
  116. package/dist/core/repo/boundary.js.map +1 -0
  117. package/dist/core/stableJson.d.ts +1 -0
  118. package/dist/core/stableJson.js +32 -0
  119. package/dist/core/stableJson.js.map +1 -0
  120. package/dist/core/state/policy.d.ts +20 -0
  121. package/dist/core/state/policy.js +51 -0
  122. package/dist/core/state/policy.js.map +1 -0
  123. package/dist/core/state/state.d.ts +67 -0
  124. package/dist/core/state/state.js +142 -0
  125. package/dist/core/state/state.js.map +1 -0
  126. package/dist/core/state/storage.d.ts +9 -0
  127. package/dist/core/state/storage.js +25 -0
  128. package/dist/core/state/storage.js.map +1 -0
  129. package/dist/core/targets/resolve.d.ts +28 -0
  130. package/dist/core/targets/resolve.js +96 -0
  131. package/dist/core/targets/resolve.js.map +1 -0
  132. package/dist/core/testGenerator/conventions.d.ts +7 -0
  133. package/dist/core/testGenerator/conventions.js +29 -0
  134. package/dist/core/testGenerator/conventions.js.map +1 -0
  135. package/dist/core/testGenerator/generate.d.ts +35 -0
  136. package/dist/core/testGenerator/generate.js +127 -0
  137. package/dist/core/testGenerator/generate.js.map +1 -0
  138. package/dist/core/testRunner/hints.d.ts +12 -0
  139. package/dist/core/testRunner/hints.js +133 -0
  140. package/dist/core/testRunner/hints.js.map +1 -0
  141. package/dist/core/testRunner/infer.d.ts +24 -0
  142. package/dist/core/testRunner/infer.js +65 -0
  143. package/dist/core/testRunner/infer.js.map +1 -0
  144. package/dist/core/testRunner/resolve.d.ts +12 -0
  145. package/dist/core/testRunner/resolve.js +31 -0
  146. package/dist/core/testRunner/resolve.js.map +1 -0
  147. package/dist/core/testRunner/runner.d.ts +24 -0
  148. package/dist/core/testRunner/runner.js +145 -0
  149. package/dist/core/testRunner/runner.js.map +1 -0
  150. package/dist/core/testability/heuristics.d.ts +7 -0
  151. package/dist/core/testability/heuristics.js +35 -0
  152. package/dist/core/testability/heuristics.js.map +1 -0
  153. package/dist/core/tests/fixers.d.ts +14 -0
  154. package/dist/core/tests/fixers.js +59 -0
  155. package/dist/core/tests/fixers.js.map +1 -0
  156. package/dist/core/tests/types.d.ts +98 -0
  157. package/dist/core/tests/types.js +2 -0
  158. package/dist/core/tests/types.js.map +1 -0
  159. package/package.json +55 -0
@@ -0,0 +1,167 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import ignore from 'ignore';
4
+ import { stableStringify } from '../stableJson.js';
5
+ const DENY_DIRS = new Set([
6
+ '.git',
7
+ '.test-agent',
8
+ 'node_modules',
9
+ 'dist',
10
+ 'build',
11
+ ]);
12
+ function toPosix(p) {
13
+ return p.split(path.sep).join('/');
14
+ }
15
+ function safeExt(p) {
16
+ const e = path.extname(p);
17
+ return e.startsWith('.') ? e.slice(1) : e;
18
+ }
19
+ function sortNames(names) {
20
+ return [...names].sort((a, b) => a.localeCompare(b));
21
+ }
22
+ function readGitignore(root) {
23
+ const p = path.join(root, '.gitignore');
24
+ if (!fs.existsSync(p))
25
+ return { patterns: [] };
26
+ try {
27
+ const raw = fs.readFileSync(p, 'utf8');
28
+ // Reading `.gitignore` is the only intentional content read in this MVP.
29
+ const lines = raw.split('\n').map((l) => l.trim());
30
+ const patterns = lines.filter((l) => l.length > 0 && !l.startsWith('#'));
31
+ return { patterns };
32
+ }
33
+ catch (e) {
34
+ return { patterns: [], error: `Failed to read .gitignore: ${String(e)}` };
35
+ }
36
+ }
37
+ function detectPackageManager(root) {
38
+ if (fs.existsSync(path.join(root, 'pnpm-lock.yaml')))
39
+ return 'pnpm';
40
+ if (fs.existsSync(path.join(root, 'package-lock.json')))
41
+ return 'npm';
42
+ if (fs.existsSync(path.join(root, 'yarn.lock')))
43
+ return 'yarn';
44
+ const pkgPath = path.join(root, 'package.json');
45
+ try {
46
+ if (fs.existsSync(pkgPath)) {
47
+ const raw = fs.readFileSync(pkgPath, 'utf8');
48
+ const pkg = JSON.parse(raw);
49
+ const pm = pkg.packageManager ?? '';
50
+ if (pm.startsWith('pnpm@'))
51
+ return 'pnpm';
52
+ if (pm.startsWith('npm@'))
53
+ return 'npm';
54
+ if (pm.startsWith('yarn@'))
55
+ return 'yarn';
56
+ }
57
+ }
58
+ catch {
59
+ // ignore; fall through
60
+ }
61
+ return 'unknown';
62
+ }
63
+ function detectJestSignals(root) {
64
+ const hasJestConfigFile = fs.existsSync(path.join(root, 'jest.config.js')) ||
65
+ fs.existsSync(path.join(root, 'jest.config.cjs')) ||
66
+ fs.existsSync(path.join(root, 'jest.config.mjs')) ||
67
+ fs.existsSync(path.join(root, 'jest.config.ts'));
68
+ const pkgPath = path.join(root, 'package.json');
69
+ let hasPackageJsonJestField = false;
70
+ let hasJestDep = false;
71
+ let hasJestInTestScript = false;
72
+ try {
73
+ if (fs.existsSync(pkgPath)) {
74
+ const raw = fs.readFileSync(pkgPath, 'utf8');
75
+ const pkg = JSON.parse(raw);
76
+ hasPackageJsonJestField = pkg.jest !== undefined;
77
+ const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
78
+ hasJestDep =
79
+ typeof deps.jest === 'string' ||
80
+ typeof deps['@jest/core'] === 'string' ||
81
+ typeof deps['ts-jest'] === 'string';
82
+ const testScript = pkg.scripts?.test ?? '';
83
+ hasJestInTestScript = /\bjest\b/.test(testScript);
84
+ }
85
+ }
86
+ catch {
87
+ // ignore parsing errors for MVP; signals remain false
88
+ }
89
+ return { hasJestConfigFile, hasPackageJsonJestField, hasJestDep, hasJestInTestScript };
90
+ }
91
+ export function buildRepoIndex(root) {
92
+ const warnings = [];
93
+ const gi = readGitignore(root);
94
+ if (gi.error)
95
+ warnings.push(gi.error);
96
+ const ig = ignore();
97
+ ig.add(gi.patterns);
98
+ const files = [];
99
+ const walk = (absDir) => {
100
+ const relDir = path.relative(root, absDir);
101
+ const relDirPosix = relDir === '' ? '' : `${toPosix(relDir)}/`;
102
+ let entries;
103
+ try {
104
+ entries = fs.readdirSync(absDir, { withFileTypes: true });
105
+ }
106
+ catch (e) {
107
+ warnings.push(`Failed to read directory ${absDir}: ${String(e)}`);
108
+ return;
109
+ }
110
+ // Deterministic traversal order.
111
+ const sorted = entries.slice().sort((a, b) => a.name.localeCompare(b.name));
112
+ for (const ent of sorted) {
113
+ const name = ent.name;
114
+ if (ent.isDirectory() && DENY_DIRS.has(name))
115
+ continue;
116
+ const relPathPosix = `${relDirPosix}${name}`;
117
+ // ignore() expects POSIX paths.
118
+ if (ig.ignores(relPathPosix))
119
+ continue;
120
+ const absPath = path.join(absDir, name);
121
+ if (ent.isDirectory()) {
122
+ walk(absPath);
123
+ continue;
124
+ }
125
+ if (!ent.isFile())
126
+ continue;
127
+ try {
128
+ const st = fs.statSync(absPath);
129
+ files.push({
130
+ path: relPathPosix,
131
+ ext: safeExt(name),
132
+ size: st.size,
133
+ lastModifiedMs: Math.trunc(st.mtimeMs),
134
+ });
135
+ }
136
+ catch (e) {
137
+ warnings.push(`Failed to stat ${absPath}: ${String(e)}`);
138
+ }
139
+ }
140
+ };
141
+ walk(root);
142
+ // Deterministic ordering.
143
+ files.sort((a, b) => a.path.localeCompare(b.path));
144
+ const signals = {
145
+ packageManager: detectPackageManager(root),
146
+ hasTsconfig: fs.existsSync(path.join(root, 'tsconfig.json')),
147
+ jest: detectJestSignals(root),
148
+ };
149
+ return {
150
+ index: {
151
+ root: '.',
152
+ schemaVersion: 1,
153
+ files,
154
+ signals,
155
+ },
156
+ warnings: sortNames(warnings),
157
+ };
158
+ }
159
+ export function writeRepoIndex(root, index) {
160
+ const outDir = path.join(root, '.test-agent');
161
+ const outPath = path.join(outDir, 'index.json');
162
+ fs.mkdirSync(outDir, { recursive: true });
163
+ // Deterministic output: stable JSON key ordering (and trailing newline).
164
+ fs.writeFileSync(outPath, stableStringify(index) + '\n', 'utf8');
165
+ return { outputPath: outPath };
166
+ }
167
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../../src/core/index/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type JestFailureKind = 'cannot_find_module' | 'typescript_compile_error' | 'expectation_failure' | 'missing_dom_testing_libs';
2
+ export type JestFailure = {
3
+ kind: JestFailureKind;
4
+ summary: string;
5
+ details?: string;
6
+ moduleName?: string;
7
+ suggestedAction?: 'skip_frontend';
8
+ };
9
+ export declare function parseJestOutput(output: string, opts?: {
10
+ maxFindings?: number;
11
+ }): {
12
+ failures: JestFailure[];
13
+ ignored: {
14
+ kind: 'snapshot_mismatch';
15
+ count: number;
16
+ };
17
+ };
@@ -0,0 +1,90 @@
1
+ const DOM_LIB_MODULES = new Set([
2
+ '@testing-library/jest-dom',
3
+ '@testing-library/react',
4
+ '@testing-library/dom',
5
+ 'jsdom',
6
+ ]);
7
+ function isDomLib(moduleName) {
8
+ return DOM_LIB_MODULES.has(moduleName);
9
+ }
10
+ function pushUnique(out, seen, item, max) {
11
+ if (out.length >= max)
12
+ return;
13
+ const key = `${item.kind}|${item.moduleName ?? ''}|${item.summary}`;
14
+ if (seen.has(key))
15
+ return;
16
+ seen.add(key);
17
+ out.push(item);
18
+ }
19
+ export function parseJestOutput(output, opts) {
20
+ const max = opts?.maxFindings ?? 25;
21
+ const failures = [];
22
+ const seen = new Set();
23
+ let snapshotMismatchCount = 0;
24
+ const lines = output.split('\n');
25
+ for (const line of lines) {
26
+ const l = line.trimEnd();
27
+ if (l.length === 0)
28
+ continue;
29
+ // Snapshot mismatch: explicitly ignore for MVP.
30
+ if (/\bSnapshot\b/i.test(l) && /\bmismatch\b/i.test(l)) {
31
+ snapshotMismatchCount++;
32
+ continue;
33
+ }
34
+ if (/^Snapshots:\s+\d+\s+failed/i.test(l)) {
35
+ snapshotMismatchCount++;
36
+ continue;
37
+ }
38
+ // Cannot find module (Jest / Node variants)
39
+ // Examples:
40
+ // Cannot find module 'x' from 'y'
41
+ // Error: Cannot find module 'x'
42
+ const m1 = l.match(/Cannot find module ['"]([^'"]+)['"]/);
43
+ if (m1) {
44
+ const moduleName = m1[1] ?? '';
45
+ if (isDomLib(moduleName)) {
46
+ pushUnique(failures, seen, {
47
+ kind: 'missing_dom_testing_libs',
48
+ summary: `Missing DOM testing dependency: ${moduleName}`,
49
+ moduleName,
50
+ suggestedAction: 'skip_frontend',
51
+ }, max);
52
+ }
53
+ else {
54
+ pushUnique(failures, seen, {
55
+ kind: 'cannot_find_module',
56
+ summary: `Cannot find module: ${moduleName}`,
57
+ moduleName,
58
+ }, max);
59
+ }
60
+ continue;
61
+ }
62
+ // TypeScript compile errors (common patterns)
63
+ // Examples:
64
+ // error TS2307: Cannot find module 'x' or its corresponding type declarations.
65
+ // TS2322: Type '...' is not assignable to type '...'
66
+ if (/\berror TS\d+:/i.test(l) || /\bTS\d+:/i.test(l)) {
67
+ pushUnique(failures, seen, {
68
+ kind: 'typescript_compile_error',
69
+ summary: 'TypeScript compile error',
70
+ details: l.trim(),
71
+ }, max);
72
+ continue;
73
+ }
74
+ // Expectation failures (very basic heuristics)
75
+ // Examples:
76
+ // expect(received).toBe(...)
77
+ // Expected: ...
78
+ // Received: ...
79
+ if (/^\s*expect\(/.test(line) || /^\s*Expected:/i.test(line) || /^\s*Received:/i.test(line)) {
80
+ pushUnique(failures, seen, {
81
+ kind: 'expectation_failure',
82
+ summary: 'Expectation failure',
83
+ details: l.trim(),
84
+ }, max);
85
+ continue;
86
+ }
87
+ }
88
+ return { failures, ignored: { kind: 'snapshot_mismatch', count: snapshotMismatchCount } };
89
+ }
90
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/core/jest/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export type LLMRequest = {
2
+ systemPrompt: string;
3
+ userPrompt: string;
4
+ model: string;
5
+ temperature: number;
6
+ maxTokens: number;
7
+ };
8
+ export type LLMResponse = {
9
+ text: string;
10
+ usage?: {
11
+ promptTokens?: number;
12
+ completionTokens?: number;
13
+ totalTokens?: number;
14
+ };
15
+ warnings?: string[];
16
+ };
17
+ export interface ILLMProvider {
18
+ generate(req: LLMRequest): Promise<LLMResponse>;
19
+ }
20
+ export declare class FakeProvider implements ILLMProvider {
21
+ private readonly texts;
22
+ private readonly warnings;
23
+ private calls;
24
+ constructor(opts: {
25
+ text?: string;
26
+ texts?: string[];
27
+ warnings?: string[];
28
+ });
29
+ generate(_req: LLMRequest): Promise<LLMResponse>;
30
+ }
31
+ type HttpProviderOpts = {
32
+ baseUrl: string | null;
33
+ endpointPath: string;
34
+ apiKeyEnvVar: string;
35
+ env: NodeJS.ProcessEnv;
36
+ timeoutMs: number;
37
+ outputCharCap: number;
38
+ dryRun: boolean;
39
+ logger?: {
40
+ debug: (s: string) => void;
41
+ } | null;
42
+ };
43
+ export declare class HttpProvider implements ILLMProvider {
44
+ private readonly baseUrl;
45
+ private readonly endpointPath;
46
+ private readonly apiKeyEnvVar;
47
+ private readonly env;
48
+ private readonly timeoutMs;
49
+ private readonly outputCharCap;
50
+ private readonly dryRun;
51
+ private readonly logger;
52
+ constructor(opts: HttpProviderOpts);
53
+ generate(req: LLMRequest): Promise<LLMResponse>;
54
+ }
55
+ export {};
@@ -0,0 +1,105 @@
1
+ export class FakeProvider {
2
+ texts;
3
+ warnings;
4
+ calls = 0;
5
+ constructor(opts) {
6
+ const list = Array.isArray(opts.texts) ? opts.texts : opts.text ? [opts.text] : [''];
7
+ this.texts = list;
8
+ this.warnings = opts.warnings ?? [];
9
+ }
10
+ async generate(_req) {
11
+ const idx = Math.min(this.calls, Math.max(0, this.texts.length - 1));
12
+ const text = this.texts[idx] ?? '';
13
+ this.calls++;
14
+ return { text, warnings: this.warnings };
15
+ }
16
+ }
17
+ function normalizeBaseUrl(baseUrl) {
18
+ const b = (baseUrl ?? '').trim();
19
+ return (b || 'https://api.openai.com/v1').replace(/\/+$/, '');
20
+ }
21
+ function joinUrl(baseUrl, endpointPath) {
22
+ const ep = endpointPath.startsWith('/') ? endpointPath : `/${endpointPath}`;
23
+ return `${baseUrl}${ep}`;
24
+ }
25
+ export class HttpProvider {
26
+ baseUrl;
27
+ endpointPath;
28
+ apiKeyEnvVar;
29
+ env;
30
+ timeoutMs;
31
+ outputCharCap;
32
+ dryRun;
33
+ logger;
34
+ constructor(opts) {
35
+ this.baseUrl = normalizeBaseUrl(opts.baseUrl);
36
+ this.endpointPath = opts.endpointPath;
37
+ this.apiKeyEnvVar = opts.apiKeyEnvVar;
38
+ this.env = opts.env;
39
+ this.timeoutMs = Math.max(1, Math.trunc(opts.timeoutMs));
40
+ this.outputCharCap = Math.max(1, Math.trunc(opts.outputCharCap));
41
+ this.dryRun = opts.dryRun;
42
+ this.logger = opts.logger ?? null;
43
+ }
44
+ async generate(req) {
45
+ if (this.dryRun)
46
+ return { text: '', warnings: ['llm_not_enabled'] };
47
+ const key = this.env[this.apiKeyEnvVar];
48
+ if (!key)
49
+ return { text: '', warnings: ['llm_not_enabled', `llm_missing_env:${this.apiKeyEnvVar}`] };
50
+ const url = joinUrl(this.baseUrl, this.endpointPath);
51
+ const controller = new AbortController();
52
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
53
+ timer.unref?.();
54
+ const started = Date.now();
55
+ try {
56
+ const res = await fetch(url, {
57
+ method: 'POST',
58
+ headers: {
59
+ 'content-type': 'application/json',
60
+ authorization: `Bearer ${key}`,
61
+ },
62
+ body: JSON.stringify({
63
+ model: req.model,
64
+ temperature: req.temperature,
65
+ max_tokens: req.maxTokens,
66
+ messages: [
67
+ { role: 'system', content: req.systemPrompt },
68
+ { role: 'user', content: req.userPrompt },
69
+ ],
70
+ }),
71
+ signal: controller.signal,
72
+ });
73
+ const text = await res.text();
74
+ const elapsedMs = Date.now() - started;
75
+ this.logger?.debug?.(`llm:http model=${req.model} elapsedMs=${elapsedMs} status=${res.status} responseChars=${text.length}`);
76
+ if (!res.ok) {
77
+ return { text: '', warnings: ['llm_http_error', `llm_http_status:${res.status}`] };
78
+ }
79
+ let content = '';
80
+ try {
81
+ const data = JSON.parse(text);
82
+ content = data?.choices?.[0]?.message?.content ?? '';
83
+ }
84
+ catch {
85
+ return { text: '', warnings: ['llm_invalid_json'] };
86
+ }
87
+ const warnings = [];
88
+ if (content.length > this.outputCharCap) {
89
+ content = content.slice(0, this.outputCharCap);
90
+ warnings.push('llm_output_truncated');
91
+ }
92
+ return { text: content, warnings };
93
+ }
94
+ catch (e) {
95
+ const msg = String(e);
96
+ if (msg.toLowerCase().includes('abort'))
97
+ return { text: '', warnings: ['llm_timeout'] };
98
+ return { text: '', warnings: ['llm_request_failed'] };
99
+ }
100
+ finally {
101
+ clearTimeout(timer);
102
+ }
103
+ }
104
+ }
105
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/core/llm/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export type Logger = {
3
+ level: LogLevel;
4
+ debug: (message: string) => void;
5
+ info: (message: string) => void;
6
+ warn: (message: string) => void;
7
+ error: (message: string) => void;
8
+ output: (text: string) => void;
9
+ };
10
+ type Writer = (text: string) => void;
11
+ export declare function createLogger(opts?: {
12
+ level?: LogLevel;
13
+ verbose?: boolean;
14
+ stdout?: Writer;
15
+ stderr?: Writer;
16
+ maxLineLen?: number;
17
+ maxLines?: number;
18
+ }): Logger;
19
+ export {};
@@ -0,0 +1,44 @@
1
+ import { redactText, truncateText } from './redact.js';
2
+ const LEVEL_ORDER = {
3
+ debug: 10,
4
+ info: 20,
5
+ warn: 30,
6
+ error: 40,
7
+ };
8
+ function shouldLog(current, msg) {
9
+ return LEVEL_ORDER[msg] >= LEVEL_ORDER[current];
10
+ }
11
+ function formatLine(level, message) {
12
+ // Deterministic: no timestamps, no pid, no random ids.
13
+ return `[${level}] ${message}`;
14
+ }
15
+ function sanitize(text, opts) {
16
+ return truncateText(redactText(text), opts);
17
+ }
18
+ export function createLogger(opts) {
19
+ const stdout = opts?.stdout ?? ((t) => process.stdout.write(`${t}\n`));
20
+ const stderr = opts?.stderr ?? ((t) => process.stderr.write(`${t}\n`));
21
+ const level = opts?.verbose ? 'debug' : (opts?.level ?? 'info');
22
+ const maxLineLen = opts?.maxLineLen ?? 400;
23
+ const maxLines = opts?.maxLines ?? 200;
24
+ const writeLog = (lvl, message) => {
25
+ if (!shouldLog(level, lvl))
26
+ return;
27
+ const clean = sanitize(message, { maxLineLen, maxLines });
28
+ // Warnings/errors to stderr; debug/info to stderr as well to avoid mixing with command output.
29
+ stderr(formatLine(lvl, clean));
30
+ };
31
+ const output = (text) => {
32
+ // Output is still sanitized to avoid accidental leaks from future code paths.
33
+ stdout(sanitize(text, { maxLineLen, maxLines }));
34
+ };
35
+ return {
36
+ level,
37
+ debug: (m) => writeLog('debug', m),
38
+ info: (m) => writeLog('info', m),
39
+ warn: (m) => writeLog('warn', m),
40
+ error: (m) => writeLog('error', m),
41
+ output,
42
+ };
43
+ }
44
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIvD,MAAM,WAAW,GAA6B;IAC5C,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAC;AAcF,SAAS,SAAS,CAAC,OAAiB,EAAE,GAAa;IACjD,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,KAAe,EAAE,OAAe;IAClD,uDAAuD;IACvD,OAAO,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,IAA8C;IAC5E,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAO5B;IACC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAEvE,MAAM,KAAK,GAAa,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,MAAM,CAAC,CAAC;IAC1E,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,GAAG,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,GAAG,CAAC;IAEvC,MAAM,QAAQ,GAAG,CAAC,GAAa,EAAE,OAAe,EAAQ,EAAE;QACxD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC;YAAE,OAAO;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,+FAA+F;QAC/F,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,IAAY,EAAQ,EAAE;QACpC,8EAA8E;QAC9E,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;QACL,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAChC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAClC,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type PlanTarget = {
2
+ id: string;
3
+ paths: string[];
4
+ reasons: string[];
5
+ estimatedRisk: 'low' | 'med' | 'high';
6
+ };
7
+ export type PlanFile = {
8
+ schemaVersion: 1;
9
+ source: {
10
+ indexSchemaVersion: number | null;
11
+ };
12
+ targets: PlanTarget[];
13
+ };
14
+ export declare function buildPlanFromIndex(indexData: unknown, opts?: {
15
+ maxTargets?: number;
16
+ }): PlanFile;
@@ -0,0 +1,91 @@
1
+ import crypto from 'node:crypto';
2
+ function stableIdForPaths(paths) {
3
+ const h = crypto.createHash('sha1').update(paths.join('\n')).digest('hex').slice(0, 8);
4
+ return `t_${h}`;
5
+ }
6
+ function isCodeExt(ext) {
7
+ return ext === 'ts' || ext === 'tsx' || ext === 'js' || ext === 'jsx' || ext === 'py';
8
+ }
9
+ function isTestPath(p) {
10
+ return (p.includes('/__tests__/') ||
11
+ p.startsWith('tests/') ||
12
+ p.endsWith('.test.ts') ||
13
+ p.endsWith('.test.tsx') ||
14
+ p.endsWith('.test.js') ||
15
+ p.endsWith('.test.jsx') ||
16
+ p.endsWith('.spec.ts') ||
17
+ p.endsWith('.spec.tsx') ||
18
+ p.endsWith('.spec.js') ||
19
+ p.endsWith('.spec.jsx'));
20
+ }
21
+ function estimateRisk(sizeBytes) {
22
+ if (sizeBytes <= 5_000)
23
+ return 'low';
24
+ if (sizeBytes <= 20_000)
25
+ return 'med';
26
+ return 'high';
27
+ }
28
+ function possibleTestPaths(modulePath) {
29
+ // modulePath is repo-relative POSIX (from index.json)
30
+ const dot = modulePath.lastIndexOf('.');
31
+ const base = dot === -1 ? modulePath : modulePath.slice(0, dot);
32
+ const ext = dot === -1 ? '' : modulePath.slice(dot); // includes ".ts"
33
+ const candidates = [
34
+ `${base}.test${ext}`,
35
+ `${base}.spec${ext}`,
36
+ ];
37
+ // Also check tests/ and __tests__/ conventions with the same filename.
38
+ const parts = modulePath.split('/');
39
+ const fileName = parts[parts.length - 1] ?? modulePath;
40
+ const dir = parts.slice(0, -1).join('/');
41
+ if (dir) {
42
+ candidates.push(`${dir}/__tests__/${base.split('/').pop()}.test${ext}`);
43
+ candidates.push(`${dir}/__tests__/${fileName.replace(ext, `.test${ext}`)}`);
44
+ }
45
+ candidates.push(`tests/${fileName.replace(ext, `.test${ext}`)}`);
46
+ candidates.push(`tests/${fileName.replace(ext, `.spec${ext}`)}`);
47
+ // Stable ordering
48
+ return [...new Set(candidates)].sort((a, b) => a.localeCompare(b));
49
+ }
50
+ export function buildPlanFromIndex(indexData, opts) {
51
+ const idx = (indexData ?? {});
52
+ const files = (idx.files ?? []).filter((f) => !!f && typeof f.path === 'string');
53
+ const fileSet = new Set(files.map((f) => f.path));
54
+ const candidates = files
55
+ .filter((f) => f.path.startsWith('src/'))
56
+ .filter((f) => isCodeExt(f.ext))
57
+ .filter((f) => !isTestPath(f.path));
58
+ const targets = [];
59
+ for (const f of candidates) {
60
+ const reasons = ['in src/', 'non-test module'];
61
+ const tests = possibleTestPaths(f.path).filter((p) => fileSet.has(p));
62
+ const hasTests = tests.length > 0;
63
+ if (!hasTests)
64
+ reasons.push('no matching test file found');
65
+ else
66
+ reasons.push(`has matching test file(s): ${tests.join(', ')}`);
67
+ const risk = estimateRisk(f.size);
68
+ const id = stableIdForPaths([f.path]);
69
+ // Heuristic ranking: prioritize untested, then lower risk, then path.
70
+ const score = (hasTests ? 0 : 100) +
71
+ (risk === 'low' ? 20 : risk === 'med' ? 10 : 0);
72
+ targets.push({
73
+ target: { id, paths: [f.path], reasons, estimatedRisk: risk },
74
+ score,
75
+ sortKey: f.path,
76
+ });
77
+ }
78
+ targets.sort((a, b) => {
79
+ if (b.score !== a.score)
80
+ return b.score - a.score;
81
+ return a.sortKey.localeCompare(b.sortKey);
82
+ });
83
+ const max = opts?.maxTargets ?? 50;
84
+ const sliced = targets.slice(0, Math.max(0, max)).map((t) => t.target);
85
+ return {
86
+ schemaVersion: 1,
87
+ source: { indexSchemaVersion: typeof idx.schemaVersion === 'number' ? idx.schemaVersion : null },
88
+ targets: sliced,
89
+ };
90
+ }
91
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/core/plan/planner.ts"],"names":[],"mappings":"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"}