Commit Graph
4 Commits
Author SHA1 Message Date
Miguel Ángel 1289734770 fix(cli): a finished capture exits even when a site's DNS never answers (#5983)
* fix(cli): a finished capture exits even when a site's DNS never answers

Capture resolved every page request with the system lookup and gave up after
10 s, but a system lookup cannot be cancelled: the abandoned one kept the
process alive until the OS resolver timed out, so a capture that had printed
its result could run past the app's 5-minute cap and lose its folder.
Resolve through c-ares instead, as hostAnswers does, and cancel it at the
same 10 s deadline.

* test(cli): a capture lookup that answers must exit right after too

Dropping the timer cleanup kept every successful lookup alive 10 s and no test noticed.

* fix(cli): capture falls back to the system lookup and exits once its result is out

c-ares answers first. When it has no answer, the system lookup (hosts file, OS-only DNS)
runs in a child process killed at the 10 s deadline, cached per host, because Node waits
for an in-process system lookup even in process.exit. Capture then asks the CLI to exit
100 ms after printing its result, as render does.

* fix(cli): capture reads the hosts file first and kills its lookup child on exit

The hosts file answers before DNS, as the system lookup does (overrides and 0.0.0.0
blocks keep working). A host whose system answer is cached skips c-ares, a caller that
joins a running lookup keeps its own deadline, and a pending lookup child is killed when
the CLI exits.

* fix(cli): capture's forced exit waits until a slow reader has the whole result

The root exit now waits for stdout and stderr to hand over what is already
written before it calls process.exit, so a large JSON result on a slow pipe
arrives complete. A hostname listed several times in the hosts file now has
every address checked, not only the first.

* fix(cli): keep process exit in the CLI root and let test fixtures exit

The output wait is now a helper that only waits; cli.ts still owns the
process.exit. The process-ownership check treats test fixtures like tests,
since each one runs as its own process.

* chore(cli): run the process-ownership check before every commit

A process.exit outside a process root used to pass the local hooks and fail
only in CI's Preflight.
2026-10-21 02:46:17 +00:00
Miguel Ángel 434ad8c41c perf(cli): a repeat check starts with the CLI and Chrome already up (#5943)
* fix(cli): the browser the CLI launches exits with it, even on kill -9

* fix(build): the root build runs on Windows

* perf(cli): a repeat check runs in a process that already has the CLI and Chrome up

* fix(cli): a warm check delivers all its output before it exits

* fix(cli): the warm check only talks to a server that proves it is the user's

The warm socket now lives in a private, owner-verified directory (XDG_RUNTIME_DIR,
~/.cache or LOCALAPPDATA) next to a 0600 token. Client and server prove the token to
each other over fresh nonces before any request is sent, the request carries an
HMAC of the environment instead of the environment itself, and frames are capped.

* fix(cli): a warm check prints its stdout even after something went to stderr

The client stopped writing frames once any frame had been written, so a check that
printed a notice to stderr first lost its JSON report.

* test(cli): list the warm-check client fixture as a fallow entry instead of an inline ignore

* fix(cli): a check started while a warm one is busy runs cold at once on Windows

The warm server stopped listening when it accepted a client. On Windows the pipe name stays alive through the served connection, so a second client's connect saw a busy pipe and waited 30 s for a free instance before running cold. It now keeps listening while serving (accept already declines anyone else) and stops when the served check finishes.

* test(cli): the orphan test reads the check's own Chrome and watchdog instead of racing a poll

On Windows each process listing is a PowerShell call of about a second, so a check that finishes quickly could start and close Chrome between two polls, and the test failed its own 'Chrome was seen' precondition. A fixture now records the Chrome tree and the watchdog from inside the check when its first page opens.
2026-10-20 19:09:11 +00:00
James ab8b50afd7 refactor(repo): resolve changed-code audit 2026-07-20 11:59:57 -07:00
James 3aa2404747 refactor(cli): centralize process lifecycle 2026-07-20 09:04:03 -07:00