Daemon outbox now stores resolved target_spec + crypto_box ciphertext
+ nonce per row. Drain worker is a forwarder; no per-row resolution at
drain time. Outbound routing is no longer a placeholder.
Schema additions (additive, NULL allowed for legacy rows): outbox.mesh,
target_spec, nonce, ciphertext, priority. v0.9.0 rows keep draining via
the broadcast fallback so existing in-flight rows finish cleanly.
IPC /v1/send resolves the user-friendly to (display name, hex prefix,
full pubkey, @group, *, #topicId) into a broker-format target_spec at
accept time. DMs encrypt via crypto_box; broadcast/topic/group base64
the plaintext. Hex prefixes (16+ chars) match against connected peers.
CLI thin-client routing extends trySendViaDaemon pattern to peer list
and skill list/get. Three new helpers in services/bridge/daemon-route.ts.
SKILL.md gains ambient mode section: after claudemesh install, raw
claude works for the daemon's attached mesh. Launch stays as the
override path.
Spec at .artifacts/specs/2026-05-04-v2-roadmap-completion.md orders
the remaining v2.0.0 work: multi-mesh daemon (1.26), CLI-to-thin-client
(1.27), mesh-to-workspace rename (1.28), HKDF identity (2.0).
Released as 1.25.0 on npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The architectural convergence v0.9.0 was building toward. CLI keeps
working without a daemon (claudemesh send/peer/inbox/...), but the MCP
push-pipe — which Claude Code uses for mid-turn channel emits, slash
commands, and resources — now requires the daemon. There is no fallback.
Daemon (additive):
- /v1/skills (list) and /v1/skills/:name (get) IPC endpoints, so the
MCP shim can surface mesh skills without holding its own broker WS.
- listSkills() / getSkill() on DaemonBrokerClient.
- SSE 'message' event now carries plaintext body, sender_member_pubkey,
priority, and subtype — full payload the MCP shim needs to render a
channel notification.
MCP server: 979 → 469 LoC (470 of the remaining 469 is the unrelated
mesh-service proxy mode; the push-pipe path is ~200 LoC including
boilerplate).
- Probes ~/.claudemesh/daemon/daemon.sock at boot. Bails loudly with
actionable instructions if missing.
- Subscribes to /v1/events SSE and translates each event into a
notifications/claude/channel emit.
- Fetches mesh skills from the daemon for ListPrompts/GetPrompt and
ListResources/ReadResource. ListTools returns []; the CLI is the API.
- No broker WS, no decryption, no reconnect logic. Daemon owns all of it.
claudemesh install: auto-installs and starts the daemon service for the
user's primary mesh (launchd / systemd-user). Pass --no-service to skip.
claudemesh launch: probes the daemon socket; if absent, spawns
'claudemesh daemon up --mesh <slug>' detached and waits up to 10s for
the socket. Surfaces a clear warning on timeout but doesn't block —
Claude Code's MCP shim will print the same error if the daemon really
isn't there.
Bundle: dist/entrypoints/mcp.js drops from 154KB → 104KB (gzipped 34KB
→ 19KB). Test: MCP boots cleanly via stdio, declares correct
capabilities, talks JSON-RPC; daemon /v1/skills returns the empty list
as expected on a mesh with no skills.
Released as 1.24.0 on npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the last functional gaps where the MCP tool registry exposed
write verbs the CLI didn't:
- vault set <k> <v> [--type env|file --mount <path> --description ...]
Client-side crypto_secretbox_easy with a fresh symmetric key sealed
to the member's own pubkey via crypto_box_seal — same pattern used
for file shares. Pairs with the existing vault list/delete.
- watch add <url> [--label --interval --mode --extract --notify-on]
Pairs with watch list/remove.
- webhook create <name> — pairs with webhook list/delete.
Cleanup: deletes 22 stub files under apps/cli/src/mcp/tools/* plus
router.ts, middleware/, handlers/ (~120 LoC). These were FAMILY/TOOLS
metadata-only re-exports left over from before the 1.5.0 tool-less
push-pipe flip; nothing imports them. The legitimate MCP surfaces
stay: the inbound <channel> push pipe, mesh skills as prompts and
skill:// resources, and the mesh-service proxy mode.
Released as 1.23.0 on npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Root --help now lists the daemon subcommand suite (was missing).
- claudemesh daemon (no subcommand) prints a usage block instead of
silently launching the foreground daemon. Adds help|--help|-h aliases.
- SKILL.md gains a "Daemon path (v0.9.0, opt-in, fastest)" section
explaining the runtime, lifecycle, and that it's independent from
claudemesh install.
Released as 1.22.1 on npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bump apps/cli/package.json to 1.22.0 (additive feature: claudemesh
daemon long-lived runtime).
- CHANGELOG entry for 1.22.0 covering subcommands, idempotency wiring,
crash recovery, and the deferred Sprint 7 broker hardening.
- Roadmap entry for v0.9.0 daemon foundation right above the v2.0.0
daemon redesign section, so the bridge release is documented as the
shipped step toward the larger architectural shift.
- Move shipped daemon specs (v1..v10 iteration trail + locked v0.9.0
spec + broker-hardening followups) from .artifacts/specs/ to
.artifacts/shipped/ per the project artifact-pipeline convention.
Not in this commit: npm publish and the cli-v1.22.0 GitHub release tag
— both are public-distribution actions and require explicit user
approval.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- apps/cli/ is now the canonical CLI (was apps/cli-v2/).
- apps/cli/ legacy v0 archived as branch 'legacy-cli-archive' and tag
'cli-v0-legacy-final' before deletion; git history preserves it too.
- .github/workflows/release-cli.yml paths updated.
- pnpm-lock.yaml regenerated.
Broker-side peer-grant enforcement (spec: 2026-04-15-per-peer-capabilities):
- 0020_peer-grants.sql adds peer_grants jsonb + GIN index on mesh.member.
- handleSend in broker fetches recipient grant maps once per send, drops
messages silently when sender lacks the required capability.
- POST /cli/mesh/:slug/grants to update from CLI; broker_messages_dropped_by_grant_total metric.
- CLI grant/revoke/block now mirror to broker via syncToBroker.
Auto-migrate on broker startup:
- apps/broker/src/migrate.ts runs drizzle migrate with pg_advisory_lock
before the HTTP server binds. Exits non-zero on failure so Coolify
healthcheck fails closed.
- Dockerfile copies packages/db/migrations into /app/migrations.
- postgres 3.4.5 added as direct broker dep.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>