Codeman is a self-hosted mission control for AI coding agents. It spawns Claude Code, OpenCode, Codex, Antigravity, Gemini, or Pi inside persistent tmux sessions, streams the real terminal to any browser, and keeps agents productive after you walk away: it re-prompts on idle, resumes when a usage limit resets, runs scheduled jobs, and shows every background agent working in real time.
Get started in one line (macOS & Linux, Windows via WSL):
curl -fsSL https://getcodeman.com/install | bash
codeman web
# Open http://localhost:3000 and start your first session
The installer asks before every system change, and re-running the same line updates in place. Full details: Quick Start - Installation.
- One dashboard, six CLIs - run Claude Code, OpenCode, Codex, Antigravity, Gemini, or Pi per session (plus plain shell), locally, in Docker, or over SSH
- Truly phone-friendly - a touch-optimized terminal with instant local echo, QR login, swipe navigation, and push notifications
- Runs while you sleep - idle detection + respawn cycling and auto-resume when a subscription limit resets, for 24+ hour unattended runs
- See your agents think - live floating windows for every subagent and teammate, with real-time transcripts
- Nothing gets lost - tmux persistence across restarts and network drops, exactly-once input delivery, full-scrollback replay
- Self-hosted and private - loopback-only by default, MIT licensed, no telemetry, runs entirely on your machine
Quick Start - Installation
curl -fsSL https://getcodeman.com/install | bash
This installs Node.js and tmux if missing, clones Codeman to ~/.codeman/app, and builds it. A few things worth knowing:
- It asks first. Every system change (package installs, AI CLI download) is prompted, and a menu at the end lets you choose: run Codeman in this terminal, install it as a background service (systemd/launchd, auto-start on boot), or don't start yet. Nothing runs in the background unless you pick it.
- Network or local-only, your choice. The installer asks whether the dashboard should be reachable from other devices on your network (
0.0.0.0, the default, with a strongly recommended password prompt) or from this machine only (127.0.0.1, safest). Skipping the password on a network bind requires an explicit confirmation and ends with a loud warning. A barecodeman webstarted by hand still defaults to loopback. - Re-run to update. The same one-liner updates a finished install in place: local changes in
~/.codeman/appare stashed (never discarded), and a running service is restarted and verified. If a first install was interrupted, re-running resumes the full setup instead.install.sh updateandinstall.sh uninstallalso exist. - CI / headless: without a terminal attached, steps that would change your system abort with instructions instead of running silently. Set
CODEMAN_NONINTERACTIVE=1to approve them for automation.
You'll need at least one AI coding CLI installed — Claude Code, OpenCode, Codex, Antigravity, Gemini CLI, or Pi (any combination works; Gemini CLI is enterprise-only since Google's consumer cutover, and Antigravity is its successor). The installer detects whichever of the six is present; if none is found, it offers to install Claude Code or OpenCode, or you can skip and install one yourself later. After install:
codeman web
# Open http://localhost:3000 and start your first session
Sharing with a small team? Start it in multi-user mode instead: each person gets their own login and workspace.
codeman users add alice --admin # create the first admin account
codeman web --multiuser # named logins + per-user case spaces
Details in Multi-User Mode below.
To outlive the shell you started it in, without setting anything up:
codeman web -d # detach; logs to ~/.codeman/web.log
codeman web --status # is it up, and on which pid
codeman web --stop # graceful SIGTERM; agents keep running in tmux
-d waits until the server actually answers before reporting success, and refuses to start a second one on the same data dir (two servers sharing a tmux socket attach to each other's sessions).
To have it come back after a reboot, install it as a service instead. The installer's final menu does this for you (option 2); codeman service is the equivalent for an npm i -g aicodeman install:
codeman service install # systemd user unit (Linux) or LaunchAgent (macOS)
codeman service status
codeman service uninstall
service install writes the unit with your current PATH baked in, which matters more than it sounds: launchd hands a job /usr/bin:/bin:/usr/sbin:/sbin, so a Homebrew or nvm node, tmux or claude is invisible to a hand-written plist. It never copies CODEMAN_PASSWORD into the unit file; add that yourself if the service needs auth.
To write the unit by hand instead:
Linux (systemd):
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/codeman-web.service << EOF
[Unit]
Description=Codeman Web Server
After=network.target
[Service]
Type=simple
ExecStart=$(which node) $HOME/.codeman/app/dist/index.js web
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now codeman-web
loginctl enable-linger $USER
macOS (launchd):
mkdir -p ~/Library/LaunchAgents
cat > ~/Library/LaunchAgents/com.codeman.web.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.codeman.web</string>
<key>ProgramArguments</key>
<array>
<string>$(which node)</string>
<string>$HOME/.codeman/app/dist/index.js</string>
<string>web</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key>
<string>/tmp/codeman.log</string>
<key>StandardErrorPath</key>
<string>/tmp/codeman.log</string>
</dict>
</plist>
EOF
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.codeman.web.plist
wsl bash -c "curl -fsSL https://getcodeman.com/install | bash"
Codeman requires tmux, so Windows users need WSL. If you don't have WSL yet: run wsl --install in an admin PowerShell, reboot, open Ubuntu, then install your preferred AI coding CLI inside WSL (Claude Code, OpenCode, Codex, Antigravity, Gemini CLI, or Pi). After installing, http://localhost:3000 is accessible from your Windows browser.
Mobile-Optimized Web UI
The most responsive AI coding agent experience on any phone. Full xterm.js terminal with local echo, swipe navigation, and a touch-optimized interface designed for real remote work — not a desktop UI crammed onto a small screen.
- Keyboard accessory bar —
/init,/clear,/compactquick-action buttons above the virtual keyboard; destructive commands require a double-press to confirm, so you never fire one by accident - Dedicated Enter button — replays the keypress through the terminal, so text buffered by local echo is flushed first rather than stranded
- Swipe navigation & smart keyboard handling — swipe left/right to switch sessions; toolbar and terminal shift up when the keyboard opens (
visualViewportAPI) - Built for phones — safe-area insets for notch and home indicator, 44px touch targets, bottom-sheet case picker, native momentum scrolling
codeman web --https
# Open on your phone: https://<your-ip>:3000
localhostworks over plain HTTP. Use--httpswhen accessing from another device, or use Tailscale (recommended): the installer can set it up for you (choose Tailscale at the network-access prompt, or runbash ~/.codeman/app/install.sh tailscaleon an existing install). That gives youhttps://<your-machine>.<tailnet>.ts.netwith a real certificate: private to your tailnet, no password required, and PWA install + push notifications work on your phone.
Secure QR Code Authentication
Typing passwords on a phone keyboard is miserable. Codeman replaces it with cryptographically secure single-use QR tokens — scan the code displayed on your desktop and your phone is authenticated instantly.
Each QR encodes a URL containing a 6-character short code that maps to a 256-bit secret (crypto.randomBytes(32)) on the server. Tokens auto-rotate every 60 seconds, are atomically consumed on first scan (replays always fail), and use hash-based Map.get() lookup that leaks nothing through response timing. The short code is an opaque pointer — the real secret never appears in browser history, Referer headers, or Cloudflare edge logs.
The security design addresses all 6 critical QR auth flaws identified in "Demystifying the (In)Security of QR Code-based Login" (USENIX Security 2025, which found 47 of the top-100 websites vulnerable): single-use enforcement, short TTL, cryptographic randomness, server-side generation, real-time desktop notification on scan (QRLjacking detection), and IP + User-Agent session binding with manual revocation. Dual-layer rate limiting (per-IP + global) makes brute force infeasible across 62^6 = 56.8 billion possible codes. Full security analysis: docs/qr-auth-plan.md
Using Codeman — A Human's Guide
A start-to-finish walkthrough for driving Codeman from the browser. If you just installed, this is where to begin.
1. Launch the server
codeman web # localhost:3000 (loopback only — safe default)
codeman web --port 8080 # custom port (or set CODEMAN_PORT)
codeman web --https # self-signed TLS (only needed for remote access)
codeman web -H 0.0.0.0 # bind LAN — REQUIRES CODEMAN_PASSWORD (see Security)
codeman web -d # detach: survives closing the shell (--status, --stop)
codeman service install # systemd/launchd service: comes back after reboots
Open the printed URL. The page is a single dashboard; everything below happens there.
2. Create your first session
Click + New Session (or Quick Start). A session is one AI CLI running in its own tmux-backed terminal. You choose:
| Field | What it does |
|---|---|
| Working directory / case | The folder the agent operates in. A "case" is just a named working dir Codeman remembers. Add Case creates one from scratch, links an existing folder, or clones a GitHub repo straight into one (Clone Repo). |
| CLI / run mode | Claude (default), OpenCode, Codex, Antigravity, Gemini, Pi, or Terminal (plain shell). |
| Model | Per-session model (App Settings → Models → New Claude sessions). A soft default — /model still works in-session. |
| Effort / Ultracode | Reasoning effort (low–max) or ultracode for dynamic multi-agent workflows. Switchable anytime with /effort. |
Hit start — Codeman spawns the CLI via a real PTY and streams it to your browser over SSE.
3. Read the dashboard
- Tabs (top) — one per session.
Alt+1-9to jump,Ctrl+Tabfor next, drag to reorder (tab order syncs across your devices). - Terminal (center) — a real
xterm.jsterminal; full TUIs render correctly. Type directly and press Enter to send.Shift+Enterinserts a newline. - Side panels — Respawn, Orchestrator, Cron, Subagents, Settings (toggled from the toolbar).
4. Talk to the agent
- Type prompts straight into the terminal — input is delivered exactly-once even across reconnects (a dropped link never loses or double-sends a prompt).
- Paste or drag-and-drop images directly into the session.
- Voice input —
Ctrl+Shift+V(Deepgram Nova-3, with auto-silence stop). - Attachments — register external files/docs and preview Office/PDF inline.
5. Make it autonomous
| Mode | Use it for | Where |
|---|---|---|
| Respawn | Long unattended runs — auto-restarts the CLI on idle/limit, with adaptive timing. Presets: solo-work, overnight-autonomous, … |
Respawn tab |
| Orchestrator | Turn one goal into a phased plan and drive it to completion across agents. | Orchestrator panel |
| Cron | Saved, named jobs on a schedule (once/interval/daily/weekly) that spawn a session and send a prompt when due. |
⏰ Cron button (opt-in: App Settings → Header & Panels → Scheduling) |
| Auto-resume | Automatically continue after a subscription rate-limit resets. | Respawn tab (top) |
6. Reach it from anywhere
- Phone/tablet — the UI is fully touch-optimized; scan the desktop QR code to log in without typing a password.
- Outside your network —
./scripts/tunnel.sh startopens a Cloudflare tunnel (setCODEMAN_PASSWORDfirst). - SSH — the
scchooser attaches to any session from a terminal (scinteractive,sc 2quick-attach,sc -llist).
7. Operate & maintain
- App Settings — model, effort, permission startup mode, theme/skin, notifications, display toggles, per-CLI options, a synced custom display name, and per-device English/Simplified Chinese UI language.
- Run it in the background —
codeman web -ddetaches from your shell (--status,--stop);codeman service installmakes it a systemd user unit / macOS LaunchAgent that survives reboots. Both verify the server actually answers before reporting success, and both refuse to start a second server on one data dir. See Keep it running in the background. - Self-update — git-clone installs update in place from App Settings → System → Updates.
- Deploy your own changes — see Development.
⚠️ Safety: if you're working inside a Codeman-managed session (
echo $CODEMAN_MUX→1), never runtmux kill-session/pkill claudedirectly — use the web UI or./scripts/tmux-manager.sh.
Zero-Lag Input Overlay
When accessing your coding agent remotely (VPN, Tailscale, SSH tunnel), every keystroke normally takes 200-300ms to round-trip. Codeman implements a Mosh-inspired local echo system that makes typing feel instant regardless of latency.
A pixel-perfect DOM overlay inside xterm.js renders keystrokes at 0ms. Background forwarding silently sends every character to the PTY in 50ms debounced batches, so Tab completion, Ctrl+R history search, and all shell features work normally. When the server echo arrives 200-300ms later, the overlay seamlessly disappears and the real terminal text takes over — the transition is invisible.
- Ink-proof architecture — lives as a
<span>at z-index 7 inside.xterm-screen, completely immune to Ink's constant screen redraws (two previous attempts usingterminal.write()failed because Ink corrupts injected buffer content) - Font-matched rendering — reads
fontFamily,fontSize,fontWeight, andletterSpacingfrom xterm.js computed styles so overlay text is visually indistinguishable from real terminal output - Full editing — backspace, retype, paste (multi-char), cursor tracking, multi-line wrap when input exceeds terminal width
- Persistent across reconnects — unsent input survives page reloads via localStorage
- Enabled by default — works on both desktop and mobile, during idle and busy sessions
Extracted as a standalone library:
xterm-zerolag-input— see Published Packages.
Live Agent Visualization
Watch background agents work in real-time. Codeman monitors agent activity and displays each agent in a draggable floating window with animated Matrix-style connection lines back to the parent session.
- Floating terminal windows — draggable, resizable panels for each agent with a live activity log showing every tool call, file read, and progress update as it happens
- Connection lines — animated green lines linking parent sessions to their child agents, updating in real-time as agents spawn and complete
- Status & model badges — green (active), yellow (idle), blue (completed) indicators with Haiku/Sonnet/Opus model color coding
- Auto-behavior — windows auto-open on spawn, auto-minimize on completion, tab badge shows "AGENT" or "AGENTS (n)" count
- Nested agents — supports 3-level hierarchies (lead session -> teammate agents -> sub-subagents)
Multi-agent Workflow runs ("ultracode") get the same treatment: a floating run window tracks the whole workflow live, with phases, per-agent token counts, and the current tool of every agent:
Agent Teams — first-class support for Claude Code's native multi-agent teams (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1). TeamWatcher polls ~/.claude/teams/, matches teammates to their lead session, and surfaces them as live subagent windows with team-aware idle detection — so the Respawn Controller won't fire while teammates are still working. See docs/agent-teams/.
Respawn Controller
The core of autonomous work. When the agent goes idle, the Respawn Controller detects it, sends a continue prompt, cycles context management commands for fresh context, and resumes — running 24+ hours completely unattended.
WATCHING → IDLE DETECTED → SEND UPDATE → /clear → /init → CONTINUE → WATCHING
- Multi-layer idle detection — completion messages, AI-powered idle check, output silence, token stability
- Auto-resume on usage limit (opt-in, off by default) — when Claude halts on a subscription limit ("You've hit your limit · resets 3pm"), Codeman parses the reset time, waits it out plus a 2-minute safety buffer, then dismisses the rate-limit dialog and sends
continue— so an overnight run survives the 5-hour window instead of stalling until morning. Recognizes every Claude Code limit-message format, retries if still limited, survives Codeman restarts, and holds respawn cycles while paused so/clearcan't wipe the waiting conversation. Enable per session at the top of the Respawn tab - Circuit breaker — prevents respawn thrashing when Claude is stuck (CLOSED -> HALF_OPEN -> OPEN states, tracks consecutive no-progress and repeated errors)
- Health scoring — 0-100 health score with component scores for cycle success, circuit breaker state, iteration progress, and stuck recovery
- Built-in presets —
solo-work(3s idle, 60min),subagent-workflow(45s, 240min),team-lead(90s, 480min),ralph-todo(8s, 480min),overnight-autonomous(10s, 480min)
Orchestrator Loop
Beyond single-session respawn, the Orchestrator turns a high-level goal into a phased plan and drives it to completion across multiple agents — a state machine that runs idle → planning → approval → executing → verifying → (replanning) → completed.
- Plan, then execute — generates a phased plan from your goal and pauses for approval before touching anything; reject with feedback to regenerate
- Per-phase verification gates — each phase is verified before the next begins; on failure the orchestrator replans instead of barreling ahead
- Multi-agent execution — fans phases out to team agents / a task queue, coordinating work too big for one session
- Crash-safe — full state persists under the
orchestratorkey instate.json, so it survives restarts - Driven from the UI or API — the Orchestrator panel, or
POST /api/orchestrator/start→/approve→/status(10 endpoints)
Full design:
docs/orchestrator-loop-architecture.md.
Multi-Session Dashboard
Run 20 parallel sessions with full visibility — real-time xterm.js terminals at 60fps, per-session token and cost tracking, tab-based navigation, and one-click management.
Persistent Sessions
Every session runs inside tmux — sessions survive server restarts, network drops, and machine sleep. Auto-recovery on startup with dual redundancy. Ghost session discovery finds orphaned tmux sessions. Managed sessions are environment-tagged so the agent won't kill its own session.
Session Manager & Command Palette
Ctrl/Cmd/Alt+K opens a fuzzy session palette; Browse all sessions opens the Session Manager: one deduped list of everything Codeman knows about (live sessions, past sessions from state and lifecycle history, and Claude transcripts), each row showing its first and most recent prompt.
- Pinning: pin a session to float it to the top of the list. Pinned sessions even survive kill (they demote to a lightweight stopped entry that stays visible and resumable).
- Name retention: resuming a past session keeps its original name instead of minting a new one.
- Cross-device tab order: drag-reordered tabs persist server-side, so your ordering follows you from desktop to phone.
Hostname-Aware Window Title
Running Codeman on multiple hosts (laptop, dev box, NAS)? The browser tab title is codeman:<hostname> so you can tell which backend each tab points at without clicking in:
codeman web # codeman:<os.hostname()>
codeman web --title-hostname dev-box # codeman:dev-box (manual override for noisy hostnames)
The title is templated into the served HTML on first byte, so it's correct from the very first paint and works without JavaScript. The same hostname prefix is applied to the tab-flash format (⚠️ (N) codeman:<host>) and to OS-level desktop notifications (codeman:<host>: <event>), so cross-host alerts in the system notification center are also unambiguous.
Smart Token Management
| Threshold | Action | Result |
|---|---|---|
| 110k tokens | Auto /compact |
Context summarized, work continues |
| 140k tokens | Auto /clear |
Fresh start with /init |
Tab Alerts
Every tab tells you its state at a glance. A running session keeps its green status dot. When a session stops and waits for input, its tab turns yellow: steady ring, tinted background, yellow dot, with a slow breathing glow on top. When a permission prompt or question is blocking the agent, the tab turns red with a faster pulse. The base tint never blinks off, so even a split-second glance (or a screenshot) reads the true state; the ring stays visible while the tab is selected, and a page reload re-arms pending alerts from the server, so a blocked session can never hide behind a fresh-looking tab.
Notifications
Real-time desktop alerts when sessions need attention — permission_prompt and elicitation_dialog trigger critical red tab blinks, idle_prompt triggers yellow blinks. Click any notification to jump directly to the affected session. Hooks auto-configured per case directory.
Run Summary
Click the chart icon on any session tab to see a timeline of everything that happened — respawn cycles, token milestones, auto-compact triggers, idle/working transitions, hook events, errors, and more.
Zero-Flicker Terminal
Terminal-based AI agents (Claude Code's Ink, OpenCode's Bubble Tea) redraw the screen on every state change. Codeman implements a 6-layer anti-flicker pipeline for smooth 60fps output across all sessions:
PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xterm.js (60fps)
More Features
- Background daemon & service install —
codeman web -druns the server detached with a pidfile,~/.codeman/web.log, and verified startup (it polls the server until it answers, so a port clash never reads as success);codeman service installwrites a systemd user unit (Linux) or LaunchAgent (macOS) with your shell's PATH baked in, so an nvm or Homebrewnode,tmuxandclaudeare actually found. Secrets are never written into unit files - Self-update — git-clone installs under systemd/launchd update in place from App Settings → System → Updates: it detects the latest release, auto-stashes a dirty tree, and streams build progress across the service restart (npm installs report as non-updatable)
- Clone a GitHub repo as a case — paste a repository URL into Add Case → Clone Repo and Codeman clones it into
~/codeman-cases/<name>and registers it as a normal case, ready to run an agent in. It preflights the URL while you type (tells you whether it can be cloned anonymously and offers the repo's real branches and tags for the optional branch/tag field), fills the case name in from the URL, and lets you pick which CLI the Run button should use. Public repositories overhttps://; Codeman never collects or stores credentials - Multi-CLI — run Claude Code, OpenCode, Codex, Antigravity, Gemini, or Pi per session; env-var prefixes auto-gate (
CLAUDE_CODE_*vsOPENCODE_*vsCODEX_*vsANTIGRAVITY_*vsGEMINI_*/GOOGLE_*vsPI_*). Seedocs/opencode-integration.mdanddocs/pi-integration.md - Docker sessions — run a case inside an isolated, hardened container. One checkbox on Create New spins up a container with sensible defaults and starts the agent inside it; multiple sessions share one per-case container; export a container + its workspace to a portable
.tar.gzto move it to another machine. Seedocs/docker-cases.md - Remote SSH sessions — point a case at another machine and run the agent there inside a durable remote tmux: survives SSH drops, auto-reconnects, and can discover + attach sessions already running on the host. See
docs/remote-sessions.md - Effort & Ultracode — set a per-session default effort (
low–max) or enable ultracode (dynamic multi-agent workflows). Soft defaults only — switchable anytime with/effortin-session. Extended-thinking budget is configurable too - Voice input — dictate prompts with Deepgram Nova-3 (Web Speech API fallback): toggle recording, auto-silence stop, live level meter (
Ctrl+Shift+V) - Image input — paste or drag-and-drop images straight into a session
- Gesture control (opt-in) — a MediaPipe hand-tracking overlay to grab/drag session windows and pinch buttons, hands-free. Enable with
CODEMAN_GESTURE=1+ App Settings → Terminal & Input - Multi-monitor span (macOS) — one click opens a browser window maximized across all displays, so floating agent/gesture panels can cross the physical seam
- File Viewer button (opt-in) — a header button that toggles the built-in file browser panel with one tap; enable under App Settings → Header & Panels → Header buttons
- CJK / IME input — full composition support for Chinese / Japanese / Korean
- OS notifications & hostname-aware titles — desktop alerts and tab titles are prefixed
codeman:<host>so multi-host setups stay unambiguous
Isolated Docker Sessions
Run a case inside its own hardened Docker container instead of directly on your host — for security isolation, reproducible toolchains, and one-click portability.
- One click — on New Case → Create New, tick 🐳 Run in an isolated Docker container. Codeman creates the case folder, spins up a container with default settings, and starts the agent inside it. No host/image/network fields to fill in.
- Resource templates — expand the checkbox for a Small / Medium / Large / GPU preset (memory, CPUs, GPU), or set your own. Disk is elastic — storage grows as data flows in, no fixed cap.
- Shared per-case container — many sessions can
docker execinto the same container; killing one session never tears the container out from under the others. - Hardened by default — non-root,
--cap-drop ALL,no-new-privileges, PID/memory caps, never--privilegedor the docker socket; a sealed profile (no host credentials, network off) is one toggle away. - Seamless auth, isolated credentials — your host Claude / Codex / Antigravity / Gemini / OpenCode / Pi logins work inside the container out of the box: credentials are seeded (copied) in at launch and onboarding/trust prompts are pre-answered, so no login wizard appears. The container keeps its own copies and never writes back to your host credential stores; only conversation transcripts are shared, and exports never capture secrets.
- Move it to another machine — export a container's whole environment (toolchain + workspace) to a portable
.tar.gz,docker loadit on the other side, and import it into a fresh case. - Durable — reconnect after a restart lands back in the same live agent; a container stop/reboot resumes the conversation from the bind-mounted transcript.
Prerequisite: just Docker (or Podman). The agent base image builds itself automatically on first use, with progress streamed to the UI (or pre-build it with node scripts/build-agent-image.mjs). Full guide: docs/docker-cases.md.
Remote SSH Sessions
Point a case at another machine and run the agent there, over SSH, with the same dashboard, mobile UI, and autonomy features. Your laptop is just a window onto a session that lives on the remote host.
- Durable by design: the agent runs inside a dedicated tmux session on the remote host, so a dropped SSH connection, network change, or laptop sleep never kills the run. Reconnecting lands back in the same live conversation.
- Auto-reconnect: a bounded-backoff watcher notices a dead SSH pane and silently reattaches to the still-running remote session (kill-switch in settings; intentional kills are never revived).
- Discover & attach: list the
codeman-*sessions already running on a host (started by that machine's own Codeman, or by another operator) and attach to one. Attached sessions you don't own detach on tab close, never kill. - Shared sessions: several clients can attach the same remote session at different window sizes without clamping each other; discovery shows a "shared" badge with the client count.
- Injection-safe: every ssh command line flows through a single shell-escaping builder, and host/path/identity fields are schema-guarded.
Set it up under New Case → Remote (host, user, identity file, optional jump host). Full design: docs/remote-sessions.md.
Multi-User Mode (opt-in)
Share one Codeman with a small trusted team, each person getting their own login and workspace. Off by default — without the flag, nothing changes.
Enable with codeman web --multiuser (or CODEMAN_MULTIUSER=1). Create the first admin, then manage users from the CLI or the Users tab in App Settings:
codeman users add alice --admin # prompts for a password (or --password-stdin)
codeman users add bob # a regular user
codeman users list
- Per-user spaces — each user's cases live under
~/codeman-users/<name>/cases; sessions, cases, search, and real-time events are scoped to their owner. Admins see everything. - Individually revocable logins — named users with scrypt-hashed passwords in
~/.codeman/users.json; disable, reset (one-time password), or delete an account at any time. Admin actions are audited to~/.codeman/admin-audit.jsonl. - Safer defaults for regular users — non-admins run Claude in
--permission-mode auto(Anthropic's classifier-guarded mode); raw shell sessions, cronlaunchCommand, and skip-permissions require an explicit per-user grant.
⚠️ This separates workspaces; it does not sandbox users from each other. Every session runs as the same OS account, so a determined user's agent can still reach another user's files. For real isolation, pair users with Docker cases or run separate instances under separate OS accounts. See
docs/multi-user-plan.mdand the multi-user section ofdocs/security-architecture.md.
Remote Access — Cloudflare Tunnel
Access Codeman from your phone or any device outside your local network using a free Cloudflare quick tunnel — no port forwarding, no DNS, no static IP required.
Browser (phone/tablet) → Cloudflare Edge (HTTPS) → cloudflared → localhost:3000
Prerequisites: Install cloudflared and set CODEMAN_PASSWORD in your environment.
# Quick start
./scripts/tunnel.sh start # Start tunnel, prints public URL
./scripts/tunnel.sh url # Show current URL
./scripts/tunnel.sh stop # Stop tunnel
./scripts/tunnel.sh status # Service status + URL
The script auto-installs a systemd user service on first run. The tunnel URL is a randomly generated *.trycloudflare.com address that changes each time the tunnel restarts.
No comments yet
Be the first to share your take.