Tencent / Tencent/BrowserSkill
[Bug] Windows: the auto-spawned daemon dies with the launching process tree (`daemon start` / `status`), and read-only commands start it as a side effect
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5.7k
- Forks
- 399
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 74
Description
Environment
- OS: Windows 10 22H2 (19045), x64
bskCLI / daemon: 0.2.1 (daemon protocol 1.1),~/.local/bin/bsk.exe,BSK_HOME=~/.bsk- Browser extension: ext-v0.3.0 (reports protocol 1.3)
- Host: DeepSeek Harness Desktop. Shell commands are invoked with a fixed per-call timeout, stdout captured through a pipe (no TTY); on timeout the harness kills the command's whole process tree.
- Plugin involved downstream:
@wxg-prc-cpg/browser-skill-dsh-plugin0.2.1
Actual behavior
bsk daemon start never returns in that context. When the harness kills the command at its 120 s timeout, the daemon dies with it — even though bsk daemon start --help says "Start the daemon (auto-detaches unless --foreground)".
bsk status behaves the same way, and it starts a daemon as a side effect: run while no daemon was alive, it printed a complete status block (daemon version 0.2.1, pid 25900, uptime 0s) and then hung; the harness killed it 90 s later — after which that daemon never logged again either.
So a caller that merely checks status can silently remove a healthy daemon. In agent harnesses that is a footgun rather than an edge case, because status / doctor are the first commands an agent runs (#265 and #24 report the unbounded wait; this is the side-effect half of it). The result: an unrelated later browser_session start has to auto-spawn a daemon, hits #180 / #183, hangs forever, and leaves the orphaned Agent Window of #245.
Evidence (~/.bsk/daemon.log.2026-09-17, UTC; local = UTC+8)
Only lines that are actually in the log:
01:12:36 daemon lock acquired; ws server listening 127.0.0.1:52800; daemon ready pid=27604
01:12:36 browser connected id=<ext-instance>
01:12:41 periodic update check failed (github.com unreachable)
01:15:11 daemon ready pid=25900
01:15:11 browser connected id=<ext-instance>
01:17:04 daemon ready pid=18152
01:17:07 browser connected id=<ext-instance>
01:22:34 idle session stopped session=cgya
How to read it (inferences, marked as such):
27604was started by mybsk daemon start; the harness killed that command at its 120 s timeout and the daemon stopped logging at the same moment. Inferred: it died with its launcher.25900was started implicitly bybsk status(the command that only meant to report); the harness killed it at its 90 s timeout and it likewise never logged again. Inferred: same cause.18152was auto-spawned by the browser extension / plugin. Its parent exited normally, so it became an orphan — this is the only one that survived (still running hours later).cgyais the session created during a 40-minute hang ofbrowser_session start(see #180 / #245); the daemon idle-reaped it after 5 minutes.
No daemon exit is logged (no shutdown line, no reason), which is what makes this hard to diagnose from the outside.
Expected behavior (suggested)
- Either detach for real, or refuse. If the spawned daemon cannot survive the launcher (
DETACHED_PROCESS/CREATE_NEW_PROCESS_GROUP, and on WindowsCREATE_BREAKAWAY_FROM_JOBso a job-object kill of the caller cannot take it down),daemon startshould fail fast with a message pointing atbsk daemon start --foreground(the pattern #263 documents for persistent host tasks). The current middle ground — appears detached, then dies silently — is the worst case: the caller has no way to notice. daemon startshould be idempotent and return immediately when a healthy daemon is already running; today it blocks in agent contexts even though the daemon is up.- Read-only commands should not auto-start a daemon (
status,doctor,browsers), or should behave asBSK_AUTO_START=0when stdout is not a TTY. Starting a service as a side effect of a query is what makes agents kill daemons by accident. - Log a reason when the daemon exits (
parent-killed/signal/idle). Diagnosing this from timestamps alone cost me a while; a single line would have made it obvious.
Related
- #55 (closed, 0.1.9) — daemon inherits the caller's stdout pipe → EOF-waiters hang. The stdio half looks fixed (the daemon now writes
~/.bsk/daemon.log), but the process-lifetime half is not. - #218 — sibling failure mode on the same platform (auto-detached process exits immediately).
- #265, #24 — unbounded waits in
doctor/status --jsonwhen auto-start happens. - #180, #183, #245 — what users see when the daemon disappears mid-handshake.
Workaround (verified on 0.2.1)
Let the extension/plugin start the daemon (its spawner exits normally, so the daemon survives as an orphan), or start it fully detached:
Start-Process -FilePath "$env:USERPROFILE\.local\bin\bsk.exe" -ArgumentList 'daemon','start' -WindowStyle Hidden
Do not run bsk daemon start / bsk status from a shell tool that kills its process tree on timeout. Read-only liveness probing that never starts anything: bsk browsers, or the owner of TCP port 52800.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Windows process-spawning paths behind daemon start, status, doctor, and browsers, then reproduce the behavior under a fixed-timeout shell that kills the process tree. Verify that daemon start returns or fails clearly, read-only commands do not unexpectedly start the daemon, and daemon termination records a reason in ~/.bsk/daemon.log.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100