Repository navigation
feat(remote): choose a pairing address and prefer Tailscale - #850
Merged
Merged
Conversation
Prefer Tailscale origins so pairing can work across networks, and let users select another advertised HTTPS origin in the pairing dialog or through remote pair --address. Preserve the token, deadline, and in-flight poll when switching addresses, and keep the choice across token rotation. Cover address validation, wire compatibility, CLI parsing, QR updates, and bounded dialog layout. Use the existing close icon and make the streaming regression accept both valid initial render shapes.
The all-feature CI run exposed an intermittent false result from the fake Herdr's server status check. Its script was written from a multithreaded test process, allowing concurrent forks to inherit writable descriptors and trigger Linux ETXTBSY. Reuse the shared executable fixture writer, which writes in a single-threaded child before the script is launched. Remove the redundant platform-specific chmod helper from the Unix-only test module.
Scope the existing test-only Command::new allowance to the shared executable writer, matching other test crates without changing production process creation.
Owner
Author
|
Local validation: |
[High impact] The reviewed changes appear safe to merge. SummaryThe PR adds Tailscale-first pairing choices and keeps each IP’s saved certificate separate.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Current addresses] --> B[Network labels and ranking]
B --> C[Pairing QR]
C --> D[Phone connects]
D --> E{DNS name supplied?}
E -->|Yes| F[Saved DNS certificate]
E -->|No| G[Saved certificate for destination IP]
Reviews (3) · Last reviewed commit: "fix(remote): rank pairing addresses usin..." · Reviewed by Greptile |
Route remote-control dialog keys to address selection: Up/Down cycle the advertised origins and Home/End select the endpoints. Share selection and scrolling with clicks so the QR and visible row stay synchronized, while Escape closes the dialog and address keys cannot act after a phone claims it. Cover the menu key route, QR updates, wraparound, long IPv6 rows in a narrow window, focus, mixed mouse and keyboard input, and claimed-pairing isolation.
Show the selected Tailscale-first design with expandable alternatives, daemon-host interface names, and network guidance. Preserve keyboard selection and scrolling, animate disclosure in both directions, and expose compatible metadata in pairing offers and remote status. Explain when a development rebuild needs a daemon restart. Cover wire compatibility, interface classification, CLI output, and selection, and include native light, dark, and narrow screenshots using synthetic pairing data.
Remove the translucent iOS status-bar setting and give standalone web apps an opaque, theme-matched top edge so the system blur does not spill into the search field. Regenerate the shipped stylesheet and preserve safe-area spacing. On-device iOS verification remains outstanding.
# Conflicts: # crates/herdr-automate/src/testing.rs
Do not scroll empty conversations to the bottom of their safe-area and composer padding, either on entry or on stream updates. Keep following populated chats only when the reader is already at the end, and keep the opaque header below the status-bar safe area. Add an icon-led empty state with distinct starting and stopped-agent messages. Cover the shipped scroll controller and rendered states, extend the browser preview fixture, and include a narrow browser screenshot.
Owner
Author
|
@greptile review |
Keep a private, atomic certificate file per IP, signed by the existing CA. Select IP certificates from the TCP destination when clients omit SNI, keep DNS and custom certificates separate, and migrate covered addresses without changing the certificate already trusted by phones. New LAN addresses no longer rotate Tailscale certificates; failed saves retain current identities. Scope cached Home Screen transfer tokens to the current browser pairing, clear them when accepting a new key, and prevent concurrent or stale offers from crossing pairings. Add direct QR-scanning recovery, regression tests for persistence, migration, real TLS handshakes and transfer caching, and document the saved identity files.
Choose the default QR origin using the same Tailscale evidence as its network label. Remove blanket CGNAT priority from certificate-origin ordering so a carrier or unrelated VPN address cannot displace LAN. Prefer confirmed Tailscale IPv4 before its IPv6 alternative and retain MagicDNS recognition for custom certificates. Cover LAN versus unrelated CGNAT, multiple adapters with confirmed Tailscale, and consistent DNS labels and ordering.
Owner
Author
|
@greptile review |
…phone The terminal screen draws each styled run as an inline span, and an inline span paints its background over the font's content area only, not the 1.32 line height. At the fractional sizes the screen is fitted to, the light terminal background showed between rows as thin horizontal stripes. Making the runs inline blocks aligned to the top lets their background fill the whole line box; a run never crosses a line, so nothing else changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFavh7nWrdsE2snYJSQHaG
An agent given a long paste reports a title that is only its `pasted_content` transport envelope, so tabs, sidebar rows, the tab ghost, annotations, and the phone's chat list showed the wrapper instead of the task. herdr-client gains `text::caption`, which unwraps a leading envelope and rejects wrapper-only text, and `text::tab_label`, which falls back to a pane, agent, or workspace caption. The snapshot itself stays unchanged. Orchestrator dispatch now names the new tab and pane explicitly with the issue or PR identifier and title, so the paste never replaces that context, and herdr-acp derives chat titles from the unwrapped prompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFavh7nWrdsE2snYJSQHaG
… the phone Workspace headers in the phone app now carry the PR number in the same tone as the desktop badge (ready, pending checks or review, blocked or behind, attention, merged, draft or unknown), and tapping it opens the pull request. The number also appears beside waiting questions and is searchable. Herdr UI publishes its existing pull request cache to the daemon over the private control socket, resending a changed snapshot at once and an unchanged one every 30 seconds, so the phone never receives GitHub credentials and no second lookup starts. Updates reach open lists through the patch stream. The daemon's status now reports its Herdr boot ID, and a badge only shows when boot, workspace, directory, and branch all match, so a recycled workspace cannot inherit another checkout's badge. `herdr_github::pull_request::Tone` gains serde, with unknown tones read as muted for forward compatibility. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFavh7nWrdsE2snYJSQHaG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
remote pair --address HTTPS_ORIGIN. Preserve the selected origin across token rotation without changing the token or interrupting an in-flight poll. Fix the close icon.remote status; explain when an older development daemon needs restarting. Use the same interface evidence for labels and default QR ordering, so unrelated CGNAT addresses never displace LAN. Recognize Tailscale DNS names for custom certificates too.QA
umask 022; just cion macOS arm64, commit12f29b0f11d8ab5ccfc178d08b0c5d1459479a7a— passed.HERDR_LINT_CACHE=<isolated cache> just lint-linux— passed on the final commit (Linux ARM64 container). The initial shared-cache run reported stale protocol types; a fresh isolated build passed.just lint-windows— passed on the final commit.just check-commitsandgit diff origin/main...HEAD --check— passed.node --test scripts/test-remote-chat-scroll.mjs scripts/test-remote-handoff.mjs— 10 passed during development; covers chat scrolling, pairing-scoped transfer reuse, re-pairing, and concurrent/stale offers.cargo test --locked -p herdr-remote-control --all-features— 351 passed, 1 opt-in preview ignored, for the ranking fix. Includes per-IP persistence/migration/renewal, real no-SNI TLS handshakes, and CGNAT ranking regressions.just test-build— release build and 14 CLI tests passed for the per-IP certificate implementation.0600per-IP files; live no-SNI loopback TLS returned the unchanged certificate.just web-cssregenerated the committed stylesheet;node --check crates/herdr-remote-control/src/web/assets/app.jspassed.Screenshots
After screenshots use synthetic data and an inactive QR. A native before screenshot was not captured.
Narrow native window and empty-chat browser preview