refactor(host-service,desktop): consolidate terminal session listing into terminal.list

Merged
SA
3mo ago
+102-150

First PR of the terminal-first mobile push: the host's terminal listing becomes one resource-search endpoint that mobile can call host-wide.

What changed

  • terminal.listSessions({workspaceId}) → terminal.list({workspaceId?}) — same daemon-truth semantics (in-memory sessions merged with alive daemon PTYs joined to active workspace rows), now host-wide when no filter is passed. Orphaned daemon rows (originWorkspaceId nulled by workspace deletion) are skipped in the unfiltered view; each merged row's workspaceId comes from its origin row.
  • terminal.countBackgroundSessions deleted. Its only consumer (BackgroundTerminalsButton) also queried the session list, so the two polls are merged into one terminal.list query (slow interval closed / fast interval open) and the count derives client-side against the debounced attachment set — same badge semantics, one endpoint fewer. The two refetch-interval helpers collapse into getBackgroundTerminalRefetchInterval.
  • Mechanical rename across all consumers: desktop v2 terminal panes/hooks, web's listHostTerminals, CLI terminals list, SDK terminals.list, MCP terminals tool, host-service integration tests (which now also cover the unfiltered host-wide path).
  • terminal.daemon.listSessions is untouched — it's the supervisor's daemon-PTY view (terminal settings), a different resource.

Version-skew note

An older client polling an upgraded host gets NOT_FOUND on the removed names during the mismatch window (remote hosts can lag the desktop/CLI). Failure mode is a failed background list/count poll — no crash path. Kept clean rather than shipping deprecated aliases; flagging for reviewer judgment.

Verification

  • bun run typecheck — 37/37 tasks pass
  • bun run lint — clean
  • packages/host-service terminal integration tests: 9 pass (incl. new host-wide assertion)
  • BackgroundTerminalsButton.utils.test.ts: 4 pass

Summary by cubic

Consolidated terminal session listing into terminal.list({ workspaceId? }), enabling a host-wide view when omitted. Removed terminal.countBackgroundSessions; desktop now derives the background count from the same list and uses a single poll.

  • Refactors

    • terminal.listSessions({workspaceId}) → terminal.list({workspaceId?}) with the same daemon-truth merge; host-wide when unfiltered. Orphaned daemon rows are skipped; each row’s workspaceId comes from its origin.
    • Deleted terminal.countBackgroundSessions. BackgroundTerminalsButton now uses one terminal.list query with getBackgroundTerminalRefetchInterval.
    • Renamed server helper listWorkspaceTerminalSessions → listLiveTerminalSessions (behavior unchanged).
    • Updated consumers: desktop terminal panes/hooks (including background/adopt flows), web listHostTerminals, CLI terminals list, SDK terminals.list, MCP terminals tool, and tests/docs. Integration tests now also cover the unfiltered host-wide path.
  • Migration

    • Replace all usage of terminal.listSessions with terminal.list and stop calling terminal.countBackgroundSessions.
    • Expect temporary NOT_FOUND errors on older clients during staggered upgrades; only background polling fails and recovers after update.
    • Desktop constants collapsed to getBackgroundTerminalRefetchInterval (single source for open/closed polling).

Summary by CodeRabbit

  • Improvements
    • Unified terminal session listings across the desktop app, web, mobile, CLI, SDK, and integrations.
    • Improved background-terminal status updates, with faster refreshes when the panel is open and efficient periodic updates when closed.
    • Terminal sessions are now more reliably associated with their actual workspace, including sessions recovered after a restart.
    • Improved synchronization after adopting, stopping, migrating, or closing terminal sessions.
  • Documentation
    • Updated terminal listing API documentation and usage guidance.