refactor(node): migrate from better-sqlite3 to node:sqlite, require Node 24+
Some checks failed
CI (Node) / build-test (push) Failing after 8s
Some checks failed
CI (Node) / build-test (push) Failing after 8s
Native binding caused install pain on every new Node major (no prebuilts +
node-gyp needs VS+Windows SDK to fall back). For this project's workload
(a few ops/day, no advanced SQLite features) better-sqlite3's perf edge is
irrelevant — node:sqlite's bundled, ABI-stable sync API is the better fit.
- db.ts: DatabaseSync, db.exec("PRAGMA …"), explicit BEGIN/COMMIT helper to
replace db.transaction(); row casts go through unknown because node:sqlite
returns Record<string, SQLOutputValue>.
- package.json: drop better-sqlite3 + @types/better-sqlite3, bump
engines.node to >=24, vitest 2 → 4 (2.x couldn't resolve `node:sqlite`).
- mailbox-doctor: add Step 1 that enforces Node ≥24 with a concrete fix
message, renumbers downstream steps.
Node 1.2.0 → 1.3.0. 35 transitive packages removed from the lockfile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,27 @@
|
||||
---
|
||||
description: Diagnose and auto-fix the Claude-Mailbox setup (binary install, port-conflict detection, daemon autostart, smoke test, optional base-prefix).
|
||||
description: Diagnose and auto-fix the Claude-Mailbox setup (Node version, binary install, port-conflict detection, daemon autostart, smoke test, optional base-prefix).
|
||||
allowed-tools: Bash, Read, Edit, Write
|
||||
---
|
||||
|
||||
You are running the **Claude-Mailbox doctor**. Walk through these checks in order. After each step, print a one-line `✓` / `✗` with the action you took. End with a summary block.
|
||||
|
||||
Use `Bash` only for `claude-mailbox` subcommands, `npm`, `where`/`which`, and HTTP probes. Use `Read`/`Edit`/`Write` for `.claude/settings.json` and `mailbox.json`. Never run `sudo` automatically — if elevation is needed, stop and ask.
|
||||
Use `Bash` only for `claude-mailbox` subcommands, `npm`, `node`, `where`/`which`, and HTTP probes. Use `Read`/`Edit`/`Write` for `.claude/settings.json` and `mailbox.json`. Never run `sudo` automatically — if elevation is needed, stop and ask.
|
||||
|
||||
## Step 1 — daemon binary on PATH
|
||||
## Step 1 — Node.js version
|
||||
|
||||
Run: `node --version`
|
||||
|
||||
claude-mailbox uses Node's built-in `node:sqlite` and therefore requires **Node 24 or newer**. Parse the major version from the output.
|
||||
|
||||
- **Major ≥ 24** → ✓ record the version, continue.
|
||||
- **Major == 22 or 23** → ✗ Stop. `node:sqlite` is experimental on these and requires `--experimental-sqlite`. Print:
|
||||
> Found Node `<X.Y.Z>`. claude-mailbox needs Node 24 LTS or newer. Install via `nvm install 24 && nvm use 24` (or `nvs` / `winget install OpenJS.NodeJS.LTS` on Windows), then re-run the doctor.
|
||||
- **Major < 22** → ✗ Stop with the same message; this Node is end-of-life.
|
||||
- **Major ≥ 26** with `better-sqlite3` still installed globally from a previous version → just note: "Node `<X.Y.Z>` is fine for the current claude-mailbox (no native deps); ignore any old `better-sqlite3` build warnings from a prior install."
|
||||
|
||||
If `node --version` itself fails (`command not found`), stop and tell the user to install Node 24+ first.
|
||||
|
||||
## Step 2 — daemon binary on PATH
|
||||
|
||||
Run: `claude-mailbox --version`
|
||||
|
||||
@@ -27,7 +41,7 @@ Run: `claude-mailbox --version`
|
||||
|
||||
After install, re-run `claude-mailbox --version`. If it still fails, stop and report.
|
||||
|
||||
## Step 2 — port-conflict check (before autostart!)
|
||||
## Step 3 — port-conflict check (before autostart!)
|
||||
|
||||
Default port is 37849. Probe whether anything is already on it:
|
||||
|
||||
@@ -35,10 +49,10 @@ Default port is 37849. Probe whether anything is already on it:
|
||||
curl -sf http://127.0.0.1:37849/health
|
||||
```
|
||||
|
||||
- **Returns a JSON body with `"status":"ok"` and a `version` field that matches `claude-mailbox --version`** → it's already our daemon, ✓ skip to Step 4.
|
||||
- **Returns a JSON body with `"status":"ok"` and a `version` field that matches `claude-mailbox --version`** → it's already our daemon, ✓ skip to Step 5.
|
||||
- **Returns 200 with `"status":"ok"` but a different `version`** → it's an older claude-mailbox; treat as running, ✓.
|
||||
- **Returns non-200, non-JSON, or any other foreign response** → **port conflict**. Some other process owns 37849.
|
||||
- **Connection refused** → port is free, ✓ continue to Step 3.
|
||||
- **Connection refused** → port is free, ✓ continue to Step 4.
|
||||
|
||||
If port conflict detected:
|
||||
1. Tell the user which process holds the port (Windows: `Get-NetTCPConnection -LocalPort 37849 | Select-Object OwningProcess`, then `Get-Process -Id <pid>`; macOS/Linux: `lsof -i :37849`).
|
||||
@@ -51,7 +65,7 @@ If port conflict detected:
|
||||
Merge into existing env, preserving other keys.
|
||||
5. Mark `restart_needed = true`.
|
||||
|
||||
## Step 3 — daemon autostart and running state
|
||||
## Step 4 — daemon autostart and running state
|
||||
|
||||
Run: `claude-mailbox status`
|
||||
|
||||
@@ -63,11 +77,11 @@ Run: `claude-mailbox status`
|
||||
|
||||
If `install-autostart` still fails after both attempts (very rare — would mean both `schtasks` and `reg add` are blocked), stop and report what `status` and `start` printed.
|
||||
|
||||
## Step 4 — health probe
|
||||
## Step 5 — health probe
|
||||
|
||||
Hit `http://127.0.0.1:<port>/health` (use the configured port, not necessarily 37849). Expect a JSON body with `"status":"ok"` AND a `version` matching `claude-mailbox --version`. If unreachable or version mismatch, stop and report.
|
||||
|
||||
## Step 5 — mailbox identity (base prefix)
|
||||
## Step 6 — mailbox identity (base prefix)
|
||||
|
||||
**No prompt by default.** Each Claude Code session gets a unique mailbox name auto-derived from its `session_id` (e.g., `claude-a8b3c1d2`).
|
||||
|
||||
@@ -80,7 +94,7 @@ Ask once: *"Want to flavor your mailbox names with a memorable prefix (e.g., `ba
|
||||
|
||||
On yes/explicit name: merge `env.CLAUDE_MAILBOX_NAME = <name>` into `.claude/settings.json`, preserving other keys. Mark `restart_needed = true`.
|
||||
|
||||
## Step 6 — smoke test
|
||||
## Step 7 — smoke test
|
||||
|
||||
Use two ephemeral names — we don't need the real session name here:
|
||||
|
||||
@@ -89,14 +103,15 @@ claude-mailbox send --from doctor-probe-a --to doctor-probe-b --body "ping from
|
||||
claude-mailbox check --name doctor-probe-b
|
||||
```
|
||||
|
||||
(If the port was changed in Step 2, pass `--url http://127.0.0.1:<port>` to both.)
|
||||
(If the port was changed in Step 3, pass `--url http://127.0.0.1:<port>` to both.)
|
||||
|
||||
The `check` output must be a JSON array with one message: `from: doctor-probe-a`, body matches. ✓ on success, ✗ otherwise.
|
||||
|
||||
## Step 7 — summary
|
||||
## Step 8 — summary
|
||||
|
||||
```
|
||||
Claude-Mailbox doctor
|
||||
node: <version>
|
||||
binary: <version>
|
||||
daemon: Running (port: <port>, what you did if anything)
|
||||
health: ok
|
||||
|
||||
Reference in New Issue
Block a user