Add ensureSession to recreate missing worktrees
This commit is contained in:
parent
c85af793cd
commit
7ebbfad8f2
|
|
@ -1,5 +1,6 @@
|
||||||
import { join } from "path"
|
import { basename, join } from "path"
|
||||||
import { unlink } from "fs/promises"
|
import { homedir } from "os"
|
||||||
|
import { mkdir, symlink, unlink } from "fs/promises"
|
||||||
import { $ } from "bun"
|
import { $ } from "bun"
|
||||||
import * as git from "../git.ts"
|
import * as git from "../git.ts"
|
||||||
import * as vm from "../vm.ts"
|
import * as vm from "../vm.ts"
|
||||||
|
|
@ -18,6 +19,40 @@ export async function requireSession(branch: string): Promise<{ root: string; se
|
||||||
return { root, session }
|
return { root, session }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Look up a session by branch, recreating the worktree/session if the branch exists but the session doesn't. */
|
||||||
|
export async function ensureSession(branch: string): Promise<{ root: string; session: Session }> {
|
||||||
|
const root = await git.repoRoot()
|
||||||
|
const existing = await state.getSession(root, branch)
|
||||||
|
if (existing) return { root, session: existing }
|
||||||
|
|
||||||
|
// No session — check if the branch exists
|
||||||
|
const exists = await git.branchExists(branch, root)
|
||||||
|
if (!exists) {
|
||||||
|
die(`No session or branch found for "${branch}".`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate worktree and session
|
||||||
|
const worktreeAbs = join(homedir(), '.sandlot', basename(root), branch)
|
||||||
|
try {
|
||||||
|
await git.createWorktree(branch, worktreeAbs, root)
|
||||||
|
await mkdir(join(root, '.sandlot'), { recursive: true })
|
||||||
|
await symlink(worktreeAbs, join(root, '.sandlot', branch))
|
||||||
|
} catch (err) {
|
||||||
|
// Clean up on failure — but do NOT delete the branch (it already existed)
|
||||||
|
await git.removeWorktree(worktreeAbs, root).catch(() => {})
|
||||||
|
await unlink(join(root, '.sandlot', branch)).catch(() => {})
|
||||||
|
die(`Failed to recreate session: ${(err as Error).message ?? err}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const session: Session = {
|
||||||
|
branch,
|
||||||
|
worktree: worktreeAbs,
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
|
}
|
||||||
|
await state.setSession(root, session)
|
||||||
|
return { root, session }
|
||||||
|
}
|
||||||
|
|
||||||
/** Tear down a session: clear activity, remove worktree, unlink symlink, remove state. */
|
/** Tear down a session: clear activity, remove worktree, unlink symlink, remove state. */
|
||||||
export async function teardownSession(root: string, branch: string, worktree: string): Promise<void> {
|
export async function teardownSession(root: string, branch: string, worktree: string): Promise<void> {
|
||||||
await vm.clearActivity(worktree, branch)
|
await vm.clearActivity(worktree, branch)
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@ import * as vm from "../vm.ts"
|
||||||
import * as state from "../state.ts"
|
import * as state from "../state.ts"
|
||||||
import { spinner } from "../spinner.ts"
|
import { spinner } from "../spinner.ts"
|
||||||
import { renderMarkdown } from "../markdown.ts"
|
import { renderMarkdown } from "../markdown.ts"
|
||||||
import { requireSession, saveChanges } from "./helpers.ts"
|
import { ensureSession, saveChanges } from "./helpers.ts"
|
||||||
|
|
||||||
export async function action(
|
export async function action(
|
||||||
branch: string,
|
branch: string,
|
||||||
prompt: string | undefined,
|
prompt: string | undefined,
|
||||||
opts: { print?: string; save?: boolean },
|
opts: { print?: string; save?: boolean },
|
||||||
) {
|
) {
|
||||||
const { root, session } = await requireSession(branch)
|
const { root, session } = await ensureSession(branch)
|
||||||
|
|
||||||
const effectivePrompt = opts.print || prompt
|
const effectivePrompt = opts.print || prompt
|
||||||
if (effectivePrompt) {
|
if (effectivePrompt) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user