fix(desktop): SSH aliases follow port changes#24449

open3
main
fix/issue-7568
opened5d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 5d ago

Problem

Adding an SSH environment through a config alias saves the resolved hostname and port as overrides. After changing the alias port, terminal SSH succeeds but the desktop keeps connecting to the old port.

Change

Preserve the entered alias and explicit username/port overrides during registration and reconnect. Discovered-host selection uses the same target parser as manual entry without converting config defaults into explicit overrides. Reconnect no longer rewrites the saved target or invalidates routing consent merely because config resolution differs.

Existing saved profiles retain their values; previously pinned connections need removal and re-addition once. Explicit overrides still take precedence. No profile migration or new persisted fields are introduced.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/7568

GitCafe: #7568

Triaged bug via the automated issue flow. Registration, reconnect, and discovered-host selection are three paths that persist or consume the same SSH alias intent.

Verification

  • Regression tests failed before the implementation: registration saved resolved defaults, and reconnect replaced an alias target with a resolved target. Both now pass, including repeated prepares and unchanged routing consent.
  • Final focused command: vp test run packages/client-runtime/src/connection/onboarding.test.ts packages/client-runtime/src/connection/resolver.test.ts packages/ssh/src/tunnel.test.ts: 25 passed. Test output.
  • Scoped connection/settings tests: 374 passed; client-runtime and web typechecks, targeted lint/format, and git diff --check passed.
  • Real Linux Electron under Xvfb: baseline alias reconnect failed against the old port after config/listener change; fixed app connected through 24570 → 24571 → 24572, preserving the connection/environment identity, one route, and the saved alias with a blank port.

Evidence

Linux Electron/Xvfb, Chromium, DPR 1, reduced motion, CSS viewport 1440×900 for the runtime pair below. The final-head runtime recording uses a different isolated local backend port from the baseline; it demonstrates connection behavior, rather than a pixel-matched comparison.

RuntimeBefore — d53873b6a4After — 78d05b9e0c0315303ba1985742e284a6d734f762
Typed alias, blank port, reconnect after config changeRecording: stale saved port failsRecording: two successive port changes succeed
Result frameBefore: saved resolved port fails to reconnectAfter: alias remains connected after two port changes

After runtime transcript records the saved target, resolved ports, stable connection/environment IDs and route count. Runtime driver.

Discovered-alias recording, runtime transcript, and driver show blank username/port remaining null while the resolved port changes from 24570 to 24571 and reconnect succeeds.

Proof matrix · Before index · Before recordings, frames, logs and drivers.

Final after index and narration · After matrix · Complete after assets and drivers.

Explicit username-only, port-only and combined overrides connected against deliberately conflicting config defaults before and after another defaults change. Allowlisted runtime transcript · Driver.

Supplemental picker-control comparisons below use the same query and suggestion at each size/theme. These are crops in addition to the whole-surface recordings and frames in the indices. Zero differences are amplified 8×; the second mask marks max RGB-channel delta >16/255. Background routes/provider state and translucency differ, so these do not establish a full-frame visual pass.

What else changed in the fixtures: before failure versus after success, resolved-address subtitles versus saved-alias subtitles, route counts during discovery testing, local backend port in the primary runtime recording, provider availability, retry countdowns, carets and route-added toasts. No layout or CSS changed in the patch. These differences prevent a “nothing else changed” claim.

Unverified: macOS execution; three Before V1 interaction cells; complete blank-and-explicit variants in every V2 cell; strict settled full-frame comparisons and full-frame diff pairs. After has four supplemental V1 and four representative V2 recordings, but only 15/24 static pairs settled identically; nine caret/toast pairs failed, including all V1 result pairs. Supplemental V1 reuses the existing alias through deduplication rather than creating four fresh environments. Runtime proof is affirmative; the full visual matrix is incomplete.

Independent proof audit supports R1/R2/R3 within the disclosed UI/IPC scope and reproduced the 390-dark result pixel-identically, but returned INSUFFICIENT for the complete visual matrix. It also leaves independently verified loaded-build provenance and complete reconnect narration unclosed. Audit inspection assets.

Written with Claude Opus 5.5 through the Claude Agent SDK; triage, review and proof with GPT-6.1-sol through the Codex harness.

Checks

22 successful · 7 skipped · 1 neutral
All checks passed
78d05b9

Added 3 commits

  • test(client-runtime): SSH registration saves the target as entered3a4e802
  • fix(client-runtime): SSH reconnects keep the alias target and routing consent78d05b9
  • fix(client-runtime): SSH connections pick up ssh config changes on reconnect9f07e62
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This focused fix makes SSH aliases re-resolve their current configuration on reconnect and avoids pinning resolved ports. It also changes persistence and pull-request routing-consent behavior when the resolved SSH endpoint changes, making human review appropriate.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between d53873b6a4799e87afd63c8d288ef0089f5a3748 and 78d05b9e0c0315303ba1985742e284a6d734f762.

External image Files selected for processing: 5
  • apps/web/src/components/settings/AddEnvironmentDialog.tsx
  • packages/client-runtime/src/connection/onboarding.test.ts
  • packages/client-runtime/src/connection/onboarding.ts
  • packages/client-runtime/src/connection/resolver.test.ts
  • packages/client-runtime/src/connection/resolver.ts
External image Files with no reviewable changes: 1
  • packages/client-runtime/src/connection/resolver.ts

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

Walkthrough

The SSH connection flow now retains the entered alias through registration and reconnects. Selecting a discovered host parses the alias with typed username and port overrides. The resolver no longer replaces the saved profile with the resolved SSH target.

Changes: SSH alias target preservation

Layer / File(s)Summary
Preserve the entered target during selection and registration
apps/web/src/components/settings/AddEnvironmentDialog.tsx, packages/client-runtime/src/connection/onboarding.ts, packages/client-runtime/src/connection/onboarding.test.ts
Selecting a discovered host parses its alias with the typed username and port overrides. SSH registration derives the connection ID from the entered target and saves that target. A test checks that an alias-only target remains saved with a null port after provisioning.
Keep the saved profile during reconnect
packages/client-runtime/src/connection/resolver.ts, packages/client-runtime/src/connection/resolver.test.ts
The resolver no longer saves an updated SSH profile or clears pull-request-routing permissions when the prepared target changes. The reconnect test checks that the original target and read-write routing consent remain unchanged.

Priority: External image Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • pingdotgg/t3code#7568: The changes preserve the SSH alias and reuse the entered target during reconnect, addressing the issue’s stale resolved host and port.

Possibly related PRs

  • pingdotgg/t3code#22142: Changes SSH config alias discovery, which supplies the discovered host suggestions used by this change.
  • pingdotgg/t3code#24107: Changes SSH launcher state when target fields change; this PR preserves those fields in the saved connection identity.

Suggested reviewers: t3dotgg

Merge Risk: External image Minimal · up to 78d05

The change appears ready to merge after normal checks. No actionable issue was established with alias preservation or reconnect consent.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary change: SSH aliases now follow port changes in the desktop client.
Description checkPassedThe description covers the problem, implementation, scope and approval, verification results, UI evidence, limitations, and agent attribution. It is complete and directly related to the changes.
Linked Issues checkPassedIssue #7568 requires SSH alias targets to remain saved as entered and to resolve through the current SSH configuration on each connection attempt. prepareSshRegistration now stores the entered targe…
Out of Scope Changes checkPassedThe reported changes are limited to SSH registration, reconnect behavior, discovered-host selection, and tests for those paths. The changed files directly support issue #7568. No unrelated product beh…
Full details: Linked Issues check

Explanation

Issue #7568 requires SSH alias targets to remain saved as entered and to resolve through the current SSH configuration on each connection attempt. prepareSshRegistration now stores the entered target and derives the connection ID from it. The SSH broker passes the entered target to preparation without rewriting the saved profile or routing consent. Discovered-host selection uses the entered alias with only typed username and port overrides. The added onboarding and resolver tests cover alias preservation, changed resolved ports, repeated connects, and retained routing consent.

Full details: Out of Scope Changes check

Explanation

The reported changes are limited to SSH registration, reconnect behavior, discovered-host selection, and tests for those paths. The changed files directly support issue #7568. No unrelated product behavior or new persisted fields are identified in the available change summary.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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