README.md

February 14, 2026 ยท View on GitHub

PinchChat

PinchChat

CI GitHub Release License: MIT Node.js Docker GitHub Stars Website Contributor Covenant

A sleek, dark-themed webchat UI for OpenClaw โ€” monitor sessions, stream responses, and inspect tool calls in real-time.

PinchChat Demo

โœจ Features

  • ๐Ÿ”ง Tool call visualization โ€” see what your agent is doing in real-time: colored badges, visible parameters, expandable results. The killer feature missing from every other chat UI.
  • ๐Ÿ’ฌ GPT-like interface โ€” sessions in a sidebar, switch between conversations. Familiar if you've used ChatGPT or Claude.
  • ๐Ÿ“‹ Multi-session navigation โ€” browse all active sessions including cron jobs, sub-agents, and background tasks
  • โšก Live streaming โ€” watch the agent think and write token by token
  • ๐Ÿ“Š Token usage tracking โ€” progress bars per session so you know how much context is left
  • ๐Ÿ–ผ๏ธ Inline images โ€” generated or read images render directly in chat with lightbox preview
  • ๐ŸŽฏ Chat-focused โ€” no settings menus or config panels cluttering the screen. Just the conversation.
  • ๐ŸŽจ Themes โ€” Dark, Light, and OLED Black modes with 6 accent colors. Persisted per-browser.
  • ๐Ÿง  Thinking/reasoning display โ€” see the agent's reasoning process in collapsible blocks with elapsed time
  • ๐Ÿ” Message search โ€” Ctrl+F to search and navigate through conversation history
  • ๐Ÿ“ Split view โ€” open 2 sessions side by side with a resizable divider
  • โœ๏ธ Syntax-highlighted input โ€” real-time markdown coloring as you type (code blocks, bold, links)
  • ๐Ÿ”€ Drag & drop reorder โ€” organize sessions in the sidebar by dragging, order persists across reloads
  • ๐Ÿ“‹ Raw JSON viewer โ€” inspect full gateway message payloads for debugging
  • ๐Ÿ—‚๏ธ Channel icons โ€” Discord, Telegram, cron, and other session types shown with distinct icons
  • ๐Ÿ“ค Export conversations โ€” download any session as a formatted Markdown file
  • ๐ŸŒ i18n โ€” English and French built-in, easy to extend
  • ๐Ÿ”” Notification sounds โ€” subtle audio chime for new messages (toggleable)
  • โŒจ๏ธ Keyboard shortcuts โ€” navigate sessions, toggle sidebar, search, and more without touching the mouse
  • ๐Ÿ“ฑ PWA support โ€” installable as a progressive web app with offline caching and auto-updates
  • โ™ฟ Accessible โ€” skip-to-chat link, focus-visible outlines, semantic HTML, prefers-reduced-motion support, ARIA live regions

๐Ÿš€ Quick Start

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 20+, 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.

VariableDescriptionDefault
VITE_GATEWAY_WS_URLPre-fill the gateway URL on the login screenws://<hostname>:18789
VITE_LOCALEUI language (en or fr)en

Note: The gateway token is entered at runtime and stored in localStorage โ€” it is never baked into the build.

๐ŸŽจ Customization

PinchChat stores all preferences in localStorage โ€” no server-side config needed.

Themes

Click the palette icon in the header to switch between:

ThemeDescription
Dark (default)Zinc-based dark theme, easy on the eyes
LightClean light mode with white backgrounds
OLEDPure black backgrounds for OLED screens
SystemFollows your OS dark/light preference

Accent Colors

Six accent colors are available: Cyan (default), Violet, Emerald, Amber, Rose, and Blue. The accent tints buttons, links, progress bars, and user message bubbles.

Other Preferences

These settings persist across sessions:

  • Sidebar width โ€” drag the right edge to resize
  • Session order โ€” drag & drop to reorder; pinned sessions stay on top
  • Syntax highlighting โ€” toggle the </> button in the input area
  • Split view โ€” open two sessions side by side (icon in header)
  • Language โ€” switch between English and French via the globe icon
  • Message drafts โ€” input text is preserved per-session when switching

๐Ÿ— Architecture

graph TD
    subgraph Browser["๐ŸŒ PinchChat (Browser)"]
        Login["LoginScreen<br/><i>credentials</i>"]
        App["App.tsx<br/><i>router</i>"]
        UI["Chat + Sidebar<br/><i>main UI</i>"]
        Hook["useGateway<br/><i>WebSocket state machine</i><br/>auth ยท sessions ยท messages"]

        Login --> App --> UI
        App & UI --> Hook
    end

    Hook <-->|"WebSocket (JSON frames)"| Gateway["๐Ÿ”Œ OpenClaw Gateway<br/><code>ws://host:18789</code>"]
    Gateway <-->|API| LLM["๐Ÿค– LLM Provider<br/><i>Anthropic, OpenAI, etc.</i>"]

Key Components

FileRole
src/hooks/useGateway.tsWebSocket connection, auth, message streaming, session management
src/components/LoginScreen.tsxRuntime credential entry (stored in localStorage)
src/components/Chat.tsxMessage list with auto-scroll and streaming display
src/components/ChatInput.tsxInput with file upload, paste, drag & drop, image compression
src/components/ChatMessage.tsxMarkdown rendering, tool calls, thinking blocks
src/components/Sidebar.tsxSession list with token usage bars and activity indicators
src/components/Header.tsxConnection status, token progress bar, logout
src/lib/i18n.tsLightweight i18n (English + French)
src/lib/gateway.tsWebSocket 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

๐Ÿ“– For a deeper dive into the codebase structure, see ARCHITECTURE.md.

๐ŸŒ Adding a Language

PinchChat uses a zero-dependency i18n system. Adding a new language takes ~5 minutes:

  1. Open src/lib/i18n.ts and duplicate the en object with your locale code:
const de: typeof en = {
  'login.title': 'PinchChat',
  'login.subtitle': 'Verbinde dich mit deinem OpenClaw-Gateway',
  // ... translate all keys
};
  1. Register it in the messages record (same file):
const messages: Record<string, typeof en> = { en, fr, de };
  1. Add a label for the language selector:
export const localeLabels: Record<string, string> = {
  en: 'EN',
  fr: 'FR',
  de: 'DE',
};
  1. Done. The language selector, VITE_LOCALE, and browser auto-detection all pick it up automatically.

Tip: TypeScript enforces that your new locale object has the same keys as en โ€” missing translations won't compile.

โŒจ๏ธ Keyboard Shortcuts

Press ? anywhere to open the shortcuts panel.

ShortcutAction
EnterSend message
Shift + EnterNew line
EscStop generation / close sidebar
Ctrl/โŒ˜ + FSearch messages in current session
Ctrl/โŒ˜ + KFocus session search
Alt + โ†‘ / Alt + โ†“Switch between sessions
?Show shortcuts help

โ“ Troubleshooting

Connection fails / "WebSocket error"

  • Make sure your OpenClaw gateway is running and reachable from the browser
  • Check the gateway URL format: ws://host:18789 (or wss:// if behind TLS)
  • If PinchChat is served over HTTPS, the gateway must also use wss:// โ€” browsers block mixed content
  • Verify the gateway token is correct (copy-paste from your OpenClaw config)

Blank screen after login

  • Open your browser's developer console (F12) and check for errors
  • Ensure the gateway is running a compatible version of OpenClaw (v0.24+)
  • Try clearing localStorage (Application tab โ†’ Storage โ†’ Clear site data) and logging in again

Messages don't appear / sessions empty

  • The WebSocket may have disconnected silently โ€” check the connection indicator in the header
  • If the gateway was restarted, PinchChat reconnects automatically, but you may need to refresh once
  • Verify the token has access to the sessions you expect

Docker: "port already in use"

# Check what's using port 3000
lsof -i :3000
# Use a different port
docker run -p 8080:80 ghcr.io/marlburrow/pinchchat:latest

Images not displaying

  • Inline images require the gateway to send media as base64 data URLs or accessible HTTP URLs
  • If images show as broken, the gateway may be behind a reverse proxy that strips large payloads โ€” check proxy buffer settings

Debugging

PinchChat includes built-in debugging tools:

WebSocket debug logging โ€” open the browser console (F12) and run:

localStorage.setItem('pinchchat:debug', '1');

Reload the page. All WebSocket frames (sent and received) will be logged to the console with a [GW] prefix. Set to '0' to disable.

Raw JSON viewer โ€” click the { } toggle on any message to see the full gateway payload as formatted JSON. Useful for understanding the protocol or reporting bugs.

Metadata inspector โ€” hover over any message and click the โ„น๏ธ icon to see message metadata (timestamp, ID, channel, sender info).

Build errors from source

# Ensure Node.js 20+
node --version
# Clean install
rm -rf node_modules package-lock.json
npm install
npm run build

๐Ÿ”€ Reverse Proxy

PinchChat is a static SPA โ€” serve it behind any reverse proxy. The only special requirement is WebSocket support for the OpenClaw gateway connection.

Note: PinchChat itself only serves static files (HTML/JS/CSS). The WebSocket connection goes directly from the browser to your OpenClaw gateway, not through PinchChat's server. You only need to proxy WebSocket if you're also putting the gateway behind the same reverse proxy.

Nginx

server {
    listen 443 ssl;
    server_name chat.example.com;

    # PinchChat static files
    location / {
        proxy_pass http://127.0.0.1:3000;
        # Or serve directly from the build output:
        # root /path/to/pinchchat/dist;
        # try_files $uri $uri/ /index.html;
    }
}

# Optional: proxy the OpenClaw gateway too
server {
    listen 443 ssl;
    server_name gw.example.com;

    location / {
        proxy_pass http://127.0.0.1:18789;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400s;  # Keep WebSocket alive
    }
}

Caddy

chat.example.com {
    reverse_proxy 127.0.0.1:3000
}

# Optional: proxy the gateway
gw.example.com {
    reverse_proxy 127.0.0.1:18789
}

Caddy handles WebSocket upgrades and TLS automatically.

Traefik (Docker labels)

services:
  pinchchat:
    image: ghcr.io/marlburrow/pinchchat:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pinchchat.rule=Host(`chat.example.com`)"
      - "traefik.http.routers.pinchchat.tls.certresolver=letsencrypt"
      - "traefik.http.services.pinchchat.loadbalancer.server.port=80"

Traefik (Kubernetes IngressRoute)

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: pinchchat
spec:
  entryPoints: [websecure]
  routes:
    - match: Host(`chat.example.com`)
      kind: Rule
      services:
        - name: pinchchat
          port: 80
  tls:
    certResolver: letsencrypt

Important notes

  • HTTPS + WSS: If PinchChat is served over HTTPS, the gateway URL must use wss:// โ€” browsers block mixed content (https page โ†’ ws:// connection)
  • Timeouts: Set generous read timeouts for the gateway proxy (WebSocket connections are long-lived). Nginx defaults to 60s which will drop the connection.
  • Buffering: If images aren't loading, increase proxy buffer sizes (proxy_buffer_size, proxy_buffers in Nginx)
  • Health checks: The PinchChat container responds to GET / with the SPA โ€” use it as a health check endpoint

๐Ÿ›  Tech Stack

๐Ÿ“„ License

MIT ยฉ Nicolas Varrot

๐Ÿ“‹ Changelog

See CHANGELOG.md for a detailed history of changes.

๐Ÿ”’ Security

See SECURITY.md for the security policy and how to report vulnerabilities.

๐Ÿค Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

  • OpenClaw โ€” the AI agent platform PinchChat connects to