docs: README + CLAUDE.md updated for v0.2/v0.3 (cockpit, tmux, hooks, toolbar)

This commit is contained in:
Yaojia Wang
2026-06-18 07:28:21 +02:00
parent 915a51e4bb
commit eb28a5593f
2 changed files with 36 additions and 7 deletions

View File

@@ -4,13 +4,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Status
**Planning stage — no code yet.** The `docs/` folder holds the authoritative spec; there is no `src/`, `public/`, or `package.json` yet. Read these before implementing:
**Built and working — v0.1 (core) + v0.2 (multi-tab) + v0.3 (Claude Code cockpit) shipped.** `src/` (TypeScript backend), `public/` (esbuild frontend), and tests all exist; 212 tests pass. v0.3 work happens on the `v0.3-cockpit` branch. Key docs:
- `docs/TECH_DOC.md` — design & rationale (the **why**). Authoritative for protocol (§4), session model (§5.2), security (§7), acceptance criteria (§8).
- `docs/ARCHITECTURE.md`development guide (the **how**). Module contracts at **function-signature level**, dependency rules, build order (§6 S1S8), and the invariant checklist (§8).
- `docs/PLAN.md` — the task plan. Dependency-ordered **waves W0W5**, fine-grained **tasks T1T21** for multi-agent parallelism (each task has `Owns:` / `Depends:`; per-task model & isolation in §4).
- `docs/PROGRESS_LOG.md` — the **memory file** (cross-session). Orchestrator-owned; subagents return their entry rather than writing it. See workflow below.
- `.claude/agents/` — project subagents: `module-builder` (TDD-implements one task), `module-reviewer` (read-only review).
- `docs/TECH_DOC.md` — design & rationale (the **why**). Protocol (§4), session model (§5.2), security (§7), acceptance (§8).
- `docs/ARCHITECTURE.md` — function-signature-level contracts, dependency rules, the **invariant checklist (§8)**. On conflict, ARCHITECTURE wins on *how*; the M*/L* anchors are cross-validated fixes.
- `docs/PROGRESS_LOG.md` — the **memory file** (cross-session). Read it first; it's the running record of what shipped (v0.1 T1T21, then v0.2/v0.3 feature entries). Orchestrator-owned.
- `docs/PLAN.md` (v0.1 task plan) and `~/.claude/plans/shimmering-wondering-island.md` (v0.3 cockpit plan).
- `.claude/agents/` — project subagents: `module-builder`, `module-reviewer` (for parallel dev).
**v0.3 additions** (cockpit): Claude Code **hooks → live status** per tab (`POST /hook`, `npm run setup-hooks`); **remote approve/reject** (held `POST /hook/permission`); **tmux keepalive** (`USE_TMUX`); plus FE: themes, search, dashboard, QR, PWA, new-tab-in-cwd. The server gained a hook side-channel but the terminal stream is still a byte-shuttle.
**Language decision: TypeScript (`.ts`), not `.js`** — ARCHITECTURE §0 records this divergence from TECH_DOC's original `.js` filenames. Wherever the two docs conflict, ARCHITECTURE wins on *how* (it was cross-validated and corrected); TECH_DOC wins on *why/scope*.
@@ -61,7 +63,7 @@ npm start # listens on 0.0.0.0:3000
npm test # unit tests (vitest, all modules)
```
Config is via env vars only (no hardcoding): `PORT`, `SHELL_PATH`, `BIND_HOST`, `IDLE_TTL`, `SCROLLBACK_BYTES`, `MAX_PAYLOAD_BYTES`, `ALLOWED_ORIGINS`. Note `allowedOrigins` is derived from the host's network-interface IPs (not from `BIND_HOST``0.0.0.0` is never a valid Origin); see ARCHITECTURE §3.1.
Config is via env vars only (no hardcoding): `PORT`, `SHELL_PATH`, `BIND_HOST`, `IDLE_TTL`, `SCROLLBACK_BYTES`, `MAX_PAYLOAD_BYTES`, `USE_TMUX` (1/0/auto), `ALLOWED_ORIGINS`. Note `allowedOrigins` is derived from the host's network-interface IPs (not from `BIND_HOST``0.0.0.0` is never a valid Origin); see ARCHITECTURE §3.1.
## Architecture (the parts that span files)

View File

@@ -6,6 +6,15 @@ Sessions survive disconnects: the shell (and whatever's running in it) keeps goi
> ⚠️ **This hands a full shell to anyone who can reach the port.** LAN-only, no authentication. **Never** port-forward or tunnel it to the public internet. See [Security](#security).
## Features
- **Multi-tab** — each tab is an independent shell session. Tabs auto-name to the current folder (double-click to rename), show a connection dot (🟢/🟡/🔴) and an unread-output dot, and can be drag-reordered. `+` opens a new tab in the active tab's directory.
- **Claude Code cockpit** (with hooks, see below) — each tab shows Claude's status (⚙ working / ⏳ needs approval / ✓ idle), sends a browser notification when it needs you, and lets you **tap Approve / Reject** on a tool request with no typing.
- **tmux keepalive** (optional) — run the shell inside tmux so sessions survive a server/host restart, not just a disconnect.
- **Mobile + desktop shortcut bar** — one-tap Esc / Esc·Esc / ⇧Tab / arrows / Enter / ^C / ^O / ^T / ^B / Tab / `/` (the Claude Code keys a phone keyboard can't produce).
- **Session keepalive + replay** — the PTY keeps running across disconnects; reconnect replays a ~2 MB scrollback ring buffer.
- **Toolbar** — 🔍 scrollback search · ⚙ themes & font size · ▦ all-sessions dashboard · 📱 QR connect (scan to open on another device). Clickable links. Installable as a PWA.
## Requirements
- Node.js ≥ 18 (developed on v24)
@@ -34,6 +43,23 @@ ipconfig getifaddr en0
For frontend development, run `npm run dev:web` (esbuild --watch) alongside `npm start`.
## Claude Code cockpit (optional)
To see Claude's status per tab and approve/reject tool calls from your phone, install the hooks once:
```bash
npm run setup-hooks # adds http hooks to ~/.claude/settings.json (backs it up)
# npm run setup-hooks -- --remove # to uninstall
```
Then run `claude` inside a tab. The hooks POST to the server (loopback only) when Claude starts/stops/needs permission; the tab badge updates live, and a `PermissionRequest` shows an **Approve / Reject** bar. The hooks are a no-op outside web-terminal (they curl `$WEBTERM_HOOK_URL`, which is only set in spawned shells), so they're safe to leave installed.
**tmux keepalive** — run with `USE_TMUX=1` (or just have `tmux` on PATH; it auto-detects) to keep sessions alive across a server restart:
```bash
USE_TMUX=1 npm start
```
## Configuration
All via environment variables (no hardcoding):
@@ -46,6 +72,7 @@ All via environment variables (no hardcoding):
| `IDLE_TTL` | `86400` (s) | reclaim a detached session after this idle time |
| `SCROLLBACK_BYTES` | `2097152` | per-session replay ring buffer (bytes) |
| `MAX_PAYLOAD_BYTES` | `1048576` | max single WS frame |
| `USE_TMUX` | `auto` | `1`/`0`/`auto` — run the shell inside tmux (keepalive across restart); `auto` = on if `tmux` is on PATH |
| `ALLOWED_ORIGINS` | (derived) | extra allowed WS origins, comma-separated |
`allowedOrigins` is **derived from the host's network-interface IPs** (plus `localhost` and anything in `ALLOWED_ORIGINS`) — never from `BIND_HOST`, since `0.0.0.0` is never a real browser Origin.