{"id":50941210,"url":"https://github.com/mpolatcan/codehub","last_synced_at":"2026-06-17T15:02:39.792Z","repository":{"id":359216309,"uuid":"1245055884","full_name":"mpolatcan/codehub","owner":"mpolatcan","description":"Tauri desktop app for managing multiple AI coding agent CLIs (Claude Code, Codex, Antigravity) in a single Docker container, multiplexed via tmux.","archived":false,"fork":false,"pushed_at":"2026-06-07T08:12:24.000Z","size":10153,"stargazers_count":3,"open_issues_count":17,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T10:11:09.704Z","etag":null,"topics":["ai-agents","claude-code","codex","docker","multiplexer","rust","tauri","terminal","tmux","xterm"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpolatcan.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"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-20T21:38:50.000Z","updated_at":"2026-06-07T08:12:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mpolatcan/codehub","commit_stats":null,"previous_names":["mpolatcan/aviary","mpolatcan/codehub"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/mpolatcan/codehub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolatcan%2Fcodehub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolatcan%2Fcodehub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolatcan%2Fcodehub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolatcan%2Fcodehub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpolatcan","download_url":"https://codeload.github.com/mpolatcan/codehub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolatcan%2Fcodehub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34453438,"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-17T02:00:05.408Z","response_time":127,"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":["ai-agents","claude-code","codex","docker","multiplexer","rust","tauri","terminal","tmux","xterm"],"created_at":"2026-06-17T15:02:38.847Z","updated_at":"2026-06-17T15:02:39.784Z","avatar_url":"https://github.com/mpolatcan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CodeHub\n\nA home for your AI coding agents.\n\nTauri desktop app that runs **Claude Code**, **Codex**, and **Antigravity** CLIs in sandboxed Docker containers, multiplexed via tmux. Each pane = one tmux session = one agent; tabs hold one or more split panes. Each workspace gets its own container (`codehub-ws-\u003ckey\u003e`) so its cpu/mem/network/state report as real, isolated data. CodeHub spawns and manages containers itself — no `docker compose` step.\n\n**Built with** Tauri 2 · Rust + tokio · React 19 + Zustand · xterm.js · Tailwind v4 + shadcn/ui · **JetBrains Mono** throughout.\n\n## Why\n\nRunning multiple agent CLIs locally is messy: separate terminals, separate auth, no unified view, no isolation. CodeHub isolates each agent in a tmux session inside a container — one container per workspace by default — and gives you a single window to switch between them.\n\n## Architecture\n\n```mermaid\nflowchart LR\n    subgraph webview[\"Tauri webview\"]\n        direction TB\n        UI[\"xterm.js · Vite\u003cbr/\u003eReact 19 + Zustand\u003cbr/\u003etabs ↔ split panes ↔ terminals\"]\n    end\n\n    subgraph backend[\"Rust backend (tokio)\"]\n        direction TB\n        LC[\"Lifecycle\u003cbr/\u003eimage + container\"]\n        DC[\"DockerClient\u003cbr/\u003eexec / streams\"]\n        PR[\"PtyRegistry\u003cbr/\u003epane_id map\"]\n    end\n\n    subgraph runtime[\"per-workspace container · codehub-ws-(key)\"]\n        direction TB\n        TMUX[\"tmux server\u003cbr/\u003eidle until first session\"]\n        CLIS[\"claude · codex\u003cbr/\u003eantigravity\"]\n        TMUX -. spawns .-\u003e CLIS\n    end\n\n    webview \u003c-- \"IPC\u003cbr/\u003einvoke / event\" --\u003e backend\n    backend \u003c-- \"/var/run/docker.sock\u003cbr/\u003ebollard\" --\u003e runtime\n\n    classDef webviewBox fill:#e8f1ff,stroke:#3b6dba,stroke-width:1.5px,color:#1a2436\n    classDef backendBox fill:#fff4dc,stroke:#b6873a,stroke-width:1.5px,color:#2a1f10\n    classDef runtimeBox fill:#e6f3e1,stroke:#4f7d3a,stroke-width:1.5px,color:#1d2a17\n    classDef inner    fill:#ffffff,stroke:#6a6a6a,stroke-width:1px,color:#1c1c1c\n\n    class webview webviewBox\n    class backend backendBox\n    class runtime runtimeBox\n    class UI,LC,DC,PR,TMUX,CLIS inner\n```\n\n### Boot sequence\n\n```mermaid\nsequenceDiagram\n    autonumber\n    participant UI as Frontend\n    participant LC as Lifecycle\n    participant D as Docker\n    participant C as codehub-ws-(key)\n\n    UI-\u003e\u003eLC: daemon reachability check (spawn bg)\n    LC-\u003e\u003eD: docker version\n    LC--\u003e\u003eUI: emit codehub://lifecycle (running)\n    UI-\u003e\u003eLC: list_sessions (all workspace containers)\n    LC--\u003e\u003eUI: existing tmux sessions\n    UI-\u003e\u003eUI: restore tabs\n    Note right of LC: containers created on demand by create_session\n```\n\n### Per-session lifecycle (new tab, split, or ⌘T)\n\n```mermaid\nsequenceDiagram\n    autonumber\n    participant UI as Frontend\n    participant B as Backend\n    participant T as tmux (in workspace container)\n\n    UI-\u003e\u003eUI: launcher — agent (claude/codex/antigravity) × mode (standard/auto/yolo)\n    UI-\u003e\u003eB: create_session(name, cli, mode, workspace)\n    Note right of B: resolve + ensure\u003cbr/\u003ecodehub-ws-(key)\n    B-\u003e\u003eT: docker exec — tmux new-session -d -s NAME CLI\n    UI-\u003e\u003eB: attach_session(name, cols, rows)\n    B-\u003e\u003eT: bollard exec tty=true — tmux attach -t NAME\n    B--\u003e\u003eUI: pane_id\n    loop while attached\n        T--\u003e\u003eB: stdout chunks\n        B--\u003e\u003eUI: pty://data/PANE_ID\n        UI-\u003e\u003eB: pty_write(paneId, data)\n        B-\u003e\u003eT: stdin\n        UI-\u003e\u003eB: pty_resize(paneId, cols, rows)\n        B-\u003e\u003eT: TIOCSWINSZ\n    end\n```\n\n## Using it\n\n- **Workspaces** — the launcher (⌘T or the `+` tab button) lists saved workspaces (name, directory, last-opened time) with search/filter, plus recent/resume entries. Each runs in its own container (`codehub-ws-\u003ckey\u003e`) with repos mounted under `/workspace/\u003crepo-name\u003e`. The launcher's **Blank workspace** card opens a 3-step wizard that picks repos (local folders + GitHub), container resources (CPU/memory), and the first agent.\n- **New agent** — ⌘N (or the action-bar \"New agent\" button) drops a *configuring* pane into the current workspace: a card to pick the agent (Claude Code / Codex / Antigravity), permission mode, **working directory** and account, then spawn. The directory field is a folder browser over the mounted `/workspace` tree — drill into any repo or sub-folder at any depth and pick it as the agent's cwd (so a workspace that mounts a parent folder of many repos still lets each agent target a specific one). ⌘⇧N spawns into a fresh group instead of the active one.\n- **Permission modes** — *Standard* (agent asks first), *Auto* (auto-accepts edits, still sandboxed), *YOLO* (skips all approvals; the container is the boundary). Antigravity is Standard-only until its flags are verified.\n- **Splits** — split any pane (its head controls, or ⌘\\) into a binary tree; drag the divider to resize. Groups organize splits; each tab holds one or more groups.\n- **Color \u0026 rename** — click the identity dot on any pane head, group tab, or workspace tab to recolor it; double-click the title to rename. Colors and names persist across reloads.\n- **Hub panels** — a Files browser (⌘E), a Source Control dock (⌘D — changes/diff, commit history, branches; full git client over the workspace repo), a Shell panel (⌘J), a Details/metrics panel (⌘I), and a Resume drawer (action-bar button) of past Claude/Codex sessions, docked beside the panes.\n- **Per-pane telemetry** — each agent pane carries a live footer: the working directory, a context-window gauge (tokens used / model max), the turn count, and total tokens. Real per-session data read from the Claude transcript / Codex rollout — never estimated. The strip is always present (zeros until the first turn produces a transcript). The sidebar mirrors each agent: name, working dir, and live status.\n- **Command palette** (⌘K) — jump to a view, focus a running session, spawn an agent, or open a recent/connected repo.\n- **Views** — Hub, Dashboard, Workspaces (container manager), Usage (token/cost rollup from session transcripts), Settings (agents · runtime · integrations · appearance · keyboard shortcuts). Three themes: dark, gray, light.\n- **GitHub integration** — connect a PAT or sign in via OAuth in Settings → Integrations. Browse repos, see scopes and permissions. Repos appear in the workspace wizard for cloning.\n- **Companion** — an always-on-top monitor window mirroring live agent status (working / awaiting input / done / failed) with inline approve/deny. On macOS a native notch \"dynamic island\" variant exists (experimental).\n- **Keyboard** — ⌘T launcher (new/recent/resume workspace) · ⌘N new agent · ⌘⇧N new agent in a new group · ⌘W close pane · ⌘⇧W close workspace · ⌘\\ split (⌘⇧\\ opposite axis) · ⌘E files · ⌘D source control · ⌘J shell · ⌘I details · ⌘B sidebar · ⌘1–9 jump to tab · ⌘[ / ⌘] prev/next tab · ⌘K palette · ⌘, settings · ⌘⇧L cycle theme · ⌘/ or ? shortcuts · ⌘⇧J companion. ⌘R is intentionally left free for webview reload.\n\n## Runtime image\n\nLives in `runtime/`. See `runtime/README.md` for build and publish instructions.\n\n## Prerequisites\n\n- Rust toolchain (`rustup`, stable)\n- Node 20+\n- Docker Desktop running\n- macOS / Linux (Windows untested)\n\n## Setup\n\n```bash\ngit clone https://github.com/mpolatcan/codehub.git\ncd codehub\nnpm install\n\n# Build runtime image locally (or wait for app to pull from the registry on first launch)\nmake image\n\n# Dev mode (hot reload frontend, rebuild Rust on change)\nmake dev\n```\n\n\u003e See `make help` for the full target list (`build`, `check`, `fix`, `image-verify`, …).\n\n\u003e **macOS:** `make dev-signed` builds + codesigns the debug binary with a stable\n\u003e self-signed cert (`CODEHUB_DEV_IDENTITY`, default `codehub-dev`) so Keychain\n\u003e \"Always Allow\" survives rebuilds instead of re-prompting on every launch.\n\u003e Create the cert once via Keychain Access → Certificate Assistant (Code Signing,\n\u003e self-signed). Rerun to pick up Rust changes (no hot Rust reload).\n\n### Browser mode (dev bridge)\n\nThe Tauri webview (WKWebView) has no remote-debugging port, so the UI can't be\ninspected or screenshotted from outside the app. For visual work, `make dev-web`\nruns the frontend in a plain browser at \u003chttp://127.0.0.1:1420\u003e against a real\nbackend — a feature-gated HTTP/WebSocket bridge that mirrors the Tauri IPC\nsurface. It is **dev-only** and never compiled into the shipped app.\n\n```bash\nmake dev-web   # Vite + standalone backend bridge, no Tauri window\n```\n\nOverride defaults:\n\n| Env var | Purpose | Default |\n|---|---|---|\n| `CODEHUB_IMAGE` | Image tag to use (all containers) | `ghcr.io/mpolatcan/codehub-runtime:0.1.3` |\n| `CODEHUB_NETWORK_MODE` | Docker network mode | `bridge` |\n| `CLAUDE_CODE_OAUTH_TOKEN` | Skip `/login` in Claude Code | unset |\n\n## Production build\n\n```bash\nmake build\n```\n\nBundles a `.dmg` on macOS, `.AppImage`/`.deb` on Linux. Output at `src-tauri/target/release/bundle/`.\n\n## Volume layout\n\nCodeHub stores all state under the OS app-data dir, namespaced by the bundle identifier\nconfigured in `src-tauri/tauri.conf.json`.\n\n| Platform | Host path | Container path | Purpose |\n|---|---|---|---|\n| macOS   | `~/Library/Application Support/\u003cbundle-id\u003e/config`    | `/config`    | Per-CLI auth state |\n| macOS   | `~/Library/Application Support/\u003cbundle-id\u003e/workspace` | `/workspace` | Project files |\n| Linux   | `~/.local/share/\u003cbundle-id\u003e/config`                   | `/config`    | Per-CLI auth state |\n| Linux   | `~/.local/share/\u003cbundle-id\u003e/workspace`                | `/workspace` | Project files |\n\n## Roadmap\n\n- [ ] Multiple bind mounts per workspace (frontend ready; backend `lifecycle.rs` still uses a single `/workspace` bind)\n- [ ] Auto-update via Tauri updater plugin\n- [ ] App icon set\n- [ ] Code-split the frontend bundle\n\nShipped since the first roadmap: per-container resource limits (`nano_cpus`/`memory` in `lifecycle.rs`), in-container `git clone` for GitHub repos, and native OS notifications on agent await/finish (`tauri-plugin-notification`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpolatcan%2Fcodehub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpolatcan%2Fcodehub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpolatcan%2Fcodehub/lists"}