### Initialize PinchChat Development Environment Source: https://github.com/marlburrow/pinchchat/blob/main/CONTRIBUTING.md Commands to clone the repository, install dependencies, configure environment variables, and start the development server. This is the standard procedure for setting up a local development instance. ```bash git clone https://github.com//pinchchat.git cd pinchchat npm install cp .env.example .env npm run dev ``` -------------------------------- ### Clean Build and Install Dependencies Source: https://github.com/marlburrow/pinchchat/blob/main/README.md Standard procedure to reset the project environment by removing existing modules and performing a fresh install using Node.js 20+. ```bash # Ensure Node.js 20+ node --version # Clean install rm -rf node_modules package-lock.json npm install npm run build ``` -------------------------------- ### Configure Reverse Proxies for PinchChat Source: https://github.com/marlburrow/pinchchat/blob/main/README.md Configuration examples for Nginx, Caddy, and Traefik to serve the static SPA and proxy the OpenClaw WebSocket gateway. ```nginx server { listen 443 ssl; server_name chat.example.com; location / { proxy_pass http://127.0.0.1:3000; } } 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; } } ``` ```caddyfile chat.example.com { reverse_proxy 127.0.0.1:3000 } gw.example.com { reverse_proxy 127.0.0.1:18789 } ``` ```yaml 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" ``` ```yaml 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 ``` -------------------------------- ### Implement Theme Management System Source: https://context7.com/marlburrow/pinchchat/llms.txt Demonstrates how to wrap an application with the ThemeProvider and use the useTheme hook to manage UI settings like theme mode, accent colors, and font sizes. ```typescript function App() { return ( ); } function SettingsPanel() { const { theme, accent, setTheme, setAccent, uiFontSize, setUiFontSize } = useTheme(); return (
setUiFontSize(Number(e.target.value))} />
); } ``` -------------------------------- ### Initialize and Connect to OpenClaw Gateway Source: https://context7.com/marlburrow/pinchchat/llms.txt Demonstrates how to instantiate the GatewayClient, manage connection status, subscribe to real-time chat events, and perform request-response operations. It requires a valid WebSocket URL and authentication credentials. ```typescript import { GatewayClient } from './lib/gateway'; const client = new GatewayClient( 'ws://localhost:18789', 'your-auth-token', 'token', 'webchat' ); client.onStatus((status) => { console.log('Connection status:', status); }); const unsubscribe = client.onEvent((event, payload) => { if (event === 'chat') { const { state, message, sessionKey } = payload; console.log(`Chat event [${state}] for session ${sessionKey}:`, message); } }); client.connect(); const response = await client.send('sessions.list', {}); console.log('Available sessions:', response.sessions); client.disconnect(); unsubscribe(); ``` -------------------------------- ### Theme System Configuration Source: https://context7.com/marlburrow/pinchchat/llms.txt Details the properties and methods available for managing the PinchChat application theme, including colors, fonts, and sizing. ```APIDOC ## Theme System ### Description Provides an interface to manage the application's visual appearance, including theme modes, accent colors, and typography settings. ### Configuration Options - **theme** ('dark' | 'light' | 'oled' | 'system') - The active theme mode. - **accent** ('cyan' | 'violet' | 'emerald' | 'amber' | 'rose' | 'blue') - The primary accent color. - **uiFont** (string) - Font family for the user interface. - **monoFont** (string) - Font family for monospaced elements. - **uiFontSize** (number) - Font size for the UI (12-20). - **monoFontSize** (number) - Font size for monospaced text (12-20). ### CSS Custom Properties - The system exposes variables such as --pc-bg-base, --pc-text-primary, and --pc-accent for custom styling. ``` -------------------------------- ### Deploy PinchChat with Docker Source: https://context7.com/marlburrow/pinchchat/llms.txt Deploy PinchChat as a Docker image. The image serves a static SPA via nginx. Configuration is managed through environment variables. Docker Compose is also supported for multi-service deployments. ```bash # Quick start with Docker docker run -p 3000:80 ghcr.io/marlburrow/pinchchat:latest # With environment variables docker run -p 3000:80 \ -e VITE_GATEWAY_WS_URL=ws://gateway.example.com:18789 \ -e VITE_LOCALE=fr \ ghcr.io/marlburrow/pinchchat:latest # Using Docker Compose # docker-compose.yml: version: '3.8' services: pinchchat: image: ghcr.io/marlburrow/pinchchat:latest ports: - "3000:80" environment: - VITE_GATEWAY_WS_URL=ws://openclaw:18789 - VITE_LOCALE=en restart: unless-stopped # Start with compose docker compose up -d # Build from source git clone https://github.com/MarlBurroW/pinchchat.git cd pinchchat npm install npm run build # Serve dist/ with any static file server # Development mode npm run dev # Starts Vite dev server on http://localhost:5173 # Production preview npm run build && npx vite preview ``` -------------------------------- ### Implementing useGateway for Chat Application State Source: https://context7.com/marlburrow/pinchchat/llms.txt This snippet demonstrates how to initialize the useGateway hook to manage connection status, session lifecycle, and message transmission. It highlights key actions like authentication, session switching, and sending messages with attachments. ```typescript import { useGateway } from './hooks/useGateway'; function ChatApp() { const { status, sessions, activeSession, messages, isGenerating, login, sendMessage, switchSession, createSessionForAgent, abort } = useGateway(); const handleLogin = () => { login('ws://localhost:18789', 'my-token', 'token'); }; const handleSend = async () => { await sendMessage('What can you help me with?', [ { mimeType: 'image/jpeg', fileName: 'screenshot.jpg', content: 'base64-encoded-image-data...' } ]); }; const handleSessionSwitch = (sessionKey: string) => { switchSession(sessionKey); }; return (
{status === 'connected' && ( <> )}
); } ``` -------------------------------- ### Project Quality Assurance Commands Source: https://github.com/marlburrow/pinchchat/blob/main/CONTRIBUTING.md Standard scripts for maintaining code quality, including linting, testing, building, and previewing the application. These must pass before submitting a pull request. ```bash npm run lint npm test npm run build npx vite preview ``` -------------------------------- ### PinchChat Demo Window Styling - CSS Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html Styles the interactive demo window, including the sidebar for chat sessions and the main chat area. It defines styles for session names, icons, token bars, and the chat input area, creating a realistic chat interface. ```css /* ─── Demo window (in hero) ─── */ .demo-window { display: flex; border: 1px solid var(--border); border-radius: 1rem; overflow: hidden; height: 420px; background: var(--bg-secondary); box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 80px rgba(34,211,238,0.06); max-width: 860px; margin: 0 auto; } .demo-sidebar { width: 210px; min-width: 210px; background: #0d0d14; border-right: 1px solid var(--border); padding: 0.75rem; display: flex; flex-direction: column; gap: 0.25rem; } .demo-sidebar-header { display: flex; align-items: center; gap: 0.5rem; font-weight: 700; font-size: 0.95rem; padding: 0.5rem 0.25rem 0.75rem; color: var(--text-primary); } .demo-sidebar-logo { width: 22px; height: 22px; border-radius: 4px; } .demo-session { padding: 0.5rem 0.6rem; border-radius: 0.5rem; cursor: default; transition: background 0.15s; } .demo-session-active { background: rgba(34,211,238,0.08); } .demo-session-name { font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 0.3rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 0.35rem; } .demo-session-active .demo-session-name { color: var(--text-primary); } .demo-session-icon { font-size: 0.7rem; opacity: 0.6; flex-shrink: 0; } .demo-token-bar { height: 3px; background: rgba(255,255,255,0.06); border-radius: 2px; overflow: hidden; } .demo-token-fill { height: 100%; background: var(--accent-cyan); border-radius: 2px; transition: width 1s ease; } .demo-token-low { background: #4ade80; } .demo-chat { flex: 1; display: flex; flex-direction: column; min-width: 0; } .demo-chat-scroll { flex: 1; overflow-y: auto; padding: 1.25rem 1.25rem 0.5rem; display: flex; flex-direction: column; gap: 1rem; text-align: left; } .demo-input { display: flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-top: 1px solid var(--border); } .demo-input-box { flex: 1; background: rgba(255,255,255,0.04); border: 1px solid var(--border); border-radius: 0.5rem; pad ``` -------------------------------- ### Directory Structure - TypeScript Source: https://github.com/marlburrow/pinchchat/blob/main/ARCHITECTURE.md Illustrates the main directories and files within the src/ folder of the PinchChat project. It shows the organization of components, hooks, types, and utility libraries. ```typescript src/ ├── App.tsx # Root: login gate, layout, lazy-loads Chat ├── main.tsx # Entry point, renders App inside ErrorBoundary ├── types.ts # Shared TypeScript types (Session, Message, etc.) ├── components/ # React components (see below) ├── hooks/ # Custom React hooks ├── lib/ # Pure utility modules (no React) └── contexts/ # React contexts (theme, tool collapse state) ``` -------------------------------- ### PinchChat Docker Deployment Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html This command provides a quick way to run the PinchChat application using Docker. It maps port 3000 on the host machine to port 80 within the container, allowing access to the web UI. ```bash docker run -p 3000:80 ghcr.io/marlburrow/pinchchat:latest ``` -------------------------------- ### Implement Internationalization (i18n) in PinchChat Source: https://context7.com/marlburrow/pinchchat/llms.txt Demonstrates how to use the reactive i18n system within React components and standard TypeScript files. It covers locale switching, subscription to changes, and environment configuration. ```typescript import { t, setLocale, getLocale, onLocaleChange, supportedLocales } from './lib/i18n'; import { useT } from './hooks/useLocale'; function LoginScreen() { const t = useT(); return (

{t('login.title')}

{t('login.subtitle')}

); } console.log(t('header.connected')); setLocale('fr'); const currentLocale = getLocale(); const unsubscribe = onLocaleChange(() => { console.log('Locale changed to:', getLocale()); }); ``` -------------------------------- ### Implement Tool Call Content Wrapping Source: https://github.com/marlburrow/pinchchat/blob/main/FEEDBACK.md Provides a mechanism to toggle between word-wrapping and raw formatting for JSON payloads in tool calls. ```css .tool-content.wrap { white-space: pre-wrap; word-break: break-word; } .tool-content.nowrap { white-space: pre; overflow-x: auto; } ``` -------------------------------- ### Resolve Docker Port Conflicts Source: https://github.com/marlburrow/pinchchat/blob/main/README.md Commands to identify processes occupying port 3000 and instructions for running the PinchChat container on an alternative port. ```bash # Check what's using port 3000 lsof -i :3000 # Use a different port docker run -p 8080:80 ghcr.io/marlburrow/pinchchat:latest ``` -------------------------------- ### Visualize AI Tool Calls with PinchChat Component Source: https://context7.com/marlburrow/pinchchat/llms.txt The ToolCall component visualizes AI tool usage, featuring syntax-highlighted parameters, collapsible results, and tool-specific styling. It requires ToolCollapseProvider for global controls and can be integrated into message rendering logic. ```typescript import { ToolCall } from './components/ToolCall'; import { ToolCollapseProvider } from './contexts/ToolCollapseContext'; import { useToolCollapse } from './hooks/useToolCollapse'; // Wrap your app to enable global collapse/expand function App() { return ( ); } // Render tool calls in messages function MessageRenderer({ blocks }) { return (
{blocks.map((block, i) => { if (block.type === 'tool_use') { return ( ); } return null; })}
); } // Global collapse/expand controls function ToolControls() { const { globalState, collapseAll, expandAll, version } = useToolCollapse(); return (
State: {globalState}
); } // Supported tool names with custom styling: // exec (⚡), web_search (🔍), web_fetch (🌐), Read/read (📖), // Write/write/Edit/edit (✏️), browser (🌐), image (🖼️), // message (💬), memory_search/memory_get (🧠), cron (⏰), // sessions_spawn (🚀), tts (🔊), gateway (⚙️), canvas (🎨) // Each tool has unique colors for light/dark themes // Results auto-detect and render inline images from base64 data // Parameters and results support syntax highlighting via highlight.js ``` -------------------------------- ### Data Flow Visualization - TypeScript Source: https://github.com/marlburrow/pinchchat/blob/main/ARCHITECTURE.md A diagram showing the data flow in PinchChat, from the OpenClaw Gateway via WebSocket to the useGateway hook and then to various UI components like Sidebar, Chat, and Header. It outlines the connection, session management, message streaming, and sending processes. ```typescript OpenClaw Gateway ←—WebSocket—→ useGateway hook │ ┌──────────┼──────────┐ ▼ ▼ ▼ Sidebar Chat Header (sessions) (messages) (status) 1. **Connect**: `LoginScreen` collects gateway URL + token → `useGateway` opens a WebSocket 2. **Sessions**: Gateway pushes session list → stored in hook state → rendered in `Sidebar` 3. **Messages**: On session select, hook requests history → streamed tokens arrive as `delta` events → accumulated into messages → rendered by `ChatMessage` 4. **Sending**: `ChatInput` calls `sendMessage()` from the hook → serialized over WebSocket 5. **Tool calls**: Arrive as structured blocks within assistant messages → rendered by `ToolCall` with collapsible params/results ``` -------------------------------- ### Vite Bundle Strategy - TypeScript Source: https://github.com/marlburrow/pinchchat/blob/main/ARCHITECTURE.md Details the chunking strategy used by Vite in `vite.config.ts` for optimizing the build. It lists the main chunks and their contents, including vendor libraries, markdown processing, icons, UI components, and application code. It also notes that the Chat component is lazy-loaded. ```typescript Vite splits the build into chunks via `manualChunks` in `vite.config.ts`: | Chunk | |-------| | `react-vendor` | React + ReactDOM | | `markdown` | react-markdown, remark/rehype plugins, highlight.js | | `icons` | lucide-react | | `ui` | @radix-ui primitives | | `index` | App code | `Chat` is lazy-loaded (`React.lazy`) so the markdown chunk only loads after login. ``` -------------------------------- ### Enable WebSocket Debug Logging Source: https://github.com/marlburrow/pinchchat/blob/main/README.md Enables verbose WebSocket frame logging in the browser console by setting a local storage flag. Reload the page after execution to see traffic with a [GW] prefix. ```javascript localStorage.setItem('pinchchat:debug', '1'); ``` -------------------------------- ### PinchChat Styling - CSS Variables and Reset Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html Defines CSS variables for color schemes and applies a CSS reset for consistent styling across browsers. It sets up the base styles for the body, including font, color, and background. ```css @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } :root { --bg-primary: #0a0a0f; --bg-secondary: #12121a; --bg-card: #1a1a2e; --border: #2a2a3e; --text-primary: #e4e4e7; --text-secondary: #a1a1aa; --accent-cyan: #22d3ee; --accent-purple: #a78bfa; --accent-pink: #f472b6; --glow-cyan: rgba(34, 211, 238, 0.15); --glow-purple: rgba(167, 139, 250, 0.15); } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; background: var(--bg-primary); color: var(--text-primary); line-height: 1.6; overflow-x: hidden; } .bg-gradient { position: fixed; inset: 0; z-index: -1; background: radial-gradient(ellipse 80% 50% at 50% -20%, var(--glow-cyan), transparent), radial-gradient(ellipse 60% 40% at 80% 60%, var(--glow-purple), transparent), var(--bg-primary); } .container { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; } ``` -------------------------------- ### Render Message Blocks Source: https://context7.com/marlburrow/pinchchat/llms.txt A utility function to map over message blocks and return the appropriate React component based on the block type. ```typescript function renderMessage(msg: ChatMessage) { return msg.blocks.map((block, i) => { switch (block.type) { case 'text': return ; case 'thinking': return ; case 'tool_use': return ; case 'tool_result': return ; case 'image': return ; } }); } ``` -------------------------------- ### PinchChat UI Styling (CSS) Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html This CSS code defines the visual appearance and layout for the PinchChat web UI. It includes styles for sections, headings, feature rows, visual panels, session items, token bars, image grids, language toggles, and the footer. It also contains responsive design rules for various screen sizes. ```css .features-section { padding: 4rem 0 2rem; } .features-heading { text-align: center; font-size: 2rem; font-weight: 700; margin-bottom: 1rem; } .features-sub { text-align: center; color: var(--text-secondary); font-size: 1rem; max-width: 560px; margin: 0 auto 3.5rem; } .feature-row { display: flex; align-items: center; gap: 3rem; margin-bottom: 4rem; opacity: 0; transform: translateY(30px); transition: opacity 0.6s ease, transform 0.6s ease; } .feature-row.visible { opacity: 1; transform: translateY(0); } .feature-row:nth-child(even) { flex-direction: row-reverse; } .feature-row-text { flex: 1; min-width: 0; } .feature-row-visual { flex: 1; min-width: 0; display: flex; justify-content: center; } .feature-row-icon { font-size: 2.5rem; margin-bottom: 0.75rem; } .feature-row-text h3 { font-size: 1.35rem; font-weight: 700; margin-bottom: 0.5rem; } .feature-row-text p { font-size: 0.95rem; color: var(--text-secondary); line-height: 1.6; } .feature-visual-panel { background: var(--bg-card); border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.25rem; width: 100%; max-width: 360px; } .fv-tool-badges { display: flex; flex-wrap: wrap; gap: 0.4rem; } .fv-session-list { display: flex; flex-direction: column; gap: 0.5rem; } .fv-session-item { display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0.6rem; border-radius: 0.5rem; background: rgba(255,255,255,0.03); } .fv-session-item.active { background: rgba(34,211,238,0.08); } .fv-session-label { font-size: 0.8rem; color: var(--text-secondary); flex: 1; } .fv-session-item.active .fv-session-label { color: var(--text-primary); } .fv-dot { width: 6px; height: 6px; border-radius: 50%; background: #4ade80; flex-shrink: 0; } .fv-dot-idle { background: var(--text-secondary); opacity: 0.4; } .fv-stream-lines { display: flex; flex-direction: column; gap: 0.4rem; } .fv-stream-line { height: 8px; border-radius: 4px; background: linear-gradient(90deg, rgba(34,211,238,0.2), rgba(167,139,250,0.1)); animation: streamPulse 2s ease-in-out infinite; } .fv-stream-line:nth-child(2) { width: 85%; animation-delay: 0.3s; } .fv-stream-line:nth-child(3) { width: 60%; animation-delay: 0.6s; } .fv-stream-line:nth-child(4) { width: 90%; animation-delay: 0.9s; } @keyframes streamPulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } } .fv-token-bar-wrapper { display: flex; flex-direction: column; gap: 0.75rem; } .fv-token-row { display: flex; align-items: center; gap: 0.75rem; } .fv-token-label { font-size: 0.78rem; color: var(--text-secondary); width: 80px; flex-shrink: 0; } .fv-token-track { flex: 1; height: 6px; background: rgba(255,255,255,0.06); border-radius: 3px; overflow: hidden; } .fv-token-value { height: 100%; border-radius: 3px; background: var(--accent-cyan); transition: width 1.5s ease; } .fv-token-pct { font-size: 0.72rem; color: var(--text-secondary); width: 32px; text-align: right; flex-shrink: 0; } .fv-image-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; } .fv-image-placeholder { aspect-ratio: 1; border-radius: 0.5rem; background: linear-gradient(135deg, rgba(34,211,238,0.1), rgba(167,139,250,0.1)); display: flex; align-items: center; justify-content: center; font-size: 1.5rem; } .fv-lang-toggle { display: flex; gap: 0.5rem; } .fv-lang-btn { padding: 0.4rem 1rem; border-radius: 0.5rem; font-size: 0.85rem; font-weight: 600; border: 1px solid var(--border); background: transparent; color: var(--text-secondary); } .fv-lang-btn.active { background: rgba(34,211,238,0.1); border-color: var(--accent-cyan); color: var(--accent-cyan); } .footer { text-align: center; padding: 4rem 0 2rem; color: var(--text-secondary); font-size: 0.85rem; } .footer a { color: var(--accent-cyan); text-decoration: none; } .footer a:hover { text-decoration: underline; } .footer-links { display: flex; gap: 2rem; justify-content: center; margin-bottom: 1rem; } @media (max-width: 700px) { .hero { padding: 3rem 0 1.5rem; } .hero h1 { font-size: 2.2rem; } .demo-sidebar { display: none; } .demo-window { height: 360px; } .feature-row, .feature-row:nth-child(even) { flex-direction: column; gap: 1.5rem; text-align: center; } .feature-visual-panel { max-width: 100%; } } ``` -------------------------------- ### Internationalization (i18n) API Source: https://context7.com/marlburrow/pinchchat/llms.txt The i18n module provides reactive translation capabilities and locale management for the PinchChat application. ```APIDOC ## Internationalization (i18n) API ### Description Manages application localization, including reactive translation hooks and runtime locale switching. ### Methods - `t(key: string)`: Translates a string key. - `setLocale(locale: string)`: Updates the active locale and persists it to localStorage. - `getLocale()`: Returns the current active locale. - `onLocaleChange(callback: () => void)`: Subscribes to locale change events. ### Supported Locales - en, fr, es, de, ja, pt, zh, it ### Usage Example ```typescript import { t, setLocale } from './lib/i18n'; // Translate const greeting = t('login.title'); // Switch Language setLocale('fr'); ``` ``` -------------------------------- ### Implement New Language in i18n System Source: https://github.com/marlburrow/pinchchat/blob/main/README.md Steps to add a new language to the PinchChat interface. This involves defining a new locale object, registering it in the messages record, and adding a label for the selector. ```typescript const de: typeof en = { 'login.title': 'PinchChat', 'login.subtitle': 'Verbinde dich mit deinem OpenClaw-Gateway', }; const messages: Record = { en, fr, de }; export const localeLabels: Record = { en: 'EN', fr: 'FR', de: 'DE', }; ``` -------------------------------- ### Gateway Protocol Message Types - TypeScript Source: https://github.com/marlburrow/pinchchat/blob/main/ARCHITECTURE.md Lists the key message types exchanged between PinchChat and the OpenClaw gateway over WebSocket. It categorizes messages into outbound (client to server) and inbound (server to client) and specifies where the protocol implementation resides. ```typescript PinchChat communicates with OpenClaw via a WebSocket protocol. Key message types: - **Outbound**: `auth`, `subscribe`, `send`, `listSessions`, `loadHistory`, `deleteSession` - **Inbound**: `authenticated`, `sessions`, `history`, `delta` (streaming tokens), `message` (complete), `error` The protocol is implemented in `src/lib/gateway.ts` (low-level) and `src/hooks/useGateway.ts` (React integration). ``` -------------------------------- ### Export Chat Conversations to Markdown Source: https://context7.com/marlburrow/pinchchat/llms.txt Provides methods to convert chat message arrays into formatted Markdown files. It supports complex message structures including thinking blocks and tool calls. ```typescript import { messagesToMarkdown, downloadFile } from './lib/exportChat'; import type { ChatMessage } from './types'; const messages: ChatMessage[] = [ { id: 'msg-1', role: 'user', content: 'Search for the latest news about AI', timestamp: Date.now(), blocks: [{ type: 'text', text: 'Search for the latest news about AI' }] } ]; const markdown = messagesToMarkdown(messages, 'AI Research Session'); downloadFile(markdown, 'chat-export.md', 'text/markdown'); function ExportButton({ messages, sessionKey }: { messages: ChatMessage[]; sessionKey: string }) { const handleExport = () => { const label = sessionKey.split(':').pop() || 'chat'; const md = messagesToMarkdown(messages, label); downloadFile(md, `${label}.md`); }; return ; } ``` -------------------------------- ### useGateway Hook Overview Source: https://context7.com/marlburrow/pinchchat/llms.txt The useGateway hook provides the primary interface for React components to interact with the OpenClaw gateway. It manages connection state, sessions, messages, and real-time streaming with automatic message caching and history persistence. ```APIDOC ## useGateway Hook The `useGateway` hook provides the primary interface for React components to interact with the OpenClaw gateway. It manages connection state, sessions, messages, and real-time streaming with automatic message caching and history persistence. ### Key Features: - Manages connection status (`status`, `authenticated`, `connectError`, `isConnecting`). - Handles session management (`sessions`, `activeSession`, `isSessionsLoaded`, `agents`, `agentIdentity`). - Processes messages (`messages`, `isGenerating`, `isLoadingHistory`). - Provides actions for interaction (`login`, `logout`, `sendMessage`, `abort`, `switchSession`, `createNewSession`, `createSessionForAgent`, `deleteSession`, `loadSessions`). - Offers advanced access to the client and event listeners (`getClient`, `addEventListener`). ### Example Usage: ```typescript import { useGateway } from './hooks/useGateway'; function ChatApp() { const { // Connection state status, authenticated, connectError, isConnecting, // Session management sessions, activeSession, isSessionsLoaded, agents, agentIdentity, // Messages messages, isGenerating, isLoadingHistory, // Actions login, logout, sendMessage, abort, switchSession, createNewSession, createSessionForAgent, deleteSession, loadSessions, // Advanced getClient, addEventListener, } = useGateway(); // Login to gateway const handleLogin = () => { login('ws://localhost:18789', 'my-token', 'token'); }; // Send a message with optional image attachments const handleSend = async () => { await sendMessage('What can you help me with?', [ { mimeType: 'image/jpeg', fileName: 'screenshot.jpg', content: 'base64-encoded-image-data...' } ]); }; // Switch to a different session const handleSessionSwitch = (sessionKey: string) => { switchSession(sessionKey); // e.g., 'agent:main:webchat-123' }; // Create a new session for a specific agent const handleNewAgentSession = async () => { await createSessionForAgent('researcher'); }; return (
{status === 'connected' && ( <> )}
); } ``` ``` -------------------------------- ### Define ChatMessage and MessageBlock Interfaces Source: https://context7.com/marlburrow/pinchchat/llms.txt Defines the core TypeScript interfaces for chat messages and the union types for message blocks, which support text, thinking, tool usage, and images. ```typescript interface ChatMessage { id: string; role: 'user' | 'assistant'; content: string; timestamp: number; blocks: MessageBlock[]; isStreaming?: boolean; runId?: string; isSystemEvent?: boolean; sendStatus?: 'sending' | 'sent' | 'error'; generationTimeMs?: number; metadata?: Record; } type MessageBlock = | { type: 'text'; text: string } | { type: 'thinking'; text: string } | { type: 'tool_use'; name: string; input: Record; id?: string } | { type: 'tool_result'; content: string; toolUseId?: string; name?: string } | { type: 'image'; mediaType: string; data?: string; url?: string }; ``` -------------------------------- ### ChatMessage Data Structure Source: https://context7.com/marlburrow/pinchchat/llms.txt Defines the structure of a chat message and its associated rich content blocks used within the PinchChat system. ```APIDOC ## ChatMessage Structure ### Description Represents a message object in the PinchChat system, containing metadata, role information, and an array of rich content blocks. ### Structure - **id** (string) - Unique identifier for the message. - **role** ('user' | 'assistant') - The sender of the message. - **content** (string) - Plain text representation of the message. - **blocks** (MessageBlock[]) - Array of rich content blocks (text, thinking, tool_use, tool_result, image). - **timestamp** (number) - Unix timestamp in milliseconds. ### MessageBlock Types - **text**: { type: 'text', text: string } - **thinking**: { type: 'thinking', text: string } - **tool_use**: { type: 'tool_use', name: string, input: Record, id?: string } - **tool_result**: { type: 'tool_result', content: string, toolUseId?: string, name?: string } - **image**: { type: 'image', mediaType: string, data?: string, url?: string } ``` -------------------------------- ### PinchChat Hero Section Styling - CSS Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html Styles the hero section of the PinchChat UI, including the main heading, tagline, and call-to-action buttons. It uses gradients for text and hover effects for buttons to create a dynamic visual appeal. ```css /* ─── Hero ─── */ .hero { text-align: center; padding: 4rem 0 2rem; } .hero-top { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 1rem; } .hero-logo { width: 72px; height: 72px; filter: drop-shadow(0 0 20px rgba(34, 211, 238, 0.3)); animation: float 4s ease-in-out infinite; } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } } .hero h1 { font-size: 3rem; font-weight: 800; letter-spacing: -0.02em; background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .hero .tagline { font-size: 1.15rem; color: var(--text-secondary); max-width: 600px; margin: 0 auto 1.5rem; } .buttons { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-bottom: 2rem; } .btn { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1.75rem; border-radius: 0.75rem; font-size: 1rem; font-weight: 600; text-decoration: none; transition: all 0.2s ease; } .btn-primary { background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple)); color: var(--bg-primary); } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 30px rgba(34, 211, 238, 0.3); } .btn-secondary { background: var(--bg-card); color: var(--text-primary); border: 1px solid var(--border); } .btn-secondary:hover { border-color: var(--accent-cyan); transform: translateY(-2px); } ``` -------------------------------- ### Implement Scroll Reveal for Feature Rows Source: https://github.com/marlburrow/pinchchat/blob/main/docs/index.html This JavaScript snippet uses the IntersectionObserver API to detect when feature rows enter the viewport and applies a 'visible' class to trigger animations. It is designed to enhance UI interactivity by revealing content as the user scrolls. ```javascript (function() { const rows = document.querySelectorAll('.feature-row'); const observer = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); observer.unobserve(e.target); } }); }, { threshold: 0.15 }); rows.forEach(r => observer.observe(r)); })(); ``` -------------------------------- ### Chat Export API Source: https://context7.com/marlburrow/pinchchat/llms.txt The export module converts chat message objects into formatted Markdown, preserving metadata, tool calls, and thinking blocks. ```APIDOC ## Chat Export API ### Description Utility functions to transform chat message arrays into Markdown strings and trigger browser-based file downloads. ### Methods - `messagesToMarkdown(messages: ChatMessage[], label: string)`: Converts an array of chat messages into a formatted Markdown string. - `downloadFile(content: string, filename: string, type: string)`: Triggers a browser download for the generated content. ### Parameters - **messages** (ChatMessage[]) - Required - Array of message objects containing role, content, and blocks. - **label** (string) - Required - Title for the exported Markdown document. ### Usage Example ```typescript import { messagesToMarkdown, downloadFile } from './lib/exportChat'; const markdown = messagesToMarkdown(messages, 'Chat Session'); downloadFile(markdown, 'export.md', 'text/markdown'); ``` ``` -------------------------------- ### Fix Textarea Horizontal Scrollbar Source: https://github.com/marlburrow/pinchchat/blob/main/FEEDBACK.md Prevents horizontal scrollbars in textareas by forcing overflow-x hidden and ensuring proper word wrapping. ```css textarea { overflow-x: hidden; resize: none; word-break: break-word; overflow-wrap: break-word; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.