Repository navigation
fix(server): open in editor works over Tailscale SSH without a local sshd - #19402
Conversation
…sshd Remote open targets returned nothing when no sshd listened on loopback :22, before Tailscale was checked. Tailscale SSH serves the tailnet name without a local listener, so the editor picker said "No SSH route". Read RunSSH from `tailscale debug prefs` and advertise the tailnet name when Tailscale SSH is on, even with no local sshd. The mDNS name still needs a local sshd, and a running tailscaled alone advertises nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a localized bug fix that detects enabled Tailscale SSH and exposes an existing tailnet editor target only for hosts without local sshd. Existing sshd behavior is preserved, failure cases fall back safely, and the new paths are covered by tests. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
## What's Changed * fix(clients): # suggestions include pull requests linked to the thread by @t3dotgg in pingdotgg/t3code#19357 * fix(clients): pairing a switched-off computer again turns it back on by @t3dotgg in pingdotgg/t3code#19354 * fix(cli): t3 triage reports the server's version, not its own, as the user's build by @t3dotgg in pingdotgg/t3code#19359 * fix(client-runtime): a new WSL backend no longer shows Limited permissions until reload by @t3dotgg in pingdotgg/t3code#19361 * fix(web): action shortcuts recorded in the browser now save by @t3dotgg in pingdotgg/t3code#19365 * fix(clients): large pasted images no longer break later Claude image reads by @t3dotgg in pingdotgg/t3code#19364 * fix(server): settled and idle-released threads no longer stay Waiting by @t3dotgg in pingdotgg/t3code#19355 * perf(client-runtime): merged pull requests are no longer re-read every minute by @t3dotgg in pingdotgg/t3code#19374 * fix(server): new Codex threads no longer miss slow MCP servers' tools by @t3dotgg in pingdotgg/t3code#19368 * fix(github): requested teams now show in pull request reviewers by @t3dotgg in pingdotgg/t3code#19375 * fix(ssh): SSH launch no longer picks a port another server answers on by @t3dotgg in pingdotgg/t3code#19372 * fix(server): a failed T3 Connect relink no longer leaves a stale managed tunnel by @t3dotgg in pingdotgg/t3code#19383 * fix(shared): Windows .cmd shims no longer print DEP0190 on every spawn by @t3dotgg in pingdotgg/t3code#19385 * fix(server): commit and title generation use your custom model when no text model is set by @t3dotgg in pingdotgg/t3code#19386 * fix(web): T3 Connect settings can repair a link that drifted to publish-only by @t3dotgg in pingdotgg/t3code#19389 * fix(server): failed Claude text generation shows the CLI's own error by @t3dotgg in pingdotgg/t3code#19394 * fix(web): terminal tells the shell its new width as soon as you release a resize drag by @t3dotgg in pingdotgg/t3code#19395 * fix(web): keybindings page says to connect an environment when none is connected by @t3dotgg in pingdotgg/t3code#19400 * fix(chat): Codex follow-up suggestions show their label instead of raw markup by @t3dotgg in pingdotgg/t3code#19401 * fix(server): open in editor works over Tailscale SSH without a local sshd by @t3dotgg in pingdotgg/t3code#19402 * fix(server): a deregistered T3 Connect host shows it was removed and offers a relink by @t3dotgg in pingdotgg/t3code#19379 * perf(server): idle servers no longer scan every process every 5 seconds by @t3dotgg in pingdotgg/t3code#19399 * chore(typecheck): bump tsc-rs to 0.7.0 by @t3dotgg in pingdotgg/t3code#19408 * fix(server): bound Bitbucket API requests with 30s timeout by @kvnloo in pingdotgg/t3code#14140 * fix(server): new worktrees no longer fail when a background fetch runs at the same time by @t3dotgg in pingdotgg/t3code#19411 * perf(server): thread search runs on the SQLite reader worker by @bompus in pingdotgg/t3code#19382 * perf(server): traces keep ~40% more history and no longer block the event loop by @t3dotgg in pingdotgg/t3code#19430 * fix(shared): SQLite checkpoints no longer fall back to the main thread silently by @t3dotgg in pingdotgg/t3code#19417 * perf(server): unchanged node updates no longer write to SQLite by @t3dotgg in pingdotgg/t3code#19429 * fix(ssh): reconnecting keeps the remote server and its agents running by @t3dotgg in pingdotgg/t3code#19432 * feat(observability): SQL spans show lock wait and connection; stalls keep their own history by @t3dotgg in pingdotgg/t3code#19425 * fix(server): threads woken by notifications no longer load their whole history by @t3dotgg in pingdotgg/t3code#19423 * fix(server): worktree cleanup no longer runs sweeps back to back by @t3dotgg in pingdotgg/t3code#19418 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3105...v0.0.46-nightly.20261014.3118 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3118
## What's Changed * fix(clients): # suggestions include pull requests linked to the thread by @t3dotgg in pingdotgg/t3code#19357 * fix(clients): pairing a switched-off computer again turns it back on by @t3dotgg in pingdotgg/t3code#19354 * fix(cli): t3 triage reports the server's version, not its own, as the user's build by @t3dotgg in pingdotgg/t3code#19359 * fix(client-runtime): a new WSL backend no longer shows Limited permissions until reload by @t3dotgg in pingdotgg/t3code#19361 * fix(web): action shortcuts recorded in the browser now save by @t3dotgg in pingdotgg/t3code#19365 * fix(clients): large pasted images no longer break later Claude image reads by @t3dotgg in pingdotgg/t3code#19364 * fix(server): settled and idle-released threads no longer stay Waiting by @t3dotgg in pingdotgg/t3code#19355 * perf(client-runtime): merged pull requests are no longer re-read every minute by @t3dotgg in pingdotgg/t3code#19374 * fix(server): new Codex threads no longer miss slow MCP servers' tools by @t3dotgg in pingdotgg/t3code#19368 * fix(github): requested teams now show in pull request reviewers by @t3dotgg in pingdotgg/t3code#19375 * fix(ssh): SSH launch no longer picks a port another server answers on by @t3dotgg in pingdotgg/t3code#19372 * fix(server): a failed T3 Connect relink no longer leaves a stale managed tunnel by @t3dotgg in pingdotgg/t3code#19383 * fix(shared): Windows .cmd shims no longer print DEP0190 on every spawn by @t3dotgg in pingdotgg/t3code#19385 * fix(server): commit and title generation use your custom model when no text model is set by @t3dotgg in pingdotgg/t3code#19386 * fix(web): T3 Connect settings can repair a link that drifted to publish-only by @t3dotgg in pingdotgg/t3code#19389 * fix(server): failed Claude text generation shows the CLI's own error by @t3dotgg in pingdotgg/t3code#19394 * fix(web): terminal tells the shell its new width as soon as you release a resize drag by @t3dotgg in pingdotgg/t3code#19395 * fix(web): keybindings page says to connect an environment when none is connected by @t3dotgg in pingdotgg/t3code#19400 * fix(chat): Codex follow-up suggestions show their label instead of raw markup by @t3dotgg in pingdotgg/t3code#19401 * fix(server): open in editor works over Tailscale SSH without a local sshd by @t3dotgg in pingdotgg/t3code#19402 * fix(server): a deregistered T3 Connect host shows it was removed and offers a relink by @t3dotgg in pingdotgg/t3code#19379 * perf(server): idle servers no longer scan every process every 5 seconds by @t3dotgg in pingdotgg/t3code#19399 * chore(typecheck): bump tsc-rs to 0.7.0 by @t3dotgg in pingdotgg/t3code#19408 * fix(server): bound Bitbucket API requests with 30s timeout by @kvnloo in pingdotgg/t3code#14140 * fix(server): new worktrees no longer fail when a background fetch runs at the same time by @t3dotgg in pingdotgg/t3code#19411 * perf(server): thread search runs on the SQLite reader worker by @bompus in pingdotgg/t3code#19382 * perf(server): traces keep ~40% more history and no longer block the event loop by @t3dotgg in pingdotgg/t3code#19430 * fix(shared): SQLite checkpoints no longer fall back to the main thread silently by @t3dotgg in pingdotgg/t3code#19417 * perf(server): unchanged node updates no longer write to SQLite by @t3dotgg in pingdotgg/t3code#19429 * fix(ssh): reconnecting keeps the remote server and its agents running by @t3dotgg in pingdotgg/t3code#19432 * feat(observability): SQL spans show lock wait and connection; stalls keep their own history by @t3dotgg in pingdotgg/t3code#19425 * fix(server): threads woken by notifications no longer load their whole history by @t3dotgg in pingdotgg/t3code#19423 * fix(server): worktree cleanup no longer runs sweeps back to back by @t3dotgg in pingdotgg/t3code#19418 **Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261014.3105...v0.0.46-nightly.20261014.3118 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261014.3118
Brings in upstream through pingdotgg#19257 (339179f). - Partly superseded: upstream's Tailscale SSH remote open (pingdotgg#19402) replaces Cody's detection. Cody now uses upstream's `tailscale debug prefs` read, which also treats `tailscale down` as off, and drops its `tailscale get` reader, Windows skip, and Tailscale 1.102 requirement. Cody keeps only the tailscale-ssh target with the server's account, so editors sign in as that user. - Adapted: Cody's install-when-idle updates now skip a version upstream reports as not applied (pingdotgg#19291), instead of reinstalling and restarting after every idle period. - Server browser: kept Windows work-account sign-in beside upstream's copy recording (pingdotgg#19561). - Mobile branch list: kept Cody's worktreeBaseRef import beside upstream's linked PR suggestions (pingdotgg#19357).
On a host that serves SSH only through Tailscale SSH, "Open in editor" said "No SSH route", even though
ssh <tailnet-name>works. The server advertised no SSH targets unless sshd listened on loopback:22, and it checked that before it looked at Tailscale.This follows the split gate from the triage on #11052:
RunSSHfromtailscale debug prefs, becausetailscale status --jsondoes not report SSH for the local node.tailscale downkeepsRunSSHstored, soWantRunning: falsecounts as off.--tailscale-serve) still advertises nothing.@t3tools/tailscalegetsreadTailscaleSshEnabled. It uses the same command runner asreadTailscaleStatus, which is now shared, soreadTailscaleStatusbehaves the same. No client or contract change:kind: "tailscale"targets already exist.Proof
advertises only the tailnet name when Tailscale SSH serves without sshdfailed onmain(got[]) and passes with the fix. Tests also cover Tailscale SSH off and a storedRunSSHaftertailscale down.RemoteOpenTargets.test.ts7/7 andpackages/tailscale15/15 pass. Typecheck passes forpackages/tailscale,apps/server, andapps/desktop. Lint is clean on the changed files.Fixes #11052
Reviewed with sol-loop: 1 round with GPT-6.1-Sol.
Model and harness: Claude Opus 5.5 in Claude Code via T3 Code.
🤖 Generated with Claude Code