@jean2/client
v1.0.6
Published
Jean2 AI Agent Client - Run the Jean2 web UI locally via npx
Readme
Jean2 Client
Cross-platform frontend for the Jean2 AI Agent. Connects to a Jean2 server over WebSocket and REST API for real-time AI chat sessions with tool execution, multi-workspace support, and multi-server management.
Three deployment targets:
- Web / PWA — Browser-based with offline support and installable as a PWA
- Electron Desktop — Native macOS and Windows application with multi-window support
- Web CLI — Run locally via
npx @jean2/client
Features
- Streaming chat with real-time message updates and token usage display
- Multi-model and multi-provider selection (budget/standard/premium tiers)
- Session management — create, close, reopen, rename, fork, compact, and revert
- Multi-server and multi-workspace support with quick switching
- Tool permission approval flow with grant scope options (once, session, workspace, always)
- File tree browser and file path autocomplete
- MCP (Model Context Protocol) server management
- Queued messages when a session is busy streaming
- Built-in remote terminal with multi-tab support and session reconnection
- Offline detection with exponential backoff auto-reconnect
- Dark and light themes (persists per platform)
- Responsive layout — works on desktop and mobile viewports
- Two view modes — Default (session list) and Overview (multi-workspace dashboard with Quick Switcher)
- PWA support — install to home screen on mobile and desktop
Prerequisites
Development
# Install dependencies (from repo root)
bun install
# Start Vite dev server (port 5173, proxies to server on port 3000)
bun run devThe Vite dev server proxies /api and /ws to http://localhost:3000.
Building
Web / PWA
bun run build
# Output: dist/CLI / npx
bun run build:npx
# Output: dist/cli.mjs (bundled Node.js server)Running via npx
npx @jean2/client
# Opens browser to http://localhost:3774
# Custom port
npx @jean2/client --port 8080The CLI bundles the built web assets and serves them with a static Node.js HTTP server.
Project Structure
packages/client/
src/
App.tsx Root component, WebSocket + REST state management
main.tsx Entry point, ThemeProvider wrapper
cli.ts npx CLI — static file server
index.css Tailwind v4, theme tokens, responsive utilities
components/
chat/ ChatView, MessageBubble, MessageInput, ToolCall, etc.
layout/ AppSidebar, QuickSwitcher, WorkspaceSwitcher, FilesPanel
modals/ SettingsDialog, MCPManagementDialog, AddServerDialog
visualizations/ CodeBlock, DiffViewer, TerminalOutput, TodoList, etc.
shared/ MarkdownRenderer, ThemeToggle, EmptyState, OfflineState
files/ FileTree, FileTreeNode, FileAutocomplete
providers/ ThemeProvider
ui/ shadcn/ui primitives (button, dialog, sidebar, etc.)
contexts/
ServerContext.tsx Multi-server state, quick connections
hooks/
useApi.ts Authenticated fetch helper
useFileSearch.ts File search utility
useLocalStorage.ts LocalStorage hook
use-mobile.ts Mobile viewport detection
config/
auth.ts Token validation, URL normalization
servers.ts Server CRUD in localStorage
lib/
utils.ts cn() and Tailwind merge
storage.ts Platform-agnostic storage (Electron store / localStorage)
path.ts Path utilities
utils/
diff.ts Diff parsing utilities
public/
favicon.ico Favicon
icon-192.png PWA icon (small)
icon-512.png PWA icon (large)
apple-touch-icon.png iOS home screen icon
components.json shadcn/ui configuration (radix-nova style)
vite.config.ts Vite — React, Tailwind, path aliases, dev proxy, PWA
package.npm.json Minimal manifest for npm publish (CLI mode)
VERSION Client versionTechnology Stack
| Layer | Technology | | ------------ | ------------------------------------------- | | Framework | React 19 | | Build | Vite 6, TypeScript | | Styling | Tailwind CSS v4, shadcn/ui, Radix UI | | Fonts | Geist Variable | | Icons | Lucide React | | Desktop | Electron — macOS, Windows | | Mobile | Web / PWA | | Markdown | react-markdown + remark-gfm | | Code blocks | prism-react-renderer | | Storage | localStorage (web) / Electron store (desktop) | | CLI | esbuild bundle, Node.js http module |
Architecture
The client connects to a Jean2 server via WebSocket (ws://host:port/ws?token=...) for real-time events and REST (http://host:port/api) for initial data loading. Authentication is optional — when the server has JEAN2_AUTH_TOKEN set, all requests require the bearer token. When not set, all requests pass through without authentication.
WebSocket protocol handles session CRUD, message streaming (including delta-based text append), part creation/updates, ask requests (permissions, questions, forms, client capabilities), permission responses, queue management, usage tracking, and compaction events. The App.tsx handler dispatches all ServerMessage types into React state.
Multi-server support allows connecting to multiple Jean2 server instances. Servers are persisted in localStorage. Switching servers clears all session state and reconnects.
Multi-workspace support isolates sessions by workspace. The active workspace is persisted and restored on reload.
Platform abstraction — the storage module (lib/storage.ts) transparently uses the Electron IPC store on desktop and falls back to localStorage on web/PWA. The Electron layer adds native-only features like multi-window (Cmd+N).
