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>
72 lines
1.8 KiB
JSON
72 lines
1.8 KiB
JSON
{
|
|
"name": "claudemesh-cli",
|
|
"version": "1.37.0",
|
|
"description": "Peer mesh for Claude Code sessions — CLI + MCP server.",
|
|
"keywords": [
|
|
"claude-code",
|
|
"mcp",
|
|
"model-context-protocol",
|
|
"claudemesh",
|
|
"peer-messaging",
|
|
"multi-agent"
|
|
],
|
|
"author": "Alejandro Gutiérrez",
|
|
"license": "MIT",
|
|
"homepage": "https://claudemesh.com",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/alezmad/claudemesh.git",
|
|
"directory": "apps/cli"
|
|
},
|
|
"type": "module",
|
|
"bin": {
|
|
"claudemesh": "./dist/entrypoints/cli.js"
|
|
},
|
|
"files": [
|
|
"dist",
|
|
"skills",
|
|
"README.md",
|
|
"LICENSE"
|
|
],
|
|
"publishConfig": {
|
|
"access": "public"
|
|
},
|
|
"scripts": {
|
|
"build": "bun build.ts",
|
|
"clean": "git clean -xdf .cache .turbo dist node_modules",
|
|
"dev": "bun --hot src/entrypoints/cli.ts",
|
|
"start": "bun src/entrypoints/cli.ts",
|
|
"format": "prettier --check . --ignore-path ../../.gitignore",
|
|
"lint": "eslint",
|
|
"prepublishOnly": "bun run build",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"prettier": "@turbostarter/prettier-config",
|
|
"engines": {
|
|
"node": ">=20"
|
|
},
|
|
"dependencies": {
|
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
"citty": "0.2.2",
|
|
"libsodium-wrappers": "0.7.15",
|
|
"qrcode-terminal": "0.12.0",
|
|
"ws": "8.20.0",
|
|
"zod": "4.1.13"
|
|
},
|
|
"devDependencies": {
|
|
"@claudemesh/sdk": "workspace:*",
|
|
"@turbostarter/eslint-config": "workspace:*",
|
|
"@turbostarter/prettier-config": "workspace:*",
|
|
"@turbostarter/tsconfig": "workspace:*",
|
|
"@turbostarter/vitest-config": "workspace:*",
|
|
"@types/libsodium-wrappers": "0.7.14",
|
|
"@types/qrcode-terminal": "0.12.2",
|
|
"@types/ws": "8.5.13",
|
|
"eslint": "catalog:",
|
|
"prettier": "catalog:",
|
|
"typescript": "catalog:",
|
|
"vitest": "catalog:"
|
|
}
|
|
}
|