fix(server): harden worktree archive with parallel teardown
Fan out agent close + terminal kill concurrently with Promise.allSettled so one failure never leaves the worktree half-dead. Await real PTY exit with SIGHUP→SIGKILL escalation before rm to avoid EBUSY races. Tolerate missing repoRoot and retry directory removal with backoff. Purge stale client workspace layout/tab state after successful archive.
This commit is contained in:
@@ -28,6 +28,10 @@ export interface TerminalManager {
|
||||
registerCwdEnv(options: { cwd: string; env: Record<string, string> }): void;
|
||||
getTerminal(id: string): TerminalSession | undefined;
|
||||
killTerminal(id: string): void;
|
||||
killTerminalAndWait(
|
||||
id: string,
|
||||
options?: { gracefulTimeoutMs?: number; forceTimeoutMs?: number },
|
||||
): Promise<void>;
|
||||
listDirectories(): string[];
|
||||
killAll(): void;
|
||||
subscribeTerminalsChanged(listener: TerminalsChangedListener): () => void;
|
||||
@@ -200,6 +204,21 @@ export function createTerminalManager(): TerminalManager {
|
||||
removeSessionById(id, { kill: true });
|
||||
},
|
||||
|
||||
async killTerminalAndWait(
|
||||
id: string,
|
||||
options?: { gracefulTimeoutMs?: number; forceTimeoutMs?: number },
|
||||
): Promise<void> {
|
||||
const session = terminalsById.get(id);
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await session.killAndWait(options);
|
||||
} finally {
|
||||
removeSessionById(id, { kill: false });
|
||||
}
|
||||
},
|
||||
|
||||
listDirectories(): string[] {
|
||||
return Array.from(terminalsByCwd.keys());
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user