Replace Claude with Pi throughout codebase
This commit is contained in:
parent
9eded80a0e
commit
e64564a045
18
src/cli.ts
18
src/cli.ts
|
|
@ -35,7 +35,7 @@ const program = new Command()
|
||||||
|
|
||||||
program
|
program
|
||||||
.name("sandlot")
|
.name("sandlot")
|
||||||
.description("Sandboxed development with Claude.")
|
.description("Sandboxed development with Pi.")
|
||||||
.configureHelp({ styleTitle: (str) => `${yellow}${str}${reset}` })
|
.configureHelp({ styleTitle: (str) => `${yellow}${str}${reset}` })
|
||||||
.helpOption(false)
|
.helpOption(false)
|
||||||
.addOption(new Option("-h, --help").hideHelp())
|
.addOption(new Option("-h, --help").hideHelp())
|
||||||
|
|
@ -59,19 +59,19 @@ program
|
||||||
program
|
program
|
||||||
.command("new")
|
.command("new")
|
||||||
.argument("[branch]", "branch name or prompt (if it contains spaces)")
|
.argument("[branch]", "branch name or prompt (if it contains spaces)")
|
||||||
.argument("[prompt]", "initial prompt for Claude")
|
.argument("[prompt]", "initial prompt for Pi")
|
||||||
.option("-p, --print <prompt>", "run Claude in non-interactive mode with -p")
|
.option("-p, --print <prompt>", "run Pi in non-interactive mode with -p")
|
||||||
.option("-n, --no-save", "skip auto-save after Claude exits")
|
.option("-n, --no-save", "skip auto-save after Pi exits")
|
||||||
.description("Create a new session and launch Claude")
|
.description("Create a new session and launch Pi")
|
||||||
.action(newAction)
|
.action(newAction)
|
||||||
|
|
||||||
program
|
program
|
||||||
.command("open")
|
.command("open")
|
||||||
.argument("<branch>", "branch name")
|
.argument("<branch>", "branch name")
|
||||||
.argument("[prompt]", "initial prompt for Claude")
|
.argument("[prompt]", "initial prompt for Pi")
|
||||||
.option("-p, --print <prompt>", "run Claude in non-interactive mode with -p")
|
.option("-p, --print <prompt>", "run Pi in non-interactive mode with -p")
|
||||||
.option("-n, --no-save", "skip auto-save after Claude exits")
|
.option("-n, --no-save", "skip auto-save after Pi exits")
|
||||||
.description("Open an existing Claude session")
|
.description("Open an existing Pi session")
|
||||||
.action(openAction)
|
.action(openAction)
|
||||||
|
|
||||||
program
|
program
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ const SKIP_RESOLVE = new Set([
|
||||||
"yarn.lock",
|
"yarn.lock",
|
||||||
])
|
])
|
||||||
|
|
||||||
/** Resolve conflict markers in files using Claude, then stage them. */
|
/** Resolve conflict markers in files using Pi, then stage them. */
|
||||||
export async function resolveConflicts(
|
export async function resolveConflicts(
|
||||||
files: string[],
|
files: string[],
|
||||||
cwd: string,
|
cwd: string,
|
||||||
|
|
@ -124,13 +124,13 @@ export async function resolveConflicts(
|
||||||
throw new Error(`Failed to read conflicted file: ${file}`)
|
throw new Error(`Failed to read conflicted file: ${file}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
const resolved = await vm.claudePipe(
|
const resolved = await vm.piPipe(
|
||||||
content,
|
content,
|
||||||
"resolve this merge conflict. output ONLY the resolved file content with no markdown fences, no explanation, no surrounding text.",
|
"resolve this merge conflict. output ONLY the resolved file content with no markdown fences, no explanation, no surrounding text.",
|
||||||
)
|
)
|
||||||
|
|
||||||
if (resolved.exitCode !== 0 || !resolved.stdout.trim()) {
|
if (resolved.exitCode !== 0 || !resolved.stdout.trim()) {
|
||||||
throw new Error(`Claude failed to resolve ${file}: ${resolved.stderr.trim() || "(no output)"}`)
|
throw new Error(`Pi failed to resolve ${file}: ${resolved.stderr.trim() || "(no output)"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
await Bun.write(join(cwd, file), resolved.stdout.trimEnd() + "\n")
|
await Bun.write(join(cwd, file), resolved.stdout.trimEnd() + "\n")
|
||||||
|
|
@ -162,7 +162,7 @@ export async function mergeAndClose(branch: string, opts?: { force?: boolean }):
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve conflicts with Claude
|
// Resolve conflicts with Pi
|
||||||
spin.text = `Resolving ${conflicts.length} conflict(s)`
|
spin.text = `Resolving ${conflicts.length} conflict(s)`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -210,7 +210,7 @@ export async function saveChanges(worktree: string, branch: string, message?: st
|
||||||
spin.text = "Generating commit message"
|
spin.text = "Generating commit message"
|
||||||
const diff = await $`git -C ${worktree} diff --staged`.nothrow().quiet().text()
|
const diff = await $`git -C ${worktree} diff --staged`.nothrow().quiet().text()
|
||||||
|
|
||||||
const gen = await vm.claudePipe(
|
const gen = await vm.piPipe(
|
||||||
diff,
|
diff,
|
||||||
"Write a commit message for this diff. Subject line: imperative mood, max 72 characters, no period. If the changes warrant it, add a blank line then a brief body explaining why, not what. Output only the raw commit message, no quotes or markdown.",
|
"Write a commit message for this diff. Subject line: imperative mood, max 72 characters, no period. If the changes warrant it, add a blank line then a brief body explaining why, not what. Output only the raw commit message, no quotes or markdown.",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ async function resolveStatus(
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try { await stat(s.worktree) } catch { return "idle" }
|
try { await stat(s.worktree) } catch { return "idle" }
|
||||||
if (vmRunning) {
|
if (vmRunning) {
|
||||||
const active = await vm.isClaudeActive(s.worktree, s.branch).catch(() => false)
|
const active = await vm.isPiActive(s.worktree, s.branch).catch(() => false)
|
||||||
if (active && s.in_review) return "review"
|
if (active && s.in_review) return "review"
|
||||||
if (active) return "active"
|
if (active) return "active"
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +58,7 @@ async function resolveStatus(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear in_review flags for sessions where Claude is no longer active. */
|
/** Clear in_review flags for sessions where Pi is no longer active. */
|
||||||
async function clearStaleReviews(
|
async function clearStaleReviews(
|
||||||
sessions: state.GlobalSession[],
|
sessions: state.GlobalSession[],
|
||||||
statusMap: Map<state.GlobalSession, string>,
|
statusMap: Map<state.GlobalSession, string>,
|
||||||
|
|
@ -79,7 +79,7 @@ async function backfillPrompts(sessions: { worktree: string; prompt?: string }[]
|
||||||
if (!vmRunning) return
|
if (!vmRunning) return
|
||||||
const needsPrompt = sessions.filter(s => !s.prompt)
|
const needsPrompt = sessions.filter(s => !s.prompt)
|
||||||
if (needsPrompt.length === 0) return
|
if (needsPrompt.length === 0) return
|
||||||
const result = await vm.exec(homedir() + "/.sandlot", "cat /home/ubuntu/.claude/history.jsonl 2>/dev/null").catch(() => null)
|
const result = await vm.exec(homedir() + "/.sandlot", "cat /home/ubuntu/.pi/history.jsonl 2>/dev/null").catch(() => null)
|
||||||
if (!result || result.exitCode !== 0 || !result.stdout) return
|
if (!result || result.exitCode !== 0 || !result.stdout) return
|
||||||
|
|
||||||
const byProject = new Map<string, string>()
|
const byProject = new Map<string, string>()
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ export async function action(
|
||||||
|
|
||||||
if (opts.print) {
|
if (opts.print) {
|
||||||
spin.text = "Running prompt…"
|
spin.text = "Running prompt…"
|
||||||
const result = await vm.claude(worktreeAbs, { prompt, print: opts.print })
|
const result = await vm.pi(worktreeAbs, { prompt, print: opts.print })
|
||||||
if (result.output) {
|
if (result.output) {
|
||||||
spin.stop()
|
spin.stop()
|
||||||
process.stdout.write(renderMarkdown(result.output) + "\n")
|
process.stdout.write(renderMarkdown(result.output) + "\n")
|
||||||
|
|
@ -134,7 +134,7 @@ export async function action(
|
||||||
spin.succeed("Done")
|
spin.succeed("Done")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await vm.claude(worktreeAbs, { prompt, print: opts.print })
|
await vm.pi(worktreeAbs, { prompt, print: opts.print })
|
||||||
}
|
}
|
||||||
|
|
||||||
await vm.clearActivity(worktreeAbs, branch)
|
await vm.clearActivity(worktreeAbs, branch)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export async function action(
|
||||||
|
|
||||||
if (opts.print) {
|
if (opts.print) {
|
||||||
spin.text = "Running prompt…"
|
spin.text = "Running prompt…"
|
||||||
const result = await vm.claude(session.worktree, { prompt, print: opts.print, continue: true })
|
const result = await vm.pi(session.worktree, { prompt, print: opts.print, continue: true })
|
||||||
if (result.output) {
|
if (result.output) {
|
||||||
spin.stop()
|
spin.stop()
|
||||||
process.stdout.write(renderMarkdown(result.output) + "\n")
|
process.stdout.write(renderMarkdown(result.output) + "\n")
|
||||||
|
|
@ -30,7 +30,7 @@ export async function action(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
spin.succeed("Session ready")
|
spin.succeed("Session ready")
|
||||||
await vm.claude(session.worktree, { prompt, print: opts.print, continue: true })
|
await vm.pi(session.worktree, { prompt, print: opts.print, continue: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
await vm.clearActivity(session.worktree, branch)
|
await vm.clearActivity(session.worktree, branch)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export async function action(branch: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchSpin.stop()
|
fetchSpin.stop()
|
||||||
console.log(`◆ Rebase conflicts in ${conflicts.length} file(s). Resolving with Claude...`)
|
console.log(`◆ Rebase conflicts in ${conflicts.length} file(s). Resolving with Pi...`)
|
||||||
const resolveSpin = spinner("Starting container", branch)
|
const resolveSpin = spinner("Starting container", branch)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,11 @@ Your thoughts, in brief.
|
||||||
try {
|
try {
|
||||||
if (opts.print) {
|
if (opts.print) {
|
||||||
spin.text = "Running review…"
|
spin.text = "Running review…"
|
||||||
const result = await vm.claude(session.worktree, { print: prompt })
|
const result = await vm.pi(session.worktree, { print: prompt })
|
||||||
if (result.output) process.stdout.write(result.output + "\n")
|
if (result.output) process.stdout.write(result.output + "\n")
|
||||||
} else {
|
} else {
|
||||||
spin.succeed("Session ready")
|
spin.succeed("Session ready")
|
||||||
await vm.claude(session.worktree, { prompt })
|
await vm.pi(session.worktree, { prompt })
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
spin.stop()
|
spin.stop()
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export async function action(branch: string) {
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const gen = await vm.claudePipe(
|
const gen = await vm.piPipe(
|
||||||
diff,
|
diff,
|
||||||
"Write a commit message summarizing all changes. Subject line: imperative mood, max 72 characters, no period. Add a blank line then a concise body with the key changes as bullet points. Output only the raw commit message, no quotes or markdown.",
|
"Write a commit message summarizing all changes. Subject line: imperative mood, max 72 characters, no period. Add a blank line then a concise body with the key changes as bullet points. Output only the raw commit message, no quotes or markdown.",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ export function register(program: Command) {
|
||||||
sessions.map(async (sess): Promise<[string, string]> => {
|
sessions.map(async (sess): Promise<[string, string]> => {
|
||||||
const key = `${basename(sess.repoRoot)}/${sess.branch}`
|
const key = `${basename(sess.repoRoot)}/${sess.branch}`
|
||||||
try {
|
try {
|
||||||
if (await vm.isClaudeActive(sess.worktree, sess.branch)) return [key, "active"]
|
if (await vm.isPiActive(sess.worktree, sess.branch)) return [key, "active"]
|
||||||
if (await git.isDirty(sess.worktree)) return [key, "dirty"]
|
if (await git.isDirty(sess.worktree)) return [key, "dirty"]
|
||||||
if (await git.hasNewCommits(sess.worktree)) return [key, "saved"]
|
if (await git.hasNewCommits(sess.worktree)) return [key, "saved"]
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user