MobileClaw is a mobile-first chat UI for the OpenClaw agent platform. Built with Next.js 16, Tailwind CSS v4, and zero component libraries. The UI has been modularized into focused components.
- Next.js 16 (App Router, Turbopack)
- Tailwind CSS v4 with OKLch color tokens
- TypeScript (strict mode disabled for speed)
- Geist font via
geistpackage (sans + mono) - pnpm — package manager (do NOT use npm or create package-lock.json)
- Vitest for unit testing
- No component library — all UI is hand-rolled with inline SVG icons
pnpm install
pnpm run dev # http://localhost:3000 (Turbopack)
pnpm run build # production build
pnpm test # run Vitest tests (63 tests)- Whenever making web changes for purposes of iOS ALWAYS run
make build-webafter completing the task. - Run
make pr-commentsto review current PR comments.
- Debug log:
lib/debugLog.tsposts structured entries to/api/log(route:app/api/log/route.ts) which appends tologs.jsonlin the project root - What's logged: chat events (
logChatEvent), agent events (logAgentEvent), and WS frames (logWsFrame) — structured one-line JSONL with timestamps - WS frame logging:
logWsFrame(direction, frame)indebugLog.ts, called fromlib/useWebSocket.tson every send/receive; noisy content/reasoning deltas are suppressed - WS connection lifecycle: logged to browser console (
[WS] Connection opened,[WS] Connection closed, etc.) vialib/useWebSocket.ts
- Modular components: UI split into focused components in
components/ - Shared types: all types in
types/chat.ts - No component library: use raw HTML elements + Tailwind classes
- Inline SVG icons: no icon library — copy SVG directly into JSX
- OKLch colors: all color tokens in
globals.cssuseoklch()— never use hex or named colors - Mobile-first:
h-dvhviewport, touch handlers, iOS Safari fixes - CSS variable animations: scroll morph bar uses
--spCSS custom property for 60fps animations
MobileClaw has a native iOS app that wraps the webapp in a WKWebView. See ios/CLAUDE.md for details.
MobileClaw connects to OpenClaw's gateway WebSocket. Protocol frames:
- Server sends
event:connect.challengewith nonce - Client responds with
req:connectincluding auth token, capabilities - Server responds with
res:hello-okincluding server info, session snapshot - Client requests
req:chat.historyto load message history - Messages flow via
event:chat(delta/final/aborted/error) andevent:agent(content/tool/reasoning/lifecycle streams) - Client sends
req:chat.sendwith user messages
- YOUR PRIMARY TOOL - Start here for ALL code exploration and discovery.
mcp__cicada__query - DEEP-DIVE TOOL: View a module's complete API and dependencies after discovering it with query.
mcp__cicada__search_module - DEEP-DIVE TOOL: Find function definitions and call sites after discovering with query.
mcp__cicada__search_function - UNIFIED HISTORY TOOL: One tool for all git history queries - replaces get_blame, get_commit_history, find_pr_for_line, and get_file_pr_history.
mcp__cicada__git_history - DRILL-DOWN TOOL: Expand a query result to see complete details.
mcp__cicada__expand_result - Force refresh the code index to pick up recent file changes.
mcp__cicada__refresh_index - ADVANCED: Execute jq queries directly against the Cicada index for custom analysis and data exploration.
mcp__cicada__query_jq
- ❌ Searching for module structure
- ❌ Searching for function definitions
- ❌ Searching for module imports/usage
- ✓ Non-code files (markdown, JSON, config)
- ✓ String literal searches
- ✓ Pattern matching in single line comments