feat(node): add TypeScript sibling project for npm-based install
Some checks failed
CI (Node) / build-test (push) Successful in 6s
CI (.NET) / build (push) Successful in 10s
Release / release (push) Successful in 8s
Release (Node) / release (push) Failing after 10s

Introduces @kuns/claude-mailbox under node/, a wire-compatible TypeScript
port of the .NET daemon that distributes via the public Gitea npm registry.
The .NET project stays in src/ClaudeMailbox/ untouched; users pick whichever
flavor they prefer.

- node/ project: fastify + @modelcontextprotocol/sdk StreamableHTTPServerTransport
  + better-sqlite3, schema and wire surface match the C# version (port 47822,
  X-Mailbox header, MCP tool names, snake_case SQLite columns)
- Cross-platform autostart: Scheduled Task (Win, no admin) / Windows Service
  (Win, --service) / launchd (mac) / systemd --user (linux)
- 9/9 vitest tests pass; end-to-end /health + send/check round-trip verified
- CI split: existing ci.yml/release.yml renamed to *-dotnet.yml with path
  filters, new ci-node.yml and release-node.yml publish to Gitea npm registry
- install.ps1 / install.sh bootstrap one-liners at repo root; homebrew/
  contains a tap formula template
- README install section reordered: npm path primary, dotnet publish secondary

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-04-30 14:06:46 +02:00
parent 757a095c10
commit 05d87d2aa7
26 changed files with 5638 additions and 40 deletions

View File

@@ -25,43 +25,48 @@ One long-running daemon binds HTTP on loopback, hosts the MCP server at `/mcp` a
## Install
The recommended path is the npm package — it works on Windows, macOS, and Linux.
```sh
# one-time per machine: point the @kuns scope at the public Gitea npm registry
npm config set @kuns:registry=https://git.kuns.dev/api/packages/releases/npm/
# install
npm install -g @kuns/claude-mailbox
```
Or use the bootstrap one-liner:
```powershell
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true
# Windows
irm https://git.kuns.dev/releases/ClaudeMailbox/raw/branch/main/install.ps1 | iex
```
Put the resulting `claude-mailbox.exe` on your `PATH`.
## Daemon lifecycle
Pick whichever level of automation you want:
1. **Manual.** `claude-mailbox serve` in a terminal.
2. **Startup shortcut.** Shortcut to `claude-mailbox serve` in `shell:startup`.
3. **Windows Service (recommended).** See below.
### Windows Service
Install (admin shell):
```
claude-mailbox install-service [--port 47822] [--bind 127.0.0.1] [--db-path <path>]
```sh
# macOS / Linux
curl -fsSL https://git.kuns.dev/releases/ClaudeMailbox/raw/branch/main/install.sh | sh
```
This:
- Creates `%ProgramData%\ClaudeMailbox\` with ACLs for `LocalService`
- Seeds `mailbox.json` with the defaults (or your flag overrides) — only on first install
- Registers the service via `sc.exe create`, running as `NT AUTHORITY\LocalService` with `start= auto`
macOS users can also install via Homebrew once the tap is published:
Control:
```
claude-mailbox start
claude-mailbox stop
claude-mailbox status # prints Running | Stopped | NotInstalled
claude-mailbox uninstall-service [--purge]
```sh
brew install kuns/tap/claude-mailbox
```
`--purge` additionally removes `%ProgramData%\ClaudeMailbox\` (config + database).
### Autostart
```sh
claude-mailbox install-autostart # per-user, no admin
claude-mailbox install-autostart --service # Windows only: register as a Windows Service (admin)
claude-mailbox status # Running | Stopped | NotInstalled
claude-mailbox uninstall-autostart [--purge]
```
| Platform | Default mechanism | `--service` mechanism |
|---|---|---|
| Windows | Scheduled Task at logon (no admin) | Windows Service (admin, via `node-windows`) |
| macOS | launchd LaunchAgent in `~/Library/LaunchAgents/` | n/a |
| Linux | systemd `--user` unit in `~/.config/systemd/user/` | n/a |
### Config precedence
@@ -69,21 +74,35 @@ claude-mailbox uninstall-service [--purge]
CLI flag > mailbox.json > built-in defaults
```
The service is invoked with `serve --config C:\ProgramData\ClaudeMailbox\mailbox.json`, so editing that file and restarting the service is enough to change port/bind/db-path.
`mailbox.json` is searched at `~/.claude-mailbox/mailbox.json` (per-user), and on Windows additionally at `%ProgramData%\ClaudeMailbox\mailbox.json` (machine-wide, written by `--service` install). Pass `--config <path>` to override.
Interactive (console) runs without `--config` use `%USERPROFILE%\.claude-mailbox\mailbox.db` (unchanged from v0).
Defaults: port `47822`, bind `127.0.0.1`, database at `~/.claude-mailbox/mailbox.db`.
### Manual smoke test
### Smoke test
```
claude-mailbox install-service
sc query ClaudeMailbox
claude-mailbox start
Invoke-WebRequest http://127.0.0.1:47822/health
claude-mailbox uninstall-service --purge
```sh
claude-mailbox install-autostart
claude-mailbox status
curl http://127.0.0.1:47822/health
claude-mailbox uninstall-autostart --purge
```
Defaults: port `47822`, bind `127.0.0.1`, database at `%ProgramData%\ClaudeMailbox\mailbox.db` (service) or `%USERPROFILE%\.claude-mailbox\mailbox.db` (console).
### Build the .NET binary (alternative)
The original .NET 8 implementation still lives in `src/ClaudeMailbox/`. Build a self-contained Windows exe with:
```powershell
dotnet publish src/ClaudeMailbox -c Release -r win-x64 --self-contained -p:PublishSingleFile=true
```
Put the resulting `claude-mailbox.exe` on your `PATH` and use the legacy `install-service` verbs (Windows-only, admin shell):
```
claude-mailbox install-service [--port 47822] [--bind 127.0.0.1] [--db-path <path>]
claude-mailbox uninstall-service [--purge]
```
The .NET and Node builds are wire-compatible (same port, same `X-Mailbox` header, same MCP tool names, same SQLite schema), so a `.mcp.json` configured against one works against the other.
## Use from a Claude session