4.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# Development (client + server with hot reload)
npm run dev
# Server only
npm run dev:server
# Client only
npm run dev:client
# Production build (frontend → dist/)
npm run build
# Run server against built dist/
npm start
No test runner is configured. Tests in test/mvp/ and tests/ are standalone Node.js scripts run directly:
node test/mvp/test-e2e.js
node test/mvp/test-hooks.js
Environment
Required: CLAWTAP_PASSWORD=<password>
Optional: PORT (default 3456), OPENAI_API_KEY (enables voice transcription)
State stored in ~/.clawtap/ — SQLite DB, VAPID keys, push subscriptions, PID file.
In production, the server runs as a systemd user service (~/.config/systemd/user/clawtap.service) with env vars loaded from ~/.clawtap/env; use ./update-service.sh (not npm install -g .) to build and redeploy.
Architecture
ClawTap bridges mobile browsers to AI CLI tools running in tmux on the dev machine.
Mobile PWA (React) ◄─ WebSocket ─► Express Server ◄─ tmux sendKeys ─► claude/codex/gemini CLI
Server (server/)
index.ts— Express app, HTTP/HTTPS server, REST routes, WS transport setup, graceful shutdownsession-manager.ts— Bridges adapter events to WebSocket clients. Transport-agnostic. Routes all adapter events (streaming-text, tool-start/done, permission-request, etc.) to connected clients. Manages push notifications when no client is watching.adapters/— Plugin system for CLI backendsinterface.ts(IAdapter) — Abstract base class all adapters extend. Emits standardized events; see JSDoc for full event list.registry.ts— Registers adapters;DEFAULT_ADAPTERis'claude'shared/tmux-manager.ts— Core tmux primitive: create windows, send keys, paste buffers (>500 chars or multiline use paste buffer instead of sendKeys)claude/,codex/,gemini/— Per-adapter implementations
transport/websocket-transport.ts— WS server; wraps rawwsintoClientConnectionabstractionsdb.ts— SQLite viabetter-sqlite3; tables:push_subscriptions,login_attempts,session_reviews,session_stats,user_preferencespush.ts— Web Push (VAPID) notificationsauth.ts— Password-based auth with bcrypt + JWT; rate-limits login attempts by IPconfig.ts— Reads env vars; auto-detects HTTPS certs at~/.clawtap/cert.pem+key.pemstores/task-aggregator.ts— Aggregates task-tool events (TodoRead/TodoWrite/Task) into round-based groups for the mobile task panel
Frontend (src/)
App.tsx— Top-level view router (sessions / newchat / chat / settings). View persisted tosessionStorage; URL updated viahistory.pushState.lib/ws.ts— WebSocket singleton; reconnect logiclib/api.ts— Fetch wrapper with JWT auth headerhooks/useChat.ts— Main chat hook: sends queries, handles all WS message types, manages message list and tool statehooks/useTaskState.ts— ConsumesTASK_STATEWS events; surfaces round-based task groups to the FABcomponents/ChatView.tsx— Full chat screen with message list, tool cards, interactive prompt overlay, review panelcomponents/FloatingReviewPanel.tsx— Multi-tab cross-AI review panelcomponents/adapters/— Adapter-specific UI (models, permission modes, branding)
WebSocket Protocol
All message types defined in server/ws-types.ts (WS const) and server/types/messages.ts. Key flows:
- Client sends
query→ server routes to adapter → adapter emitsstreaming-text/tool-start/tool-done/session-idle→ server broadcasts to clients - Adapter emits
permission-request→ server sendsinteractive-promptto client → client sendsprompt-response→ server callsrespondInteractivePrompt - Cross-AI review: client calls
POST /api/reviews/register→ server broadcastsreview-startedto parent session clients
Adding a New Adapter
- Create
server/adapters/<name>/index.tsextendingIAdapter - Set static
id,displayName,command - Implement
setup(app),startSession,resumeSession,sendMessage,interrupt,getSessions,getMessages - Register in
server/adapters/init.ts - Add frontend branding in
src/lib/adapter-brands.ts