fix(interactive-subagents): avoid Orca polling fan-out

This commit is contained in:
jb
2026-09-02 20:50:21 -04:00
parent 3b5a11c815
commit bd378960b2
7 changed files with 110 additions and 21 deletions
@@ -153,18 +153,28 @@ function readCompletionFile(path: string): PollResult | null {
return { reason: "sentinel", exitCode };
}
type PollOptions = {
interval: number;
sessionFile?: string;
sentinelFile?: string;
completionFile?: string;
onTick?: (elapsed: number) => void;
};
/** Avoid launching a terminal CLI reader when a local completion signal is authoritative. */
function shouldPollSurface(
options: Pick<PollOptions, "sessionFile" | "sentinelFile" | "completionFile">,
): boolean {
return !options.sessionFile && !options.sentinelFile && !options.completionFile;
}
export const __pollForExitTest__ = { interpretExitSidecar, readCompletionFile };
export async function pollForExit(
surface: string,
signal: AbortSignal,
options: {
interval: number;
sessionFile?: string;
sentinelFile?: string;
completionFile?: string;
onTick?: (elapsed: number) => void;
},
options: PollOptions,
readSurface: (surface: string, lines?: number) => Promise<string> = readScreenAsync,
): Promise<PollResult> {
const start = Date.now();
@@ -197,12 +207,14 @@ export async function pollForExit(
} catch {}
}
try {
const screen = await readScreenAsync(surface, 5);
const match = screen.match(/__SUBAGENT_DONE_(\d+)__/);
if (match) return { reason: "sentinel", exitCode: Number.parseInt(match[1], 10) };
} catch {
// Surface reads are best-effort. Filesystem completion remains authoritative.
if (shouldPollSurface(options)) {
try {
const screen = await readSurface(surface, 5);
const match = screen.match(/__SUBAGENT_DONE_(\d+)__/);
if (match) return { reason: "sentinel", exitCode: Number.parseInt(match[1], 10) };
} catch {
// Surface reads are a best-effort fallback when no completion file is available.
}
}
const elapsed = Math.floor((Date.now() - start) / 1000);