PinchChat
[](https://github.com/MarlBurroW/pinchchat/actions/workflows/ci.yml)
[](https://opensource.org/licenses/MIT)
[](https://nodejs.org/)
[](https://github.com/MarlBurroW/pinchchat/pkgs/container/pinchchat)
[](https://marlburrow.github.io/pinchchat/)
**A sleek, dark-themed webchat UI for [OpenClaw](https://github.com/openclaw/openclaw) โ monitor sessions, stream responses, and inspect tool calls in real-time.**
> ๐ผ๏ธ *Screenshot coming soon โ [contributions welcome](https://github.com/MarlBurroW/pinchchat/issues)!*
## โจ 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)
```bash
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:
```bash
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.
```bash
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:
```env
VITE_GATEWAY_WS_URL=ws://localhost:18789
VITE_LOCALE=en # or "fr" for French UI
```
### Production build
```bash
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://: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
1. **Login** โ User enters gateway URL + token โ stored in `localStorage`
2. **Connect** โ `useGateway` opens a WebSocket and authenticates with the token
3. **Sessions** โ Gateway pushes session list; user selects one in the sidebar
4. **Messages** โ Messages stream in via WebSocket frames; the hook assembles partial chunks into complete messages
5. **Send** โ User input (+ optional file attachments) is sent as a JSON frame over the WebSocket
## ๐ Tech Stack
- [React](https://react.dev/) 19
- [Vite](https://vite.dev/) 7
- [Tailwind CSS](https://tailwindcss.com/) v4
- [Radix UI](https://www.radix-ui.com/) primitives
- [highlight.js](https://highlightjs.org/) via rehype-highlight
- [Lucide React](https://lucide.dev/) icons
- [react-markdown](https://github.com/remarkjs/react-markdown) with GFM
## ๐ License
[MIT](LICENSE) ยฉ Nicolas Varrot
## ๐ค Contributing
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## ๐ Links
- [OpenClaw](https://github.com/openclaw/openclaw) โ the AI agent platform PinchChat connects to