Files
opencode/specs/14-prompt-worktree-timeout-cleanup.md
2026-01-27 15:25:07 -06:00

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.race resolves
  • 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 | undefined
    • timeoutId = window.setTimeout(...)
  • After Promise.race(...) resolves (success, abort, or timeout), call clearTimeout(timeoutId) when set.

  • Keep the existing 5-minute duration and result handling.


Implementation steps

  1. In waitForWorktree() create the timeout promise with an outer timeoutId variable

  2. After awaiting the race, clear the timeout if it exists

  3. 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