A multi-column chat interface for OpenClaw agents. Chat with multiple AI agents side-by-side in a clean, responsive deck layout.
- Multi-column layout — Chat with 7 agents simultaneously by default
- Markdown rendering — Full markdown support with syntax highlighting
- Keyboard navigation — Fast switching between columns (Tab, Cmd+1-9, Cmd+K)
- Real-time WebSocket — Live connection to OpenClaw Gateway
- Clean UI — Compact, readable design optimized for productivity
- Prerequisites
- Installation
- Configuration
- Running the Application
- Usage
- Troubleshooting
- Development
- Architecture
- Contributing
-
Node.js (v18 or higher)
- Check your version:
node --version - Install from: https://nodejs.org/
- Recommended: Use nvm for version management
- Check your version:
-
OpenClaw Gateway (running locally)
- Install OpenClaw: https://openclaw.ai
- Or via npm:
npm install -g openclaw - Verify installation:
openclaw --version
-
Git (for cloning)
- Check:
git --version - Install: https://git-scm.com/
- Check:
- GitHub CLI (
gh) for easier repo management - A modern browser (Chrome, Firefox, Safari, Edge)
git clone https://github.com/kellyclaudeai/openclaw-deck.git
cd openclaw-decknpm installThis will install:
- React, TypeScript, and Vite (core framework)
- Zustand (state management)
- react-markdown and highlight.js (rendering)
- All other required packages
Expected output:
added 170 packages, and audited 171 packages in 8s
If you see any warnings about vulnerabilities, they're typically safe to ignore for development.
Before configuring the Deck, ensure your OpenClaw Gateway is running:
# Check if OpenClaw is installed
openclaw --version
# Check gateway status
openclaw status
# If not running, start it
openclaw gateway startExpected output:
✓ Gateway running at ws://127.0.0.1:18789
✓ Status: healthy
Your gateway token is required for authentication:
openclaw config get gateway.tokenExample output:
5fd19a1df600fdb1968fadd098b8a7f376a826a7f64ae51f
Copy this token — you'll need it in the next step.
cp .env.example .envEdit the .env file:
# Use your preferred editor
nano .env
# or
code .env
# or
vim .envUpdate with your token:
VITE_GATEWAY_URL=ws://127.0.0.1:18789
VITE_GATEWAY_TOKEN=your_actual_token_hereImportant:
- Replace
your_actual_token_herewith the token from Step 2 - Do not commit this file to git (it's in
.gitignore) - The gateway URL should match your OpenClaw setup (default is usually correct)
Start the Vite dev server with hot-reload:
npm run devExpected output:
VITE v6.4.1 ready in 423 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
Open your browser to http://localhost:5173
You should see 7 agent columns load. If input fields are enabled, you're connected successfully!
For deployment or testing the production build:
npm run build
npm run previewThe build output will be in dist/ and preview will run at http://localhost:4173
- Click or Tab into any agent column input field
- Type your message and press Enter
- Watch the agent respond in real-time with streaming output
- Markdown is rendered automatically (headers, lists, code blocks, etc.)
| Shortcut | Action |
|---|---|
Tab |
Move to next column input |
Shift+Tab |
Move to previous column input |
Cmd+1 through Cmd+9 |
Jump directly to column 1-9 |
Cmd+K |
Open "Add Agent" modal |
Enter |
Send message (when in input field) |
Each column represents an independent agent conversation:
- Labeled 1-7 for quick reference
- Color-coded for visual distinction
- Independent scroll — scroll one column without affecting others
- Persistent — messages remain until you clear them
- Your messages appear in a smaller, monospace font with a cyan tint
- Agent responses appear larger with markdown formatting:
- Headers (
#,##,###) - Lists (bulleted and numbered)
- Code blocks with syntax highlighting
- Inline code, quotes, tables, and more
- Headers (
Symptoms:
- All input fields are disabled/grayed out
- Status bar shows connection error
- Console shows WebSocket errors
Solutions:
-
Verify Gateway is Running
openclaw status
If not running:
openclaw gateway start
-
Check Your Token
# Get current token openclaw config get gateway.token # Compare with your .env file cat .env | grep VITE_GATEWAY_TOKEN
If they don't match, update
.envwith the correct token. -
Verify Gateway URL Most setups use
ws://127.0.0.1:18789, but check your OpenClaw config:openclaw config get gateway.port
If different, update
VITE_GATEWAY_URLin.env -
Restart Dev Server After changing
.env, stop the dev server (Ctrl+C) and restart:npm run dev
Solution:
Your .env file is likely missing or has an incorrect token.
-
Verify
.envexists:ls -la .env
-
Check token format (should be a long hex string):
cat .env
-
Regenerate if needed:
openclaw gateway restart openclaw config get gateway.token
Solutions:
-
Check Browser Console
- Open Developer Tools (F12 or Cmd+Option+I)
- Look for JavaScript errors
- Common issues: CORS errors, module loading failures
-
Clear Browser Cache
- Hard refresh:
Cmd+Shift+R(Mac) orCtrl+Shift+R(Windows/Linux) - Or clear cache in browser settings
- Hard refresh:
-
Verify Build
rm -rf dist node_modules npm install npm run dev
Cause: Gateway connection failed (see Connection Issues)
Quick check: Look at the status bar at the bottom of the page. It should show a green indicator when connected.
Solution: This is a known issue in some browsers with strict content security policies.
- Try a different browser (Chrome works best)
- Check browser console for CSP errors
- Ensure you're on the latest version:
git pull origin master npm install
Solutions:
-
Reduce Active Columns Edit
src/App.tsxand change:buildDefaultAgents(7) // Change to 3 or 4
-
Disable Syntax Highlighting If code blocks are causing lag, you can disable highlighting by commenting out the import in
src/components/AgentColumn.tsx:// import "highlight.js/styles/github-dark.css"; -
Check Gateway Health
openclaw doctor
Solutions:
-
Check Node Version
node --version
Must be v18 or higher. Upgrade if needed.
-
Clear npm Cache
npm cache clean --force rm -rf node_modules package-lock.json npm install
-
Try Different Registry
npm install --registry https://registry.npmjs.org/
openclaw-deck/
├── src/
│ ├── components/ # React UI components
│ │ ├── AgentColumn.tsx # Individual agent chat column
│ │ ├── TopBar.tsx # Header with navigation
│ │ ├── StatusBar.tsx # Connection status footer
│ │ └── AddAgentModal.tsx # Agent creation dialog
│ ├── lib/ # Core libraries
│ │ ├── gateway-client.ts # WebSocket client for OpenClaw Gateway
│ │ └── store.ts # Zustand state management
│ ├── hooks/ # React hooks
│ │ └── index.ts # Custom hooks (useAgentSession, etc.)
│ ├── types/ # TypeScript type definitions
│ │ └── index.ts # AgentConfig, Message, etc.
│ ├── App.tsx # Main application component
│ ├── App.css # Global styles
│ └── main.tsx # Application entry point
├── public/ # Static assets
├── dist/ # Build output (gitignored)
├── .env # Environment config (gitignored)
├── .env.example # Example environment config
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── vite.config.ts # Vite build configuration
└── README.md # This file
# Development
npm run dev # Start dev server with hot reload
# Building
npm run build # Production build to dist/
npm run preview # Preview production build locally
# Code Quality
npm run type-check # Run TypeScript type checking
npm run lint # Run ESLint (if configured)
# Maintenance
npm run clean # Remove dist/ and node_modules/Edit src/App.tsx:
const AGENT_ACCENTS = [
"#22d3ee", // cyan
"#a78bfa", // purple
"#34d399", // green
"#f59e0b", // orange
"#f472b6", // pink
"#60a5fa", // blue
"#facc15", // yellow
// Add more colors here
];Edit src/App.tsx:
const [initialAgents] = useState<AgentConfig[]>(() =>
buildDefaultAgents(7) // Change this number
);Edit src/components/AgentColumn.module.css:
/* User messages */
.userMsg .messageText {
font-size: 12px;
line-height: 1;
color: rgba(255, 255, 255, 0.86);
/* Customize here */
}
/* Assistant messages */
.assistantMsg .messageText {
line-height: 1.22;
/* Customize here */
}User Input
↓
AgentColumn Component
↓
useSendMessage Hook
↓
GatewayClient (WebSocket)
↓
OpenClaw Gateway
↓
AI Model (Claude, GPT, etc.)
↓
Gateway Response (streaming)
↓
GatewayClient (WebSocket)
↓
Zustand Store Update
↓
React Re-render
↓
Message Display (Markdown)
The app uses Zustand for state management:
useDeckStore— Global store for all agent sessions- Each agent has:
messages[]— Chat historyisStreaming— Current streaming stategatewayConnected— Connection status
The GatewayClient (src/lib/gateway-client.ts) handles:
- Authentication — Token-based handshake with Gateway
- Message Routing — Sending user input, receiving agent responses
- Streaming — Real-time token streaming from AI responses
- Reconnection — Automatic reconnect on connection loss
- User types message and presses Enter
- Message added to local state immediately (optimistic update)
- WebSocket sends message to Gateway
- Gateway streams response back in chunks
- Each chunk triggers a React state update
react-markdownrenders the accumulated texthighlight.jsapplies syntax highlighting to code blocks
If you're an AI agent helping someone set up OpenClaw Deck, use these exact steps:
# 1. Verify prerequisites
node --version # Should be v18+
openclaw --version # Should show OpenClaw is installed
# 2. Start OpenClaw Gateway (if not running)
openclaw gateway start
openclaw status # Verify it's running
# 3. Get gateway token
export GATEWAY_TOKEN=$(openclaw config get gateway.token)
echo "Gateway token: $GATEWAY_TOKEN"
# 4. Clone and setup
git clone https://github.com/kellyclaudeai/openclaw-deck.git
cd openclaw-deck
npm install
# 5. Configure environment
cat > .env << EOF
VITE_GATEWAY_URL=ws://127.0.0.1:18789
VITE_GATEWAY_TOKEN=$GATEWAY_TOKEN
EOF
# 6. Start dev server
npm run dev
# 7. Open browser
echo "✓ Setup complete! Open http://localhost:5173 in your browser"Expected result: Browser opens with 7 agent columns, all input fields enabled and ready for messages.
If there are errors:
- Check that gateway is running:
openclaw status - Verify token in
.envmatches:openclaw config get gateway.token - Check browser console for specific errors (F12)
- Try restarting dev server: Stop with Ctrl+C, then
npm run devagain
Contributions are welcome! Here's how to contribute:
- Check existing issues
- Open a new issue with:
- Clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Screenshots if applicable
- Browser and OS information
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/openclaw-deck.git
- Create a branch:
git checkout -b feature/your-feature-name
- Make your changes and test thoroughly
- Commit with clear messages:
git commit -m "Add feature: description of what you added" - Push to your fork:
git push origin feature/your-feature-name
- Open a Pull Request on GitHub
- Follow existing code style (TypeScript + React best practices)
- Add comments for complex logic
- Test in multiple browsers if changing UI
- Update README if adding features or changing setup
- Keep commits focused and atomic
Yes! Update VITE_GATEWAY_URL in .env:
VITE_GATEWAY_URL=wss://your-gateway-domain.com
VITE_GATEWAY_TOKEN=your_remote_tokenNote: Use wss:// for secure connections over HTTPS.
Yes, edit src/App.tsx and change the number in buildDefaultAgents(7).
Yes! As long as your OpenClaw Gateway is accessible, the Deck will work.
Yes, but you need to configure models in your OpenClaw Gateway settings. The Deck connects to whatever agents are configured in your gateway.
Not yet, but contributions welcome! The current setup is optimized for local development.
Yes:
- Run
npm run build - Deploy the
dist/folder to any static hosting (Vercel, Netlify, GitHub Pages, etc.) - Configure your environment variables in the hosting platform
- Ensure your OpenClaw Gateway is accessible from the deployed URL
MIT License - see LICENSE file for details
- OpenClaw — The main OpenClaw project
- OpenClaw Docs — Official documentation
- ClawHub — Community skills and tools
Built with ❤️ for the OpenClaw community by @kellyclaudeai
Special thanks to all contributors and the OpenClaw team.
- Documentation: This README + OpenClaw Docs
- Issues: GitHub Issues
- Community: OpenClaw Discord
Need help? Open an issue with the question label and include:
- What you're trying to do
- What's happening instead
- Relevant error messages or screenshots
- Your environment (OS, Node version, OpenClaw version)