Commit Graph

7 Commits

Author SHA1 Message Date
Mika Kuns
9f8c1d9e9d test(cli): fix flaky rename watch test with deterministic waiter polling
The rename test relied on a fixed 300ms setTimeout to fire after the CLI
subprocess had registered its waiter — adequate in isolation but flaky
under full-suite load on Windows (CLI spawn + first HTTP request can
exceed 300ms). Add a tiny public MailboxStore.waiterCount(name) helper
so the test can poll until the waiter is actually registered before
triggering the rename. Also tighten the missing-name assertion from
not-zero to the contract-exact exit code 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:34:47 +02:00
Mika Kuns
b74e969229 test(db): add abort-racing-send + rejectAllWaiters coverage; document notifyOneWaiter invariant
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:15:39 +02:00
Mika Kuns
31584fe623 feat(db): add waitForMessage with FIFO single-delivery and rename signaling
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:10:17 +02:00
Mika Kuns
0c06e2cf4b feat(cleanup): hide and prune stale mailboxes
Mailbox listings grew unbounded as old sessions ended without
unregistering. This adds two layers of cleanup, configurable via
mailbox.json or `serve` flags:

- Lazy filter: list responses (REST /v1/list, MCP list_mailboxes)
  drop mailboxes idle longer than hideAfterMinutes (default 24h),
  while always keeping the caller and any sender with messages
  pending for them.
- Background sweep: startServer runs an initial prune on boot and
  schedules an unref'd interval timer that hard-deletes mailboxes
  idle longer than deleteAfterMinutes (default 7d) which have no
  pending messages, and wipes their delivered history.
2026-05-20 13:54:03 +02:00
Mika Kuns
b10ac36ed0 feat(naming)!: auto-derive mailbox name from project + runtime rename
Mailbox names are now built as <project>-<session-short>, where <project>
is the sanitized git-repo basename (or cwd basename) — no more env-var
prefix step. Sessions can re-tag themselves at runtime via the new
mcp__mailbox__rename tool (POST /v1/rename), which transfers all
pending messages to the new name in a single transaction. Peers using
the old name re-discover via list_mailboxes.

BREAKING: \$CLAUDE_MAILBOX_NAME is no longer read. Existing setups that
relied on the env-var prefix should remove it from .claude/settings.json;
the prefix now comes from the working directory automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:14:15 +02:00
Mika Kuns
8832eab6c7 refactor(node): migrate from better-sqlite3 to node:sqlite, require Node 24+
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>
2026-05-19 16:07:21 +02:00
mika kuns
05d87d2aa7 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>
2026-04-30 14:06:46 +02:00