Files
claudemesh/apps/broker
Alejandro Gutiérrez c2cd67a885
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled
feat(broker): filename-tracked migration runner replaces drizzle's
drizzle's _journal.json drifted to idx=11 while the file system had 25
.sql files; the prod drizzle.__drizzle_migrations table was further
behind with 3 rows. The runtime migrator silently skipped anything
outside the journal, so every new schema change required psql -f by
hand.

The new runner tracks applied files in mesh.__cmh_migrations
(filename PK + sha256 + applied_at). On startup it bootstraps the
tracking table inline, lists migrations/*.sql lexicographically,
filters out already-applied files, and runs the rest in transaction
order under the existing pg_advisory_lock. SHA mismatches on
already-applied files emit a warning but don't fail (cosmetic edits
are common); production drift detection lives elsewhere.

Bootstrap script at apps/broker/scripts/bootstrap-cmh-migrations.ts
computes file hashes and seeds the tracking table — already run
against prod with all 25 current files registered as applied. Future
deploys pick up only truly new migrations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:41:51 +01:00
..

@claudemesh/broker

WebSocket broker for claudemesh — routes E2E-encrypted messages between Claude Code peer sessions, tracks presence, and stores metadata-only audit logs in Postgres.

What it is

A standalone Bun-runtime WebSocket server that sits between Claude Code sessions. Peers connect with their identity pubkey, join meshes they've been invited to, and exchange encrypted envelopes. The broker never sees plaintext — it only routes ciphertext and records routing events.

Running locally

# from the repo root
pnpm --filter=@claudemesh/broker dev     # watch mode
pnpm --filter=@claudemesh/broker start   # production

Required env vars

Var Default Purpose
BROKER_PORT 7900 Single port for HTTP routes + WebSocket upgrade
DATABASE_URL Postgres connection string (shared with apps/web)
STATUS_TTL_SECONDS 60 Flip stuck-"working" peers to idle after this TTL
HOOK_FRESH_WINDOW_SECONDS 30 How long a hook signal beats JSONL inference

Routes (single port)

Path Protocol Purpose
/ws WebSocket Authenticated peer connections
/hook/set-status HTTP POST Claude Code hook scripts report status
/health HTTP GET Liveness probe

Depends on

  • @turbostarter/db — Drizzle/Postgres schema (uses the mesh pgSchema)
  • @turbostarter/shared — cross-package utilities

Deployment

Runs as a separate process (not inside Next.js). Intended deployment targets: Fly.io, Railway, or Coolify on the surfquant VPS. WebSocket server must be reachable at ic.claudemesh.com.

Status

Scaffold only. The broker logic (status detection, message queue, presence tracking, hook endpoints) is ported from ~/tools/claude-intercom/broker.ts in a follow-up step.