- Multi-stage Dockerfile (node build + nginx:alpine serve) - nginx.conf with SPA fallback, gzip, asset caching - docker-compose.yml for easy deployment - GitHub Actions workflow to build & push to ghcr.io on every push - .dockerignore to keep image lean - Updated README with Docker-first quick start and badge
🦞 PinchChat
A sleek, dark-themed webchat UI for OpenClaw — monitor sessions, stream responses, and inspect tool calls in real-time.
🖼️ Screenshot coming soon — contributions welcome!
✨ Features
- 🌑 Dark neon theme — easy on the eyes, built with Tailwind CSS v4
- 📊 Token progress bars — track token usage per session in real-time
- 🔧 Tool call badges — expandable panels with syntax-highlighted JSON
- 📋 Session sidebar — browse active sessions with live activity indicators
- 📝 Markdown rendering — full GFM support with code highlighting
- 📎 File upload — attach files to your messages
- ⚡ Streaming responses — watch the AI think in real-time
- 🔐 Runtime login — enter gateway credentials at runtime, no secrets in the build
- 🌐 i18n support — English and French, configurable via
VITE_LOCALE
🚀 Quick Start
Docker (recommended)
docker run -p 3000:80 ghcr.io/marlburrow/pinchchat:latest
Open http://localhost:3000 and enter your OpenClaw gateway URL + token on the login screen.
Or use Docker Compose:
curl -O https://raw.githubusercontent.com/MarlBurroW/pinchchat/main/docker-compose.yml
docker compose up -d
From source
Prerequisites: Node.js 18+, an OpenClaw gateway running and accessible.
git clone https://github.com/MarlBurroW/pinchchat.git
cd pinchchat
npm install
cp .env.example .env
npm run dev
Optionally edit .env to pre-fill the gateway URL:
VITE_GATEWAY_WS_URL=ws://localhost:18789
VITE_LOCALE=en # or "fr" for French UI
Production build
npm run build
npx vite preview
Or serve the dist/ folder with nginx, Caddy, or any static file server.
⚙️ Configuration
All configuration is optional — credentials are entered at runtime via the login screen.
| Variable | Description | Default |
|---|---|---|
VITE_GATEWAY_WS_URL |
Pre-fill the gateway URL on the login screen | ws://<hostname>:18789 |
VITE_LOCALE |
UI language (en or fr) |
en |
Note: The gateway token is entered at runtime and stored in
localStorage— it is never baked into the build.
🏗 Architecture
┌─────────────────────────────────────────────────────┐
│ PinchChat (Browser) │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │
│ │ Login │→ │ App.tsx │→ │ Chat + Sidebar │ │
│ │ Screen │ │ (router) │ │ (main UI) │ │
│ └──────────┘ └─────┬─────┘ └────────┬─────────┘ │
│ │ │ │
│ ┌─────▼──────────────────▼─────┐ │
│ │ useGateway (hook) │ │
│ │ WebSocket state machine │ │
│ │ auth · sessions · messages │ │
│ └─────────────┬────────────────┘ │
└──────────────────────────────┼───────────────────────┘
│ WebSocket (JSON frames)
▼
┌─────────────────────┐
│ OpenClaw Gateway │
│ (ws://host:18789) │
└─────────────────────┘
Key Components
| File | Role |
|---|---|
src/hooks/useGateway.ts |
WebSocket connection, auth, message streaming, session management |
src/components/LoginScreen.tsx |
Runtime credential entry (stored in localStorage) |
src/components/Chat.tsx |
Message list with auto-scroll and streaming display |
src/components/ChatInput.tsx |
Input with file upload, paste, drag & drop, image compression |
src/components/ChatMessage.tsx |
Markdown rendering, tool calls, thinking blocks |
src/components/Sidebar.tsx |
Session list with token usage bars and activity indicators |
src/components/Header.tsx |
Connection status, token progress bar, logout |
src/lib/i18n.ts |
Lightweight i18n (English + French) |
src/lib/gateway.ts |
WebSocket protocol helpers and message types |
Data Flow
- Login — User enters gateway URL + token → stored in
localStorage - Connect —
useGatewayopens a WebSocket and authenticates with the token - Sessions — Gateway pushes session list; user selects one in the sidebar
- Messages — Messages stream in via WebSocket frames; the hook assembles partial chunks into complete messages
- Send — User input (+ optional file attachments) is sent as a JSON frame over the WebSocket
🛠 Tech Stack
- React 19
- Vite 7
- Tailwind CSS v4
- Radix UI primitives
- highlight.js via rehype-highlight
- Lucide React icons
- react-markdown with GFM
📄 License
MIT © Nicolas Varrot
🤝 Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
🔗 Links
- OpenClaw — the AI agent platform PinchChat connects to