Skip to content

Remote Orca Servers: one list instead of six sections; SSH Hosts: bulk remove that stays removed - #31082

Merged
nwparker merged 5 commits into
mainfrom
nwparker/remote-server-page-UX
Oct 20, 2026
Merged

nwparker merged 5 commits into
mainfrom
nwparker/remote-server-page-UX

Conversation

@nwparker

@nwparker nwparker commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 33 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1191 $\color{#cf222e}{\Huge{\mathbf{−}}}$​177 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1014
Prod 78 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​6922 $\color{#cf222e}{\Huge{\mathbf{−}}}$​2887 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​4035

ELI5

The Remote Orca Servers settings page showed the same server in up to three places and hid the important setting under "Advanced". It also buried everything under mode tabs and walls of grey status text. It's now one list: each server gets one row with its status, one button and a "⋯" menu.

The SSH Hosts page imports every alias in ~/.ssh/config, and before this you had to delete them one confirm at a time. Now you can tick several hosts and remove them with one confirm. Deleted hosts also stay deleted.

What Changed

Remote Orca Servers

  • Before: three big mode cards (Connect / Share / Cloud VM), then:
    • a server list where each row stacked 4–5 grey lines (Disconnected, Status unavailable, a truncated error, Orca version unavailable, an Offline chip)
    • an "Advanced" fold that hid "Default host for new projects"
    • an always-visible "Deploy server" form
    • a second copy of every managed server
    • a third copy of every paired server under "SSH access for paired servers"
    • a troubleshooting accordion
  • After:
    • One list. Each server is one row: a chip (Default / Managed / SSH tunnel), one line saying "Never connected" or "Last seen …" with the address and a Details link, a status column, at most one action (Retry / Update / Re-pair… / Resume), and a ⋯ menu for everything else.
    • Details expands inline with a plain-language explanation. The raw error sits behind "Show error" / "Copy error".
    • Add server ▾ is the single entry point: paste an access link, install on an SSH host, or set up a Cloud VM. Each opens a dialog that wraps the existing form.
    • "New projects open on" is always visible and keeps the default-runtime deep link.
    • Share this computer and Cloud VMs are compact cards; Share opens a dialog with the existing link generator.
    • Copy drops "runtime", "advertise" and "access grant".

Nothing is removed, only moved. Managed-server stop / forget / recover / roll back, the pending state for reaching a server through SSH (with Retry and Cancel), and per-server update checks all live on the row or in its menu.

SSH Hosts

  • Before: a 23-row list with 4 inline buttons per row, no selection, and one confirm per delete. "Import" re-adopted every alias, including ones you had deleted.
  • After:
    • Rows are compact.
    • Hosts are grouped "From ~/.ssh/config" and "Added in Orca".
    • Selection works by checkbox or Shift-range, there's a filter, and "Select all n matching".
    • Remove n asks once and runs the removals one at a time. Hosts that run a managed server or have workspaces are skipped and named in one summary toast.
    • Bulk Test is available.
    • Sync ~/.ssh/config now uses importConfig({ reAdopt: false }), so removed aliases stay removed. Restore removed hosts (n)… is a separate, confirmed menu action.

How it works: this is a renderer-only rework. It reuses the existing data hooks, IPC, dialogs and state machines (ManagedServerRow logic is now managed-server-row-parts). Bulk removal calls the existing per-host removeTarget, so every main-process guard still applies. The only main/CLI edits are user-facing strings that pointed at the old layout ("Share this host" → "Share this computer", "Advanced > Default host" → "New projects open on").

Why

The page was organised around how it's built (a managed-server subsystem, an SSH-access subsystem, three modes) rather than the user's question: "which machines can I work on, are they OK, and how do I add one?" We mocked three directions:

  • A, single list (this PR): fits the existing settings column and removes every duplicate.
  • B, tabs: cheaper, but keeps a mode switch most people don't need.
  • C, master/detail: the most detail, but needs a wider layout and is the biggest build.

For SSH Hosts, bulk delete alone wouldn't help: the old Import button cleared every deletion, so removed aliases came back in the host pickers.

Two adversarial review rounds (one design reviewer, one front-end reviewer) caught and fixed several problems:

  • Shift-range selection could cross groups.
  • Hosts hidden by the filter stayed selected and could be removed.
  • The bulk confirm broke host names mid-word.
  • The default-host deep link had no target when there were no servers.
  • Stale "Connected" status could be shown from cache.

Visual Proof

Screenshots use fake hosts and servers.

Before After
before-servers after-servers
Details expanded: details
Row menu: menu
before-ssh after-ssh
Bulk selection: selected
One confirm: confirm

The "before" SSH screenshot is cropped, to leave out the rows for real hosts.

Testing

  • I manually tested these changes locally (macOS dev build via CDP, seeded with offline paired servers and about 20 SSH hosts; 1280 px and 900 px; dark and light themes). The bulk remove ran end-to-end on fake hosts.
  • Automated tests added/updated:
    • new ssh-target-list-model.test.ts, including Shift-range in display order
    • SshPane.test.tsx: bulk remove, the filter dropping hidden hosts from the selection, bulk Test, and the Sync / Restore split
    • managed-server-row-parts.test.tsx
    • runtime-server-row-meta.test.ts
    • updated row, form and e2e specs

Gates:

  • pnpm tc:web and pnpm tc:node: clean.
  • Settings, runtime-environment IPC and managed-server CLI tests: 280 files / 1868 tests pass. One test failed on the first run and passed on three reruns.
  • check:code-quality:changed: 0 new findings across 88 files.
  • Localization catalogs, coverage and extraction: pass.
  • e2e:
    • ssh-host-form-modal, ssh-config-host-import and ephemeral-vm-cleanup-retry pass.
    • wsl-host-fake-transport has 3 of 4 tests passing. The failing test is "adds a WSL distro as a host, adds a project on it…": the project added through "Open host project" ends up with no host. It fails the same way on clean main (ba6599eabbd), so it isn't caused by this PR. That failure stops the test before the WSL Remove step this PR updated (it now goes through the row's ⋯ menu), so that change hasn't run in e2e.

Not exercised live: managed, WSL, Cloud VM, update-available, access-revoked and connected rows (covered by unit tests and review), and the web client (gating checked in code).

Review

Suggested order:

  1. RuntimeEnvironmentsPane.tsx → runtime-server-list*.tsx → runtime-server-row-*
  2. The dialogs
  3. SshPane.tsx → SshTargetList.tsx → use-ssh-target-selection.ts / use-ssh-bulk-remove.ts / use-ssh-config-sync.ts

About 40% of the diff is locale catalogs.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • SSH and remote: no wire or protocol change, so mixed client and host versions are unaffected. Bulk remove goes through the existing per-target guards (managed-server fence, workspace check, teardown).
  • Cross-platform: Ctrl-A on Linux and Windows, ⌘A on Mac. The WSL section shows only on Windows, as before.
  • Web client: Share, Install on an SSH host, Connect through SSH and WSL are hidden there.

Checklist

  • This PR is small and focused. It is large: it could split into SSH Hosts and Servers if preferred.
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass. Typecheck and the scoped tests and lint pass locally; CI covers the full suite.

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in 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

The pull request reorganizes remote-server and SSH settings. It adds reusable server-list components and updates managed-server, pairing, sharing, and Cloud VM controls. SSH settings gain filtering, multi-selection, bulk testing and removal, and restoration of removed SSH-config hosts. Related tests and localized copy are updated, including guidance that points to “New projects open on.”

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to effc3

The remote server and SSH host settings rework appears mergeable with small follow-ups. Users may see misleading feedback when installing Orca on an SSH host. Leaving the dialog through the "Add an SSH host" link drops the notice that installation continues in the background. A refresh failure after a successful install can also show an error even though the install worked. Neither issue blocks the install itself.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description thoroughly covers the user-facing changes, rationale, visual proof, testing, risks, and checklist. However, it omits the required Linked Issue section and issue reference. Add the required Linked Issue section with an actual issue reference, such as Fixes #12345. Keep the existing explanation if no other changes are needed.
Docstring Coverage Warning Docstring coverage is 47.62% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 105 functions across 74 files. (7 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly summarizes both primary changes: consolidating Remote Orca Servers into one list and adding persistent bulk removal for SSH Hosts.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 47.62% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 105 functions across 74 files. (7 skipped: 7 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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: Advanced
  • Run ID: bc4f8d00-9786-4b2a-85d2-1f6a1620560c
📥 Commits

Reviewing files that changed from the base of the PR and between 41f1580 and 003013e38a08767d5d20fb500f4eae805a9075d0.

📒 Files selected for processing: 103
  • src/cli/handlers/managed-server.test.ts
  • src/main/ipc/runtime-environments/runtime-environment-connectivity-handlers.ts
  • src/main/ipc/runtime-environments/runtime-environment-host-dispatch.test.ts
  • src/main/ipc/runtime-environments/runtime-environments-pairing.test.ts
  • src/main/ipc/wsl-host-handlers.ts
  • src/main/managed-server/lifecycle/orcad-runtime-decommission.ts
  • src/renderer/src/components/settings/CloudVmSetupGuide.test.tsx
  • src/renderer/src/components/settings/CloudVmSetupGuide.tsx
  • src/renderer/src/components/settings/EphemeralVmRuntimesSection.test.tsx
  • src/renderer/src/components/settings/EphemeralVmRuntimesSection.tsx
  • src/renderer/src/components/settings/ManagedServerRow.tsx
  • src/renderer/src/components/settings/ManagedServersSection.tsx
  • src/renderer/src/components/settings/RuntimeAccessGrantList.tsx
  • src/renderer/src/components/settings/RuntimeEnvironmentsPane.test.ts
  • src/renderer/src/components/settings/RuntimeEnvironmentsPane.tsx
  • src/renderer/src/components/settings/RuntimeHostAccessForm.test.tsx
  • src/renderer/src/components/settings/RuntimeHostAccessForm.tsx
  • src/renderer/src/components/settings/RuntimePairingGeneratorForm.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx
  • src/renderer/src/components/settings/RuntimeRepairDialog.tsx
  • src/renderer/src/components/settings/RuntimeSshAccessControl.tsx
  • src/renderer/src/components/settings/SshDestructiveActionDialog.tsx
  • src/renderer/src/components/settings/SshHostChangedActions.tsx
  • src/renderer/src/components/settings/SshHostKeepServerVersionDialog.tsx
  • src/renderer/src/components/settings/SshHostMoveAnywayAction.test.tsx
  • src/renderer/src/components/settings/SshHostMoveAnywayAction.tsx
  • src/renderer/src/components/settings/SshHostRestartServerAction.test.tsx
  • src/renderer/src/components/settings/SshHostRestartServerAction.tsx
  • src/renderer/src/components/settings/SshPane.test.tsx
  • src/renderer/src/components/settings/SshPane.tsx
  • src/renderer/src/components/settings/SshPaneToolbar.tsx
  • src/renderer/src/components/settings/SshRestoreRemovedHostsDialog.tsx
  • src/renderer/src/components/settings/SshTargetCard.test.tsx
  • src/renderer/src/components/settings/SshTargetCard.tsx
  • src/renderer/src/components/settings/SshTargetDestructiveActions.test.tsx
  • src/renderer/src/components/settings/SshTargetDestructiveActions.tsx
  • src/renderer/src/components/settings/SshTargetForm.test.tsx
  • src/renderer/src/components/settings/SshTargetForm.tsx
  • src/renderer/src/components/settings/SshTargetList.tsx
  • src/renderer/src/components/settings/SshTargetServerStatus.tsx
  • src/renderer/src/components/settings/WslHostsSection.tsx
  • src/renderer/src/components/settings/cli-source-control-integration-cards.test.tsx
  • src/renderer/src/components/settings/managed-server-copy.test.ts
  • src/renderer/src/components/settings/managed-server-copy.ts
  • src/renderer/src/components/settings/managed-server-row-parts.test.tsx
  • src/renderer/src/components/settings/managed-server-row-parts.tsx
  • src/renderer/src/components/settings/network-address-label.ts
  • src/renderer/src/components/settings/provider-account-scope.test.ts
  • src/renderer/src/components/settings/provider-account-scope.ts
  • src/renderer/src/components/settings/runtime-active-server-section.tsx
  • src/renderer/src/components/settings/runtime-add-server-dialog.tsx
  • src/renderer/src/components/settings/runtime-default-host-row.tsx
  • src/renderer/src/components/settings/runtime-environment-dialogs.tsx
  • src/renderer/src/components/settings/runtime-environment-host-details.ts
  • src/renderer/src/components/settings/runtime-environments-search.ts
  • src/renderer/src/components/settings/runtime-install-server-dialog.tsx
  • src/renderer/src/components/settings/runtime-server-default-name.ts
  • src/renderer/src/components/settings/runtime-server-list-row.tsx
  • src/renderer/src/components/settings/runtime-server-list.tsx
  • src/renderer/src/components/settings/runtime-server-row-details.tsx
  • src/renderer/src/components/settings/runtime-server-row-menu.tsx
  • src/renderer/src/components/settings/runtime-server-row-meta.test.ts
  • src/renderer/src/components/settings/runtime-server-row-meta.ts
  • src/renderer/src/components/settings/runtime-server-row-presentation.test.ts
  • src/renderer/src/components/settings/runtime-server-row-presentation.ts
  • src/renderer/src/components/settings/runtime-server-row-state.ts
  • src/renderer/src/components/settings/runtime-server-row-unverifiable-host.test.tsx
  • src/renderer/src/components/settings/runtime-server-row.tsx
  • src/renderer/src/components/settings/runtime-server-workflow-sections.test.tsx
  • src/renderer/src/components/settings/runtime-server-workflow-sections.tsx
  • src/renderer/src/components/settings/runtime-servers-connect-section.tsx
  • src/renderer/src/components/settings/runtime-servers-header-actions.tsx
  • src/renderer/src/components/settings/runtime-servers-page-context.tsx
  • src/renderer/src/components/settings/runtime-share-computer-card.tsx
  • src/renderer/src/components/settings/runtime-ssh-access-dialog.tsx
  • src/renderer/src/components/settings/settings-remote-security-section-renderers.tsx
  • src/renderer/src/components/settings/ssh-bulk-remove-summary.ts
  • src/renderer/src/components/settings/ssh-hosts-header-slot.tsx
  • src/renderer/src/components/settings/ssh-target-list-model.test.ts
  • src/renderer/src/components/settings/ssh-target-list-model.ts
  • src/renderer/src/components/settings/task-tracker-integration-cards.test.tsx
  • src/renderer/src/components/settings/use-managed-server-catalog.ts
  • src/renderer/src/components/settings/use-managed-server-lifecycle.ts
  • src/renderer/src/components/settings/use-runtime-environment-catalog.ts
  • src/renderer/src/components/settings/use-runtime-environment-mutation-actions.ts
  • src/renderer/src/components/settings/use-ssh-bulk-remove.ts
  • src/renderer/src/components/settings/use-ssh-config-sync.ts
  • src/renderer/src/components/settings/use-ssh-target-selection.ts
  • src/renderer/src/components/settings/use-ssh-target-tests.ts
  • src/renderer/src/components/sidebar/AddRemoteHostFields.tsx
  • src/renderer/src/hooks/settings-navigation-remote-sections.ts
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • tests/e2e/ephemeral-vm-cleanup-retry.spec.ts
  • tests/e2e/helpers/ssh-config-host-picker.ts
  • tests/e2e/ssh-config-host-import.spec.ts
  • tests/e2e/ssh-host-form-modal.spec.ts
  • tests/e2e/wsl-host-fake-transport.spec.ts
💤 Files with no reviewable changes: 8
  • src/renderer/src/components/settings/ManagedServerRow.tsx
  • src/renderer/src/components/settings/runtime-servers-connect-section.tsx
  • src/renderer/src/components/settings/ManagedServersSection.tsx
  • src/renderer/src/components/settings/runtime-server-workflow-sections.test.tsx
  • src/renderer/src/components/settings/RuntimePairingUrlGenerator.tsx
  • src/renderer/src/components/settings/runtime-server-workflow-sections.tsx
  • src/renderer/src/components/settings/runtime-active-server-section.tsx
  • src/renderer/src/components/settings/SshHostChangedActions.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

@nwparker
nwparker force-pushed the nwparker/remote-server-page-UX branch from 003013e to 2273d64 Compare October 20, 2026 09:51

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

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Clear the bulk selection before awaiting the reload. · use-ssh-bulk-remove.ts:39-62

src/renderer/src/components/settings/use-ssh-bulk-remove.ts:39-62
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clear the bulk selection before awaiting the reload.

runBulkRemove clears the dialog and per-target busy guards before finishBulkRemove starts its awaited reload. The old targets and selection remain rendered during that await, so the user can confirm bulk removal again for hosts that were already removed.

The second IPC call still enters removeRegisteredSshTarget; the backend does not reject the missing target before repeating teardown and store.removeTarget. If it resolves, the renderer counts the target as removed and shows another removal summary. Clear the selection before args.reload() to prevent this duplicate confirmation and result.

Suggested fix
     if (result.removed.length > 0) {
       recordFeatureInteraction('ssh')
+      if (mountedRef.current) {
+        args.clearSelection()
+      }
       await args.reload()
+    } else if (mountedRef.current) {
+      args.clearSelection()
     }
     if (!mountedRef.current) {
       return
     }
-    args.clearSelection()
     const notify =

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 09ae428c-bdc9-4504-b344-7112fb5857e6
📥 Commits

Reviewing files that changed from the base of the PR and between 003013e38a08767d5d20fb500f4eae805a9075d0 and 2273d64c1e7a3f9861ca35da20908b97e1f3cfb3.

📒 Files selected for processing: 8
  • src/renderer/src/components/settings/SshPane.tsx
  • src/renderer/src/components/settings/SshTargetServerStatus.tsx
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.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: 5
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/zh.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

@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: 165a5464-58cd-464b-9596-77f4ea59c8c1
📥 Commits

Reviewing files that changed from the base of the PR and between 2273d64c1e7a3f9861ca35da20908b97e1f3cfb3 and 3a85003.

📒 Files selected for processing: 32
  • src/main/ipc/runtime-environments/runtime-environment-connectivity-handlers.ts
  • src/main/ipc/runtime-environments/runtime-environments-pairing.test.ts
  • src/main/ssh/connection/ssh-connection-store.ts
  • src/renderer/src/components/settings/RuntimeEnvironmentsPane.tsx
  • src/renderer/src/components/settings/RuntimeHostAccessForm.tsx
  • src/renderer/src/components/settings/SshPane.test.tsx
  • src/renderer/src/components/settings/SshPane.tsx
  • src/renderer/src/components/settings/SshTargetList.test.tsx
  • src/renderer/src/components/settings/SshTargetList.tsx
  • src/renderer/src/components/settings/runtime-add-server-dialog.tsx
  • src/renderer/src/components/settings/runtime-default-host-row.test.tsx
  • src/renderer/src/components/settings/runtime-default-host-row.tsx
  • src/renderer/src/components/settings/runtime-server-default-name.test.ts
  • src/renderer/src/components/settings/runtime-server-default-name.ts
  • src/renderer/src/components/settings/runtime-server-list.tsx
  • src/renderer/src/components/settings/runtime-server-row-presentation.test.ts
  • src/renderer/src/components/settings/runtime-server-row-presentation.ts
  • src/renderer/src/components/settings/runtime-server-row.tsx
  • src/renderer/src/components/settings/runtime-share-computer-card.test.tsx
  • src/renderer/src/components/settings/runtime-share-computer-card.tsx
  • src/renderer/src/components/settings/ssh-target-list-model.test.ts
  • src/renderer/src/components/settings/ssh-target-list-model.ts
  • src/renderer/src/components/settings/use-runtime-environment-mutation-actions.ts
  • src/renderer/src/components/settings/use-ssh-target-selection.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/ssh-target-source.test.ts
  • src/shared/ssh-target-source.ts
🚧 Files skipped from review as they are similar to previous changes: 8
  • src/main/ipc/runtime-environments/runtime-environments-pairing.test.ts
  • src/main/ipc/runtime-environments/runtime-environment-connectivity-handlers.ts
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/i18n/locales/ko.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

Comment on lines +292 to +295
onDeployed={async () => {
void loadEnvironments()
await managedCatalog.reload()
}}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

cat src/renderer/src/components/settings/use-managed-server-catalog.ts
rg -n 'onDeployed|toast\.|catch|try' src/renderer/src/components/settings/runtime-install-server-dialog.tsx
sed -n '170,182p;285,300p' src/renderer/src/components/settings/RuntimeEnvironmentsPane.tsx

Repository: stablyai/orca

Length of output: 4976


🏁 Script executed:

sed -n '1,115p' src/renderer/src/components/settings/runtime-install-server-dialog.tsx
sed -n '35,75p' src/renderer/src/components/settings/use-managed-server-catalog.ts
rg -n -F --glob '*.ts' --glob '*.tsx' -e 'listTargets' -e 'listPendingMigrations' src/renderer/src src/preload src/shared | head -80

Repository: stablyai/orca

Length of output: 14950


Keep catalog refresh failures out of the install error toast.

managedCatalog.reload() can reject because it awaits both API calls without catching failures. RuntimeInstallServerDialog.deploy awaits onDeployed() inside its try block after showing the success toast. A refresh failure can therefore show an install-failure toast for a successful install.

Handle the failure in reload and set loadFailed. Catching only at the call site would suppress the error but would not update loadFailed.

Suggested fix
   const reload = useCallback(async () => {
     if (!api) {
       return
     }
-    const [nextTargets, nextPending] = await Promise.all([
-      window.api.ssh.listTargets(),
-      api.listPendingMigrations()
-    ])
-    if (mountedRef.current) {
-      setTargets(nextTargets)
-      setPending(nextPending)
-      setLoadFailed(false)
+    try {
+      const [nextTargets, nextPending] = await Promise.all([
+        window.api.ssh.listTargets(),
+        api.listPendingMigrations()
+      ])
+      if (mountedRef.current) {
+        setTargets(nextTargets)
+        setPending(nextPending)
+        setLoadFailed(false)
+      }
+    } catch {
+      if (mountedRef.current) {
+        setLoadFailed(true)
+      }
     }
   }, [api, mountedRef])

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

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Handle preflight failures in the shared update action. · remote-server-updates.ts:96-114

src/renderer/src/store/slices/remote-server-updates.ts:96-114
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Handle preflight failures in the shared update action.

If runtimeEnvironments.list() or updater.getVersion() rejects, refreshRemoteServerUpdates clears its checking flag but leaves the open dialog without an error or retry state. The dialog can show stale data, an empty result, or rows stuck in “Checking…”. Handle the rejection in the shared action and expose a terminal error state with retry behavior so both current callers receive the same fallback.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e5e67c34-43af-4eab-b414-095f74c8bab6
📥 Commits

Reviewing files that changed from the base of the PR and between 3a85003 and a25dce9af156da423895d9934603779e64f64fbc.

📒 Files selected for processing: 1
  • tests/e2e/wsl-host-fake-transport.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

… SSH Hosts

Remote Orca Servers: replace the three mode cards, Advanced fold, duplicate
managed/SSH-access lists and troubleshooting accordion with a single list
(one row per server: status, one action, overflow menu), an always-visible
'New projects open on' row, and Share / Cloud VM cards that open dialogs.

SSH Hosts: group by source, filter, checkbox + shift-range selection, one
confirm for bulk remove (skipping hosts with a managed server or
workspaces), bulk Test. 'Sync ~/.ssh/config' no longer clears removal
tombstones; 'Restore removed hosts (n)' is a separate confirmed action.
- SSH filter stays clearable when the list shrinks under the threshold
- Cmd/Ctrl-A only selects hosts when pressed in the list itself
- group legacy no-source hosts with main's import predicate (now shared)
- capture the shift-range anchor before queuing the selection update
- blank server names de-duplicate instead of colliding
- Share dialog Done refreshes link count and resets name editing
- Install / SSH-route dialogs reload SSH hosts when opened
- default-host row shows the selector when the default is a WSL host
- managed 'Not running' no longer masks connecting/revoked/update states
- servers without a dropped transport can be re-checked
…hells

repo.rm now stops the project's terminals on the host (#29964), so the
'orphan left by older builds' setup can no longer be built; use a shell
only the host knows of instead. Resolve the project path so macOS
/private/var matches what the host reports.
… into the new server list

Ports #31099 and #31100 into the redesigned rows, install dialog and SSH
host dialogs.
@nwparker
nwparker force-pushed the nwparker/remote-server-page-UX branch from a25dce9 to effc359 Compare October 20, 2026 11:34

@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: 5112a146-48a3-4ae7-8040-5054f680ad9f
📥 Commits

Reviewing files that changed from the base of the PR and between a25dce9af156da423895d9934603779e64f64fbc and effc359.

📒 Files selected for processing: 28
  • src/renderer/src/components/settings/ManagedServerRow.tsx
  • src/renderer/src/components/settings/ManagedServersSection.tsx
  • src/renderer/src/components/settings/SshHostChangedActions.tsx
  • src/renderer/src/components/settings/SshHostKeepServerVersionDialog.tsx
  • src/renderer/src/components/settings/SshHostMoveAnywayAction.tsx
  • src/renderer/src/components/settings/SshHostRestartServerAction.test.tsx
  • src/renderer/src/components/settings/SshHostRestartServerAction.tsx
  • src/renderer/src/components/settings/SshManagedHostRemoveDialog.tsx
  • src/renderer/src/components/settings/SshPane.test.tsx
  • src/renderer/src/components/settings/SshTargetServerStatus.tsx
  • src/renderer/src/components/settings/managed-server-row-parts.test.tsx
  • src/renderer/src/components/settings/managed-server-row-parts.tsx
  • src/renderer/src/components/settings/runtime-environments-search.ts
  • src/renderer/src/components/settings/runtime-install-server-dialog.tsx
  • src/renderer/src/components/settings/runtime-server-list.tsx
  • src/renderer/src/components/settings/runtime-server-row-meta.test.ts
  • src/renderer/src/components/settings/runtime-server-row-meta.ts
  • src/renderer/src/components/settings/runtime-server-row-unverifiable-host.test.tsx
  • src/renderer/src/components/settings/runtime-server-row.tsx
  • src/renderer/src/components/settings/runtime-servers-connect-section.tsx
  • src/renderer/src/components/settings/runtime-servers-header-actions.tsx
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
💤 Files with no reviewable changes: 4
  • src/renderer/src/components/settings/SshHostChangedActions.tsx
  • src/renderer/src/components/settings/runtime-servers-connect-section.tsx
  • src/renderer/src/components/settings/ManagedServersSection.tsx
  • src/renderer/src/components/settings/ManagedServerRow.tsx
🚧 Files skipped from review as they are similar to previous changes: 7
  • src/renderer/src/i18n/en-runtime-required.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/fr.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

Comment on lines +176 to +179
onClick={() => {
onOpenChange(false)
openSettingsTarget({ pane: 'ssh', repoId: null })
}}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Route the "Add an SSH host" link through handleOpenChange.

The link calls onOpenChange(false) directly. This skips the background-install notice in handleOpenChange. During a deploy, the dialog closes and the install continues. The user does not get the "Setting up Orca on … in the background" toast. The user can then think the install was cancelled. The Cancel/Close button and the dialog's own onOpenChange already use handleOpenChange.

Proposed fix
--- "a/src/renderer/src/components/settings/runtime-install-server-dialog.tsx"
+++ "b/src/renderer/src/components/settings/runtime-install-server-dialog.tsx"
@@ -173,10 +173,10 @@
               <button
                 type="button"
                 className="cursor-pointer text-foreground underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                 onClick={() => {
-                  onOpenChange(false)
+                  handleOpenChange(false)
                   openSettingsTarget({ pane: 'ssh', repoId: null })
                 }}
               >
                 {translate('auto.components.settings.serverList.addSshHost', 'Add an SSH host')}
               </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onClick={() => {
onOpenChange(false)
openSettingsTarget({ pane: 'ssh', repoId: null })
}}
onClick={() => {
handleOpenChange(false)
openSettingsTarget({ pane: 'ssh', repoId: null })
}}

@nwparker
nwparker merged commit 49a2203 into main Oct 20, 2026
72 checks passed
smwbev added a commit to smwbev/orca that referenced this pull request Oct 20, 2026
main moved 408 commits. One kind of conflict:

- en, es, fr, ja, ko and zh: stablyai#31082 and this branch both appended keys
  to the end of auto.components.sidebar.AddRemoteHostDialog. main's
  pairingHelpShareComputer comes first, then the two sshImportSynced
  sentences from this branch.

en-runtime-required.json and the Korean overrides merged on their own;
the branch still only swaps the drop-upload toast key in the runtime
catalog. Against main the branch still removes the same twelve keys and
adds the same 24 in all six catalogs, with no other value changed.
smwbev added a commit to smwbev/orca that referenced this pull request Oct 20, 2026
208 commits landed on main between 1529b0f and ebc8b06, and all six catalogs conflicted along with en-runtime-required.json, so the catalogs and en-runtime-required.json are taken from main and the prune is recomputed in one pass. It is the previous 1,509 keys plus 109: 108 lost their reader when stablyai#31082 folded the six Remote Orca Servers sections into one list and stablyai#31099 retitled the SSH host section, and SshTargetList.selectGroup arrived with stablyai#31082 without a reader. None left the set. en.json goes from 16,704 entries to 15,086; en-runtime-required.json keeps 579 of them.
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.

1 participant