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
package/README.md
CHANGED
|
@@ -1,41 +1,99 @@
|
|
|
1
1
|
# phantom-pr
|
|
2
2
|
|
|
3
|
-
`phantom-pr` is a CI-friendly CLI that opens PRs with passing Jest unit tests (bounded + deterministic, PR-only, no auto-merge).
|
|
3
|
+
`phantom-pr` is a CI-friendly CLI that opens PRs with passing Jest/Vitest/pytest unit tests (bounded + deterministic, PR-only, no auto-merge).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g phantom-pr
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Or use directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx phantom-pr --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Create config file
|
|
21
|
+
cat > phantom-pr.yml << EOF
|
|
22
|
+
baseBranch: main
|
|
23
|
+
github:
|
|
24
|
+
owner: your-org
|
|
25
|
+
repo: your-repo
|
|
26
|
+
tokenEnvVar: GITHUB_TOKEN
|
|
27
|
+
mode:
|
|
28
|
+
dryRun: true
|
|
29
|
+
test:
|
|
30
|
+
command: npm test
|
|
31
|
+
EOF
|
|
32
|
+
|
|
33
|
+
# 2. Index your codebase
|
|
34
|
+
phantom-pr index --root .
|
|
35
|
+
|
|
36
|
+
# 3. Generate a plan
|
|
37
|
+
phantom-pr plan --root .
|
|
38
|
+
|
|
39
|
+
# 4. Run in dry mode first
|
|
40
|
+
phantom-pr full --root . --dryRun
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
### π§ͺ Automatic Test Generation
|
|
46
|
+
|
|
47
|
+
Generate unit tests for any file:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
phantom-pr tests src/components/Button.tsx --local
|
|
13
51
|
```
|
|
14
52
|
|
|
15
|
-
|
|
53
|
+
### π AST-Powered Analysis (New in 0.5.0)
|
|
54
|
+
|
|
55
|
+
The test generator now uses AST analysis to:
|
|
56
|
+
|
|
57
|
+
- **Detect branches** - Finds `if`, ternary, switch, and `&&`/`||` operators
|
|
58
|
+
- **Identify effects** - Detects `useEffect`, `useLayoutEffect` with cleanup detection
|
|
59
|
+
- **Map child components** - Finds components that need mocking
|
|
60
|
+
- **Track external calls** - Identifies imported functions being called
|
|
61
|
+
|
|
62
|
+
This enables smarter test generation with better branch coverage.
|
|
63
|
+
|
|
64
|
+
### π Smart Retry with Error Parsing
|
|
16
65
|
|
|
17
|
-
|
|
18
|
-
- **Minimal formatting**: Prettier config in `.prettierrc.json`
|
|
19
|
-
- **CLI entrypoint**: `src/cli.ts` (prints `--help`, exits 0)
|
|
20
|
-
- **Config MVP + status**: `phantom-pr status` loads `phantom-pr.yml` (or `--config <path>`) and prints resolved config + missing fields
|
|
21
|
-
- **Full orchestration**: `phantom-pr full` is the βone safe unit of workβ command for CI (caps + stale handling + deterministic target choice)
|
|
22
|
-
- **Testability lane (MVP)**: `phantom-pr testability` can open a minimal βadd data-testidβ PR for React targets
|
|
23
|
-
- **Tests lane**: `phantom-pr tests` generates tests, runs the test command, and writes `.phantom-pr/report.json`
|
|
24
|
-
- **Folder structure**:
|
|
25
|
-
- `src/core/` (domain logic)
|
|
26
|
-
- `src/adapters/` (IO boundaries: git hosting, filesystem, process, network)
|
|
27
|
-
- `src/commands/` (CLI commands)
|
|
66
|
+
When tests fail, the retry system now:
|
|
28
67
|
|
|
29
|
-
|
|
68
|
+
- Parses Jest/Vitest error output
|
|
69
|
+
- Identifies specific error types (mock not called, assertion mismatch, import errors)
|
|
70
|
+
- Generates targeted fix suggestions
|
|
71
|
+
- Creates focused retry prompts
|
|
30
72
|
|
|
31
|
-
|
|
32
|
-
- **test**: unit tests for the CLI itself (`node --test tests`)
|
|
33
|
-
- **lint**: typecheck-only (`tsc --noEmit`)
|
|
34
|
-
- **smoke**: build + run `--help`
|
|
73
|
+
### π Post-Generation Validation
|
|
35
74
|
|
|
36
|
-
|
|
75
|
+
After generating tests, validation checks:
|
|
37
76
|
|
|
38
|
-
|
|
77
|
+
- Branch coverage completeness
|
|
78
|
+
- Effect cleanup testing (for `useEffect` with cleanup)
|
|
79
|
+
- Child component mocking
|
|
80
|
+
- Returns specific `llm_reject_*` codes for failures
|
|
81
|
+
|
|
82
|
+
## Commands
|
|
83
|
+
|
|
84
|
+
| Command | Description |
|
|
85
|
+
|---------|-------------|
|
|
86
|
+
| `phantom-pr status` | Show config and status |
|
|
87
|
+
| `phantom-pr index` | Index the codebase |
|
|
88
|
+
| `phantom-pr plan` | Generate test plan |
|
|
89
|
+
| `phantom-pr tests <file>` | Generate tests for a file |
|
|
90
|
+
| `phantom-pr full` | Full orchestration (CI mode) |
|
|
91
|
+
| `phantom-pr pr --prNumber <n>` | PR companion mode |
|
|
92
|
+
| `phantom-pr testability <file>` | Add data-testid attributes |
|
|
93
|
+
|
|
94
|
+
## Configuration
|
|
95
|
+
|
|
96
|
+
Create `phantom-pr.yml` at repo root:
|
|
39
97
|
|
|
40
98
|
```yaml
|
|
41
99
|
baseBranch: main
|
|
@@ -43,8 +101,7 @@ github:
|
|
|
43
101
|
owner: your-org
|
|
44
102
|
repo: your-repo
|
|
45
103
|
tokenEnvVar: GITHUB_TOKEN
|
|
46
|
-
# Safety default
|
|
47
|
-
allowForkPrs: false
|
|
104
|
+
allowForkPrs: false # Safety default
|
|
48
105
|
limits:
|
|
49
106
|
maxFilesChanged: 50
|
|
50
107
|
maxLinesChanged: 5000
|
|
@@ -52,92 +109,171 @@ limits:
|
|
|
52
109
|
maxOpenBotPRs: 3
|
|
53
110
|
maxPRsPerRun: 1
|
|
54
111
|
mode:
|
|
55
|
-
dryRun: true
|
|
112
|
+
dryRun: true # Set false for real PRs
|
|
56
113
|
test:
|
|
57
114
|
command: npm test
|
|
58
115
|
```
|
|
59
116
|
|
|
60
|
-
|
|
117
|
+
### Config Options
|
|
118
|
+
|
|
119
|
+
| Option | Description | Default |
|
|
120
|
+
|--------|-------------|---------|
|
|
121
|
+
| `baseBranch` | Target branch for PRs | `main` |
|
|
122
|
+
| `limits.maxIterations` | Max test retry attempts | `5` |
|
|
123
|
+
| `limits.maxPRsPerRun` | Max PRs per CI run | `1` |
|
|
124
|
+
| `mode.dryRun` | Disable real Git/GitHub operations | `true` |
|
|
125
|
+
| `test.command` | Test command to run | `npm test` |
|
|
126
|
+
|
|
127
|
+
## CI Integration
|
|
61
128
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
129
|
+
### Scheduled Runs (Recommended: 4x/day)
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
# GitHub Actions example
|
|
133
|
+
on:
|
|
134
|
+
schedule:
|
|
135
|
+
- cron: '0 1,7,13,19 * * *'
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
phantom-pr:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@v4
|
|
142
|
+
- uses: actions/setup-node@v4
|
|
143
|
+
- run: npm ci
|
|
144
|
+
- run: npx phantom-pr full --root .
|
|
145
|
+
env:
|
|
146
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
65
147
|
```
|
|
66
148
|
|
|
67
|
-
|
|
149
|
+
### Jenkins
|
|
150
|
+
|
|
151
|
+
See `docs/jenkins.md` for Pipeline examples.
|
|
152
|
+
|
|
153
|
+
## Understanding Reports
|
|
154
|
+
|
|
155
|
+
### `tests` command β `.phantom-pr/report.json`
|
|
156
|
+
|
|
157
|
+
See `docs/report-json.md` for schema details.
|
|
158
|
+
|
|
159
|
+
Key fields:
|
|
160
|
+
- `finalOutcome`: `pass` | `fail` | `timeout`
|
|
161
|
+
- `attempts`: Array of test run attempts
|
|
162
|
+
- `generatorWarnings`: Any validation issues
|
|
68
163
|
|
|
69
|
-
|
|
164
|
+
### `full` command β `.phantom-pr/full.json`
|
|
70
165
|
|
|
71
|
-
|
|
166
|
+
- `caps`: Open PR count and limits
|
|
167
|
+
- `chosenTarget`: What file was selected
|
|
168
|
+
- `lane`: `tests` | `testability` | `skipped`
|
|
169
|
+
|
|
170
|
+
## Contributing
|
|
171
|
+
|
|
172
|
+
### Development Setup
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
git clone https://github.com/norralak/blacksand-phantom-pr.git
|
|
176
|
+
cd blacksand-phantom-pr
|
|
177
|
+
npm install
|
|
72
178
|
npm run build
|
|
73
|
-
|
|
74
|
-
node dist/cli.js plan --root .
|
|
75
|
-
node dist/cli.js full --root . --dryRun --report .phantom-pr/full.json
|
|
179
|
+
npm test
|
|
76
180
|
```
|
|
77
181
|
|
|
78
|
-
|
|
79
|
-
- `full` exits `0` and prints a stable JSON object to stdout.
|
|
80
|
-
- In dryRun, it never opens/closes/comments on PRs and may set `refreshSkippedReason` (e.g. `dryrun_no_github_token`).
|
|
182
|
+
### Project Structure
|
|
81
183
|
|
|
82
|
-
|
|
184
|
+
```
|
|
185
|
+
src/
|
|
186
|
+
βββ cli.ts # CLI entrypoint
|
|
187
|
+
βββ commands/ # Command implementations
|
|
188
|
+
βββ adapters/ # IO boundaries (git, github, fs)
|
|
189
|
+
βββ core/
|
|
190
|
+
βββ analysis/ # AST extraction (NEW)
|
|
191
|
+
βββ context/ # Context packing & selection
|
|
192
|
+
βββ validation/ # Post-generation validation (NEW)
|
|
193
|
+
βββ retry/ # Error parsing & feedback (NEW)
|
|
194
|
+
βββ generator/ # Test generators (LLM, smoke)
|
|
195
|
+
βββ testRunner/ # Test execution
|
|
196
|
+
βββ ...
|
|
197
|
+
```
|
|
83
198
|
|
|
84
|
-
|
|
199
|
+
### Running Tests
|
|
85
200
|
|
|
86
|
-
|
|
201
|
+
```bash
|
|
202
|
+
# All tests
|
|
203
|
+
npm test
|
|
87
204
|
|
|
88
|
-
|
|
205
|
+
# Specific test file
|
|
206
|
+
npm test -- tests/ast-extractor.test.mjs
|
|
89
207
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- `limits.maxPRsPerRun` is enforced (default `1`): one run does at most one unit of work.
|
|
208
|
+
# With verbose output
|
|
209
|
+
npm test -- --test-reporter=spec
|
|
210
|
+
```
|
|
94
211
|
|
|
95
|
-
|
|
212
|
+
### Code Style
|
|
96
213
|
|
|
97
|
-
|
|
98
|
-
-
|
|
214
|
+
- **TypeScript**: Strict mode enabled
|
|
215
|
+
- **Formatting**: Prettier (run `npm run format`)
|
|
216
|
+
- **Linting**: TypeScript compiler (`npm run lint`)
|
|
99
217
|
|
|
100
|
-
###
|
|
101
|
-
`phantom-pr` uses the env var named by `github.tokenEnvVar` from `phantom-pr.yml` (and never prints its value).
|
|
218
|
+
### Adding New Features
|
|
102
219
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
220
|
+
1. **Create types first** in `types.ts`
|
|
221
|
+
2. **Implement with tests** - follow TDD
|
|
222
|
+
3. **Add barrel export** in `index.ts`
|
|
223
|
+
4. **Update README** if user-facing
|
|
224
|
+
|
|
225
|
+
### Risk Register
|
|
226
|
+
|
|
227
|
+
When adding features with heuristics (parsing, detection), document risks:
|
|
108
228
|
|
|
109
|
-
|
|
229
|
+
| When to add risk | Example |
|
|
230
|
+
|------------------|---------|
|
|
231
|
+
| Regex-based parsing | Error parser patterns |
|
|
232
|
+
| Static lists | External package detection |
|
|
233
|
+
| Heuristic detection | Branch/effect identification |
|
|
110
234
|
|
|
111
|
-
|
|
235
|
+
### Pull Request Guidelines
|
|
112
236
|
|
|
113
|
-
|
|
237
|
+
- One feature per PR
|
|
238
|
+
- Include tests for new functionality
|
|
239
|
+
- Update documentation
|
|
240
|
+
- Run `npm test` before submitting
|
|
114
241
|
|
|
115
|
-
##
|
|
242
|
+
## Required Permissions
|
|
116
243
|
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
- **`stale`** summarizes stale PR consideration and actions
|
|
121
|
-
- **`chosenTarget`** and **`lane`** show what it decided to do
|
|
244
|
+
### Git
|
|
245
|
+
- Create branches
|
|
246
|
+
- Push commits
|
|
122
247
|
|
|
123
|
-
|
|
248
|
+
### GitHub API (via `tokenEnvVar`)
|
|
249
|
+
- **Contents**: Read & Write
|
|
250
|
+
- **Pull requests**: Read & Write
|
|
251
|
+
- **Issues**: Read & Write (for comments)
|
|
252
|
+
- **Metadata**: Read
|
|
253
|
+
|
|
254
|
+
## Troubleshooting
|
|
124
255
|
|
|
125
|
-
|
|
256
|
+
### "Cannot find module" errors
|
|
126
257
|
|
|
127
|
-
|
|
258
|
+
The test generator mocks child components. If you see import errors:
|
|
128
259
|
|
|
129
|
-
```
|
|
130
|
-
|
|
260
|
+
```typescript
|
|
261
|
+
// Add to test file
|
|
262
|
+
jest.mock('./ChildComponent');
|
|
131
263
|
```
|
|
132
264
|
|
|
133
|
-
|
|
265
|
+
### Tests timing out
|
|
266
|
+
|
|
267
|
+
- Check for async operations without proper `await`
|
|
268
|
+
- Use `waitFor()` from testing-library
|
|
269
|
+
- Increase timeout in jest config
|
|
134
270
|
|
|
135
|
-
|
|
136
|
-
- Scheduled: `full` (opens/updates a bot PR on `baseBranch`)
|
|
137
|
-
- PR companion: `pr --prNumber <n>` (opens/updates a companion PR)
|
|
271
|
+
### LLM not generating tests
|
|
138
272
|
|
|
139
|
-
|
|
273
|
+
Check `.phantom-pr/report.json` for:
|
|
274
|
+
- `llm.allowed`: Must be `true`
|
|
275
|
+
- `generatorWarnings`: Shows rejection reasons
|
|
140
276
|
|
|
141
277
|
## License
|
|
142
|
-
Proprietary β All Rights Reserved. See LICENSE.
|
|
143
278
|
|
|
279
|
+
Proprietary β All Rights Reserved. See LICENSE.md.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST extractor that analyzes React/TypeScript component files.
|
|
3
|
+
* Uses TypeScript's built-in compiler API (no external parser dependency).
|
|
4
|
+
*
|
|
5
|
+
* Pure function: parse file β return ComponentAnalysis.
|
|
6
|
+
* Handles parse errors gracefully (returns partial analysis, doesn't throw).
|
|
7
|
+
*/
|
|
8
|
+
import type { ComponentAnalysis } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Extract component analysis from a React/TypeScript file.
|
|
11
|
+
* @param filePath - Path to the file (for reference in output)
|
|
12
|
+
* @param fileContent - Source code content
|
|
13
|
+
* @returns ComponentAnalysis with extracted structure info
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractComponentAnalysis(filePath: string, fileContent: string): ComponentAnalysis;
|