Nine UX bugs surfaced from a real two-session interconnect smoke
test, shipped together.
Self-identity is visible
- peer list now shows the caller as (this session), sorted to top.
Daemon path resolves session pubkey via /v1/sessions/me so
isThisSession is set correctly warm.
- whoami shows session pubkey, session id, mesh, role, groups, cwd,
pid when run inside a launched session.
Sibling-session disambiguation
- peer list rows carry sid:<short> tag so visually-identical rows
can be told apart at a glance.
Daemon hidden by default
- claudemesh-daemon presence rows hidden from peer list by default.
--all opts back in. Header shows N daemon hidden when applicable.
--self flag works end-to-end
- Argv parser was greedy: --self ate the next arg as its value.
BOOLEAN_FLAGS set in cli/argv.ts now lists known no-value switches.
- message send subcommand now passes self through (only legacy send
was wired before).
- Help text lists --self.
Member-pubkey fan-out
- Sending to your own member pubkey with --self now resolves to every
connected sibling session and sends one message per recipient.
Required because the broker drain matches target_spec only against
full session pubkeys; member-pubkey sends queued but never drained.
Broker welcome at launch
- After the launch banner, one line confirms WS state, peer count,
and unread inbox count. Best-effort — falls back gracefully.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Patch release on top of 1.6.0:
- Revoke-by-id-prefix bug fix (broker.revokeApiKey now returns
structured status; CLI surfaces not_found / not_unique). Pasting
the 8-char prefix from `apikey list` output now works as users
expect, instead of silently no-op'ing with a misleading "✔
revoked" message. Already deployed to broker.
- whoami falls back to local mesh-config view when no web session
is signed in. Users who joined via invite (and never ran
`claudemesh login`) now see their member ids and pubkey prefixes
per mesh, instead of a "Not signed in" dead end.
- README updated: REST surface lives at claudemesh.com/api/v1/*
(web app), NOT ic.claudemesh.com/api/v1/* (broker). Surfaced
during CLI-only smoke test against prod when curl on the broker
host returned 404.
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>