Files
hyperframes/packages
miga-heygenandMiguel Ángel fcc637068c fix(cli): honor an explicit --port for background preview reuse and launch (#3915)
* fix: honor explicit --port when reusing a background preview server

startBackgroundPreview never compared a reuse candidate's actual bound
port against the caller's explicitly requested --port before returning
it, so a second `preview --port <N>` call could silently return an
existing server on a different port instead of honoring the request.

Reuses the existing PreviewServerPortMismatchError (already used by
findPreviewServerForProject for the same discipline) instead of adding
a new error type: an explicit --port that doesn't match the reuse
candidate now throws a clear conflict rather than substituting the
wrong port silently. A bare launch with no --port keeps reusing any
project-matching server, unchanged.

Deliberately out of scope: the interactive/embedded launch path
(runEmbeddedMode -> findPortAndServe) has the same silent-substitution
shape when a same-project server is found mid-scan at a port other
than the one requested. That path's output isn't the JSON lifecycle
schema this bug was reported against, and fixing it would mean
touching the interactive dev-server bind/scan loop rather than a
simple pre-return check, so it's left as a follow-up candidate.

Co-Authored-By: Miguel Angel <miguel.sierra@heygen.com>

* fix: honor explicit --port on every background preview exit path

`startBackgroundPreview` already refused to reuse a same-project server on
the wrong port when --port was explicit, but the fresh-launch path still
trusted whatever port the detached child bound. The child scans upward from
--port and takes the first free port, so `--background --port N` with N busy
reported `{ type: "started", port: N+1 }` and recorded ownership of it.

- After the child comes up, compare its port with the explicit --port. On a
  mismatch, reap the wrapper, wait until the substitute stops answering, and
  throw `PreviewPortUnavailableError` (JSON code `preview-port-unavailable`).
  If the substitute never stops, fail loudly instead of reporting it.
- Share one `unmetPreferredPort` predicate between the reuse and launch
  paths, and one `awaitServerGone` wait between the reap path and
  `stopBackgroundPreview`.
- When several same-project servers are running, prefer the one on the
  explicit --port as the reuse candidate instead of the lowest port.
- Map launch failures to JSON codes in one place
  (`backgroundStartFailureCode`).

Tests: preferred port bound → reported as-is; preferred port taken → reaped
and rejected with both ports, no session record; substitute that keeps
serving → distinct error; bare launch keeps the next free port; explicit
port picks the matching sibling. Deleting the launch-path check, the
candidate ordering, or the post-kill wait each turns its test red.

Co-Authored-By: Miguel Ángel <miguel.sierra@heygen.com>

* fix(cli): reuse the same-project server on the explicit --port

`startBackgroundPreview` picked its reuse candidate before honouring
`--port`, so with an owned server on 3002 and an unmanaged same-project
server on 3003, `--port 3003` rejected with "No Studio preview server …
on port 3003. Matching server port: 3002" even though 3003 was running.

- A policy-matching same-project server already on the explicit port is
  now the reuse candidate, owned or not; the owned server stays
  authoritative otherwise, and an explicit GPU-policy change on the
  requested port still replaces it.
- `PreviewServerPortMismatchError` receives every policy-matching
  same-project server, so the ports it reports are the ones running.
- `policyMatchingServers` is the single owner of the same-project +
  GPU-policy predicate; `matchingServer` derives from it.
- `BackgroundPreviewResult` names the launch result union once;
  `PREVIEW_PORT_MISMATCH_CODE` replaces three literal error codes.

Tests: unmanaged sibling on the explicit port is reused without touching
the owned server; mismatch error lists every same-project port and no
foreign-project port; owned server on the explicit port is replaced on a
GPU-policy change. Each new check fails when its guard is removed.

Co-Authored-By: Miguel Ángel <miguel.sierra@heygen.com>

* refactor(cli): keep the --port honour comments short

* fix(cli): drop the scan binding stopBackgroundPreview no longer reads

* refactor(cli): keep comment share at base in the preview lifecycle files

* fix(cli): reuse a same-project server on an explicit --port beyond the scan window

* test(cli): pin the JSON codes for a background start that misses --port

* refactor(cli): probe an out-of-window --port in its own helper

---------

Co-authored-by: Miguel Angel <miguel.sierra@heygen.com>
2026-10-02 18:26:05 +00:00
..
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00
2026-10-02 08:36:30 -07:00