Spaces:
Sleeping
Claw-Web Developer Guide
Complete documentation for the Claw-Web project β a web-based port of Claude Code (Rust CLI) to a full-stack TypeScript web application.
Total codebase: ~32,700 lines of TypeScript/TSX across 126 source files.
Table of Contents
- Architecture Overview
- Project Structure
- Tech Stack
- Getting Started
- Server Runtime Modules
- Client Components
- Buddy Companion Pet System
- Tools and Executor
- MCP Integration
- Configuration System
- Permissions System
- Plugin System
- Deployment
- Parity Status with Original
- Known Issues and TODOs
Architecture Overview
Claw-Web is a full-stack TypeScript application that ports the original Claude Code Rust CLI to a web interface. It uses a client-server architecture where:
- Client (React + Vite + TailwindCSS) provides the chat UI, settings, file manager, terminal, and buddy companion
- Server (Express + tRPC + esbuild) runs the agent loop, tool executor, LLM API calls, and all runtime modules
- Database (MySQL/TiDB via Drizzle ORM) stores sessions, messages, settings, and user data
- LLM (HuggingFace Router API, OpenAI-compatible) powers the AI agent with tool calling
The agent loop in server/runtime/agent.ts is a direct port of the original conversation.rs Rust module, implementing the same iteration model with Number.MAX_SAFE_INTEGER max iterations (matching Rust's usize::MAX).
Project Structure
claw-web/
βββ client/ # Frontend (React + Vite)
β βββ src/
β βββ buddy/ # Companion pet system (6 modules)
β β βββ types.ts # Type definitions (BuddyState, BuddyStats, etc.)
β β βββ sprites.ts # Sprite configs (6 stages x 10 moods)
β β βββ companion.ts # State management, XP, leveling, evolution
β β βββ prompt.ts # Personality, messages, achievements
β β βββ useBuddyNotification.tsx # React hook for buddy state
β β βββ index.ts # Barrel export
β βββ components/ # UI components
β β βββ BuddySprite.tsx # Companion pet UI (stats panel, interactions)
β β βββ ChatInput.tsx # Message input with slash commands
β β βββ FileManagerPanel.tsx # File browser
β β βββ MessageBubble.tsx # Chat message rendering
β β βββ PluginMarketplace.tsx # Plugin management UI
β β βββ SettingsPanel.tsx # Settings (Model, Parameters, Permissions, MCP, etc.)
β β βββ Sidebar.tsx # Session sidebar
β β βββ TaskManagerPanel.tsx # Task/todo management
β β βββ TerminalPanel.tsx # Embedded terminal
β β βββ ThinkingBlock.tsx # AI thinking display
β β βββ ToolCallCard.tsx # Tool call visualization
β β βββ ui/ # shadcn/ui components (70+ files)
β βββ contexts/ # React contexts
β βββ hooks/ # Custom hooks (useChat, useMobile, etc.)
β βββ pages/ # Page components (Home, NotFound, etc.)
β βββ lib/ # Utilities (trpc client, utils)
βββ server/ # Backend
β βββ _core/ # Framework core (tRPC, auth, LLM, etc.)
β β βββ llm.ts # LLM API client (OpenAI-compatible)
β β βββ oauth.ts # OAuth handling
β β βββ ... # Other core modules
β βββ runtime/ # Agent runtime (ported from Rust)
β β βββ agent.ts # Main agent loop (β conversation.rs)
β β βββ bootstrap.ts # Project bootstrap/onboarding
β β βββ chat-endpoint.ts # Chat SSE endpoint + slash commands
β β βββ compact.ts # Context compaction (527 lines)
β β βββ config.ts # Config loading + deep merge
β β βββ lsp-client.ts # LSP client for diagnostics
β β βββ mcp-client.ts # MCP server manager
β β βββ permissions.ts # Permission policy system
β β βββ plugins.ts # Plugin manager
β β βββ remote.ts # Remote/proxy configuration
β β βββ sandbox.ts # Container sandbox detection
β β βββ session.ts # Session serialization/validation
β β βββ system-prompt.ts # System prompt + TOOL_DEFINITIONS
β β βββ usage.ts # Token/cost tracking
β βββ tools/ # Tool implementations
β β βββ executor.ts # 30+ tool implementations (1600+ lines)
β β βββ file-ops.ts # File operation utilities
β βββ db.ts # Database schema (Drizzle)
β βββ routers.ts # tRPC routers
β βββ storage.ts # File storage
βββ shared/ # Shared types between client/server
β βββ claw-types.ts # Core shared types
β βββ types.ts # Additional types
βββ drizzle/ # Database migrations
βββ package.json
βββ vite.config.ts
βββ tsconfig.json
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, TailwindCSS, shadcn/ui |
| Backend | Express, tRPC, esbuild |
| Database | MySQL/TiDB via Drizzle ORM |
| Auth | Manus OAuth (session-based) |
| LLM | HuggingFace Router API (OpenAI-compatible) |
| Deployment | HuggingFace Spaces (Docker) |
| Language | TypeScript throughout |
Getting Started
Prerequisites
- Node.js 22+
- pnpm
- MySQL/TiDB database
Development
cd claw-web
pnpm install
pnpm dev # Starts both client (Vite) and server (esbuild)
Build
pnpm build # Builds client (Vite) + server (esbuild)
Environment Variables
| Variable | Description |
|---|---|
DATABASE_URL |
MySQL/TiDB connection string |
HF_TOKEN |
HuggingFace API token for LLM |
SESSION_SECRET |
Session encryption key |
Server Runtime Modules
agent.ts β Main Agent Loop
Original: conversation.rs (Rust)
Parity: ~95%
The core agent loop that:
- Builds system prompt with
TOOL_DEFINITIONS+ dynamically injected MCP tools - Calls LLM API with streaming
- Processes tool calls from LLM response
- Executes tools via
executor.ts - Runs pre/post-tool hooks
- Appends results to conversation
- Loops until LLM stops calling tools or max iterations reached
Key constants:
MAX_ITERATIONS = Number.MAX_SAFE_INTEGER(matches Rustusize::MAX)- Tools are dynamically merged:
TOOL_DEFINITIONS + mcpTools
compact.ts β Context Compaction
Original: compact.rs (Rust)
Parity: ~99%
Full implementation (527 lines) of context window compaction:
shouldCompact()β checks if conversation exceeds token thresholdcompactSession()β summarizes old messages, preserves recent context- Triggered manually via
/compactslash command
config.ts β Configuration System
Original: config.rs (Rust)
Parity: ~90%
Loads configuration from multiple sources with deep merge:
.claw/settings.json(project-level)~/.claw/settings.json(user-level)deepMergeObjects()β recursive merge for nested configsextendUnique()/pushUnique()β deduplicated array merging for hooksmergeHooksConfig()β proper PreToolUse/PostToolUse hook merging
permissions.ts β Permission Policy
Original: permissions.rs (Rust)
Parity: ~85%
Permission modes (ordered by severity, matching Rust derive(PartialOrd, Ord)):
ReadOnly = 0 // Can only read files
WorkspaceWrite = 1 // Can write within workspace
DangerFullAccess = 2 // Can execute dangerous operations
Prompt = 3 // Must prompt user for approval
Allow = 4 // Auto-approve everything
mcp-client.ts β MCP Server Manager
Original: mcp.rs (Rust)
Parity: ~80%
Model Context Protocol integration:
McpServerManagerβ manages multiple MCP server connectionsconnectAndListAllTools()β discovers tools from all configured serversnormalizeNameForMcp()β name normalization (preserves case, handlesclaude.aiprefix)callTool()β executes MCP tool calls via JSON-RPC- Dynamic tool injection into agent's
TOOL_DEFINITIONS
sandbox.ts β Container Sandbox Detection
Original: sandbox.rs (Rust)
Parity: ~85%
Detects container environments:
- Docker (
.dockerenv, cgroup) - Podman (
/run/.containerenv) - Kubernetes (
KUBERNETES_SERVICE_HOST) - containerd (cgroup)
- libpod (cgroup)
session.ts β Session Serialization
Original: Session handling in Rust Parity: ~90%
Validated deserialization with SessionError class:
validateSessionData()β validates all required fieldsdeserializeSession()β safe JSON parsing with error handlingserializeSession()β serialization with validation
usage.ts β Token/Cost Tracking
Original: usage.rs (Rust)
Parity: ~85%
Tracks API usage:
UsageTrackerβ accumulates token counts and costsformatUsd()β formats costs with 4 decimal places (matches Rustformat!("${:.4}"))summaryLines()β generates usage summary
Client Components
Home.tsx β Main Page (~1020 lines)
The primary page component containing:
- Chat interface with message bubbles
- Sidebar with session management
- Settings panel
- File manager, terminal, task manager panels
- Buddy companion pet integration
- Plan mode with step visualization
- Ask-user dialog for agent questions
- Export/import session functionality
SettingsPanel.tsx β Settings UI
Tabs: Model, Parameters, Permissions, MCP, Costs, Memory
Note: API tab was intentionally removed (built-in HuggingFace Router).
BuddySprite.tsx β Companion Pet UI
Full companion pet with:
- Evolution-stage sprites (egg β baby β junior β senior β master β legendary)
- Interactive stats panel (XP, happiness, energy, hunger)
- Achievement system (17 achievements)
- Notification system (level-ups, evolutions, achievements)
- Feed and Pet interactions
- Rename functionality
Buddy Companion Pet System
The buddy system is a 6-module subsystem matching the original Claude Code architecture:
| Module | Lines | Description |
|---|---|---|
types.ts |
95 | Full type system: BuddyState, BuddyStats, evolution stages, XP rewards |
sprites.ts |
160 | Sprite configs for 6 evolution stages x 10 moods, colors, animations |
companion.ts |
250 | State management, XP/leveling, evolution, persistence, time decay |
prompt.ts |
210 | Personality messages, stage greetings, 17 achievements, stats formatting |
useBuddyNotification.tsx |
140 | React hook: state loading, event handlers, mood calculation, decay timer |
BuddySprite.tsx |
300 | Full UI: sprite, speech bubbles, stats panel, achievements, notifications |
Evolution Stages
| Stage | Level Range | Description |
|---|---|---|
| Egg | 0-2 | Just hatched, minimal interaction |
| Baby | 3-5 | Learning, simple faces |
| Junior | 6-10 | Growing, more expressive |
| Senior | 11-20 | Experienced, accessories |
| Master | 21-50 | Expert, special effects |
| Legendary | 51+ | Transcended, full effects |
XP Rewards
| Action | XP |
|---|---|
| Tool call | 5 |
| File created | 10 |
| File edited | 3 |
| Bug fixed | 25 |
| Test passed | 15 |
| Session completed | 20 |
| Streak day | 50 |
| First session | 100 |
Tools and Executor
server/tools/executor.ts implements 30+ tools (1600+ lines):
| Tool | Description |
|---|---|
bash |
Shell command execution with sandbox support |
read_file |
Read file contents with line ranges |
write_file |
Create/overwrite files |
edit_file |
Surgical file edits (find/replace) |
multi_edit |
Multiple edits in one call |
grep_search |
Regex search across files |
glob_search |
File path pattern matching |
list_dir |
Directory listing |
TodoRead / TodoWrite |
Task management |
NotebookRead / NotebookEdit |
Jupyter notebook support |
Agent |
Sub-agent spawning with presets |
WebSearch / WebFetch |
Web browsing |
REPL |
Python REPL execution |
mcp__* |
Dynamic MCP tool routing |
MCP Tool Routing
When the LLM calls a tool with prefix mcp__, the executor:
- Splits the name:
mcp__servername__toolname - Finds the MCP server by name
- Calls
McpServerManager.callTool(serverName, toolName, args) - Returns the result to the LLM
MCP Integration
Configuration
MCP servers are configured in .claw/settings.json:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["./mcp-server.js"],
"env": {}
}
}
}
Dynamic Tool Injection
At agent loop start:
initializeMcpFromConfig(workDir)loads MCP configconnectAndListAllTools()discovers tools from all servers- MCP tools are converted to OpenAI function calling format
- Merged with static
TOOL_DEFINITIONS - Full tool list sent to LLM
Configuration System
Config Loading Order
.claw/settings.json(project-level)~/.claw/settings.json(user-level)- Database settings (per-session)
- Environment variables
Deep Merge
Uses deepMergeObjects() for recursive merging. Arrays in hooks use extendUnique() for deduplication (matching original Rust extend_unique).
Permissions System
Permission Modes
ReadOnly (0) < WorkspaceWrite (1) < DangerFullAccess (2) < Prompt (3) < Allow (4)
This ordering matches the original Rust derive(PartialOrd, Ord) enum ordering.
Tool Permission Mapping
Each tool has a required permission level. The agent checks modeGte(toolPermission, currentMode) before executing.
Plugin System
Plugin Structure
.claw-plugins/
βββ my-plugin/
βββ .claw-plugin/
β βββ plugin.json # Manifest
βββ hooks/
βββ pre.sh # Pre-tool hook
βββ post.sh # Post-tool hook
Hook Environment Variables
Pre-tool hooks receive:
HOOK_EVENT_NAMEβ "PreToolUse"HOOK_TOOL_NAMEβ tool nameHOOK_TOOL_INPUTβ tool input (first 10KB)HOOK_TOOL_INPUT_JSONβ full JSON inputHOOK_SESSION_IDβ session identifierHOOK_WORKING_DIRβ working directory
Post-tool hooks additionally receive:
HOOK_TOOL_OUTPUTβ tool output (first 10KB)HOOK_TOOL_RESULT_IS_ERRORβ "true" or "false"
Deployment
HuggingFace Spaces
The project deploys to HuggingFace Spaces via git push:
git remote add space https://huggingface.co/spaces/drt2221143/claw-web
git push space main
The Space uses a Docker container with Node.js 22.
Live URL
https://drt2221143-claw-web.hf.space/
Parity Status with Original
Overall: ~92%
| Module | Parity | Notes |
|---|---|---|
| agent.ts (conversation.rs) | 95% | Full loop, unlimited iterations, MCP injection |
| compact.ts | 99% | Full implementation |
| config.ts | 90% | Deep merge + extendUnique for hooks |
| permissions.ts | 85% | Correct ordering, authorize logic |
| mcp-client.ts | 80% | Full normalize, dynamic injection, callTool |
| session.ts | 90% | Validated deserialization |
| sandbox.ts | 85% | Full container detection |
| remote.ts | 85% | All 8 proxy env keys |
| usage.ts | 85% | formatUsd matches original |
| executor.ts | 85% | 30+ tools, MCP routing, hook payloads |
| lsp-client.ts | 85% | stderr drain, graceful shutdown |
| plugins.ts | 70% | Install/execute work, update/uninstall basic |
| bootstrap.ts | 100% | Full implementation |
| buddy system | 90% | 6/6 modules implemented |
Not Ported (CLI-specific, not needed for web)
coordinator modeβ multi-agent CLI coordinationvim modeβ terminal vim keybindingsvoice modeβ microphone input (CLI-specific)auto updaterβ self-update (not applicable to web)magic docsβ auto-documentation (future enhancement)prompt suggestionβ smart suggestions (future enhancement)
Known Issues and TODOs
High Priority
- Duplicate
/contextcase inchat-endpoint.ts(line 645 and 2070) β causes build warning - Plugin update/uninstall β basic stubs, need full implementation
- LSP diagnostics enrichment β LSP works but doesn't enrich agent context
Medium Priority
- Session history/resume β no conversation resume across page reloads
- Cost tracker hooks β real-time cost tracking not integrated
- Agent summary β no session summary generation
- Output styles β basic implementation, needs loadOutputStylesDir
Low Priority
- OAuth PKCE/refresh β web app uses session auth, not needed
- Sandbox OverlayFS β mount isolation not enforced
- Keybindings β minimal, original has 14 modules
Contributing
Code Style
- TypeScript strict mode
- ESLint + Prettier
- Functional components with hooks (React)
- tRPC for type-safe API calls
Adding a New Tool
- Add tool definition to
TOOL_DEFINITIONSinsystem-prompt.ts - Add case handler in
executor.tsswitch statement - Set required permission level
- Add pre/post hook support if needed
Adding an MCP Server
- Configure in
.claw/settings.jsonundermcpServers - Tools are automatically discovered and injected
- No code changes needed
Last updated: April 2026 Maintained by: drt2221143