Skip to content

fix(hub): wait for daemon readiness in SEA mode before success#66

Merged
oorabona merged 3 commits into
mainfrom
fix/hub-daemon-sea
Jun 10, 2026
Merged

fix(hub): wait for daemon readiness in SEA mode before success#66
oorabona merged 3 commits into
mainfrom
fix/hub-daemon-sea

Conversation

@oorabona

@oorabona oorabona commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #60

Summary

termora-hub start --daemon (SEA build) used to print success and exit 0 while the daemon died instantly: it spawned a non-existent ./main.js sibling, stdio: "ignore" swallowed the error, and there was no readiness check.

  • In SEA builds, --daemon re-execs the binary with CLI argv (start --port N) instead of spawning a JS path; dev keeps the main.js sibling
  • New daemon-launch.ts: buildDaemonSpawnPlan (spawn plan per mode) + waitForDaemonReady (polls runtime.json for the child pid, then /api/health on the actual port — zero_conf safe)
  • Child stdout/stderr go to hub-daemon.log in the state dir (truncated per start, chmod 600); failures print the child's exit code or timeout with a bounded log tail and exit non-zero
  • A readiness timeout terminates the detached child via the ChildProcess handle (a reported failure never leaves a daemon running); health probes are individually bounded so a stalled socket can't hang the CLI

Test plan

  • 11 unit tests in daemon-launch.spec.ts (spawn plan per mode, ready/child-died/timeout paths, stalled health probe, log tail bounding, log truncation + permissions)
  • Full suite green: 2589 passed | 10 skipped; @termora/hub build green; biome clean on touched files
  • Manual smoke on a real SEA build (Linux, build ceb2bb1): start --daemonHub daemon ready, /api/health ok, hub-daemon.log is -rw-------, stop kills the daemon; failure injection (broken config dir) → exit 1 with Daemon process exited before readiness (code 1…) + log tail, no false success

oorabona added 3 commits June 10, 2026 21:16
- In SEA builds, `--daemon` re-execs the binary with CLI argv
  [`start`, `--port`, N] instead of spawning a non-existent
  ./main.js sibling
- New `daemon-launch.ts` exports buildDaemonSpawnPlan (spawn plan
  per mode), waitForDaemonReady (polls runtime.json then GETs
  /api/health), and log-tail utilities
- CLI daemon branch now writes child stdout/stderr to
  hub-daemon.log, polls for readiness, and exits non-zero with
  daemon log tail on failure
- Fixes silent spawn failure where stdio: "ignore" swallowed errors
  and success was printed before daemon proved reachable (#60)
Use the ChildProcess handle for daemon termination instead of a raw
process.kill(pid) to prevent hitting an unrelated process if the OS
reuses the pid. Also consolidate the health-check timeout into a single
constant to keep both bounds (fetch AbortSignal and race timeout) in sync.
@oorabona oorabona merged commit a6e3960 into main Jun 10, 2026
8 checks passed
@oorabona oorabona deleted the fix/hub-daemon-sea branch June 10, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hub: start --daemon dies silently in the SEA build (spawns a non-existent main.js)

1 participant