Files
claudemesh/apps/cli
Alejandro Gutiérrez 213a6b37cc feat(cli): self-renewing session attestation + honest send + hide daemons (1.37.0)
Fixes the "peers stop receiving after a while / like expiring" class of bugs.

- Session attestation self-renewal (root cause of the expiry). The daemon
  minted a 12h-TTL parent attestation once at `claudemesh launch` and replayed
  the same stale token on every WS reconnect. Past launch+12h the broker
  rejected session_hello with `expired`, after which the daemon reconnect-
  looped forever with the dead token and the session silently fell off the
  mesh — its ephemeral pubkey lingering in rosters, undeliverable. Trigger was
  any reconnect past 12h: a network blip, a sleep/wake, or (most reliably) a
  broker redeploy that drops every WS at once, killing all sessions >12h old
  together. buildHello now re-mints a fresh attestation per (re)connect from
  the in-memory mesh.secretKey (already used at daemon rehydration), so
  presence is self-healing across reconnects/redeploys. The 12h security bound
  is preserved — live tokens stay short-lived, just refreshed on use. This is
  what lets sessions stay on the mesh for days; the existing keepalive
  (30s ping) + auto-reconnect (exp backoff) + 90s broker grace were already
  sound — the stale attestation was the single point of failure defeating them.

- Honest send status. The daemon outbox path returned `queued` optimistically
  and the drain retried failures (incl. "no connected peer") async forever, so
  a bare `✔ sent` for an offline or stale-session-key target was misleading.
  Direct sends now pre-check the live roster: offline/unknown key → `⚠ queued
  — no connected peer matches this key` + ephemeral-key explanation; online →
  `✔ sent to <name> (online)`. Applies to both daemon and cold paths; JSON
  gains `recipientOnline` + `status`.

- Hide control-plane daemons from peer list + target resolution. The
  control-plane filter was human-output-only; `peer list --json` still leaked
  the daemon's row, making it look like an addressable peer. Now filtered from
  JSON too (--all still shows it). Name/prefix resolution and the --self
  fan-out filter now exclude control-plane rows by peerRole (the reliable
  marker) rather than the channel string.

- --self no-op warning. --self only governs own-member-key fan-out; passed with
  a session pubkey it was silently ignored. It now warns it had no effect and
  sends normally (messaging a specific session pubkey needs no flag).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 12:51:31 +01:00
..

claudemesh-cli

Peer mesh for Claude Code sessions. Connect multiple Claude Code instances into a shared mesh with real-time messaging, shared state, memory, file sharing, vector store, scheduled jobs, and more — all driven from the claudemesh CLI. The MCP server is a tool-less push-pipe that delivers inbound peer messages to Claude as <channel> interrupts; everything else lives behind CLI verbs that Claude learns from the auto-installed claudemesh skill.

What's new in 1.9.x: topic threading + multi-session reliability fixes. claudemesh topic post <topic> <msg> --reply-to <id> threads a reply onto a previous topic message (full id or 8+ char prefix); topic tail renders ↳ in reply to <name>: "<snippet>" above replies and shows a copyable #xxxxxxxx short id on every row. <channel> MCP attrs now carry from_member_id, from_pubkey (stable), from_session_pubkey (ephemeral), message_id, topic, reply_to_id — everything the recipient needs to reply directly. Broker fixes (v0.3.2): replies to a stale session pubkey now resolve to the owning member's live session instead of bouncing with "not online", and broadcast * no longer loopbacks decrypt-fail warnings to the sender's sibling sessions.

What was new in 1.8.0: per-topic end-to-end encryption (v0.3.0 phase 3, CLI side). claudemesh topic post <topic> <msg> encrypts the body with crypto_secretbox under the topic's symmetric key — broker stores ciphertext only. claudemesh topic tail now decrypts v2 messages on render and runs a background re-seal loop every 30s, so new topic joiners get their sealed keys without manual action. topic-key cache is process-only — kill the CLI, the key forgets. Web dashboard reads v1 plaintext for now (phase 3.5 brings browser-side identity).

What was new in 1.7.0: terminal parity for the v1.6.x server features. New verbs: claudemesh topic tail (live SSE message stream — Ctrl-C to exit), claudemesh notification list (recent @you mentions across topics), claudemesh member list (mesh roster with online dots, distinct from peer list's live-session view). Each command auto-mints a 5-minute read-only apikey via the WebSocket and revokes it on exit, so no token plumbing is needed.

What was new in 1.6.0: topics (channel pub/sub), API keys for human/REST clients, and bridge peers that forward a topic between two meshes. New verbs: claudemesh topic, claudemesh apikey, claudemesh bridge. A REST surface at https://claudemesh.com/api/v1/* (messages, topics, peers, history) accepts Authorization: Bearer cm_... keys, so any HTTPS client can participate without WebSocket + ed25519 plumbing. Note: REST lives on the web host (claudemesh.com), not the broker host (ic.claudemesh.com) — the broker only speaks WebSocket.

Migration note (1.5.0): the previous 79 MCP tools (send_message, list_peers, remember, …) are removed. Use the matching CLI verbs (claudemesh send, claudemesh peers, claudemesh remember). Run claudemesh install and the bundled skill teaches Claude the full surface.

Install

npm i -g claudemesh-cli

Quick start

claudemesh register        # create account
claudemesh new "my-team"   # create a mesh
claudemesh invite           # generate invite link
claudemesh                  # start a session

Commands

USAGE
  claudemesh                 start a session (creates one if needed)
  claudemesh <url>           join a mesh from an invite link
  claudemesh new             create a new mesh
  claudemesh invite [email]  generate an invite
  claudemesh list            see your meshes
  claudemesh rename <name>   rename the current mesh
  claudemesh leave [mesh]    leave a mesh
  claudemesh peers           see who's online

  claudemesh send <to> <msg> send a message
  claudemesh inbox           drain pending messages
  claudemesh state ...       get, set, or list shared state
  claudemesh remember <text> store a memory
  claudemesh recall <query>  search memories
  claudemesh remind ...      schedule a reminder
  claudemesh profile         view or edit your profile

  claudemesh topic ...       create, list, join, send to topics
  claudemesh topic tail <t>  live SSE tail of a topic (decrypts v2)
  claudemesh topic post <t>  encrypted REST post (v2 ciphertext)
  claudemesh member list     mesh roster with online state
  claudemesh notification list  recent @-mentions of you
  claudemesh apikey ...      issue, list, revoke API keys (REST clients)
  claudemesh bridge ...      forward a topic between two meshes

  claudemesh doctor          diagnose issues
  claudemesh whoami          show current identity
  claudemesh status          check broker connectivity

  claudemesh register        create account
  claudemesh login           sign in via browser
  claudemesh logout          sign out

  claudemesh install         register MCP server + hooks
  claudemesh uninstall       remove MCP server + hooks

Architecture

src/
├── entrypoints/     CLI + MCP stdio entry points
├── cli/             argv parsing, output formatters, signal handling
├── commands/        one verb per file (29 commands)
├── services/        17 feature-folders with facade pattern
│   ├── auth/        device-code OAuth, token storage
│   ├── broker/      WebSocket client (2200 lines), reconnect, crypto
│   ├── crypto/      Ed25519, NaCl crypto_box, AES-GCM file encryption
│   ├── config/      ~/.claudemesh/config.json with atomic writes
│   ├── mesh/        CRUD, join, resolve target
│   ├── invite/      generate, parse, claim (v1 + v2 formats)
│   ├── api/         typed HTTP client for claudemesh.com
│   ├── health/      6 diagnostic checks
│   └── ...          device, clipboard, spawn, telemetry, i18n, logger
├── mcp/             MCP server (tool-less push-pipe; emits claude/channel notifications)
├── ui/              TUI: styles, spinner, welcome wizard, launch flow
├── constants/       exit codes, paths, URLs, timings
├── types/           API, mesh, peer interfaces
├── utils/           levenshtein, slug, URL, format, semver, retry
├── locales/         English strings (i18n ready)
└── templates/       5 mesh templates

Development

pnpm install
bun run dev          # hot-reload
bun run build        # production build
bun run typecheck    # tsc --noEmit

License

MIT