2026-06-24 09:54:11 +08:00
2026-03-18 04:03:54 +00:00

CC-Web

A lightweight browser interface for Claude Code and Codex, designed to keep each agent close to its native CLI workflow while sharing the same web shell.

Node.js License

Screenshots

Screenshot 1 Screenshot 2 Screenshot 3

Features

  • Lightweight runtime: low backend overhead, browser-based control panel.
  • Dual-agent sessions: create Claude or Codex sessions on the same backend core.
  • Agent-isolated views: switching Claude / Codex only shows that agent's sessions, recent state, settings, and import entry points.
  • Agent-specific settings: Claude keeps template-based model config; Codex has its own path, default model, mode, and search settings.
  • Multi-session management: create, switch, rename, and delete sessions; deleting a session also removes the local Claude history record.
  • Local history import: import Claude history from ~/.claude/projects/ and Codex rollout history from ~/.codex/sessions/.
  • Session resume: context continuity via --resume; you can also reattach via SSH + tmux attach -t claude when needed.
  • Background task support: Claude processes continue after browser disconnect and notify you on completion.
  • Multi-channel notifications: PushPlus / Telegram / ServerChan / Feishu bot / QQ (Qmsg), configurable in Web UI.
  • Process persistence: detached subprocess + PID files; running tasks survive service restarts.
  • Multi-API switching: configure multiple API profiles and switch between them instantly from the UI.
  • Password-based auth: initial password generation, forced first-login reset, and password change in Web UI.

Requirements

  • Node.js >= 18
  • Claude Code CLI and/or Codex CLI installed and configured
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex

Quick Start

Linux / macOS

git clone https://github.com/ZgDaniel/cc-web.git
cd cc-web
npm install
cp .env.example .env    # optional; if omitted, an initial password is auto-generated
npm start

Windows

git clone https://github.com/ZgDaniel/cc-web.git
cd cc-web
npm install
copy .env.example .env  & REM optional

Then run start.bat, or start manually with node server.js.

After startup, open http://localhost:8002 and sign in with your password.

Configuration

Environment Variables (.env)

Variable Required Default Description
CC_WEB_PASSWORD No Auto-generated Web login password (migrated into config/auth.json on first start)
PORT No 8002 Service port
CLAUDE_PATH No claude Executable path to Claude CLI
CODEX_PATH No codex Executable path to Codex CLI
PUSHPLUS_TOKEN No - PushPlus token (migrated into notification config on first start)

Notification Configuration

Open the Settings (⚙) button in the sidebar to configure notifications in Web UI.

Channel Required Fields How to Get
PushPlus Token Register at pushplus.plus
Telegram Bot Token + Chat ID Create bot via @BotFather
ServerChan SendKey Register at sct.ftqq.com
Feishu Bot Webhook URL Feishu group → Settings → Group Bot
QQ (Qmsg) Qmsg Key Obtain from qmsg.zendee.cn

Settings are stored in config/notify.json. Tokens are masked in UI display.

Password Management

Passwords are stored in config/auth.json and support generation + UI updates:

  • First startup (no password in .env and no auth.json): auto-generates a random 12-character password, prints it to console, and requires password reset on first login.
  • Migration from .env: if CC_WEB_PASSWORD is already set, it is migrated to auth.json automatically at startup.
  • Change password in UI: Settings panel → Change Password (requires current password).
  • Password policy: at least 8 characters, with at least 2 of these categories: uppercase, lowercase, number, special character.
  • After password change: all existing logged-in sessions are invalidated.

Project Structure

cc-web/
├── server.js              # Node.js backend (HTTP + WebSocket + process management + notifications)
├── public/
│   ├── index.html          # UI structure
│   ├── app.js              # Frontend logic (WebSocket, UI interactions)
│   ├── style.css           # Styles
│   └── sw.js               # Service Worker (mobile notifications)
├── config/
│   ├── notify.json         # Notification channel config (generated at runtime)
│   └── auth.json           # Auth config (generated at runtime)
├── sessions/               # Chat history JSON files (generated at runtime)
├── logs/                   # Process lifecycle logs (generated at runtime)
├── lib/                    # Agent runtime + Codex rollout parsing helpers
├── scripts/                # Regression tooling + mock CLIs
├── .env.example            # Environment variable template
├── start.bat               # Windows startup script
├── .gitignore
├── package.json
└── README.md

Architecture

Process Model

Browser ←WebSocket→ Node.js (server.js) ←file I/O→ Claude / Codex CLI (detached)
  • Each user message spawns either a Claude or Codex subprocess depending on the session agent.
  • Subprocesses use detached: true + proc.unref() and run independently from Node.js lifecycle.
  • stdin/stdout/stderr are bridged via files in sessions/{id}-run/.
  • PID is persisted to disk and recovered after service restart (recoverProcesses()).
  • FileTailer streams file updates to frontend in real time.

Background Task Flow

  1. User sends a message → spawn Claude subprocess.
  2. User closes browser → subprocess keeps running.
  3. Process completes → PID monitor detects exit.
  4. Completion notification is sent.
  5. User reconnects → completed response is synced.

Process Logs

logs/process.log uses JSONL format with automatic 2MB rotation.

Event Description
process_spawn Process created (PID, mode, model)
process_complete Process finished (exit code, duration, cost)
ws_connect / ws_disconnect Client connected/disconnected
ws_resume_attach Client reconnected to running process
recovery_alive / recovery_dead Process recovery during service restart
heartbeat Active process snapshot every 60 seconds

View logs:

tail -f logs/process.log | jq .

Production Deployment

systemd Service

Create /etc/systemd/system/cc-web.service:

[Unit]
Description=CC-Web - Claude Code Web Chat UI
After=network.target

[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/cc-web
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
# Important: only stop Node.js process, not Claude child processes
KillMode=process

[Install]
WantedBy=multi-user.target

KillMode=process is important. It ensures systemd restart only stops Node.js, while Claude subprocesses continue and are reattached after recovery.

sudo systemctl enable cc-web
sudo systemctl start cc-web

Nginx Reverse Proxy

server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8002;
        proxy_http_version 1.1;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # Long-running tasks may take time
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

Windows Deployment

Use this mode when running CC-Web on a personal PC and controlling Claude / Codex from mobile.

Start with start.bat, or run manually:

cd cc-web
npm install
node server.js

LAN access (same Wi-Fi):

  • Open http://<your-lan-ip>:8002

Remote access:

Release Notes

  • v1.2.10

    • Implemented /init behavior aligned with native Claude Code and Codex CLI
  • v1.2.8

    • Dual-agent (Codex): create Claude or Codex sessions on the same backend; agent-isolated sidebar, settings, and import
    • Image upload: drag, paste, or attach images in both Claude and Codex sessions; client-side WebP compression, 7-day server cache, up to 4 images per message
    • Session loading: loading overlay, hot session cache (4 slots, strong/weak hit), fix for streaming content disappearing on tab switch
    • Theme system: full theme engine with CoolVibe Light, washi, and editorial variants; theme picker moved to sub-page
    • Mobile UX: swipe-to-open/close sidebar, running-state badge replaces cwd label, button sizing fixes
    • Backend refactor: spawn spec + event parsing extracted to lib/agent-runtime.js; isolated regression script npm run regression
  • v1.2.2

    • Aligned context compression with Claude Code native behavior: /compact is now actually sent to CLI instead of doing a local pseudo-reset.
    • Added automatic overflow recovery: when Request too large (max 20MB) occurs, CC-Web runs /compact and replays the failed prompt automatically.
    • Added retry guard: if context is still too large after compacting, CC-Web stops auto-retry and asks for a narrower prompt range.
  • v1.2.1

    • Fixed missing AskUserQuestion options in Web UI by preserving structured tool input in backend and rendering question/option cards on frontend.
    • Added option-to-input shortcut: click an option to append it into the input box for quick confirmation.
  • v1.2

    • Fixed layout overflow caused by long code blocks in messages. The page no longer stretches horizontally; code blocks scroll within the block.
    • Improved mobile input behavior: Enter inserts newline by default, and sending is done via the send button.
  • v1.1

    • Added compatibility improvements for Claude Code CLI on Windows.

Notes

  • Claude support is still the more mature path, while Codex now supports isolated sessions, resume, import, background execution, and local cleanup.
Description
No description provided
Readme 420 MiB
Languages
JavaScript 51.7%
HTML 19.8%
Python 16.1%
CSS 8.6%
Shell 2.6%
Other 1.2%