Skip to content

fix(client): register running sessions missed while disconnected - #53012

Open
kitlangton wants to merge 2 commits into
devfrom
reconnect-family-sync
Open

kitlangton wants to merge 2 commits into
devfrom
reconnect-family-sync

Conversation

@kitlangton

@kitlangton kitlangton commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Why

When the TUI's event stream drops while a subagent starts, or the TUI starts while one is already running, it never receives that child's session.created. Reconnect hydration restores the child's running status from /api/session/active, but never loads the child's session info, so the child never joins its root's family. Anything derived from the family is then wrong until the TUI restarts: the open picker shows the root as idle while its background subagent is still running, and tab busy state and family cost miss the child too.

What Changes

After the reconnect snapshot is applied, any running session the client has no info for is synced, which registers it under its root.

Before: TUI offline → background subagent starts → TUI reconnects → Release checklist row in Ctrl-O shows no spinner, although its child is running.

After: Same sequence → the row shows the running spinner.

sequenceDiagram
    participant TUI
    participant Server
    Note over TUI,Server: TUI disconnected
    Server-)TUI: session.created (child), missed
    Server-)TUI: session.execution.started (child), missed
    TUI->>Server: reconnect, server.connected
    TUI->>Server: GET /api/session/active
    Server-->>TUI: { child: running }
    TUI->>Server: GET /api/session/{child}  (new)
    Server-->>TUI: child info with parentID
    Note over TUI: child joins the root's family, root row shows running
Loading

Demo

Real production TUI driven by opencode-drive with a simulated model. Same script and fixture for both: the TUI's connections are refused, a background subagent starts and holds its response, connections heal, then Ctrl-O filters to the root. Left: v2 at d1f8f5b35e. Right: this branch.

reconnect-child-family.mp4

Scope

Hydration now loads info only for sessions the snapshot reports as running and the client has never seen. That covers sessions created while disconnected and sessions already running when the client started, which had the same problem: a running child under a root that isn't open never joined its family. On reconnect this matches what a client that stayed connected would hold, since the live session.created handler already loads every new session server-wide. It reads nothing beyond session info.

Known limits, unchanged by this PR:

  • A child that finished while disconnected still isn't registered, because only running sessions affect activity.
  • A running grandchild whose idle parent is unknown registers under that parent rather than the root.
  • A session deleted while its info read is in flight can produce the same "Request failed" toast in the app (or reappear as idle) as the existing session.created path.

This does not change how execution status itself is reconciled. The original report, a spinner still running long after a session went idle, happened around managed-service restarts and has not been reproduced yet.

Verification

cd packages/client
bun run test test/solid-data.test.ts -t "family|activity"
bun run test
bun typecheck
cd ../.. && bun run check
  • The new adds running sessions created while disconnected to their family test fails without the change and passes with it; the 8 family/activity tests pass.
  • Full client suite: 176 pass, 4 fail. The same 4 (public import boundaries, exposes every standard HTTP API group, and two session HTTP/Effect contract tests) fail identically on the untouched base.
  • bun run check: 36/36 tasks succeed.
  • End to end with test(drive): add running-indicator gauntlet and reconnect family probe opencode-drive#105: reconnect-child-family.ts fails on d1f8f5b35e (rootRowRunning: false) and passes here (rootRowRunning: true). Gauntlet seed 5, which found this, failed twice on d1f8f5b35e and passes on this branch along with seeds 4 and 8.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant