• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive-studio / 25792633745 / 1
70%
main: 70%

Build:
DEFAULT BRANCH: main
Ran 13 May 2026 10:15AM UTC
Files 511
Run time 14s
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

13 May 2026 10:11AM UTC coverage: 68.673% (+0.02%) from 68.652%
25792633745.1

push

github

web-flow
fix(main): prevent orphaned thv serve when parent exits before SIGKILL timer (#2217)

* fix(main): prevent orphaned thv serve when parent exits before SIGKILL timer

stopToolhive() nulled the module-level toolhiveProcess reference immediately
after sending SIGTERM and schedule SIGKILL via setTimeout. When Electron's
parent process exited before the 2s timer fired, the synchronous
process.on('exit') handler called stopToolhive({ force: true }) but it
short-circuited on !toolhiveProcess, leaving the child alive and blocking
the next launch's port.

Hold the reference until the child's 'exit' event fires (tracked via a new
isStopping flag for isToolhiveRunning) so the synchronous parent-exit force
kill actually SIGKILLs the orphaned PID. Guard the exit handler against
clobbering a fast-restart's new spawn.

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

* fix(main): use exitCode/signalCode for liveness instead of .killed

Addresses Copilot review feedback on PR #2217.

`ChildProcess.killed` is only set after a successful `kill()` call - it
reflects "we sent a signal", not "the process has exited". After a
graceful SIGTERM the flag becomes true while the child is still running,
which caused the very fix this PR is for to short-circuit: the
parent-exit handler's `stopToolhive({ force: true })` returned early on
`toolhiveProcess.killed` and never escalated to SIGKILL. The mock test
deliberately did not auto-set `.killed`, so the regression was masked.

- isToolhiveRunning() now checks exitCode/signalCode for true liveness
- stopToolhive() early return uses the same liveness check
- exit handler clears the pending killTimer so a quick graceful exit
  does not leave a 2s setTimeout holding the event loop open
- MockProcess gains exitCode/signalCode (null defaults) to match the
  real ChildProcess API; regression test now sets mockProcess.killed
  after the first stop so the escalation path mirrors production

Co-Authored-By: Claude Opus... (continued)

4851 of 7622 branches covered (63.64%)

7234 of 10534 relevant lines covered (68.67%)

118.73 hits per line

Source Files on job 25792633745.1
  • Tree
  • List 511
  • Changed 1
  • Source Changed 1
  • Coverage Changed 1
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Build 25792633745
  • 1e1f92bc on github
  • Prev Job for on main (#25788606567.1)
  • Next Job for on main (#25808404938.1)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc