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,132 @@
1
+ import { loadConfigFile } from '../core/config/load.js';
2
+ import { validateConfig } from '../core/config/validate.js';
3
+ import { stableStringify } from '../core/stableJson.js';
4
+ import path from 'node:path';
5
+ import { loadOrInitPolicy } from '../core/state/policy.js';
6
+ import { loadOrInitState } from '../core/state/state.js';
7
+ import fs from 'node:fs';
8
+ import { findNearestRepoBoundary } from '../core/repo/boundary.js';
9
+ import { inferTestCommandAndRunner } from '../core/testRunner/infer.js';
10
+ function parseStatusArgs(argv) {
11
+ const errors = [];
12
+ let configPath;
13
+ for (let i = 0; i < argv.length; i++) {
14
+ const a = argv[i] ?? '';
15
+ if (a === '--config' || a === '-c') {
16
+ const v = argv[i + 1];
17
+ if (typeof v !== 'string' || v.trim() === '') {
18
+ errors.push('status: --config requires a path');
19
+ }
20
+ else {
21
+ configPath = v;
22
+ i++;
23
+ }
24
+ continue;
25
+ }
26
+ if (a.startsWith('--config=')) {
27
+ const v = a.slice('--config='.length);
28
+ if (v.trim() === '')
29
+ errors.push('status: --config requires a path');
30
+ else
31
+ configPath = v;
32
+ continue;
33
+ }
34
+ if (a === '--help' || a === '-h') {
35
+ // handled by CLI top-level help for now
36
+ continue;
37
+ }
38
+ errors.push(`status: unknown argument "${a}"`);
39
+ }
40
+ errors.sort((x, y) => x.localeCompare(y));
41
+ const args = {};
42
+ if (configPath !== undefined)
43
+ args.configPath = configPath;
44
+ return { args, errors };
45
+ }
46
+ export function runStatus(argv, io) {
47
+ const parsed = parseStatusArgs(argv);
48
+ if (parsed.errors.length > 0) {
49
+ for (const e of parsed.errors)
50
+ io.err(e);
51
+ return 2;
52
+ }
53
+ const loaded = loadConfigFile(parsed.args.configPath);
54
+ const validated = validateConfig(loaded.data);
55
+ // Store state/policy alongside the chosen config location (or CWD default).
56
+ const repoRoot = path.dirname(loaded.configPath);
57
+ const stateLoaded = loadOrInitState({ root: repoRoot });
58
+ const policyLoaded = loadOrInitPolicy({ root: repoRoot });
59
+ const boundary = findNearestRepoBoundary({ rootAbs: repoRoot, targetPathOrDirAbs: repoRoot });
60
+ const pkgPath = path.join(boundary.packageRootAbs, 'package.json');
61
+ const pkg = boundary.kind === 'js' && fs.existsSync(pkgPath)
62
+ ? JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
63
+ : null;
64
+ const inferred = inferTestCommandAndRunner({
65
+ rootAbs: boundary.packageRootAbs,
66
+ packageJson: pkg,
67
+ pythonBoundary: boundary.kind === 'py' ? { boundaryFileRel: boundary.boundaryFileRel } : null,
68
+ config: { testCommand: validated.resolved.test.command },
69
+ policy: { workingTestCommand: policyLoaded.policy.workingTestCommand },
70
+ });
71
+ const targets = Object.values(stateLoaded.state.scheduledTargets);
72
+ const statusCounts = {
73
+ total: 0,
74
+ none: 0,
75
+ open: 0,
76
+ merged: 0,
77
+ closed: 0,
78
+ };
79
+ for (const t of targets) {
80
+ statusCounts.total++;
81
+ statusCounts[t.status]++;
82
+ }
83
+ const report = {
84
+ command: 'status',
85
+ configPath: loaded.configPath,
86
+ configFileFound: loaded.exists,
87
+ token: {
88
+ envVar: validated.token.envVar,
89
+ present: validated.token.present,
90
+ // Never print the token value.
91
+ },
92
+ missingFields: validated.missingFields,
93
+ errors: [...loaded.errors, ...validated.errors].sort((a, b) => a.localeCompare(b)),
94
+ warnings: [...loaded.warnings, ...validated.warnings].sort((a, b) => a.localeCompare(b)),
95
+ resolvedConfig: validated.resolved,
96
+ state: {
97
+ path: stateLoaded.path,
98
+ schemaVersion: stateLoaded.state.schemaVersion,
99
+ updatedAtMs: stateLoaded.state.updatedAtMs,
100
+ scheduledTargets: statusCounts,
101
+ companionTargets: {
102
+ total: Object.keys(stateLoaded.state.companionTargets).length,
103
+ },
104
+ },
105
+ policy: {
106
+ path: policyLoaded.path,
107
+ schemaVersion: policyLoaded.policy.schemaVersion,
108
+ workingTestCommand: policyLoaded.policy.workingTestCommand,
109
+ allowTestabilityEdits: policyLoaded.policy.allowTestabilityEdits,
110
+ notesCount: policyLoaded.policy.notes.length,
111
+ },
112
+ inferredTest: {
113
+ boundary: {
114
+ kind: boundary.kind,
115
+ boundaryFileRel: boundary.boundaryFileRel,
116
+ packageRootAbs: boundary.packageRootAbs,
117
+ packageRootRel: path.relative(repoRoot, boundary.packageRootAbs).replace(/\\/g, '/'),
118
+ },
119
+ decision: inferred,
120
+ },
121
+ };
122
+ io.out(stableStringify(report));
123
+ if (report.errors.length > 0)
124
+ return 2;
125
+ if (report.missingFields.length > 0)
126
+ return 1;
127
+ return 0;
128
+ }
129
+ export function runStatusWithLogger(argv, logger) {
130
+ return runStatus(argv, { out: (s) => logger.output(s), err: (s) => logger.error(s) });
131
+ }
132
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Logger } from '../core/logger.js';
2
+ export declare function runTestWithLogger(argv: readonly string[], logger: Logger): Promise<number>;
@@ -0,0 +1,143 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { stableStringify } from '../core/stableJson.js';
4
+ import { loadConfigFile } from '../core/config/load.js';
5
+ import { validateConfig } from '../core/config/validate.js';
6
+ import { loadOrInitPolicy } from '../core/state/policy.js';
7
+ import { resolveTestCommand } from '../core/testRunner/resolve.js';
8
+ import { runTestCommand } from '../core/testRunner/runner.js';
9
+ import { parseJestOutput } from '../core/jest/parser.js';
10
+ function parsePositiveInt(value) {
11
+ const n = Number(value);
12
+ if (!Number.isInteger(n) || n <= 0)
13
+ return null;
14
+ return n;
15
+ }
16
+ function parseTestArgs(argv) {
17
+ const errors = [];
18
+ let root;
19
+ let configPath;
20
+ let timeoutMs;
21
+ for (let i = 0; i < argv.length; i++) {
22
+ const a = argv[i] ?? '';
23
+ if (a === '--root') {
24
+ const v = argv[i + 1];
25
+ if (typeof v !== 'string' || v.trim() === '')
26
+ errors.push('test: --root requires a path');
27
+ else {
28
+ root = v;
29
+ i++;
30
+ }
31
+ continue;
32
+ }
33
+ if (a.startsWith('--root=')) {
34
+ const v = a.slice('--root='.length);
35
+ if (v.trim() === '')
36
+ errors.push('test: --root requires a path');
37
+ else
38
+ root = v;
39
+ continue;
40
+ }
41
+ if (a === '--config' || a === '-c') {
42
+ const v = argv[i + 1];
43
+ if (typeof v !== 'string' || v.trim() === '')
44
+ errors.push('test: --config requires a path');
45
+ else {
46
+ configPath = v;
47
+ i++;
48
+ }
49
+ continue;
50
+ }
51
+ if (a.startsWith('--config=')) {
52
+ const v = a.slice('--config='.length);
53
+ if (v.trim() === '')
54
+ errors.push('test: --config requires a path');
55
+ else
56
+ configPath = v;
57
+ continue;
58
+ }
59
+ if (a === '--timeout-ms') {
60
+ const v = argv[i + 1];
61
+ if (typeof v !== 'string' || v.trim() === '')
62
+ errors.push('test: --timeout-ms requires a number');
63
+ else {
64
+ const n = parsePositiveInt(v);
65
+ if (n == null)
66
+ errors.push('test: --timeout-ms must be a positive integer');
67
+ else
68
+ timeoutMs = n;
69
+ i++;
70
+ }
71
+ continue;
72
+ }
73
+ if (a.startsWith('--timeout-ms=')) {
74
+ const v = a.slice('--timeout-ms='.length);
75
+ const n = parsePositiveInt(v);
76
+ if (n == null)
77
+ errors.push('test: --timeout-ms must be a positive integer');
78
+ else
79
+ timeoutMs = n;
80
+ continue;
81
+ }
82
+ if (a === '--help' || a === '-h')
83
+ continue;
84
+ errors.push(`test: unknown argument "${a}"`);
85
+ }
86
+ errors.sort((x, y) => x.localeCompare(y));
87
+ const args = {};
88
+ if (root !== undefined)
89
+ args.root = root;
90
+ if (configPath !== undefined)
91
+ args.configPath = configPath;
92
+ if (timeoutMs !== undefined)
93
+ args.timeoutMs = timeoutMs;
94
+ return { args, errors };
95
+ }
96
+ export async function runTestWithLogger(argv, logger) {
97
+ const parsedArgs = parseTestArgs(argv);
98
+ if (parsedArgs.errors.length > 0) {
99
+ for (const e of parsedArgs.errors)
100
+ logger.error(e);
101
+ return 2;
102
+ }
103
+ const root = path.resolve(process.cwd(), parsedArgs.args.root ?? '.');
104
+ const loadedCfg = loadConfigFile(parsedArgs.args.configPath, {
105
+ cwd: () => root,
106
+ resolve: (...parts) => path.resolve(...parts),
107
+ existsSync: (p) => fs.existsSync(p),
108
+ readFileSync: (p, enc) => fs.readFileSync(p, enc),
109
+ });
110
+ const validated = validateConfig(loadedCfg.data);
111
+ const policy = loadOrInitPolicy({ root }).policy;
112
+ const resolved = resolveTestCommand({
113
+ root,
114
+ configTestCommand: validated.resolved.test.command,
115
+ policyWorkingTestCommand: policy.workingTestCommand,
116
+ boundaryKind: 'unknown',
117
+ boundaryFileRel: null,
118
+ });
119
+ if (!resolved) {
120
+ logger.output(stableStringify({
121
+ command: 'test',
122
+ root,
123
+ resolvedCommand: null,
124
+ error: 'No test command could be resolved (config.test.command, policy.workingTestCommand, or package.json scripts test/test:unit).',
125
+ }));
126
+ return 2;
127
+ }
128
+ const timeoutMs = parsedArgs.args.timeoutMs ?? 10 * 60 * 1000;
129
+ logger.info(`Running tests (${resolved.source}): ${resolved.command}`);
130
+ const result = await runTestCommand({ command: resolved.command, cwd: root, timeoutMs });
131
+ const jestParsed = parseJestOutput(result.rawOutput);
132
+ logger.output(stableStringify({
133
+ command: 'test',
134
+ root,
135
+ resolvedCommand: resolved,
136
+ result: { ...result, parsedFailures: jestParsed.failures },
137
+ jest: { ignored: jestParsed.ignored },
138
+ }));
139
+ if (result.timedOut)
140
+ return 2;
141
+ return result.exitCode === 0 ? 0 : 1;
142
+ }
143
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Logger } from '../core/logger.js';
2
+ import { createGitAdapter } from '../adapters/git.js';
3
+ import { createGithubAdapter } from '../adapters/github.js';
4
+ import { type ForkContext } from '../core/config/forkPolicy.js';
5
+ export declare function runTestabilityWithLogger(argv: readonly string[], logger: Logger, deps?: {
6
+ createGitAdapter?: typeof createGitAdapter;
7
+ createGithubAdapter?: typeof createGithubAdapter;
8
+ /** Injected fork context for testing; undefined = not applicable (scheduled mode default). */
9
+ forkContext?: ForkContext;
10
+ }): Promise<number>;