Skip to content

fix(dashboard): reveal remote agent sessions from the dashboard - #16732

Closed
PannenetsF wants to merge 2 commits into
stablyai:mainfrom
PannenetsF:fix/dashboard-remote-session-reveal
Closed

PannenetsF wants to merge 2 commits into
stablyai:mainfrom
PannenetsF:fix/dashboard-remote-session-reveal

Conversation

@PannenetsF

Copy link
Copy Markdown
Contributor

Summary

Fixes #16731.

Clicking an agent in the Agent Dashboard (pop-out window or in-window drawer) failed to open remote/SSH sessions: the terminal preview falsely reported "this agent's pane has closed", and "Open worktree" never focused the agent's pane. Entering the same remote project from the sidebar worked, which isolated the bug to the dashboard reveal path.

Two root causes, both fixed here:

  1. Lost focus event. activateTabAndFocusPane dispatches FOCUS_TERMINAL_PANE_EVENT one requestAnimationFrame after setActiveTab. A cold-parked TerminalPane mounts its focus listener several frames later (or behind the SSH connect gate), so the dispatch landed on no listener. The focus detail is now parked in a pending registry; a late-mounting pane consumes it on the way up, and the live listener clears it on success.
  2. Incomplete worktree activation. The dashboard reveal paths called bare setActiveWorktree, skipping setActiveView('terminal'), ensureWorktreeHasInitialTerminal, and resumeSleepingAgentSessionsForWorktree. They now use activateAndRevealWorktree(..., { revealInSidebar: false }) — the same helper the sidebar's working path uses.

Additionally, when an SSH PTY has no serializable snapshot (no getBufferSnapshot on SshPtyProvider, no headless emulator, no mounted renderer serializer), the preview now shows an honest "Live preview is unavailable for this remote session — open the worktree to view the terminal." instead of the false "pane has closed". A full live SSH preview (relay buffer-snapshot RPC) is a follow-up enhancement noted in the issue.

Screenshots

No visual change for local sessions. For remote sessions without a mounted pane, the preview message changes from "No live terminal — this agent's pane has closed." to "Live preview is unavailable for this remote session — open the worktree to view the terminal."

Testing

  • oxlint on all changed files (via lint-staged pre-commit hook)
  • tsc --noEmit -p config/tsconfig.tc.web.json
  • vitest on affected tests + the full terminal-pane/, dashboard/, dashboard-popout/ directories (236 files, 3010 tests)
  • pnpm test (full suite) — not run; the change is renderer-only and covered by the directory sweep above
  • pnpm build — not run
  • Added/updated tests: pending-pane-focus.test.ts (new registry), activate-tab-and-focus-pane.test.ts (parking), focus-terminal-pane-event.test.ts (clearing on success), useDashboardPopoutBridge.test.tsx (reveal uses activateAndRevealWorktree), AgentTerminalPreview.test.tsx (remote message)

AI Review Report

Reviewed the focus-dispatch race and the reveal activation gap. Main risks checked:

  • Double-focus: the live listener and the mount-consumer could both fire. Verified clearPendingPaneFocus runs on successful resolution, and consumePendingPaneFocus is destructive, so only one path fires per detail.
  • Stale focus on a genuinely missing pane: fail-closed behavior is preserved — handleFocusTerminalPaneDetail still calls surfaceStaleAgentRow when the leaf cannot resolve; the parked copy is only cleared on success.
  • Effect ordering: the consuming effect relies on managerRef.current being set by the lifecycle effect, which is declared before the global-effects hook in TerminalPane.tsx, so React runs it first. Confirmed replayTerminalLayout creates panes synchronously in that same lifecycle effect.
  • Cross-platform: no platform-specific code added. The SSH ptyId check uses the shared parseAppSshPtyId parser, which is host-agnostic. Keyboard shortcuts, labels, and paths are untouched.
  • React hooks rules: useConsumePendingPaneFocus is called unconditionally; the hook file keeps the global-effects file under the 300-line max-lines limit (no max-lines disables added, per project rules).

Security Audit

No new input handling, command execution, path handling, auth, secrets, or IPC surface. The pending-focus registry stores a FocusTerminalPaneDetail (tabId/leafId/flags) in memory with a 15s TTL — no persistence, no cross-origin exposure. The SSH ptyId is parsed with the existing shared parser and only used to select a display string. No follow-up needed.

Notes

@coderabbitai

coderabbitai Bot commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The changes add deferred, per-tab terminal-pane focus storage with a 15-second TTL. Mounted panes consume parked focus requests, and successful live focus clears them. Dashboard reveal tests verify worktree activation and pane focusing. SSH terminal previews use a remote-specific unavailable message when no snapshot exists. English, Spanish, Japanese, Korean, and Chinese locales include the new message.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: 🔵 Low · up to 8211b

Dashboard reveal behavior may regress without the test detecting use of the wrong activation flow. Update the assertion before merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 13 files. (5 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: fixing dashboard access to remote agent sessions.
Description check ✅ Passed The description provides the problem, root causes, implemented changes, linked issue (#16731), visual behavior, testing results, risk review, security notes, and scope limitations. It uses alternative…
Linked Issues check ✅ Passed The PR meets the coding requirements in [#16731]. activateTabAndFocusPane parks focus details, and the terminal-pane consumer retrieves them when a pane mounts late. Successful live handling clears …
Out of Scope Changes check ✅ Passed The changed code stays within [#16731]. The pending-focus registry, terminal-pane integration, dashboard activation changes, preview message, localization entries, and regression tests directly suppor…
Full details: Docstring Coverage

Explanation

Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 13 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 732e15d6-e792-4e53-8c46-1506c9065f5d

📥 Commits

Reviewing files that changed from the base of the PR and between 5631aa0 and e0febd41f3e6737e3e5cbd6ce5cb991432f5d8a5.

📒 Files selected for processing (18)
  • src/renderer/src/components/dashboard-popout/AgentTerminalPreview.test.tsx
  • src/renderer/src/components/dashboard-popout/AgentTerminalPreview.tsx
  • src/renderer/src/components/dashboard/AgentDashboardDrawer.tsx
  • src/renderer/src/components/dashboard/useDashboardPopoutBridge.test.tsx
  • src/renderer/src/components/dashboard/useDashboardPopoutBridge.ts
  • src/renderer/src/components/terminal-pane/focus-terminal-pane-event.test.ts
  • src/renderer/src/components/terminal-pane/focus-terminal-pane-event.ts
  • src/renderer/src/components/terminal-pane/use-pending-pane-focus-consumer.ts
  • src/renderer/src/components/terminal-pane/use-terminal-pane-global-effects.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/lib/activate-tab-and-focus-pane.test.ts
  • src/renderer/src/lib/activate-tab-and-focus-pane.ts
  • src/renderer/src/lib/pending-pane-focus.test.ts
  • src/renderer/src/lib/pending-pane-focus.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread src/renderer/src/i18n/locales/es.json Resolved
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

1 similar comment
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown

Greptile Summary

This PR repairs dashboard navigation to remote agent sessions by using the complete worktree-activation path and retaining pane-focus intent until a cold terminal pane mounts.

  • Routes drawer and popout reveals through activateAndRevealWorktree, preserving execution-host selection and terminal/session recovery.
  • Adds a short-lived, destructive pending-focus registry and consumes parked focus during terminal-pane mount.
  • Distinguishes unavailable SSH previews from genuinely closed local panes and adds localized messaging.
  • Expands focused tests for reveal routing, pending-focus lifecycle, live-listener cleanup, and remote preview presentation.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking defects identified.

The worktree activation remains synchronous for existing dashboard tabs, pending focus is consumed only after pane-manager setup, and successful live handling clears the parked copy to avoid duplicate focus.

Important Files Changed

Filename Overview
src/renderer/src/lib/pending-pane-focus.ts Adds a tab-keyed, 15-second focus-intent registry with destructive consumption and explicit cleanup.
src/renderer/src/lib/activate-tab-and-focus-pane.ts Parks focus details alongside the existing animation-frame event and clears superseded requests.
src/renderer/src/components/terminal-pane/use-pending-pane-focus-consumer.ts Replays parked focus after pane-manager initialization using the existing focus-resolution path.
src/renderer/src/components/terminal-pane/focus-terminal-pane-event.ts Clears the parked copy after the live listener successfully resolves and focuses a pane.
src/renderer/src/components/dashboard/useDashboardPopoutBridge.ts Routes popout reveal requests through complete worktree activation before selecting the requested tab and pane.
src/renderer/src/components/dashboard/AgentDashboardDrawer.tsx Applies the same full activation flow to in-window dashboard reveals.
src/renderer/src/components/dashboard-popout/AgentTerminalPreview.tsx Presents an accurate remote-preview-unavailable message for recognized SSH PTY identifiers.

Sequence Diagram

sequenceDiagram
  participant D as Agent Dashboard
  participant A as Worktree Activation
  participant F as Focus Registry
  participant T as Terminal Pane
  D->>A: activateAndRevealWorktree(worktreeId, host)
  A->>A: Select terminal view and worktree
  A->>A: Resume sessions / ensure terminal
  D->>F: Queue pane-focus detail
  D-->>T: Dispatch focus event
  alt Pane listener is mounted
    T->>T: Resolve and focus leaf
    T->>F: Clear parked detail
  else Pane mounts later
    T->>F: Consume parked detail
    T->>T: Resolve and focus leaf
  end
Loading

Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

PannenetsF and others added 2 commits September 12, 2026 21:51
Clicking an agent in the dashboard (pop-out window or in-window drawer)
failed to open remote/SSH sessions: the focus event was dispatched one
frame after tab activation, but a cold-parked TerminalPane mounts its
listener several frames later (or behind an SSH connect gate), so the
event landed on no listener. The reveal paths also used bare
setActiveWorktree, skipping setActiveView('terminal') and the
initial-terminal/session-resume guards a remote worktree needs.

- Park the focus detail in a pending registry so a late-mounting pane
  consumes it on the way up; the live listener clears it on success.
- Switch dashboard reveal paths to activateAndRevealWorktree
  (revealInSidebar: false) for the full activation sequence.
- Show an honest "remote preview unavailable" message instead of
  "pane has closed" when an SSH pty has no serializable snapshot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A queued focus for tab A stayed parked after a later tab-B activation,
so a slow-mounting SSH pane for A could replay the obsolete request.
Track the last queued tab and clear its parked focus on any newer
activation, with A-then-B regression coverage. Also localize the
remote-preview-unavailable string for es/ja/ko instead of copying
English text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@PannenetsF
PannenetsF force-pushed the fix/dashboard-remote-session-reveal branch from e3121da to 8211b47 Compare September 12, 2026 13:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 25ffc357-5f56-4c97-bad0-d844d8d97139

📥 Commits

Reviewing files that changed from the base of the PR and between e3121da74c13e3d937cd0104d05c42e107d2817c and 8211b47.

📒 Files selected for processing (8)
  • src/renderer/src/components/dashboard-popout/AgentTerminalPreview.test.tsx
  • src/renderer/src/components/dashboard/useDashboardPopoutBridge.test.tsx
  • src/renderer/src/components/terminal-pane/use-terminal-pane-global-effects.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/en.json

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.

@nwparker

Copy link
Copy Markdown
Contributor

Closing as superseded by #18403, which states: "Supersedes #16732, which attempted this before the defect spread to Activity." @PannenetsF — I see recent pushes here, so please reopen if your branch covers anything #18403 misses.

@nwparker nwparker closed this Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Agent dashboard cannot open remote (SSH) sessions — shows "terminal closed"

2 participants