openpitstop 1.5.2 → 1.6.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.
@@ -2,97 +2,389 @@ import { Command } from "commander";
2
2
  import chalk from "chalk";
3
3
  import boxen from "boxen";
4
4
  import path from "node:path";
5
+ import fs from "node:fs";
6
+ import { fileURLToPath } from "node:url";
5
7
  import { execa } from "execa";
8
+ import { execSync } from "node:child_process";
6
9
  import { loadScan, repro } from "../repro/index.js";
7
- import { resolveFinding } from "../repro/ids.js";
10
+ import { resolveFinding, findingIdFor, ledgerFindingId } from "../repro/ids.js";
8
11
  import { loadPenLatest, resolvePenFinding } from "../pen/store.js";
12
+ import { analyzeSecurity } from "../analyzers/security.js";
13
+ import { analyzeAccessibility } from "../analyzers/accessibility.js";
14
+ import { analyzeDevex } from "../analyzers/devex.js";
15
+ import { analyzeDuplication } from "../analyzers/duplication.js";
16
+ import { analyzeReliability } from "../analyzers/reliability.js";
17
+ import { runLedgerAnalyzer } from "../analyzers/ledger/index.js";
9
18
  import { runVerify } from "./verify.js";
19
+ import { computeNext, celebrateCard, printNextCard } from "./next.js";
10
20
  /**
11
21
  * `pitstop drive <finding-id>` — hand a finding to YOUR agent, then verify.
12
22
  *
13
23
  * OpenPitStop never fixes your code itself (no magic auto-edits on a repo it does
14
24
  * not own). Instead: drive builds a precise mission prompt for the agent you
15
- * already trust (claude/codex/opencode/...), runs it, then runs `pitstop
16
- * verify` on the result and reports PASS/FAIL honestly.
25
+ * already trust (claude/codex/opencode/...), runs it, then checks the result with
26
+ * a hard acceptance gate (a failing-first repro that now PASSES, or a clean
27
+ * `pitstop verify`) and reports PASS/FAIL honestly.
17
28
  *
18
- * The agent command comes from --agent or PITSTOP_AGENT; `{prompt}` is where
19
- * the mission text is inserted, e.g.:
20
- * pitstop drive security-abc123 --agent "claude -p \"{prompt}\""
29
+ * **Loop Engineering:** `drive` does not stop after one attempt. It loops — each
30
+ * failed attempt feeds the verify/repro failure back into the next mission — until
31
+ * the finding is *verified* solved or `--max-attempts` is exhausted. With no
32
+ * finding id, `pitstop drive` drives the whole repo: it repeatedly runs the next
33
+ * command from `pitstop next` until the repo is fully fixed.
34
+ *
35
+ * The agent command comes from --agent or PITSTOP_AGENT; `{prompt}` is where the
36
+ * mission text is inserted, e.g. `pitstop drive id --agent "claude -p \"{prompt}\""`.
37
+ */
38
+ const cliPath = fileURLToPath(new URL("../cli.js", import.meta.url));
39
+ /**
40
+ * Auto-detect a usable agent so `/pitstop-drive` works without manual setup.
41
+ * Falls back to PITSTOP_AGENT, then probes common CLIs (claude, codex, opencode,
42
+ * aider, gemini) for one that exists on PATH.
43
+ */
44
+ function commandExists(bin) {
45
+ try {
46
+ if (process.platform === "win32")
47
+ execSync(`where ${bin}`, { stdio: "ignore" });
48
+ else
49
+ execSync(`command -v ${bin}`, { stdio: "ignore" });
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ const AGENT_CANDIDATES = [
57
+ { bin: "claude", cmd: 'claude -p "{prompt}"' },
58
+ { bin: "codex", cmd: 'codex exec -- "{prompt}"' },
59
+ { bin: "opencode", cmd: 'opencode run "{prompt}"' },
60
+ { bin: "aider", cmd: 'aider --message "{prompt}"' },
61
+ { bin: "gemini", cmd: 'gemini -p "{prompt}"' },
62
+ ];
63
+ function resolveAgentCmd(provided) {
64
+ if (provided)
65
+ return { cmd: provided };
66
+ const env = process.env.PITSTOP_AGENT;
67
+ if (env)
68
+ return { cmd: env };
69
+ for (const c of AGENT_CANDIDATES) {
70
+ if (commandExists(c.bin))
71
+ return { cmd: c.cmd, detected: c.bin };
72
+ }
73
+ return { cmd: "" };
74
+ }
75
+ /**
76
+ * Re-run the analyzer that owns `finding`'s source and confirm the finding id is
77
+ * gone. Returns true (present), false (confirmed absent), or null (no applicable
78
+ * analyzer — fall back to the repro gate). This is what lets `drive` verify fixes
79
+ * for a11y / devex / security findings, not just runtime repro-able ones.
21
80
  */
22
- function missionPrompt(repo, finding, reproHint, fromPen) {
81
+ async function freshScanStillHas(repo, finding) {
82
+ try {
83
+ if (finding.source === "security") {
84
+ const r = await analyzeSecurity(repo);
85
+ return (r.issues ?? []).some((i) => findingIdFor("security", i.type, i.file, i.description) === finding.id);
86
+ }
87
+ if (finding.source === "a11y") {
88
+ const r = analyzeAccessibility(repo);
89
+ return (r.issues ?? []).some((i) => findingIdFor("a11y", i.type, i.file, i.description) === finding.id);
90
+ }
91
+ if (finding.source === "devex") {
92
+ const r = analyzeDevex(repo);
93
+ return (r.unusedExports ?? []).some((i) => findingIdFor("devex", i.type, i.file, i.description) === finding.id);
94
+ }
95
+ if (finding.source === "duplication") {
96
+ const r = analyzeDuplication(repo);
97
+ return (r.clones ?? []).some((c) => findingIdFor("duplication", "duplication", c.files[0], `${c.lines}`) === finding.id);
98
+ }
99
+ if (finding.source === "reliability") {
100
+ // runs:1 keeps the acceptance re-check cheap; race-smell greps still run.
101
+ const r = await analyzeReliability(repo, { runs: 1 });
102
+ const flaky = (r.flakyTests ?? []).some((f) => findingIdFor("reliability", "flaky-test", f.file, f.name) === finding.id);
103
+ const race = (r.raceSmells ?? []).some((i) => findingIdFor("reliability", "race-condition", i.file, i.description) === finding.id);
104
+ return flaky || race;
105
+ }
106
+ if (finding.source === "ledger") {
107
+ // Ledger analysis boots the app and fires live traffic — only re-run it when the
108
+ // user already opted in via `pitstop scan --ledger` (a ledger baseline exists).
109
+ const base = loadScan(repo);
110
+ if (!base?.ledger?.evidence?.length)
111
+ return null;
112
+ const r = await runLedgerAnalyzer(repo);
113
+ return (r.evidence ?? []).some((e) => ledgerFindingId(e) === finding.id);
114
+ }
115
+ }
116
+ catch {
117
+ return null;
118
+ }
119
+ return null;
120
+ }
121
+ const DRIVEN_PATH = (repo) => path.join(repo, ".pitstop", "driven.json");
122
+ function loadDriven(repo) {
123
+ try {
124
+ const raw = fs.readFileSync(DRIVEN_PATH(repo), "utf8");
125
+ const arr = JSON.parse(raw);
126
+ return new Set(Array.isArray(arr) ? arr : []);
127
+ }
128
+ catch {
129
+ return new Set();
130
+ }
131
+ }
132
+ function markDriven(repo, id) {
133
+ const set = loadDriven(repo);
134
+ set.add(id);
135
+ fs.mkdirSync(path.dirname(DRIVEN_PATH(repo)), { recursive: true });
136
+ fs.writeFileSync(DRIVEN_PATH(repo), JSON.stringify([...set], null, 2));
137
+ }
138
+ function missionPrompt(repo, finding, reproHint, fromPen, loop) {
139
+ const loopSection = loop
140
+ ? `
141
+ ## Loop context (attempt ${loop.attempt} of ${loop.maxAttempts})
142
+ ${loop.lastFailure
143
+ ? `The previous attempt did NOT pass the acceptance gate:\n ${loop.lastFailure}\nRe-read that evidence. Do NOT repeat the same change — try a different minimal fix that addresses the actual root cause.`
144
+ : `This is the first attempt.`}
145
+ `
146
+ : "";
23
147
  return [
24
148
  `You are fixing one specific OpenPitStop finding in the repo at ${repo}.`,
25
149
  ``,
26
150
  `Finding: ${finding.id} (${finding.source}/${finding.type}, severity ${finding.severity})`,
27
151
  `Description: ${finding.description}`,
28
152
  finding.file ? `Location: ${finding.file}${finding.line ? ":" + finding.line : ""}` : "",
153
+ loopSection,
154
+ ``,
155
+ `## Loop Engineering Principles (follow on EVERY attempt)`,
156
+ `- Repro-first: RUN the repro first — \`npx openpitstop repro ${finding.id}\` MUST FAIL (the bug is live) before you change anything. If it passes/refuses, STOP and re-read the finding; do not fix blind.`,
157
+ `- Minimal: change the smallest unit that addresses the root cause. No unrelated refactors.`,
158
+ `- Verify-each-iteration: after each change, re-run the SAME repro; it must now PASS.`,
159
+ `- No faking: never claim success without a passing repro or a clean \`pitstop verify\`.`,
160
+ `- Revert-on-regression: if you caused a regression, revert the smallest unit and try a different minimal fix.`,
161
+ `- Stop ONLY when the acceptance gate below is green.`,
29
162
  ``,
30
- `Work like this, in order, without skipping:`,
31
- `1. RUN the repro first: \`npx openpitstop repro ${finding.id}\`. It MUST FAIL (the bug is live).`,
32
- ` If it refuses or passes, STOP and re-read the finding — do not fix blind.`,
163
+ `Work in this exact order:`,
164
+ `1. RUN the repro first: \`npx openpitstop repro ${finding.id}\`. It MUST FAIL.`,
33
165
  reproHint,
34
166
  `2. Make the smallest fix that addresses the root cause. Do not refactor unrelated code.`,
35
167
  `3. Re-run the SAME repro: it must now PASS.`,
36
168
  fromPen
37
- ? `4. \`npx openpitstop verify\` is a static gate — for runtime pen findings the repro PASS is the real verdict;`
169
+ ? `4. For runtime pen findings the repro PASS is the real verdict; \`npx openpitstop verify\` is a static gate for context.`
38
170
  : `4. Run \`npx openpitstop verify\` — it must come back clean (no regressions, integrity intact).`,
39
171
  `5. If anything regressed, revert the smallest unit and try again.`,
40
172
  ``,
41
173
  `Finish by reporting: what was wrong, what you changed, and the exact commands you ran.`,
42
- ].filter(Boolean).join("\n");
174
+ ]
175
+ .filter(Boolean)
176
+ .join("\n");
43
177
  }
44
- export const drive = new Command("drive")
45
- .description("Hand a finding to YOUR own agent (claude/codex/opencode/...), then verify the result. " +
46
- "Mission: repro FAILS first → fix → repro PASSES → `pitstop verify` clean. OpenPitStop never auto-edits your code.")
47
- .argument("<finding-id>", "finding id from scan-latest.json or pen-latest.json")
48
- .argument("[repo]", "path to the repo", ".")
49
- .option("--agent <cmd>", "agent command with {prompt} placeholder (or set PITSTOP_AGENT)")
50
- .action(async (findingId, repoArg, options) => {
51
- const repo = path.resolve(repoArg);
178
+ async function runAgent(repo, agentCmd, prompt) {
179
+ const tokens = agentCmd.split(/\s+/).map((t) => (t.includes("{prompt}") ? prompt : t)).filter(Boolean);
180
+ const [cmd, ...args] = tokens;
181
+ const finalArgs = args.map((a) => a.replace("{prompt}", prompt));
182
+ try {
183
+ const sub = execa(cmd, finalArgs, {
184
+ cwd: repo,
185
+ stdout: "inherit",
186
+ stderr: "inherit",
187
+ reject: false,
188
+ timeout: 30 * 60 * 1000,
189
+ windowsHide: true,
190
+ });
191
+ return (await sub).exitCode ?? -1;
192
+ }
193
+ catch (err) {
194
+ console.log(chalk.red(`agent could not be started: ${err.message}`));
195
+ return -1;
196
+ }
197
+ }
198
+ /**
199
+ * Loop the agent + acceptance gate on a single finding until it is verified solved
200
+ * or attempts run out. Each failed attempt's evidence is fed back into the next
201
+ * mission so the agent converges instead of repeating itself.
202
+ */
203
+ async function loopDriveFinding(repo, finding, fromPen, reproHint, agentCmd, maxAttempts) {
204
+ const trajectory = [];
205
+ let lastFailure;
206
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
207
+ console.log(chalk.cyan(`\n[attempt ${attempt}/${maxAttempts}] driving ${finding.id} → agent (its own credits; OpenPitStop verifies)\n`));
208
+ const prompt = missionPrompt(repo, finding, reproHint, fromPen, { attempt, maxAttempts, lastFailure });
209
+ const agentCode = await runAgent(repo, agentCmd, prompt);
210
+ // Acceptance gate: the bug must actually be gone, not merely "no regression".
211
+ // 1) a failing-first repro that now PASSES (gold standard), or
212
+ // 2) the owning analyzer's fresh re-scan no longer contains this finding id.
213
+ const r = await repro(repo, finding.id);
214
+ const ran = r.status === "generated-and-ran";
215
+ const reproPassed = ran && r.ran?.passed === true;
216
+ const still = await freshScanStillHas(repo, finding);
217
+ const freshScanGone = still === false; // confirmed absent by the relevant analyzer
218
+ let accepted = reproPassed || freshScanGone;
219
+ if (accepted) {
220
+ trajectory.push(`attempt ${attempt}: agent exited ${agentCode} → ACCEPTED (${reproPassed ? "repro PASSES" : "finding gone from re-scan"})`);
221
+ markDriven(repo, finding.id);
222
+ return { solved: true, attempts: attempt, trajectory };
223
+ }
224
+ const v = await runVerify(repo);
225
+ const stillTxt = still === null ? "re-scan n/a for this source" : still ? "finding still present in re-scan" : "finding gone from re-scan";
226
+ lastFailure =
227
+ `repro ${ran ? (r.ran?.passed ? "passed" : "still FAILS") : "unavailable (" + (r.reason ?? r.status) + ")"}${still ? "; " + stillTxt : ""}` +
228
+ ` · pitstop verify exited ${v.exitCode} (risk ${v.risk}, integrity ${v.integrity.verdict})`;
229
+ trajectory.push(`attempt ${attempt}: agent exited ${agentCode} → ${lastFailure}`);
230
+ console.log(chalk.yellow(` ${lastFailure}\n feeding evidence back into the next attempt…\n`));
231
+ }
232
+ return { solved: false, attempts: maxAttempts, lastFailure, trajectory };
233
+ }
234
+ function resolveById(repo, findingId) {
52
235
  const scan = loadScan(repo);
53
236
  const pen = loadPenLatest(repo);
54
- let finding = null;
55
- let reproHint = "";
56
- let fromPen = false;
57
- const scanHit = scan ? resolveFinding(scan, findingId) : null;
58
- if (scanHit) {
59
- finding = {
60
- id: scanHit.id,
61
- source: scanHit.source,
62
- severity: scanHit.severity,
63
- type: scanHit.type,
64
- description: scanHit.description,
65
- file: scanHit.file,
66
- line: scanHit.line,
67
- };
68
- reproHint = `The repro generator exists for ${scanHit.source}/${scanHit.type} — use it as your contract.`;
69
- }
70
- else if (pen) {
237
+ if (scan) {
238
+ const hit = resolveFinding(scan, findingId);
239
+ if (hit) {
240
+ return {
241
+ finding: {
242
+ id: hit.id,
243
+ source: hit.source,
244
+ severity: hit.severity,
245
+ type: hit.type,
246
+ description: hit.description,
247
+ file: hit.file,
248
+ line: hit.line,
249
+ },
250
+ fromPen: false,
251
+ reproHint: `The repro generator exists for ${hit.source}/${hit.type} — use it as your contract.`,
252
+ };
253
+ }
254
+ }
255
+ if (pen) {
71
256
  const pf = resolvePenFinding(pen, findingId);
72
257
  if (pf) {
73
- fromPen = true;
74
- finding = {
75
- id: pf.id,
76
- source: pf.source,
77
- severity: pf.severity,
78
- type: pf.type,
79
- description: pf.title,
80
- file: pf.file,
81
- line: pf.line,
258
+ return {
259
+ finding: {
260
+ id: pf.id,
261
+ source: pf.source,
262
+ severity: pf.severity,
263
+ type: pf.type,
264
+ description: pf.title,
265
+ file: pf.file,
266
+ line: pf.line,
267
+ },
268
+ fromPen: true,
269
+ reproHint: pf.attack
270
+ ? `Replay the attack if needed: ${pf.attack.method} ${pf.attack.path}`
271
+ : `This is a static observation — apply the fix guidance, then re-run \`npx openpitstop pen\` for this finding.`,
82
272
  };
83
- reproHint = pf.attack
84
- ? `Replay the attack if needed: ${pf.attack.method} ${pf.attack.path}`
85
- : `This is a static observation — apply the fix guidance, then re-run \`npx openpitstop pen\` for this finding.`;
86
273
  }
87
274
  }
88
- if (!finding) {
89
- console.log(chalk.yellow(`\nfinding "${findingId}" not found in scan-latest.json or pen-latest.json\n`));
90
- return;
275
+ return null;
276
+ }
277
+ async function runPitstop(repo, args) {
278
+ try {
279
+ const sub = execa(process.execPath, [cliPath, ...args], {
280
+ cwd: repo,
281
+ stdout: "inherit",
282
+ stderr: "inherit",
283
+ reject: false,
284
+ timeout: 30 * 60 * 1000,
285
+ windowsHide: true,
286
+ });
287
+ return (await sub).exitCode ?? -1;
288
+ }
289
+ catch (err) {
290
+ console.log(chalk.red(`pitstop could not be started: ${err.message}`));
291
+ return -1;
91
292
  }
92
- const agentCmd = options.agent ?? process.env.PITSTOP_AGENT ?? "";
293
+ }
294
+ /**
295
+ * No-id mode: drive the entire repo to fully-fixed. Repeatedly run the next command
296
+ * from `pitstop next`, looping each `pitstop drive <id>` until verified, until the
297
+ * repo is fully fixed or the round cap is hit.
298
+ */
299
+ async function driveRepoLoop(repo, agentCmd, maxAttempts) {
300
+ const MAX_ROUNDS = 24;
301
+ const paint = (ok) => (ok ? chalk.green : chalk.red);
302
+ for (let round = 0; round < MAX_ROUNDS; round++) {
303
+ const s = computeNext(repo);
304
+ if (s.fullyFixed) {
305
+ await celebrateCard();
306
+ return true;
307
+ }
308
+ const actionable = s.plan.filter((p) => p.command.startsWith("pitstop drive") ||
309
+ p.command.startsWith("pitstop pen") ||
310
+ p.command.startsWith("pitstop lockfile"));
311
+ if (actionable.length === 0) {
312
+ // Only verify/gate/report remain — refresh the baseline so the score reflects
313
+ // the fixes, then re-evaluate (avoids acting on a stale scan).
314
+ console.log(chalk.cyan(`\n[round ${round + 1}] no fixable steps left in plan — refreshing baseline (pitstop scan)…\n`));
315
+ await runPitstop(repo, ["scan", repo]);
316
+ const s2 = computeNext(repo);
317
+ if (s2.fullyFixed) {
318
+ await celebrateCard();
319
+ return true;
320
+ }
321
+ const stillNoFix = s2.plan.every((p) => !p.command.startsWith("pitstop drive") &&
322
+ !p.command.startsWith("pitstop pen") &&
323
+ !p.command.startsWith("pitstop lockfile"));
324
+ if (stillNoFix) {
325
+ console.log(chalk.yellow(`\nNo auto-fixable steps remain — running verify, then handing back to you.\n`));
326
+ await runPitstop(repo, ["verify", repo]);
327
+ await printNextCard(repo);
328
+ return false;
329
+ }
330
+ continue;
331
+ }
332
+ const step = actionable[0];
333
+ if (step.command.startsWith("pitstop drive")) {
334
+ const id = step.findingId ?? step.command.split(/\s+/)[2];
335
+ if (!id)
336
+ continue;
337
+ const resolved = resolveById(repo, id);
338
+ if (!resolved) {
339
+ console.log(chalk.yellow(`finding "${id}" not found — skipping.\n`));
340
+ markDriven(repo, id);
341
+ continue;
342
+ }
343
+ const res = await loopDriveFinding(repo, resolved.finding, resolved.fromPen, resolved.reproHint, agentCmd, maxAttempts);
344
+ const ok = res.solved;
345
+ console.log(boxen(`${paint(ok)("DRIVE " + (ok ? "SOLVED" : "NOT SOLVED"))} — ${resolved.finding.id}\n\n` +
346
+ res.trajectory.map((t) => ` ${t}`).join("\n") +
347
+ (ok ? "" : `\n\nnext: re-run \`pitstop drive ${resolved.finding.id}\` or fix by hand.`), {
348
+ title: ` PITSTOP — Drive ${resolved.finding.id} `,
349
+ titleAlignment: "center",
350
+ borderStyle: "round",
351
+ padding: 1,
352
+ borderColor: ok ? "green" : "red",
353
+ }));
354
+ if (!ok) {
355
+ process.exitCode = 1;
356
+ return false;
357
+ }
358
+ }
359
+ else if (step.command.startsWith("pitstop pen")) {
360
+ console.log(chalk.cyan(`\n[round ${round + 1}] ${step.command}\n`));
361
+ await runPitstop(repo, ["pen", "--fix", repo]);
362
+ }
363
+ else if (step.command.startsWith("pitstop lockfile")) {
364
+ console.log(chalk.cyan(`\n[round ${round + 1}] ${step.command}\n`));
365
+ await runPitstop(repo, ["lockfile", repo]);
366
+ }
367
+ }
368
+ console.log(chalk.yellow(`\nReached round cap without a fully-fixed repo — review the remaining plan:\n`));
369
+ await printNextCard(repo);
370
+ return false;
371
+ }
372
+ export const drive = new Command("drive")
373
+ .description("Hand a finding to YOUR own agent (claude/codex/opencode/...), then VERIFY in a loop until it's actually solved. " +
374
+ "With no id, drives the whole repo to fully-fixed. OpenPitStop never auto-edits your code.")
375
+ .argument("[finding-id]", "finding id from scan-latest.json or pen-latest.json (omit to drive the whole repo)")
376
+ .argument("[repo]", "path to the repo", ".")
377
+ .option("--agent <cmd>", "agent command with {prompt} placeholder (or set PITSTOP_AGENT)")
378
+ .option("--max-attempts <n>", "max drive loop attempts per finding", "5")
379
+ .action(async (findingId, repoArg, options) => {
380
+ const repo = path.resolve(repoArg);
381
+ const maxAttempts = Math.max(1, Math.floor(Number(options.maxAttempts) || 5));
382
+ const agent = resolveAgentCmd(options.agent);
383
+ const agentCmd = agent.cmd;
93
384
  if (!agentCmd) {
94
- console.log(boxen(`pitstop drive ${findingId}\n\n` +
385
+ console.log(boxen(`pitstop drive${findingId ? " " + findingId : ""}\n\n` +
95
386
  `${chalk.yellow("no agent command configured")}\n\n` +
387
+ `OpenPitStop auto-looked for claude / codex / opencode / aider / gemini on your PATH and found none.\n` +
96
388
  `Pass one with --agent (use {prompt} as the placeholder) or export PITSTOP_AGENT.\n\n` +
97
389
  `Examples:\n` +
98
390
  ` --agent 'claude -p "{prompt}"'\n` +
@@ -106,65 +398,34 @@ export const drive = new Command("drive")
106
398
  }));
107
399
  return;
108
400
  }
109
- const prompt = missionPrompt(repo, finding, reproHint, fromPen);
110
- const tokens = agentCmd.split(/\s+/).map((t) => (t.includes("{prompt}") ? prompt : t)).filter(Boolean);
111
- const [cmd, ...args] = tokens;
112
- const finalArgs = args.map((a) => a.replace("{prompt}", prompt));
113
- console.log(chalk.cyan(`\nDriving ${findingId} → ${cmd} (agent's own credits; OpenPitStop verifies the result)\n`));
114
- console.log(chalk.dim(prompt.split("\n").slice(0, 4).join("\n") + "\n"));
115
- let agentCode = -1;
116
- try {
117
- const sub = execa(cmd, finalArgs, {
118
- cwd: repo,
119
- stdout: "inherit",
120
- stderr: "inherit",
121
- reject: false,
122
- timeout: 30 * 60 * 1000,
123
- windowsHide: true,
124
- });
125
- agentCode = (await sub).exitCode ?? -1;
126
- }
127
- catch (err) {
128
- console.log(chalk.red(`agent could not be started: ${err.message}`));
401
+ if (agent.detected)
402
+ console.log(chalk.dim(`(auto-detected agent: ${agent.detected})\n`));
403
+ // No id → drive the whole repo to fully-fixed.
404
+ if (!findingId) {
405
+ const ok = await driveRepoLoop(repo, agentCmd, maxAttempts);
406
+ process.exitCode = ok ? 0 : 1;
129
407
  return;
130
408
  }
131
- console.log(chalk.dim(`\nagent exited with code ${agentCode} — verifying the result...\n`));
132
- if (fromPen) {
133
- const r = await repro(repo, findingId);
134
- const pass = r.status === "generated-and-ran" && r.ran?.passed === true;
135
- const paint = pass ? chalk.green : chalk.red;
136
- const why = pass
137
- ? "repro now PASSES — the runtime hypothesis is unproven, the fix holds."
138
- : r.status === "generated-and-ran"
139
- ? "repro still FAILS — the bug is live; the agent did not address it."
140
- : `repro could not run: ${r.reason ?? r.status}`;
141
- const v = await runVerify(repo);
142
- console.log(boxen(`${paint(pass ? "VERIFIED — repro now PASSES (bug addressed)" : "NOT VERIFIED — repro still FAILS (bug live)")}\n\n` +
143
- `${why}\n\n` +
144
- `test: ${r.file ?? "?"} · ${pass ? "PASS" : "FAIL"}\n` +
145
- `verify (static gate, context only): score ${v.currentScore.score}/100 (${v.currentScore.grade}) vs baseline ${v.baselineScore.score}/100 (${v.baselineScore.grade}) · delta ${v.scoreDelta >= 0 ? "+" : ""}${v.scoreDelta} · integrity ${v.integrity.verdict}`, {
146
- title: ` PITSTOP — Drive ${findingId} `,
147
- titleAlignment: "center",
148
- borderStyle: "round",
149
- padding: 1,
150
- borderColor: pass ? "green" : "red",
151
- }));
152
- process.exitCode = pass ? 0 : 1;
409
+ const resolved = resolveById(repo, findingId);
410
+ if (!resolved) {
411
+ console.log(chalk.yellow(`\nfinding "${findingId}" not found in scan-latest.json or pen-latest.json\n`));
153
412
  return;
154
413
  }
155
- const v = await runVerify(repo);
156
- const paint = v.exitCode === 0 ? chalk.green : chalk.red;
157
- console.log(boxen(`${paint(v.exitCode === 0 ? "VERIFIED — pitstop verify is clean" : `NOT VERIFIED — pitstop verify exited ${v.exitCode}`)}\n\n` +
158
- `score: ${v.currentScore.score}/100 (${v.currentScore.grade}) vs baseline ${v.baselineScore.score}/100 (${v.baselineScore.grade}) · delta ${v.scoreDelta >= 0 ? "+" : ""}${v.scoreDelta}\n` +
159
- `integrity: ${v.integrity.verdict} · stale baseline: ${v.stale ? "yes" : "no"}\n` +
160
- (v.exitCode !== 0 ? `\nnext: \`pitstop verify\` shows the failing categories — drive it again or fix by hand.` : ""), {
414
+ const res = await loopDriveFinding(repo, resolved.finding, resolved.fromPen, resolved.reproHint, agentCmd, maxAttempts);
415
+ const ok = res.solved;
416
+ const paint = ok ? chalk.green : chalk.red;
417
+ console.log(boxen(`${paint(ok ? "VERIFIED — finding solved" : "NOT VERIFIED — finding still live")}\n\n` +
418
+ res.trajectory.map((t) => ` ${t}`).join("\n") +
419
+ (ok
420
+ ? "\n\nthe repro now passes (or verify is clean) — the fix holds."
421
+ : `\n\nnext: re-run \`pitstop drive ${findingId}\` (it loops) or fix by hand.`), {
161
422
  title: ` PITSTOP — Drive ${findingId} `,
162
423
  titleAlignment: "center",
163
424
  borderStyle: "round",
164
425
  padding: 1,
165
- borderColor: v.exitCode === 0 ? "green" : "red",
426
+ borderColor: ok ? "green" : "red",
166
427
  }));
167
- process.exitCode = v.exitCode === 0 ? 0 : 1;
428
+ process.exitCode = ok ? 0 : 1;
168
429
  });
169
430
  export default drive;
170
431
  //# sourceMappingURL=drive.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../src/commands/drive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../src/commands/drive.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,26 @@
1
1
  import { Command } from "commander";
2
+ export interface RepoContext {
3
+ language: string;
4
+ packageManager?: string;
5
+ frameworks: string[];
6
+ testFramework?: string;
7
+ hasCI: boolean;
8
+ hasEnv: boolean;
9
+ isWeb: boolean;
10
+ isApi: boolean;
11
+ stackSummary: string;
12
+ }
13
+ /**
14
+ * Inspect the working tree (not just the scan) so the recommendation is accurate
15
+ * for *this* repo — language, package manager, frameworks, test runner, CI, env.
16
+ */
17
+ export declare function detectRepoContext(repo: string): RepoContext;
18
+ export interface PlanStep {
19
+ command: string;
20
+ why: string;
21
+ priority: number;
22
+ findingId?: string;
23
+ }
2
24
  export interface NextState {
3
25
  nextCommand: string;
4
26
  why: string;
@@ -6,6 +28,9 @@ export interface NextState {
6
28
  counts: Record<string, number>;
7
29
  fullyFixed: boolean;
8
30
  topId?: string;
31
+ plan: PlanStep[];
32
+ repoContext: RepoContext;
33
+ confidence: "high" | "medium" | "low";
9
34
  }
10
35
  export declare function computeNext(repo: string): NextState;
11
36
  export declare function celebrateCard(): Promise<void>;