|
| 1 | +// pnpm try [repoPath] [prompt] [--approve | --reject]: one real run through the runner, one event per line. |
| 2 | +// Without a flag it asks approve / reject / keep at the end (or keeps, when not in a terminal). |
| 3 | +// Costs real money (capped by budgetUsd below). Run scripts/reset-fixture.sh afterwards. |
| 4 | +import { randomUUID } from "node:crypto"; |
| 5 | +import { homedir } from "node:os"; |
| 6 | +import { join } from "node:path"; |
| 7 | +import { createInterface } from "node:readline/promises"; |
| 8 | +import { createRunner } from "../src/index.js"; |
| 9 | + |
| 10 | +const flags = process.argv.slice(2).filter((a) => a.startsWith("--")); |
| 11 | +const [repoPath = join(homedir(), "codehands-fixtures", "date-bug"), prompt = "Fix the failing test. Run npm test to check."] = |
| 12 | + process.argv.slice(2).filter((a) => !a.startsWith("--")); |
| 13 | + |
| 14 | +const runner = createRunner(); |
| 15 | +const sessionId = randomUUID(); |
| 16 | +let finished = false; |
| 17 | +for await (const e of runner.start({ sessionId, repoPath, prompt, agent: "claude-code", model: "sonnet", budgetUsd: 0.5 })) { |
| 18 | + const p = e.payload; |
| 19 | + const detail = p.reason ?? p.command ?? p.path ?? (typeof p.text === "string" ? p.text.slice(0, 80) : "") ?? ""; |
| 20 | + const extra = e.type === "test.result" ? ` passed=${p.passed}` : e.type === "task.finished" ? ` $${p.total_cost_usd}` : ""; |
| 21 | + console.log(`${String(e.seq).padStart(3)} ${e.type.padEnd(17)} ${String(detail).replace(/\s+/g, " ")}${extra}`); |
| 22 | + if (e.type === "task.finished") finished = true; |
| 23 | +} |
| 24 | +if (!finished) process.exit(1); |
| 25 | + |
| 26 | +console.log(`\n${(await runner.diff(sessionId)).stat}\n`); |
| 27 | + |
| 28 | +let choice = flags.includes("--approve") ? "a" : flags.includes("--reject") ? "r" : "k"; |
| 29 | +if (!flags.length && process.stdin.isTTY) { |
| 30 | + const rl = createInterface({ input: process.stdin, output: process.stdout }); |
| 31 | + choice = (await rl.question("approve, reject or keep? [a/r/k] ")).trim().toLowerCase()[0] ?? "k"; |
| 32 | + rl.close(); |
| 33 | +} |
| 34 | + |
| 35 | +if (choice === "a") { |
| 36 | + const { branch, commit } = await runner.approve(sessionId, prompt); |
| 37 | + console.log(`approved: ${branch} @ ${commit.slice(0, 7)} (git log ${branch} --oneline -1)`); |
| 38 | +} else if (choice === "r") { |
| 39 | + await runner.reject(sessionId); |
| 40 | + console.log("rejected: worktree and branch deleted"); |
| 41 | +} else { |
| 42 | + console.log("kept: the worktree is still there, see `git worktree list` in the repo"); |
| 43 | +} |
0 commit comments