Commit Graph

57 Commits

Author SHA1 Message Date
Alejandro Gutiérrez
f698aaeac7 feat(cli): stateful welcome screen + v0.1.4 bump
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled
Running \`claudemesh\` with no args now detects install state and
prints context-appropriate guidance: suggests \`install\` if MCP
not registered, \`join\` if no meshes, \`launch\` if ready.
Replaces the static HELP dump with a first-run wizard that meets
users where they are.

Static HELP still available via --help.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 23:19:27 +01:00
Alejandro Gutiérrez
8810aa1e9e feat(cli): --version, status, doctor commands (v0.1.3)
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled
Three Tier-2 polish commands for debugging + discoverability:

- claudemesh --version / -v: print CLI version (baked from
  package.json at build time via Bun JSON import).
- claudemesh status: WS-probe each joined mesh's broker, report
  reachability per mesh. Exit 1 if any broker unreachable.
- claudemesh doctor: run 6 preconditions — Node>=20, claude on PATH,
  MCP registered, hooks registered, config file parses + chmod 0600,
  mesh keypairs validate. Each check has a pass/fail + fix hint.
  Exit 0 if all pass.

Help text now leads with version (\"claudemesh v0.1.3 —\").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 23:01:52 +01:00
Alejandro Gutiérrez
7ab3c8d465 feat(cli): claudemesh launch command with transparency banner (v0.1.2)
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>
2026-04-05 22:22:46 +01:00
Alejandro Gutiérrez
b1f428c44b feat(cli): wss push → mcp channel injection + status hooks in install
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled
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>
2026-04-05 19:17:33 +01:00
Alejandro Gutiérrez
64ca600195 chore(cli): rename package to claudemesh-cli (unscoped) for npm publish
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
@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>
2026-04-05 14:41:59 +01:00
Alejandro Gutiérrez
714d82e4e7 chore(cli): bundle for node, prep for npm publish
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
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>
2026-04-05 14:31:27 +01:00
Alejandro Gutiérrez
8931296e82 feat(cli): scaffold @claudemesh/cli MCP client package (stubs)
The user-facing tool. Two invocation modes:
  - `claudemesh mcp`           → MCP server (stdio), consumed by Claude Code
  - `claudemesh <subcommand>`  → human CLI

Layout:
  apps/cli/
  ├── package.json       bin: { claudemesh: ./src/index.ts }
  ├── README.md          install + usage
  └── src/
      ├── index.ts       dispatcher (mcp | install | join | list | leave | --help)
      ├── env.ts         CLAUDEMESH_BROKER_URL, CONFIG_DIR, DEBUG
      ├── mcp/
      │   ├── server.ts  MCP stdio server with 5 tools
      │   ├── tools.ts   tool schemas (send_message, list_peers,
      │   │              check_messages, set_summary, set_status)
      │   └── types.ts
      ├── ws/client.ts   broker connection (stub for 15b)
      ├── state/config.ts ~/.claudemesh/config.json (joined meshes + keys)
      └── commands/
          ├── install.ts print `claude mcp add ...` instruction
          ├── join.ts    parse ic://join/... (stub, Step 17)
          ├── list.ts    show joined meshes
          └── leave.ts   remove mesh from local config

Tool stubs return "not connected, run `claudemesh join <invite-link>`"
errors until 15b wires the WS client.

Verified:
- `bun src/index.ts --help` → prints usage
- `bun src/index.ts install` → prints MCP add command with resolved path
- `bun src/index.ts list` → "No meshes joined yet"
- `bun src/index.ts mcp` (via stdin) → returns tools/list with all 5 tools

Deps: @modelcontextprotocol/sdk, ws, libsodium-wrappers, zod.
Lockfile regenerated in the same commit per claudemesh-3's flag —
avoids breaking Coolify's --frozen-lockfile deploys.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:23:12 +01:00