1.9 KiB
Prompt worktree timeout cleanup
Clear waitForWorktree() timers to avoid retaining closures for 5 minutes
Summary
packages/app/src/components/prompt-input.tsx creates a 5-minute setTimeout inside waitForWorktree() as part of a Promise.race. If the worktree becomes ready quickly, the timeout still stays scheduled until it fires, retaining its closure (which can capture session and UI state) for up to 5 minutes. Repeated sends can accumulate many concurrent long-lived timers.
This spec makes the timeout cancelable and clears it when the race finishes.
Scoped files (parallel-safe)
packages/app/src/components/prompt-input.tsx
Goals
- Ensure the 5-minute timeout is cleared as soon as
Promise.raceresolves - Avoid retaining large closures unnecessarily
- Keep behavior identical for real timeouts
Non-goals
- Changing the worktree wait UX
- Changing the WorktreeState API
Proposed approach
-
Track the timeout handle explicitly:
let timeoutId: number | undefinedtimeoutId = window.setTimeout(...)
-
After
Promise.race(...)resolves (success, abort, or timeout), callclearTimeout(timeoutId)when set. -
Keep the existing 5-minute duration and result handling.
Implementation steps
-
In
waitForWorktree()create the timeout promise with an outertimeoutIdvariable -
After awaiting the race, clear the timeout if it exists
-
Ensure
pending.delete(session.id)and UI cleanup behavior remains unchanged
Acceptance criteria
- When the worktree becomes ready quickly, no 5-minute timeout remains scheduled
- When the worktree truly times out, behavior is unchanged (same error shown, same cleanup)
Validation plan
- Manual:
- Trigger prompt send in a directory that is already ready; confirm no long timers remain (devtools)
- Trigger a worktree pending state and confirm:
- timeout fires at ~5 minutes
- cleanup runs