Move ListSession interface to module scope and harden error paths
Simplify stale-lock recovery to just retry the loop instead of nesting a second mkdir, and surface lock failures in actionRemove rather than letting them propagate as unhandled exceptions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ac168d3019
commit
3d07643547
|
|
@ -6,6 +6,11 @@ import * as vm from "../vm.ts"
|
||||||
import * as state from "../state.ts"
|
import * as state from "../state.ts"
|
||||||
import { die, reset, dim, green, yellow, cyan, magenta, red } from "../fmt.ts"
|
import { die, reset, dim, green, yellow, cyan, magenta, red } from "../fmt.ts"
|
||||||
|
|
||||||
|
interface ListSession extends state.Session {
|
||||||
|
repoRoot: string
|
||||||
|
repo?: string
|
||||||
|
}
|
||||||
|
|
||||||
// ── Shared rendering ─────────────────────────────────────────────────
|
// ── Shared rendering ─────────────────────────────────────────────────
|
||||||
|
|
||||||
const styleDefs: [string, string, string][] = [
|
const styleDefs: [string, string, string][] = [
|
||||||
|
|
@ -17,9 +22,9 @@ const styles = Object.fromEntries(
|
||||||
)
|
)
|
||||||
|
|
||||||
function renderSessions(
|
function renderSessions(
|
||||||
sessions: { branch: string; prompt?: string }[],
|
sessions: ListSession[],
|
||||||
statuses: Record<string, string>,
|
statuses: Record<string, string>,
|
||||||
keyFn: (s: { branch: string }) => string,
|
keyFn: (s: ListSession) => string,
|
||||||
) {
|
) {
|
||||||
const branchWidth = Math.max(6, ...sessions.map(s => s.branch.length))
|
const branchWidth = Math.max(6, ...sessions.map(s => s.branch.length))
|
||||||
const cols = process.stdout.columns || 80
|
const cols = process.stdout.columns || 80
|
||||||
|
|
@ -49,7 +54,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)
|
const active = await vm.isClaudeActive(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"
|
||||||
}
|
}
|
||||||
|
|
@ -120,11 +125,6 @@ async function backfillPrompts(sessions: { worktree: string; prompt?: string }[]
|
||||||
|
|
||||||
// ── Commands ─────────────────────────────────────────────────────────
|
// ── Commands ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
interface ListSession extends state.Session {
|
|
||||||
repoRoot: string
|
|
||||||
repo?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function action(opts: { json?: boolean; all?: boolean; add?: string; remove?: string }) {
|
export async function action(opts: { json?: boolean; all?: boolean; add?: string; remove?: string }) {
|
||||||
if (opts.add) return actionAdd(opts.add)
|
if (opts.add) return actionAdd(opts.add)
|
||||||
if (opts.remove) return actionRemove(opts.remove)
|
if (opts.remove) return actionRemove(opts.remove)
|
||||||
|
|
@ -185,7 +185,12 @@ async function actionAdd(dir: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function actionRemove(dir: string) {
|
async function actionRemove(dir: string) {
|
||||||
const removed = await state.unregisterProject(dir)
|
let removed: boolean
|
||||||
|
try {
|
||||||
|
removed = await state.unregisterProject(dir)
|
||||||
|
} catch {
|
||||||
|
die("Could not acquire registry lock")
|
||||||
|
}
|
||||||
if (removed) {
|
if (removed) {
|
||||||
console.log(`${red}-${reset} ${dir}`)
|
console.log(`${red}-${reset} ${dir}`)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,7 @@ async function withGlobalLock<T>(fn: () => Promise<T>): Promise<T> {
|
||||||
const info = await stat(lockPath)
|
const info = await stat(lockPath)
|
||||||
if (Date.now() - info.mtimeMs > 300_000) {
|
if (Date.now() - info.mtimeMs > 300_000) {
|
||||||
await rmdir(lockPath).catch(() => {})
|
await rmdir(lockPath).catch(() => {})
|
||||||
// Retry mkdir immediately instead of continuing the loop
|
continue
|
||||||
try {
|
|
||||||
await mkdir(lockPath)
|
|
||||||
break
|
|
||||||
} catch {}
|
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
if (i === 19) throw new Error("Could not acquire registry lock")
|
if (i === 19) throw new Error("Could not acquire registry lock")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user