{"id":50142001,"url":"https://github.com/skzv/ccmux","last_synced_at":"2026-06-02T23:00:31.021Z","repository":{"id":357506370,"uuid":"1235161765","full_name":"skzv/ccmux","owner":"skzv","description":"One TUI for every AI coding session — Claude Code, Codex, Gemini CLI, in sync across every device.","archived":false,"fork":false,"pushed_at":"2026-05-28T06:23:57.000Z","size":53279,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T07:22:25.726Z","etag":null,"topics":["agentic-coding","ai-coding","anthropic","bubble-tea","claude-code","developer-tools","golang","mosh","tailscale","terminal-ui","tmux","tui"],"latest_commit_sha":null,"homepage":"https://ccmux.ai","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skzv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T04:19:15.000Z","updated_at":"2026-05-28T06:24:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/skzv/ccmux","commit_stats":null,"previous_names":["skzv/ccmux"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/skzv/ccmux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skzv%2Fccmux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skzv%2Fccmux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skzv%2Fccmux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skzv%2Fccmux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skzv","download_url":"https://codeload.github.com/skzv/ccmux/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skzv%2Fccmux/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33840214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-coding","ai-coding","anthropic","bubble-tea","claude-code","developer-tools","golang","mosh","tailscale","terminal-ui","tmux","tui"],"created_at":"2026-05-24T02:01:29.576Z","updated_at":"2026-06-02T23:00:31.012Z","avatar_url":"https://github.com/skzv.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"docs/screenshots/ccmux-logo.png\" alt=\"ccmux\" width=\"520\" /\u003e\n\n_Terminal session manager for AI coding agents._\n\n**Run your coding agents from any device — even your phone.**\n\nccmux is one TUI for every coding-agent session you've got running — Claude Code, Codex, Cursor, and more. Start, resume, and supervise them all from your Mac, your laptop, or your phone. No tmux session names to memorize, no `claude --resume \u003chash\u003e` to type, no SSH-then-attach gymnastics. It runs over your tailnet and attaches over SSH or Mosh. Setup is one command.\n\n[![CI](https://github.com/skzv/ccmux/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/skzv/ccmux/actions/workflows/ci.yml)\n[![Go Version](https://img.shields.io/badge/go-1.26+-00ADD8.svg)](https://go.dev/)\n[![License: FSL-1.1-MIT](https://img.shields.io/badge/license-FSL--1.1--MIT-blue.svg)](LICENSE)\n[![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](#status)\n[![Made with Charm](https://img.shields.io/badge/made_with-Charm-FF66CC.svg)](https://charm.sh/)\n\n\u003cimg src=\"docs/vhs/out/cuj00_hero.gif\" alt=\"ccmux full tour: dashboard with five parallel agent sessions, attach to Claude Code, then tour Conversations, Notes, Agents, Settings, Network.\" width=\"900\" /\u003e\n\n\u003c/div\u003e\n\n## 🚀 Install\n\n```bash\nbrew install skzv/tap/ccmux\nccmux setup\n```\n\nHomebrew is recommended on macOS; Linuxbrew works on Linux. `ccmux setup` finishes first-run setup for Tailscale, agent CLIs, and the background daemon.\n\nOther paths:\n\n- No Homebrew: `curl -fsSL https://raw.githubusercontent.com/skzv/ccmux/main/scripts/install.sh | sh`, then `ccmux setup`.\n- From source: `git clone https://github.com/skzv/ccmux.git \u0026\u0026 cd ccmux \u0026\u0026 make setup`.\n\nWorks on macOS, Linux, and Windows via WSL2. Source builds require Go 1.26+.\n\n---\n\n## The loop\n\nIt's 11pm. The session you started this morning on your Mac is still running — your laptop's lid has been closed for hours, but the daemon held a `caffeinate` lock and Claude kept thinking.\n\nYour phone vibrates: Claude is asking a question. You tap the notification, you're attached. You answer, hit `Ctrl-b d`, lock the phone.\n\nTomorrow morning on the train, you open your laptop, type `ccmux` — the same session is right there, exactly where you left it. **Three device transitions. Zero CLI commands.**\n\nThat's ccmux. The same session, the same TUI, on every device. No host config, no session-name memory, no `claude --resume`. Just press `Enter` on the row you want.\n\n---\n\n## 🎛️ One view. Every session, every project, every device.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj02_dashboard.gif\" alt=\"ccmux dashboard showing parallel sessions color-coded by state (active / idle / needs_input), Devices panel listing every machine on the tailnet, and Claude's 5-hour usage panel.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nColor-coded by state — **active**, **idle**, **needs your input**. The Devices panel shows every other ccmux-running machine on your tailnet right next to it. The usage panel tallies Claude's 5-hour quota and per-agent prompt counts. Live updates as each session moves through states.\n\n---\n\n## 🔁 Same session. No commands in between.\n\nThe \"start on Mac, continue on phone\" loop, end to end:\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"docs/vhs/out/cuj03_attach_detach.gif\" alt=\"ccmux on desktop: select a session, press Enter to attach to Claude Code running inside tmux, then Ctrl-b d to detach and return to the dashboard.\" width=\"900\" /\u003e\n\n\u003cem\u003eyour Mac — attach with \u003ccode\u003eEnter\u003c/code\u003e, detach with \u003ccode\u003eCtrl-b d\u003c/code\u003e\u003c/em\u003e\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n\u003cimg src=\"docs/vhs/out/cuj08_phone.gif\" alt=\"ccmux TUI running in a 430-pixel phone-width terminal — single-column dashboard layout, same keys as desktop, attaches over Mosh.\" width=\"240\" /\u003e\n\n\u003cem\u003eyour phone — same TUI, narrower (Blink, Termius, or the Moshi app)\u003c/em\u003e\n\n\u003c/div\u003e\n\ntmux is the session store; ccmux is the lens. The phone-width layout collapses everything into a single scrollable column when ccmux runs in a narrow terminal. Mosh makes the connection survive cell→wifi roaming, lid-close, walking-out-of-range — so you can detach the phone on the train and reattach two stops later.\n\n---\n\n## 🆕 Spawn from any device.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj01_new_project.gif\" alt=\"ccmux new project flow: open the Projects tab, press n, pick an agent (Claude / Codex / Antigravity / Cursor), submit, ccmux creates the directory and attaches you to the new session.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nOpen the Projects tab, press `n`. Pick which device should host the new project — local, or any reachable peer running `ccmuxd` on your tailnet. The remote daemon creates the directory natively and starts the agent. ccmux SSH-attaches you in. You never typed `ssh`, never typed `mkdir`, never typed `tmux new-session`.\n\nThe new-project form also picks the agent (Claude, Codex, Cursor, and more) for this project — the choice sticks at `\u003cproject\u003e/.ccmux/agent`.\n\n---\n\n## 💬 Every conversation. One tap.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj04_resume.gif\" alt=\"ccmux Conversations screen showing past Claude / Codex / Antigravity threads sorted by recency. Selecting one and pressing Enter resumes the agent with the correct session ID.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nccmux remembers every past Claude / Codex / Antigravity thread, sorted by recency. Press `2` for the Conversations screen, navigate, press `Enter`. The daemon resumes the agent with the correct session ID. You don't type `claude --resume \u003chash\u003e` ever again.\n\nHeadless agent runs (`claude -p`, `codex exec`, SDK invocations) are filtered out by default so a scripted workflow doesn't drown the list — press `H` to toggle them back on.\n\n---\n\n## 🤖 Every agent. One workflow.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj05_pick_agent.gif\" alt=\"ccmux new-project form: cycle Claude / Codex / Antigravity / Cursor with arrow keys, the agent picker writes the per-project choice into .ccmux/agent.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nPick per project which AI runs it — ccmux works with [Claude Code](https://claude.ai/code), [Codex](https://github.com/openai/codex), [Antigravity CLI](https://antigravity.google/download), [Cursor](https://cursor.com/cli), [pi](https://pi.dev), [Grok](https://x.ai/cli), and more, speaking each one's launch and resume dialect. The choice is sticky, stored at `\u003cproject\u003e/.ccmux/agent`. The dashboard, daemon state-detection, and dispatch all follow per-project. Press `a` in the Projects tab to switch the selected project's agent (cycles claude → codex → antigravity → cursor → pi → grok).\n\nDashboard rows on non-default agents get a small `[codex]`, `[antigravity]`, `[cursor]`, `[pi]`, or `[grok]` tag so a single glance tells you what's running where.\n\n---\n\n## 📝 Project notes, terminal-native.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj06_notes.gif\" alt=\"ccmux notes screen browsing markdown files in the project tree, showing a Glamour-rendered preview and a ripgrep search for refresh token.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nPer-project Notes tab — every `.md` file in the project, organized as a collapsible folder tree, with markdown rendered inline by [Glamour](https://github.com/charmbracelet/glamour). Folders open **collapsed** so a deep notes tree doesn't bury you: `→`/`l` expands a folder (or drills in), `←`/`h` collapses it (or jumps out to the parent). Want it all open? Launch with `ccmux --expand-notes` or set `[notes] expand_folders = true`. Ripgrep-backed `/` search. Plain markdown on disk is the source of truth. No sync service. No cloud. Press `e` to edit a note in `$EDITOR`; ccmux reads notes, writing them is the agent's job.\n\nNotes follow you across devices: press `H` to toggle which machine you're viewing notes from — the local box or any reachable ccmuxd peer on your tailnet. The list, preview, and search all re-scope to the selected device (read-only for remote). Scriptable too: `ccmux notes list|read|search \u003cproject\u003e [--host \u003cname\u003e]`.\n\n---\n\n## 🩺 Manage your agents.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj09_agents.gif\" alt=\"ccmux Agents screen showing Claude, Codex, and Antigravity with install status, sign-in status, and per-agent config root path.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nOne screen for \"is my agent installed and signed in?\" Per-agent CLI version, config root, login status, and a command palette to re-run setup or open the config directory.\n\n---\n\n## ⚙️ Setup is a flow, not a README.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj10_setup_doctor.gif\" alt=\"ccmux setup wizard interactively checking and offering to install tmux, mosh, tailscale, claude, gh — then running ccmux doctor as a non-interactive verification pass.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\n`ccmux setup` is the interactive wizard. It checks `tmux` / `mosh` / `tailscale` / `claude` / `gh` and offers to `brew install` whatever's missing. The first time you launch `ccmux` on an unconfigured machine it offers to run setup for you (decline once and it won't ask again; set `CCMUX_NO_SETUP_NUDGE=1` to always skip the prompt). For dotfiles / provisioning, `ccmux setup --yes` runs non-interactively — it takes the recommended answer at every prompt (install deps, generate the SSH key, install the daemon autostart) and skips the integrations that can't be scripted (Moshi pairing, Tailscale/`gh` browser auth). `ccmux doctor` is the non-interactive health check — perfect for scripting or when something stops working.\n\n---\n\n## 🔄 Updates are in-place.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/vhs/out/cuj11_update.gif\" alt=\"ccmux dashboard showing an update-available banner; running ccmux update pulls the latest tag, rebuilds, and reloads the daemon.\" width=\"900\" /\u003e\n\u003c/div\u003e\n\nDashboard shows a banner when a new release lands. `ccmux update` git-pulls the checkout, rebuilds, reloads `ccmuxd`. Flags: `--dry-run`, `--skip-pull`, `--no-restart`. The Devices panel tags any tailnet peer running a behind-version of ccmuxd so you see at a glance which machines need an update.\n\n---\n\n## 📱 Mobile setup\n\nThe way to use ccmux on your phone today is the **[Moshi](https://getmoshi.app/) app**. Moshi holds a Mosh connection to your Mac alive through roaming and lid-close, raises a real push notification when an agent needs you, and shows a live picker of your sessions — tap one and you're attached to ccmux's TUI on your phone.\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"docs/screenshots/moshi.png\" alt=\"ccmux running inside the Moshi app on an iPhone: a live ccmux session, the status line reading 'reachable via Moshi', and Moshi's on-screen key bar (Ctrl / Esc / Tab) at the bottom.\" width=\"260\" /\u003e\n\u003cbr/\u003e\n\u003cem\u003eccmux in the Moshi app — a live session on your phone, attached over Mosh\u003c/em\u003e\n\u003c/div\u003e\n\n```bash\nccmux moshi-setup\n```\n\nInstalls [moshi-hook](https://getmoshi.app/) on the Mac, runs **Easy Pair** (a QR code appears in your terminal — scan it with the Moshi iOS app, done), and wires the Claude Code hooks that turn `needs_input` events into **categorized** push notifications (approval_required vs task_complete). Tap the notification, the Moshi app shows your live tmux session list, pick one, attach, answer, detach. No tokens to copy.\n\nPlain BEL fallback works in any iOS terminal client (Blink Shell, Termius) — you lose the categories, that's it. For headless / scripted setups: `ccmux moshi-setup --token \u003ctoken\u003e` bypasses the QR flow.\n\n**Native apps:** dedicated iOS and Android apps that talk to `ccmuxd` directly over your tailnet are in active development.\n\n---\n\n## 🛰️ Multi-machine (auto-discovered)\n\n```bash\n# On the always-on Mac Mini:\nccmux daemon install                       # ccmuxd survives reboot\n# edit ~/.config/ccmux/config.toml: listen_tailnet = true\n\n# On the laptop — nothing to do:\nccmux                                      # dashboard already lists the Mini\n```\n\nEvery refresh, ccmux runs `tailscale status --json`, probes each online non-mobile peer for a `ccmuxd /v1/health`, and merges the responders into the host list. Install ccmux on a new device, start its daemon, and it shows up on every other device on your tailnet within seconds.\n\nThe Devices panel on the Dashboard shows every device on your tailnet:\n\n- 🟢 **peers running ccmuxd** — with their reported version + an \"update available\" tag whenever they lag this build\n- ⚪ **peers NOT running ccmuxd** (Macs/Linux boxes you haven't installed on yet) — with a one-line \"ccmux not installed\" hint\n- 📱 **phones / iPads** — with a \"connect via Moshi app\" hint (the iOS Moshi app is their picker; they don't run ccmux directly)\n\nAttaching to an auto-discovered peer execs `ssh -t \u003chost\u003e -- tmux attach -t \u003cname\u003e` (cross-platform PATH prepend so Homebrew/Snap/Linuxbrew tmux is found). If you've pinned a host with `ccmux host add --mosh \u003cname\u003e …`, ccmux uses `mosh` instead — tolerates roaming and stalls.\n\n\u003e Manually pinning a host with `ccmux host add` still works — useful for non-Tailscale hosts, or to force a specific port. Discovered hosts and pinned hosts coexist on the dashboard without duplicates.\n\n---\n\n## ⚙️ Config\n\n`~/.config/ccmux/config.toml` — the knobs that matter:\n\n```toml\n[projects]\nroot = \"~/Projects\"                  # where ccmux looks for projects\n\n[daemon]\npoll_interval_seconds = 2\nidle_seconds_for_needs_input = 3\nlisten_tailnet = false               # set true on your server-mode host\ntailnet_port = 7474\n\n[sleep]\nmode = \"safe\"                        # \"safe\" | \"dangerous\" | \"very_dangerous\"\nidle_release_minutes = 10\nlow_battery_cutoff = 20              # dangerous mode auto-downgrades below this\n\n[notifications]\nbell = true                          # ring local terminal BEL on needs_input\n```\n\n\u003e **Notifications:** the bell always rings on `needs_input` transitions when `bell = true`, regardless of whether moshi-hook is paired. The audible chime at your desk and the push on your phone are complementary, not duplicates. Set `bell = false` if you'd rather rely on phone pushes alone.\n\n\u003e **Sleep-mode notes:**\n\u003e\n\u003e - `safe` — `caffeinate -s` on macOS (Apple's policy keeps it AC-only). `systemd-inhibit --what=sleep:idle` on Linux.\n\u003e - `dangerous` — `caffeinate -d -i -m -s` on macOS, works on battery too. Daemon polls battery once a minute and downgrades to `safe` when below `low_battery_cutoff` (so a forgotten laptop doesn't run flat).\n\u003e - `very_dangerous` — adds `sudo -n pmset -a disablesleep 1` (macOS) / `sudo -n systemctl mask sleep.target …` (Linux). Requires passwordless sudo for the specific command; silently degrades to `dangerous` if sudo prompts. Always reverted when ccmuxd exits cleanly.\n\u003e\n\u003e Example sudoers entry (run `sudo visudo -f /etc/sudoers.d/ccmux`):\n\u003e\n\u003e ```\n\u003e # macOS\n\u003e %admin ALL=(ALL) NOPASSWD: /usr/bin/pmset -a disablesleep *\n\u003e # Linux\n\u003e %sudo ALL=(ALL) NOPASSWD: /bin/systemctl mask *, /bin/systemctl unmask *\n\u003e ```\n\n`projects.root` and `subscription.tier` are also editable inline from the Settings screen — `↑/↓` to move, `Enter` to edit, `e` to open `$EDITOR` for the prose-heavy fields. After editing, run `ccmux update` to reload the daemon with the new config.\n\n---\n\n## ✨ Full feature list\n\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n### 🎛️ Session management\n\n- Live dashboard of every agent session across every project, with state (active / idle / **needs_input**) and per-row agent tags\n- One-key attach, kill, rename — applies a styled tmux status bar so you always know where you are\n- Per-session \"keep awake\" pin — the daemon holds a sleep-prevention lock while any pinned or active session is alive\n- **Three sleep-prevention modes** — `safe`, `dangerous`, `very_dangerous` (sudo-gated; system-wide override that survives lid-close)\n\n### 🏗️ New projects\n\n- `ccmux new \u003cname\u003e` — creates the directory + starts the agent. **No CLAUDE.md, no docs/ tree, no git init.** Bootstrapping is the agent's job.\n- **Open a project = see its history.** Enter on a project lists running sessions _and_ past conversations.\n- **Conversations list hides automation noise.** Headless `claude -p` / SDK runs and `codex exec` invocations are filtered by default. Press `H` to toggle. Antigravity transcripts carry no headless tag, so those are always shown.\n- **Create on any device.** Press `n` in Projects, pick a host, the remote daemon does the work.\n- **Every subdirectory of your projects root shows up** — no marker file required. `git · CLAUDE · docs/` tags tell you which dirs are real software projects vs scratch dirs.\n\n### 🤝 Multi-agent\n\n- Per-project agent stored in `\u003cproject\u003e/.ccmux/agent` — sticky across sessions\n- New-project form cycles Claude / Codex / Antigravity / Cursor / pi / Grok with `←/→`\n- Press `a` in Projects to switch the selected project's agent\n- Dashboard rows on non-default agents get a small `[codex]`, `[antigravity]`, `[cursor]`, `[pi]`, or `[grok]` tag\n- Daemon state-detection (active / idle / needs_input) dispatches per agent for correct heuristics\n- `ccmux doctor` enumerates installed agents; setup wizard points at the right install command for each\n- Moshi push integration is currently Claude-only — Codex / Antigravity sessions get the audible terminal bell (still triggers a generic iOS push). Phase-2 work tracked in [`docs/01_Specs/02_Multi_Agent.md`](docs/01_Specs/02_Multi_Agent.md)\n\n### 🤖 Claude Code config management\n\n- Dedicated \"Claude\" screen for everything in `~/.claude/`\n- Model picker (Opus 4.7 / Sonnet 4.6 / Haiku 4.5 / opusplan / custom) — global or per-project\n- Reasoning-effort picker (`low` / `medium` / `high` / `xhigh` / `max`) + `alwaysThinkingEnabled` toggle. Writes `effortLevel` to `~/.claude/settings.json` so every new Claude Code session inherits your default.\n- Browse + create slash-command aliases, manage MCP servers, hooks, permission allowlists\n- View \u0026 edit global and per-project `CLAUDE.md` from the TUI\n\n### 📝 Notes, terminal-native\n\n- Per-project Notes tab — every `.md` file in the project, as a collapsible folder tree, rendered by Glamour\n- Folders open collapsed; `→`/`←` (or `l`/`h`) expand/collapse them — or open everything with `ccmux --expand-notes`\n- Ripgrep-backed `/` search; plain markdown on disk is the source of truth (no required cloud)\n- Browse, preview, edit-in-`$EDITOR` — ccmux reads your notes; writing them is the agent's job\n- Cross-device: `H` toggles which device's notes you're viewing (local or any tailnet peer); also via `ccmux notes list|read|search --host \u003cname\u003e`\n\n### 📲 Mobile workflow (Moshi / iOS / Android)\n\n- **Easy Pair via QR code** — `ccmux moshi-setup`; scan the QR code with the Moshi app, you're paired. No token paste.\n- **Categorized push notifications** via `moshi-hook` plugging into Claude Code's hooks system (approval_required, task_complete)\n- **In-app session picker** — the Moshi app lists every tmux session on the paired host\n- **Auto-detection** — ccmuxd suppresses its BEL trigger when moshi-hook is paired so you don't get duplicate notifications\n\n### 🌐 Local \u0026 remote modes\n\n- **Local** — manages tmux sessions on this machine; prevents sleep while sessions are active\n- **Server** — daemon binds an HTTP API to your Tailscale interface for remote ccmux clients\n- **Mixed** — dashboard shows local + remote sessions, color-coded by origin\n\n### 🩺 Setup, doctor, update\n\n- `ccmux setup` — interactive wizard, checks every dep, offers `brew install` for missing pieces; `--yes` runs it non-interactively for scripts, and the first launch on a fresh machine offers to run it for you\n- `ccmux doctor` — non-interactive health check (great for scripting)\n- `ccmux update` — pulls the git checkout, rebuilds, reloads ccmuxd\n- `ccmux uninstall` — clean removal, never touches your projects or `~/.claude/`\n\n### 🎨 Quality of life\n\n- Catppuccin Mocha by default; Dracula / Nord / Gruvbox / Tokyo Night planned\n- `?` opens contextual key help on every screen\n- Vim-style (`h/j/k/l`) and arrow keys both work\n- Auto-switches to a curated narrow-terminal layout under 120 cols (phone mode) — reference detail is dropped so the essentials fit a phone screen\n- Mouse support on by default (hold **Option (⌥)** while dragging to bypass tmux mouse reporting in iTerm2 / Terminal.app)\n- **Cross-device clipboard via OSC 52** — selecting text inside a remote tmux pane lands on your _local_ clipboard. Works in iTerm2, Ghostty, WezTerm, Alacritty, kitty. Terminal.app does NOT support OSC 52 writes. `ccmux doctor` tells you exactly which side is missing.\n- **No telemetry. Ever.**\n\n\u003c/details\u003e\n\n---\n\n## 📚 Tutorials\n\nSix hands-on walkthroughs. Each is self-contained — pick whichever maps to what you're trying to do.\n\n### 1. Your first project, end-to-end (≈3 min)\n\nThe core loop: create → talk to your agent → take notes.\n\n```bash\nccmux new auth-redesign            # or: ccmux new auth-redesign --agent codex\n```\n\nThat command does two things, and **only** two things:\n\n1. Creates `~/Projects/auth-redesign/` — an empty directory.\n2. Opens a tmux session named `c-auth-redesign` and starts your agent inside it (Claude by default).\n\nccmux does **not** scaffold the project — no `CLAUDE.md`, no `docs/` tree, no `git init`, no GitHub repo. Bootstrapping is the agent's job, done inside the session: run `/init` to have the agent write `CLAUDE.md`, `openspec` to set up specs, `git init` whenever you want version control. ccmux opens the door; what the project becomes is up to you and your agent.\n\nTo check on the session without joining the conversation: `ccmux list`. To attach: `ccmux attach auth-redesign`. The session keeps running after you detach.\n\n### 2. Juggling multiple agent sessions (≈2 min)\n\n```bash\nccmux\n```\n\nThe Dashboard shows all sessions, color-coded by state:\n\n- **active** — the agent is generating output right now.\n- **idle** — finished, no prompt visible.\n- **needs_input** — the agent's input box is up and the pane has been quiet for ≥ 3 seconds. **This is the one to watch.**\n\nWhen a session transitions to `needs_input`, ccmuxd injects a terminal BEL. Any iOS terminal client that maps BEL→notification raises a push.\n\nUseful keys on the Sessions screen:\n\n- `Enter` — attach\n- `x` — kill the highlighted session\n- `R` — rename\n- `?` — full keymap\n\n### 3. Working from your phone (≈3 min, one-time setup)\n\nSee the [Mobile setup](#-mobile-setup) section above.\n\n### 4. Configure ccmux (≈2 min)\n\nSee the [Config](#%EF%B8%8F-config) section above. `~/.config/ccmux/config.toml` has the full set of knobs.\n\n### 5. Multi-machine: laptop + always-on Mac Mini (≈5 min)\n\nSee the [Multi-machine](#-multi-machine-auto-discovered) section above. Heavy users live in this flow: sessions on the Mini, clients on laptop/phone, no host config — auto-discovery handles it.\n\n### 6. Maintenance (≈1 min)\n\n```bash\nccmux doctor          # one-shot health check\nccmux update          # git pull + rebuild + reinstall + restart daemon\nccmux uninstall       # clean removal\n```\n\n`ccmux update` auto-detects your git checkout (defaults to `~/Projects/ccmux`). Flags: `--dry-run`, `--skip-pull`, `--no-restart`.\n\n---\n\n## Uninstall\n\n```bash\nccmux uninstall            # interactive: shows what it'll do, asks y/N\nccmux uninstall --yes      # skip the prompt\nccmux uninstall --dry-run  # preview only\n```\n\nWhat gets removed:\n\n- Running `ccmuxd` (SIGTERM)\n- `~/.local/bin/ccmux` and `~/.local/bin/ccmuxd`\n- `~/.local/state/ccmux/` (socket, logs)\n- `~/.local/share/ccmux/` (snapshots, daemon db)\n- `~/.config/ccmux/` (unless `--keep-config`)\n- The ccmux-styled tmux status bar on every `c-*` session (unless `--keep-chrome`)\n\nWhat is **never** touched:\n\n- Your project directories\n- Notes under `\u003cproject\u003e/docs/`\n- `~/.claude/` (Claude Code state + moshi-hook entries)\n\nTo also remove `moshi-hook`: `brew services stop moshi-hook \u0026\u0026 brew uninstall moshi-hook \u0026\u0026 brew untap rjyo/moshi`.\n\n---\n\n## 🏛️ Architecture\n\n```\n        LAPTOP (client + local)                MINI (local + server)\n   ┌─────────────────────────────┐         ┌──────────────────────────────┐\n   │  ccmux TUI                  │ ──http──►  ccmuxd HTTP                 │\n   │   ├─ local sessions ◄─unix──┤ tailnet │   ├─ sessions (mini-foo)     │\n   │   │   • laptop-bar          │ ────────►   │   • mini-foo (active)    │\n   │   │   • laptop-baz          │         │   │   • mini-cas (waiting 🔔)│\n   │   └─ remote: mini           │         │   └─ caffeinate -s while active\n   │      • mini-foo             │         │                              │\n   │                             │         │ ccmuxd Unix socket           │\n   │                             │         │  (for local TUI on mini)     │\n   └─────────────────────────────┘         └──────────────────────────────┘\n                                                       ▲\n                                                       │ Mosh\n                                                       │ (when phone connects)\n                                              ┌────────┴──────────┐\n                                              │  iPhone (Moshi /  │\n                                              │  Blink / Termius) │\n                                              └───────────────────┘\n```\n\nFull design: [`docs/02_Architecture/00_System_Design.md`](docs/02_Architecture/00_System_Design.md).\nTUI design system: [`docs/02_Architecture/04_TUI_Design_System.md`](docs/02_Architecture/04_TUI_Design_System.md).\n\n---\n\n## 🗺️ Roadmap\n\nPhasing in [`ROADMAP.md`](ROADMAP.md). Headline:\n\n- **v0.1** — TUI, sessions, notes, setup wizard, daemon, local + server + mixed modes, terminal-bell notifications, Homebrew tap\n- **v0.2** — Snapshots, themes, command palette, tailnet web viewer for notes, cost tracking from Claude transcripts\n- **v0.3** — Multi-select session ops, activity heatmap, daily-journal rollups, mDNS host discovery\n- **Long term** — Native SwiftUI iOS app talking directly to ccmuxd over Tailscale\n\nInfrastructure follow-ups tracked in [`docs/01_Specs/03_Testing_And_CI.md`](docs/01_Specs/03_Testing_And_CI.md):\n\n- 🔁 **CI integration** — GitHub Actions matrix (test + cross-compile + integration) so PRs can't merge with regressions\n- 💪 **Stress testing** — `cmd/ccmux-stress/` harness for 20+ session loads, notification storms, 24h long-haul, with pprof + FD-leak detection\n- 🐛 **Terminal crawling** — `cmd/ccmux-crawl/` monkey-tester + native fuzzers + `rapid` property tests to find the bugs no human would think to try\n\n---\n\n## Design principles\n\n1. **Terminal-first, not terminal-only.** Must work in a Mosh pane on an iPhone.\n2. **One source of truth: tmux.** ccmux is a view; tmux is the database.\n3. **Plain markdown on disk** beats vendor lock-in. No required cloud, no required sync.\n4. **Notifications by terminal bell.** Reuses what every iOS terminal client already supports.\n5. **Setup is a flow, not a README.** First-run wizard installs what it can, instructs for what it can't.\n6. **No telemetry. Ever.**\n\n---\n\n## Status\n\n**Alpha.** Core flows (attach, new, kill, notes, daemon, Moshi) work end-to-end. Expect rough edges; file issues. Wait for v0.1 if you want it for real work.\n\n---\n\n## Built with\n\nStanding on the shoulders of [Charm](https://charm.sh/):\n\n- [Bubble Tea](https://github.com/charmbracelet/bubbletea) — the TUI framework\n- [Lipgloss](https://github.com/charmbracelet/lipgloss) — styling\n- [Bubbles](https://github.com/charmbracelet/bubbles) — list, viewport, textinput, spinner, help\n- [Huh](https://github.com/charmbracelet/huh) — forms for the setup wizard\n- [Glamour](https://github.com/charmbracelet/glamour) — markdown rendering\n\nPlus [Cobra](https://cobra.dev/) for the CLI surface and [SQLite](https://gitlab.com/cznic/sqlite) for daemon state.\n\n---\n\n## Contributing\n\nIssues and PRs welcome. See `CONTRIBUTING.md` (TBD). The short version:\n\n- Code style: `gofmt`, `go vet`, `staticcheck`\n- Tests: `make test` (unit) and `make test-e2e` (integration — requires `tmux`)\n- Bug reports: include `ccmux doctor` output\n- Feature requests: read `docs/01_Specs/01_Feature_Catalog.md` first\n\n---\n\n## License\n\n[FSL-1.1-MIT](LICENSE) — Functional Source License with MIT future grant.\n\nIn plain English: you can use, modify, and redistribute ccmux freely for any purpose **except** offering it (or a substantially-similar feature set) as a competing commercial product or managed service. Two years after each release, that version automatically relicenses to plain MIT.\n\nIf you want to commercialize a derivative work sooner, get in touch.\n\n---\n\n## Acknowledgements\n\nThe workflow this tool wraps was developed in public by the AI-first software engineering community over 2024–2026. Particular thanks to:\n\n- Charm for the best TUI stack in any language\n- The Tailscale and Mosh teams for the connectivity layers\n- Anthropic for shipping Claude Code\n- The Blink Shell and Moshi maintainers for making mobile terminals actually good\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskzv%2Fccmux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskzv%2Fccmux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskzv%2Fccmux/lists"}