Commit Graph
3 Commits
Author SHA1 Message Date
Jinwoo HongandOrca 02a0aad987 Refresh ports when advertised URLs change (#2638)
Co-authored-by: Orca <help@stably.ai>
2026-05-22 12:17:21 -07:00
5ca6828371 feat: surface dev-server URLs in the ports panel (#2534)
* Surface dev-server URLs in workspace ports panel

Why: the OS scanner only sees `127.0.0.1:3001`, so clicking a Vite
port in the panel opens the wrong host/protocol when the dev server
binds with a custom hostname or HTTPS (e.g. `https://local.getmontecarlo.com:3001/`).
We now watch PTY output for advertised origins and prefer them at
display, copy, and open time. Falls back to the OS-derived address.

The watcher taps the central `runtime.onPtyData` path so it sees local,
daemon-backed, and SSH PTYs uniformly. URL candidates are validated with
`new URL()`, sanitized to origin only (no path/query/fragment/userinfo),
and gated by listener-PID validation so stale entries get evicted when
a different process reuses the port.

SSH `DetectedPort` enrichment is out of scope here — that panel uses
separate data shapes and port-forwarding may rewrite the local port,
making naive URL reuse incorrect. Tracked as a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Extend advertised-URL enrichment to SSH ports

Why: the first cut only enriched the local workspace ports panel. SSH
worktrees use a separate panel with `DetectedPort` and `PortForwardEntry`
shapes scanned by the remote relay, so the same dev-server banners that
flow through Orca's SSH PTYs were captured by the watcher but never
surfaced.

The renderer-side SSH scanner doesn't know which worktreeId the watcher
keyed an entry under, so a small helper walks the store to find every
worktree attached to a given connection and asks the watcher for the
best match per port (custom DNS host > loopback > LAN IP, https and
recency as tie-breakers). Enrichment runs at every broadcast and list
site in src/main/ipc/ssh.ts.

For a forwarded SSH port, the open action now uses
`advertisedProtocol://customHost:localPort`. We deliberately reuse the
local forward port — the remote port number is not reachable from the
local machine — and we only reuse the host when it's a custom DNS name
(IP literals and the remote's `localhost` get ignored, falling back to
127.0.0.1 like before). Loopback advertisements from the remote box are
a no-op because they don't translate to the local browser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Address Codex review of advertised-URL enrichment

Four findings from the post-implementation review:

- Watcher rejects wildcard advertised hosts (`0.0.0.0`, `::`, `*`). The
  OS scanner already normalizes wildcards to localhost for the connect
  host; if a dev server prints `http://0.0.0.0:3000/` verbatim we keep
  that sensible default instead of letting the watcher overwrite it
  with a host the browser can't open.

- Pre-bind pending buffer is now capped at 32 distinct PTY IDs with
  LRU eviction. Spawn-failure paths could otherwise leave never-bound
  entries forever — per-PTY 16 KiB bound was the only guard.

- `clearProviderPtyState` now calls `advertisedUrlWatcher.unbindPty`.
  SSH reattach failures, `clearPtyOwnershipForConnection`, and daemon
  spawn-failure cleanup bypass `runtime.onPtyExit`; routing through the
  central provider teardown plugs those holes (and is idempotent with
  the existing `onPtyExit` hook for natural exits).

- `lookupBest` accepts an optional current listener PID and runs the
  same pin-then-evict logic as `lookup`. `enrichSshDetectedPorts`
  threads `DetectedPort.pid` through so a stale advertised URL gets
  evicted on remote port reuse. Forward enrichment stays best-effort
  (forwards are persisted config, not observed listeners — detected
  enrichment is the eviction path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: refresh SSH ports when advertised URLs change

Co-authored-by: Orca <help@stably.ai>

* fix: show advertised URLs in port rows

Co-authored-by: Orca <help@stably.ai>

* fix: address advertised URL review issues

Co-authored-by: Orca <help@stably.ai>

* fix: tighten advertised URL cache handling

Co-authored-by: Orca <help@stably.ai>

* fix: align advertised URL edge cases

Co-authored-by: Orca <help@stably.ai>

* fix: handle advertised URL cache invalidation

Co-authored-by: Orca <help@stably.ai>

* fix: show status port action tooltips

Co-authored-by: Orca <help@stably.ai>

* fix: keep port action tooltips above popover

Co-authored-by: Orca <help@stably.ai>

* fix: clear port action focus after click

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-05-22 03:52:51 -04:00
Jinwoo HongandOrca 062725da76 Add workspace port management (#2316)
Co-authored-by: Orca <help@stably.ai>
2026-05-19 10:23:40 -07:00