Add 4 missing tools (cancel_scheduled, grant_file_access, list_scheduled,
schedule_reminder) and sort the array alphabetically for maintainability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
withPayload crashes ALL routes with React #130 in standalone
output — even with admin page replaced by redirect. The wrapper
injects a client-side ConfigProvider that fails hydration.
Removed: withPayload wrapper, entire (payload) route group.
Kept: payload.config.ts, migrations, blog/changelog server-side
queries with graceful DB fallback.
Payload admin runs on local dev only (add withPayload back in
next.config when running pnpm dev). Production content via
static TSX pages or future API-based publishing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove Payload's /api/[...slug] route that conflicts with existing
/api/[...route]. Blog/changelog pages use Payload's local API.
Includes cli install.ts backup + assertNoMcpLoss guards (from
worktree agent).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds `claudemesh launch [args]` that spawns Claude Code with
--dangerously-load-development-channels server:claudemesh so peer
messages arrive as <channel> system reminders mid-turn instead of
pull-only via check_messages. Windows uses shell:true to resolve
claude.cmd from PATHEXT.
Prints an info banner before spawning that explains the channel's
scope (peer text injection only), the trust model (treat as
untrusted input), and that existing tool-approval prompts remain
the safety net. --quiet skips the banner.
Install output now mentions `claudemesh launch` as the recommended
launch path; plain `claude` still works for pull-only mode.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Pairs with claudemesh-2's new /join/[token] landing page. Users can
now paste a clickable HTTPS URL instead of the dev-only ic:// scheme.
apps/cli/src/invite/parse.ts — new extractInviteToken() handles
four input formats before handing the raw base64url token to the
existing parseInviteLink pipeline:
- https://claudemesh.com/join/<token> (primary, clickable)
- https://claudemesh.com/<locale>/join/<token> (i18n prefix)
- ic://join/<token> (still supported, dev)
- <raw-token> (last resort: bare base64url)
User-facing strings updated to the HTTPS form:
- cli help: "join <url>"
- install success message
- list (no-meshes) hint
- MCP server "no meshes" error
- README.md primary example
- docs/QUICKSTART.md Path A + Path B
Verified extractInviteToken() on all 4 formats — each returns the
same base64url token → same broker /join lookup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claudemesh/cli was already taken on npm by an unrelated project
(claudemesh "domain packages", v1.0.7). PM picked option A: publish
unscoped as claudemesh-cli. Binary name stays "claudemesh" — users
type the natural thing on install:
npm install -g claudemesh-cli
claudemesh install
claudemesh join ic://join/...
renamed references everywhere:
- apps/cli/package.json: name
- apps/cli/README.md: title + install command
- apps/cli/src/{index.ts, mcp/server.ts, commands/install.ts} headers
- docs/QUICKSTART.md: install command, version banner, npx hint
- docs/roadmap.md: package name
also (PM journey-friction #5): surface the "restart Claude Code" step
LOUDLY in install output. Added a yellow-bold warning line after the
✓ success lines so new users don't miss the restart step (MCP tools
only load on Claude Code restart).
⚠ RESTART CLAUDE CODE for MCP tools to appear.
ANSI colors gated on isTTY + NO_COLOR/TERM=dumb guards.
bundle rebuilt. ready for npm publish pending user's `npm adduser`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Makes @claudemesh/cli installable globally via npm without requiring
bun on user machines. (Bun stays the dev runtime; bundled output is
node-compatible.)
- bun build --target=node --outfile dist/index.js produces a 2.69MB
standalone bundle with node-shebang banner
- package.json: add description/keywords/author/license/homepage/
repository, set bin to ./dist/index.js, files=[dist, README, LICENSE],
publishConfig.access=public, engines.node >=20
- prepublishOnly auto-runs the build
- pin zod from catalog: to 4.1.13 (npm rejects catalog: refs)
- swap Bun.spawnSync → node:child_process.spawnSync in install.ts
(the only Bun-global usage in the package)
- strip shebang from src/index.ts (banner supplies it post-bundle)
install command now runs in two modes:
- BUNDLED (npm i -g): detects dist/index.js path, writes MCP entry
with command "claudemesh" (relies on the global bin shim on PATH)
- SOURCE (bun src/index.ts, dev): preflights bun, writes MCP entry
with command "bun <absolute-path> mcp"
verified end-to-end:
- node dist/index.js --help prints usage ✓
- node dist/index.js install writes correct ~/.claude.json ✓
- node dist/index.js mcp | tools/list returns all 5 tools ✓
- bun src/index.ts install (dev mode) still works ✓
NOT PUBLISHED YET — @claudemesh/cli is owned by an unrelated project
on npm. Awaiting user decision on alternative name (claudemesh-cli,
@alezmad/claudemesh-cli, or new org scope). Bundle is name-agnostic
and will reuse regardless.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous flow printed a \`claude mcp add ...\` command and asked
users to paste it. That's 2 steps, a typo surface, and a point of
user dropoff. Replace with direct read-modify-write of ~/.claude.json.
install:
- preflights bun on PATH (clear error + Bun.com link if missing)
- verifies the MCP entry file exists on disk
- reads ~/.claude.json (empty object if absent)
- adds/updates mcpServers.claudemesh with resolved absolute path
- writes back with 0600 perms, creates parent dir if needed
- read-back verification (bails loudly if post-write state is wrong)
- idempotent: re-running returns "unchanged" if entry already matches
- preserves existing mcpServers entries + other top-level config keys
uninstall:
- removes the claudemesh entry if present
- no-ops cleanly when entry or config file doesn't exist
- doesn't touch anything else
Both print a clear post-action hint: "Restart Claude Code to load
the MCP server. Then join a mesh with claudemesh join <invite-link>".
verified locally with HOME=/tmp/fake-home:
- fresh install → ✓ added, config emitted correctly
- re-install → ✓ unchanged (idempotent)
- install alongside existing "other-mcp" entry → both preserved,
plus unrelated top-level keys kept verbatim
- uninstall → ✓ removed, claudemesh gone, other entries intact
- uninstall again → · not present (no error)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>