feat(cli): wss push → mcp channel injection + status hooks in install
Full parity with claude-peers:
1. Push-injection (the "tap on shoulder" UX)
- MCP server now declares experimental.claude/channel capability
- BrokerClient onPush handlers emit server.notification({
method: "notifications/claude/channel",
params: { content, meta: {from_id, from_name, mesh_slug,
mesh_id, priority, sent_at, delivered_at, kind}}
})
- Claude Code injects each push as <channel source="claudemesh">
system reminder, so the receiver session sees inbound messages
WITHOUT calling check_messages manually
- Updated MCP instructions with the "RESPOND IMMEDIATELY" framing
(adapted from claude-peers)
2. Status hooks in install (default-on, --no-hooks to opt out)
- new apps/cli/src/commands/hook.ts: reads stdin JSON (Claude Code
hook payload), extracts cwd+session_id, POSTs /hook/set-status
to every joined mesh's broker in parallel with process.ppid +
1s timeout per POST. Silent fail, fire-and-forget.
- install.ts: writes to ~/.claude/settings.json registering
`claudemesh hook idle` on Stop + `claudemesh hook working` on
UserPromptSubmit. Idempotent, preserves other hook entries.
- uninstall.ts: removes both hook entries + MCP entry; leaves
unrelated hook/MCP entries alone.
- dedupes by brokerUrl (multiple meshes on same broker → one POST)
3. CLI surface
- new subcommand: `claudemesh hook <status>` (internal, but
exposed so Claude Code can invoke it via the hook shell command)
- `install --no-hooks` for users who want bare MCP registration
- --help updated
Coexistence with claude-peers: both tools register Stop and
UserPromptSubmit hooks, each POSTs to its own broker. Claude Code
fires multiple hooks per event without conflict.
npm version 0.1.0 → 0.1.1 (patch).
Verified:
- install with hooks → 2 entries added to settings.json ✓
- install --no-hooks → "Hooks skipped" ✓
- uninstall → both MCP entry + 2 hook entries removed ✓
- `echo '{...}' | claudemesh hook idle` with no joined meshes →
silent no-op ("no joined meshes, nothing to do") ✓
- MCP initialize response includes experimental.claude/channel ✓
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import { runJoin } from "./commands/join";
|
||||
import { runList } from "./commands/list";
|
||||
import { runLeave } from "./commands/leave";
|
||||
import { runSeedTestMesh } from "./commands/seed-test-mesh";
|
||||
import { runHook } from "./commands/hook";
|
||||
|
||||
const HELP = `claudemesh — peer mesh for Claude Code sessions
|
||||
|
||||
@@ -21,8 +22,9 @@ Usage:
|
||||
claudemesh <command> [args]
|
||||
|
||||
Commands:
|
||||
install Register claudemesh as a Claude Code MCP server
|
||||
uninstall Remove claudemesh MCP server registration
|
||||
install Register MCP + Stop/UserPromptSubmit status hooks
|
||||
(add --no-hooks for bare MCP registration)
|
||||
uninstall Remove MCP server + hooks
|
||||
join <url> Join a mesh via https://claudemesh.com/join/... URL
|
||||
list Show all joined meshes
|
||||
leave <slug> Leave a joined mesh
|
||||
@@ -45,11 +47,14 @@ async function main(): Promise<void> {
|
||||
await startMcpServer();
|
||||
return;
|
||||
case "install":
|
||||
runInstall();
|
||||
runInstall(args);
|
||||
return;
|
||||
case "uninstall":
|
||||
runUninstall();
|
||||
return;
|
||||
case "hook":
|
||||
await runHook(args);
|
||||
return;
|
||||
case "join":
|
||||
await runJoin(args);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user