Project Structure
ClawControl is organized into distinct layers that separate concerns:TUI Framework
ClawControl uses @opentui/core and @opentui/react to build a terminal-based user interface with React.How It Works
The TUI framework provides JSX components that render to the terminal:<box>- Container with flexbox layout<scrollbox>- Scrollable container<text>- Styled text with foreground/background colors<input>- Text input field<textarea>- Multi-line text input<button>- Interactive button
Entry Point
The application initializes the TUI renderer insrc/index.tsx:
Hooks
OpenTUI React provides hooks for terminal interactions:useRenderer()- Access the underlying rendereruseKeyboard(callback)- Listen for keyboard eventsuseFocus()- Manage focus state
src/components/Home.tsx:
View System
ClawControl uses a view-based navigation system managed by the rootApp component.
App Component
TheApp component (src/App.tsx) manages:
- Current view state - Which screen is currently displayed
- Selected deployment - The active deployment context
- Deployments list - All saved deployments
- Navigation - Route between views
AppContext
All views receive anAppContext prop that provides shared state and navigation:
View Types
Views are defined by theViewName type in src/types/index.ts:
View Rendering
TheApp component maps view names to components:
Key Modules
Services Layer
Thesrc/services/ directory contains all business logic:
config.ts (src/services/config.ts)
Manages deployment configuration storage:getAllDeployments()- Load all deployments from diskgetDeployment(name)- Get a specific deploymentsaveDeploymentConfig(name, config)- Save deployment configsaveDeploymentState(name, state)- Save deployment statedeleteDeployment(name)- Remove a deployment
~/.clawcontrol/deployments/{name}/:
config.json- Deployment configuration (provider, settings, etc.)state.json- Deployment state (status, IPs, checkpoints, etc.)id_rsa/id_rsa.pub- SSH key pair
deployment.ts (src/services/deployment.ts)
Orchestrates the full deployment process:runDeployment(deploymentName)- Execute deployment from start to finish- Handles checkpointing for resume-on-failure
- Manages deployment phases:
- Server provisioning
- SSH setup
- System updates
- Dependency installation (Node, pnpm, Chrome)
- OpenClaw installation and configuration
- Tailscale setup
- Daemon startup
ssh.ts (src/services/ssh.ts)
SSH client operations using thessh2 library:
connectSSH(host, keyPath)- Establish SSH connectionexecuteCommand(conn, command)- Run a command over SSHuploadFile(conn, localPath, remotePath)- Upload files via SFTPstreamLogs(conn, logPath, callback)- Stream logs in real-time
secrets.ts (src/services/secrets.ts)
Secure storage for reusable API keys:loadSecrets()- Load saved secrets from~/.clawcontrol/secrets.jsonsaveSecret(id, name, value)- Save a new secretdeleteSecret(id)- Remove a secret
Providers Layer
Thesrc/providers/ directory contains cloud provider integrations.
Provider Interface
Each provider implements a consistent interface:Hetzner Provider (src/providers/hetzner/)
HetznerClient- API client for Hetzner CloudcreateServer()- Provisions a CX11 or CPX11 serverwaitForServerRunning()- Polls until server is ready- Supports locations:
ash(Ashburn),fsn1(Falkenstein),nbg1(Nuremberg), etc.
https://api.hetzner.cloud/v1/
DigitalOcean Provider (src/providers/digitalocean/)
DigitalOceanClient- API client for DigitalOceancreateDroplet()- Provisions a dropletwaitForDropletActive()- Polls until droplet is ready- Supports sizes:
s-1vcpu-2gb,s-2vcpu-4gb, etc.
https://api.digitalocean.com/v2/
Type System
Thesrc/types/index.ts file defines all TypeScript types and Zod validation schemas.
Core Types
Zod Schemas
All types have corresponding Zod schemas for runtime validation:Binary Wrapper
Thebin/clawcontrol.js file is a Node.js wrapper that:
- Checks for updates - Fetches the latest version from npm
- Auto-updates - Runs
bun add -g clawcontrol@latestif newer version available - Delegates to Bun - Executes
dist/index.jswith the Bun runtime
Data Flow
Creating a Deployment
- User runs
/newcommand NewDeploymentcomponent collects configurationsaveDeploymentConfig()writes to~/.clawcontrol/deployments/{name}/config.json- Initial state is saved with status “initialized”
Running a Deployment
- User runs
/deploycommand DeployViewconfirms the configurationrunDeployment()starts the orchestration:- Creates server via provider API
- Waits for server to be ready
- Generates SSH key pair
- Connects over SSH
- Executes provisioning steps sequentially
- Each step saves a checkpoint on success
DeployingViewdisplays real-time progress- Final state is saved with status “deployed”
Resume on Failure
If deployment fails:- The last successful checkpoint is saved in
state.json - User can re-run
/deploy runDeployment()resumes from the last checkpoint- Failed steps are retried
Next Steps
- Set up your Development Environment
- Learn about Testing practices
- Explore the CLI Reference for command documentation