Skip to content

vscode: add manual-reconnect affordance to terminal give-up state #939

@amrmelsayed

Description

@amrmelsayed

Context

Follows on from #936 (terminal-adapter reconnect-loop fix). Once that work lands, the terminal will give up after N failed reconnect attempts and print a red "max reconnect attempts reached" message. At that point the terminal is dead — the user has to close the tab and re-open via the sidebar / command palette to recover. Three clicks across two UI surfaces, with the user needing to know where each control lives.

This issue tracks adding a manual-reconnect affordance: a one-click recovery control surfaced where the user just saw the failure, so they don't have to do the close+reopen dance.

Why split from #936

#936's original scope bundled the spam-loop fix (adapter-level resilience: backoff, max-retries, state reset, identity-checked close-events) with the recovery-after-give-up UX. They're orthogonal concerns:

Splitting lets #936's PR land cleanly without dragging in UX work, and lets this issue go through PIR (where the design calls and visual verification belong) without being gated on the defect fix.

Three shape options

Each works; the plan-approval gate picks one (or composes).

Shape 1 — Terminal link (cheapest, ~15-20 LOC)

The give-up message itself becomes a clickable token:

[Codev: Connection lost — max reconnect attempts reached. Click Reconnect to try again]
                                                                 ^^^^^^^^^
                                                                 clickable

Mechanism: vscode.window.registerTerminalLinkProvider — extensions can register link providers that detect specific patterns in terminal text and surface them as clickable links. Click → run command → adapter.reconnect().

Pros: localized to the terminal pane where the user just saw the failure; no cross-surface jump; one click to recover; minimal new surface area.

Cons: discoverable only if the user reads the failure message; the link styling depends on the user's theme's terminal.foreground vs link-decoration tokens.

Shape 2 — Toast notification with button

After N failed attempts, fire a vscode.window.showWarningMessage with [Reconnect] [Dismiss] actions. Same mechanism the existing gate-toast uses (packages/vscode/src/notifications/gate-toast.ts).

Pros: high visibility — the user sees the recovery option even if they weren't watching the terminal at the give-up moment; toast affordances are a familiar pattern in the extension.

Cons: more intrusive (toast slides in over other UI); harder to dismiss if the user wants to acknowledge the failure but not act on it; doesn't preserve the failure context the way the in-terminal message does.

Shape 3 — Status-bar action

When any terminal hits the give-up state, flip the Codev status-bar chip from Codev: Connected to Codev: Reconnect Terminal (with a click action calling the appropriate adapter.reconnect()).

Pros: persistent, always-visible (no time-out like toast); doesn't require the user to be looking at the terminal.

Cons: ambiguous when multiple terminals are in give-up state (which one does "Reconnect" target?); status-bar is shared real-estate with other indicators; less localized than Shape 1.

Recommended default for the plan

Shape 1 (terminal link). Justification: lowest cost, most contextually appropriate (recovery affordance lives where the failure was shown), no ambiguity with multi-terminal scenarios, no contention for status-bar real estate, doesn't add a toast to the user's notification stream.

Shapes 2 and 3 are optional follow-ons if usage shows Shape 1 is insufficient.

Design calls for plan-approval

  1. Affordance shape: Shape 1 / 2 / 3 / combination (see above; recommended default: Shape 1).
  2. Reconnect attempts counter on retry: does clicking "Reconnect" reset the attempt counter to 0 (full fresh retry chain), or restart from the last attempt (1 more retry, then give up again)? Recommended default: full reset — the user is signaling intent, so honor it with a full retry budget.
  3. Visual styling of the terminal link (Shape 1 only): use VSCode's default link color tokens, or a Codev-specific accent? Recommended default: VSCode's default link styling so it auto-themes against dark/light/high-contrast.
  4. Repeated give-up cycles: if the user clicks "Reconnect", retries fail again, gives up again — does the new link still work, or do we transition to a different state (e.g. "persistent failure — restart Tower")? Recommended default: link still works every time; trust the user to know when to escalate to a Tower restart.

Acceptance

Out of scope

Why PIR

Real design surface (three shape choices with tradeoffs documented above) and the result is user-visible UI behavior that needs running-app verification across themes — both gates of PIR earn their keep here. AIR would technically fit if Shape 1 is locked in pre-spawn, but the plan-approval gate is worth having for the four design-call defaults to land deliberately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/terminalArea: Terminal-specific (PTY, vscode terminal pane)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions