Skip to content

Fix Bun v1.1.42 compatibility, daemon startup race conditions, and CLI polling reliability (Vibed some parts of it, but tested by me)#5

Open
sh1ftred wants to merge 9 commits into
Egge21M:masterfrom
Routstr:master
Open

Conversation

@sh1ftred
Copy link
Copy Markdown

This PR fixes critical compatibility issues with Bun v1.1.42 and hardens the daemon startup flow against race conditions and misleading "ready" states.

1. Fix Bun v1.1.42 compatibility (src/daemon.ts, src/routes.ts)

Bun v1.1.42 does not match requests against the declarative routes object in Bun.serve(). Every request falls through to fetch(), making the daemon completely
unresponsive. We moved route dispatch into the fetch handler using the existing routes lookup table.

Additionally, Bun.file().delete() is unavailable in v1.1.42, so we replaced all calls with unlink() from node:fs/promises.

2. Harden daemon startup against races (src/daemon.ts)

Previously, running two CLI commands in quick succession could spawn two daemon processes because PID-file creation was non-atomic and the socket-existence check was
racy.

We introduced an atomic PID lock (openSync(..., "wx")) plus a stale-PID detector:

  • If a PID file exists and the process is alive → exit immediately.
  • If a PID file exists but the process is dead → clean it up and proceed.
  • If the atomic lock fails → another process is currently starting → exit immediately.

3. Make CLI polling wait for actual readiness (src/cli-shared.ts)

Before, the CLI only polled isDaemonRunning() (socket existence) with a hard 5-second timeout. On slower systems the daemon socket could exist before routes were
loaded, causing confusing connection errors.

We changed the loop to:

  • Poll indefinitely every 100 ms instead of giving up after 5 s.
  • After the socket exists, call /status and wait until the daemon reports LOCKED, UNLOCKED, or ERROR.
  • Warn the user after 30 s if startup is slow.

4. Minor logging & packaging tweaks

  • Moved the wallet.uninitialized log so it fires immediately when the config is missing, rather than after the HTTP server starts.
  • Scoped the package name to @routstr/cocod.

────────────────────────────────────────────────────────────────────────────────

Commits included:

  • 3f6ac14 – fetch-based routing + node:fs/promises unlink
  • 41acdc4 – indefinite polling with /status readiness check
  • 70f6951 – atomic PID lock to prevent duplicate daemon starts
  • 0da617e – version bump

────────────────────────────────────────────────────────────────────────────────

If you want, I can also make it shorter / more casual, or split it into a commit-by-commit changelog style.

Placeholder and others added 7 commits April 23, 2026 14:35
Bun.serve() declarative routes object doesn't match any routes in
Bun v1.1.42 - all requests fall through to the fetch handler, making
the daemon completely unresponsive. Move route matching into the
fetch handler using the existing routes lookup table.

Also replace Bun.file().delete() with unlink() from node:fs/promises,
as Bun.file().delete() is not available in Bun v1.1.42.
Placeholder added 2 commits April 27, 2026 19:03
- CONFIG_DIR now respects COCOD_DIR, with all paths (socket, pid,
  log, config, salt, db) deriving from it.
- Individual overrides (COCOD_SOCKET, COCOD_PID, COCOD_LOG_FILE)
  still work as before.
- Update README.md and docs/API.md with new env var.
- Bump version to 0.0.19.
- src/cli-shared.ts: import SOCKET_PATH and LOG_FILE from config.ts
  instead of recomputing from /home/user42/.cocod, so COCOD_DIR is honored.
- src/utils/state.ts: use CONFIG_FILE in the reset error message
  instead of hardcoded ~/.cocod/config.json.
- docs/daemon-api.json: document COCOD_DIR in the transport block.
- README.md: remove remaining hardcoded ~/.cocod reference in logging.
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.

1 participant