2026-02-13 11:30:35 +00:00
2026-02-13 10:25:10 +00:00
2026-02-13 11:30:35 +00:00
2026-02-13 09:40:34 +00:00
2026-02-11 00:48:43 +00:00
2026-02-13 11:30:35 +00:00

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.

🎬 See the live demo → — interactive preview of the UI with tool call visualization, streaming, and more.

PinchChat Screenshot

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

🚀 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 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.

🎨 Customization

PinchChat stores all preferences in localStorage — no server-side config needed.

Themes

Click the palette icon in the header to switch between:

Theme Description
Dark (default) Zinc-based dark theme, easy on the eyes
Light Clean light mode with white backgrounds
OLED Pure black backgrounds for OLED screens
System Follows 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

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. ConnectuseGateway 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.

Shortcut Action
Enter Send message
Shift + Enter New line
Esc Stop generation / close sidebar
Ctrl/⌘ + F Search messages in current session
Ctrl/⌘ + K Focus 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 18+
node --version
# Clean install
rm -rf node_modules package-lock.json
npm install
npm run build

🛠 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
Description
No description provided
Readme MIT 9.2 MiB
Languages
TypeScript 96.9%
CSS 1.9%
JavaScript 0.6%
HTML 0.5%