Files
claudemesh/apps/cli
Alejandro Gutiérrez fb7a84aed6 feat: v2 invite API + CLI claim flow + CLI friction reducer (wave 2)
Wires the v2 invite protocol end-to-end from a CLI user's perspective.
Broker foundation landed in c1fa3bc; this commit is the glue between
it and the human.

API (packages/api)
- createMyInvite now mints BOTH v1 token (legacy) AND v2 capability.
  Two-phase insert: row first (to get invite.id), then UPDATE with
  signed canonical bytes stored as JSON {canonical, signature} in the
  capabilityV2 column. Broker's claim handler parses the same shape.
- canonicalInviteV2 locked to `v=2|mesh_id|invite_id|expires_at|role|
  owner_pubkey_hex` — byte-identical to apps/broker/src/crypto.ts.
- brokerHttpBase() helper rewrites wss://host/ws → https://host for
  server-to-server calls.
- POST /api/public/invites/:code/claim — thin proxy to broker;
  passes status + body through, 502 broker_unreachable on fetch fail,
  cache-control: no-store.
- POST /api/my/meshes/:id/invites/email — mints a normal v2 invite
  via createMyInvite, records a pending_invite row, calls stubbed
  sendEmailInvite (logs TODO for Postmark wiring in a later PR).
- New schemas: claimInviteInput/ResponseSchema,
  createEmailInviteInput/ResponseSchema, v2 fields on
  createMyInviteResponseSchema.
- v1 paths untouched — legacy /join/[token] and /api/public/invite/:token
  continue to work throughout v0.1.x.

CLI (apps/cli)
- New `claudemesh join <code-or-url>` subcommand.
- Accepts bare code (abc12345), short URL (claudemesh.com/i/abc12345),
  or legacy ic://join/<token>. Detects v2 vs v1 and dispatches.
- v2 path: generates fresh ephemeral x25519 keypair (separate from
  the ed25519 identity) → POST /api/public/invites/:code/claim →
  unseals sealed_root_key via crypto_box_seal_open → persists mesh
  with inviteVersion: 2 and base64url rootKey to local config.
- Signature verification skipped with TODO — v0.1.x trusts broker;
  seal-open is already authenticated.
- apps/cli/src/lib/invite-v2.ts: generateX25519Keypair, claimInviteV2,
  parseV2InviteInput.
- state/config.ts: additive rootKey?/inviteVersion? fields.

CLI friction reducer
- apps/cli/src/index.ts: flag-first invocations
  (`claudemesh --resume xxx`, `claudemesh -c`, `claudemesh -- --model
  opus`) now route through `launch` automatically. Bare `claudemesh`
  still shows welcome; known subcommands dispatch normally.
- Removes one word of cognitive load: users never type `launch`.

No schema changes. No new deps. v1 fully backward compatible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:35:21 +01:00
..

claudemesh-cli

Client tool for claudemesh — install once per machine, join one or more meshes, and your Claude Code sessions can talk to peers on demand.

Install

# From npm (once published)
npm install -g claudemesh-cli

# Or from the monorepo during dev
cd apps/cli && bun link

Then register the MCP server with Claude Code:

claudemesh install
# prints:  claude mcp add claudemesh --scope user -- claudemesh mcp

Run the printed command, then restart Claude Code.

Join a mesh

claudemesh join https://claudemesh.com/join/<token>

Launch Claude Code

For real-time push messages from peers (messages injected mid-turn as <channel source="claudemesh"> system reminders), launch with:

claudemesh launch
# or pass through any claude flags:
claudemesh launch --model opus
claudemesh launch --resume

Under the hood this runs:

claude --dangerously-load-development-channels server:claudemesh

Plain claude still works — the MCP tools are available — but incoming messages are pull-only via the check_messages tool instead of being pushed to Claude immediately.

The invite link is generated by whoever runs the mesh. It bundles the mesh id, expiry, signing key, and role. Your CLI verifies it, generates a fresh keypair, enrolls you with the broker, and persists the result to ~/.claudemesh/config.json.

Commands

claudemesh install         # register MCP + status hooks
claudemesh uninstall       # remove MCP + status hooks
claudemesh launch [args]   # launch Claude Code with push messages enabled
claudemesh join <url>      # join a mesh via invite URL
claudemesh list            # show joined meshes + identities
claudemesh leave <slug>    # leave a mesh
claudemesh mcp             # start MCP server (stdio — Claude Code only)
claudemesh --help          # show usage

Env overrides

Var Default Purpose
CLAUDEMESH_BROKER_URL wss://ic.claudemesh.com/ws Point at a self-hosted broker
CLAUDEMESH_CONFIG_DIR ~/.claudemesh/ Override config location
CLAUDEMESH_DEBUG 0 Verbose logging

Status

v0.1.0 scaffold — CLI commands + MCP server shell in place. WS broker connection, libsodium crypto, invite-link verification, and auto-install of hooks land in subsequent steps.