Compare commits

..

7 Commits

3 changed files with 37 additions and 8 deletions

View File

@ -97,8 +97,10 @@ export async function action(
}
const spin = spinner("Creating worktree", branch)
let branchCreated = false
try {
await git.createWorktree(branch, worktreeAbs, root)
const wt = await git.createWorktree(branch, worktreeAbs, root)
branchCreated = wt.branchCreated
const symlinkPath = join(root, '.sandlot', branch)
await mkdir(dirname(symlinkPath), { recursive: true })
await symlink(worktreeAbs, symlinkPath)
@ -109,7 +111,7 @@ export async function action(
} catch (err) {
spin.fail(String((err as Error).message ?? err))
await git.removeWorktree(worktreeAbs, root).catch(() => {})
await git.deleteLocalBranch(branch, root).catch(() => {})
if (branchCreated) await git.deleteLocalBranch(branch, root).catch(() => {})
await unlinkSessionSymlink(root, branch)
process.exit(1)
}

View File

@ -11,13 +11,22 @@ export async function action(branch: string, extra: string | undefined, opts: {
let prompt = `
You're a grumpy old senior software engineer. You need to review some code my co-worker wrote.
Launch three code review agents to review the changes between this branch and main with the following specializations:
Launch four agents to review the changes between this branch and main with the following specializations:
1. Checks CLAUDE.md compliance
2. Looks specifically for bugs
3. Looks for opportunities to simplify code
3. Also looks specifically for bugs
4. Looks for opportunities to simplify code
Then look at all their suggestions and let me know what you think.
Each one should deliver you a report in this format (the <tags> are just for you, not part of their output):
<agentOutput>
# Problem Identified
Description of problem.
</agentOutput>
Once the agents are done, look at all their suggestions and let me know what you think.
`
if (extra) prompt += "\n\n" + extra

View File

@ -36,7 +36,7 @@ export async function branchExists(branch: string, cwd?: string, opts?: { fetch?
}
/** Create a worktree for the given branch. */
export async function createWorktree(branch: string, worktreePath: string, cwd: string): Promise<void> {
export async function createWorktree(branch: string, worktreePath: string, cwd: string): Promise<{ branchCreated: boolean }> {
// Clean up stale worktree path if it exists
if (existsSync(worktreePath)) {
await $`git worktree remove ${worktreePath} --force`.cwd(cwd).nothrow().quiet()
@ -49,7 +49,20 @@ export async function createWorktree(branch: string, worktreePath: string, cwd:
const exists = await branchExists(branch, cwd, { fetch: true })
let result
let switchedFromBranch = false
if (exists === "local") {
const main = await mainBranch(cwd)
if (branch === main) {
throw new Error(`Cannot create a worktree for the main branch "${main}".`)
}
// If the branch is checked out in the main worktree, switch it to main first
if (await currentBranch(cwd) === branch) {
if (await isDirty(cwd)) {
throw new Error(`Cannot move branch "${branch}" to a worktree: the main worktree has uncommitted changes. Commit or stash them first.`)
}
await checkout(main, cwd)
switchedFromBranch = true
}
result = await $`git worktree add ${worktreePath} ${branch}`.cwd(cwd).nothrow().quiet()
} else if (exists === "remote") {
result = await $`git worktree add ${worktreePath} -b ${branch} origin/${branch}`.cwd(cwd).nothrow().quiet()
@ -58,8 +71,10 @@ export async function createWorktree(branch: string, worktreePath: string, cwd:
result = await $`git worktree add -b ${branch} ${worktreePath}`.cwd(cwd).nothrow().quiet()
}
if (result.exitCode !== 0) {
if (switchedFromBranch) await checkout(branch, cwd).catch(() => {})
throw new Error(`Failed to create worktree for "${branch}": ${result.stderr.toString().trim()}`)
}
return { branchCreated: exists !== "local" }
}
/** Remove a worktree. Silently succeeds if the worktree is already gone. */
@ -228,6 +243,9 @@ export async function branchDiff(branch: string, main: string, cwd: string): Pro
/** Detect the main branch name (main or master). */
export async function mainBranch(cwd?: string): Promise<string> {
const dir = cwd ?? "."
const result = await $`git -C ${dir} rev-parse --verify --quiet refs/heads/main`.nothrow().quiet()
return result.exitCode === 0 ? "main" : "master"
const main = await $`git -C ${dir} rev-parse --verify --quiet refs/heads/main`.nothrow().quiet()
if (main.exitCode === 0) return "main"
const master = await $`git -C ${dir} rev-parse --verify --quiet refs/heads/master`.nothrow().quiet()
if (master.exitCode === 0) return "master"
throw new Error("Could not detect main branch: neither \"main\" nor \"master\" exists.")
}