get2knowio / get2knowio/deacon
auto-forward: honor onAutoForward openBrowser/openPreview (host browser open)
- Dominant language
- Rust
- Stars
- 2
- Forks
- 0
- Avg merge
- 2h 36m
- Merged PRs (30d)
- 78
Description
Tracked deferral from `up --auto-forward` (spec `015-auto-forward-ports`, task **T059**; shipped in #188). v1 honors `onAutoForward` values `ignore`/`silent`/`notify`; `openBrowser`/`openPreview` are accepted but **treated as `notify`**.
## Goal / acceptance
`portsAttributes.onAutoForward: openBrowser` (and `openPreview`) trigger opening the forwarded `http://127.0.0.1:` URL on the host when the port becomes active.
## Background
`to_resolved()` in `crates/core/src/port_forward/daemon.rs` currently collapses `OpenBrowser`/`OpenPreview` → `Notify`. The forward still happens and is reported; nothing is auto-opened.
## Hidden issues / gotchas
- **The forwarder is a detached, headless background process** (stdio redirected to a log; `setsid`). It has **no display/session context**, so naively shelling `xdg-open`/`open` from the daemon may target the wrong session, fail silently, or do nothing on a headless server / SSH host. This is the core reason it's awkward.
- **"openPreview" has no meaning outside an IDE.** It's a VS Code in-editor webview concept. A CLI can at best treat it like `openBrowser`; true preview belongs to an editor integration, not deacon.
- **Cross-platform divergence:** `xdg-open` (Linux), `open` (macOS), `start`/`rundll32` (Windows) — and none of them are right on a remote/headless host.
- **Risk in CI/automation:** must be a no-op (not an error) when there's no usable browser/display (`$DISPLAY` unset, `$SSH_CONNECTION` set, `$BROWSER` empty, CI), and must never block or fail `up`/the daemon. Hard to assert meaningfully in hermetic tests beyond "doesn't crash / no-ops headlessly."
- Should likely respect the `$BROWSER` env var and be suppressible.
## Recommended path forward
1. Implement `openBrowser` (map `openPreview` → same, with a doc note that true preview is editor-only): on first activation of such a port, best-effort launch the host browser via `$BROWSER` else platform default (`xdg-open`/`open`/`start`).
2. **Guard hard:** skip silently when headless/remote/CI (`!$DISPLAY && !$WAYLAND_DISPLAY` on Linux, `$SSH_CONNECTION` set, `CI` set) or no opener found — log at debug, never error.
3. Add a kill-switch (e.g. `--no-open` / honor `$BROWSER=""`).
4. Tests: unit-test the decision logic (which value → open vs notify, headless → no-op); integration just asserts the forward still works and nothing blocks.
## Notes
Low effort, low risk if the headless guard is strict. Lowest-value of the set on a server/SSH workflow (where you'd open the SSH-tunneled URL on your laptop yourself).
Contributor guide
Assessment
This issue has not been assessed yet.