A macOS Dashboard and CLI for running AI coding agents in isolated git worktrees, managed tmux sessions, SSH remote hosts, and Android relay clients.
Install · Quick Start · Dashboard · Remote Hosts · Android Relay · Manual
AI agents are most useful when every task has its own branch, terminal, files, logs, and recoverable state. tmux-worktree turns that into a repeatable workflow:
| Surface | What it gives you |
|---|---|
tw CLI |
Headless control plane for managed worktrees/terminals, SSH Hosts, automations, relay, and machine-readable RPC. |
tw-dashboard |
Native macOS control plane for worktrees, terminals, files, Git status, diffs, automations, and remote hosts. |
| SSH remote runtime | Lets the local Dashboard create and attach to TW-managed sessions on devboxes over SSH. |
| Android relay | Pairs a phone with the Mac admin connector so mobile can see the same managed sessions. |
Mac Dashboard
|-- local tw -> git worktree + tmux + AI command
|-- ssh host -> remote tw -> remote worktree + tmux
`-- relay host -> broker -> Android client
| Capability | Details |
|---|---|
| Isolated agent workspaces | Every task can run in its own git worktree and tmux session without disturbing the main checkout. |
| Native terminal control | Dashboard attaches to tmux through a Tauri PTY bridge with resize, history capture, local clipboard paste, and remote tmux copy support. |
| Remote sessions that feel local | Add SSH hosts, create worktrees remotely, attach to remote tmux, and use mouse selection plus Cmd+C / Cmd+V from the local app. |
| Git and file context | Inspect branch state, changed files, history, diffs, file tree, editor, Markdown preview, and search beside the terminal. |
| Automations | Save repeatable agent instructions, run them on demand, or schedule them with cron-style local Dashboard polling. |
| Mobile visibility | Android connects through the relay broker and sees TW-managed worktrees and terminals from the Mac admin connector. |
Download the DMG from the latest GitHub release:
Download the latest tw-dashboard DMG
Then install it like a normal macOS app and open it:
open -a tw-dashboardThe current DMG bundles the exact Dashboard CLI JavaScript but not a separate Node runtime. Install Node.js 20+ on the Mac so local managed create, restore, and kill operations can use that bundled same-version RPC implementation. A globally installed tw is accepted only when both its version and lifecycle capabilities match the Dashboard.
When a repository or its main Git checkout lives in Desktop, Documents, or Downloads, macOS asks for access the first time the Dashboard opens its files or Git metadata. Allow that folder so worktree Git status and diffs can resolve the linked main repository.
Install tw from source on every machine that should create or manage sessions:
git clone https://github.com/Sskift/tmux-worktree.git
cd tmux-worktree
npm install
npm run build
npm link
tw setupThe current Compose Android client is built and released separately from the macOS Dashboard. This repository revision has not completed a signed Android production release; do not use an older GitHub debug APK to evaluate the current source.
Build the device-test APK from the current checkout:
npm run verify:androidThis builds mobile/android/app/build/outputs/apk/debug/app-debug.apk after the Android JVM and Lint gates. The Debug APK is for direct device testing. :app:assembleRelease currently produces an unsigned verification artifact, not an app-store or production-distributable build. See the Android relay guide for installation and pairing.
Create a config file:
{
"projects": {
"myapp": "/Users/me/code/myapp",
"backend": {
"path": "/Users/me/code/backend",
"branch": "develop"
}
},
"worktreeBase": "/Users/me/.tmux-worktree/worktrees",
"hosts": ["remote-dev"]
}Start a local AI coding session:
tw claude myapp
tw codex backend fix-auth
tw "claude --model opus" /Users/me/code/myappNew CLI and Dashboard worktree sessions use the same managed, single-pane tmux contract. A configured project name or a direct git repository path always creates a worktree and records it in ~/.tmux-worktree/state.json; non-git paths are rejected. The AI command runs in the single pane and returns to a login shell when it exits. Older multi-pane CLI sessions remain attachable until you close them; tw does not rewrite live sessions.
tw intentionally does not duplicate Dashboard presentation features. Files, the editor, Git graph, themes, layout, Pinned, and selection state remain Dashboard responsibilities. The binary owns the host/runtime mutations that humans and agents need to automate reliably.
Open the Dashboard:
open -a tw-dashboardTypical Dashboard flow:
- Click
New worktree. - Choose a local project or SSH host.
- Choose one of the supported agents detected as available on that machine.
- Attach to the tmux terminal, inspect Git state, edit files, and keep scratch terminals nearby.
The macOS app is built with Tauri 2, React, xterm.js, and a Rust PTY backend.
| Area | Purpose |
|---|---|
| Worktrees | Create, restore, attach, clean up, and drag to reorder TW-managed git worktrees. |
| Terminals | Keep and drag to reorder standalone tmux login-shell terminals next to agent sessions. |
| Git panel | Track active branch, changed files, diffs, and recent commits for the selected session cwd. |
| File tree and editor | Browse files, edit source, preview Markdown and images, and search by filename or content. |
| Automations | Define reusable instructions, run them now, pause them, or schedule them. |
| Layout | Persist window state, sidebar state and ordering, column order, editor state, and selected panes. |
Runtime state is stored in user-local JSON files:
| File | Owner | Purpose |
|---|---|---|
~/.tmux-worktree.json |
CLI and Dashboard | Projects, SSH hosts, and worktree root. |
~/.tmux-worktree/state.json |
CLI and Dashboard | TW-managed sessions and worktrees. |
~/.tw-dashboard-layout.json |
Dashboard | Window, columns, sidebar ordering, file tree, editor, diff, and selection state. |
~/.tw-dashboard-terminals.json |
Dashboard | Saved standalone terminals. |
~/.tw-dashboard-automations.json |
Dashboard | Automation definitions. |
~/.tw-dashboard-automation-runs.json |
Dashboard | Recent automation run history. |
Common commands:
tw setup
tw ls
tw serve
tw relay-server
tw relay-host
tw rpc list
tw rpc capabilities
tw host ls --json
tw host probe --json
tw automation lsCreate managed sessions:
tw claude myapp
tw claude myapp fix-auth
tw codex ~/code/backend
tw rpc create-worktree --project myapp --ai-command "claude" --name fix-auth
tw rpc create-terminal --cwd ~/code/backend
tw rpc create-terminal --cwd ~/code/backend --ai-command "codex"
tw rpc restore-worktree --path ~/.tmux-worktree/worktrees/myapp/myapp-fix-abc12 --name myapp-fix
tw rpc kill-session --name tw-term-abc12The Dashboard's New terminal flow always creates the TW-managed single-pane terminal
directly in a login shell. The lower-level CLI/RPC command still accepts an explicit
--ai-command for automated callers that need one.
tw ls is non-interactive and exits after printing the current session list; tw status remains a compatibility alias. Session switching remains available through tw attach <session> and native tmux; the CLI no longer opens an alternate-screen status UI or creates status/extra-shell panes.
Manage and operate configured SSH Hosts without opening the Dashboard:
tw host add --id remote-dev --host remote-dev.example.com --user alice --json
tw host probe remote-dev --json
tw host connect remote-dev --json
tw host rpc remote-dev create-worktree --path /home/alice/code/demo --project demo --name fix-auth --ai-command codex
tw host attach remote-dev demo-fix-auth
tw host disconnect remote-dev --jsontw host uses an isolated SSH ControlMaster socket with bounded keepalives. probe reports SSH reachability, tmux availability, and TW RPC capabilities separately; a missing tmux binary is no longer reported as an SSH outage.
Manage automations:
tw automation create \
--name nightly-review \
--project myapp \
--cmd "codex" \
--instruction "Review recent changes and propose cleanup tasks" \
--schedule "0 9 * * 1-5" \
--timezone Asia/Shanghai
tw automation ls
tw automation rm nightly-reviewRemote Dashboard support assumes the host is reachable by SSH and has git, tmux, Node.js 20+, npm, and tw.
- Add a normal SSH alias:
Host remote-dev
HostName remote-dev.example.com
User alice- Install
twon the remote host:
ssh remote-dev -- 'mkdir -p ~/.local/src'
ssh remote-dev -- 'git clone https://github.com/Sskift/tmux-worktree.git ~/.local/src/tmux-worktree'
ssh remote-dev -- 'cd ~/.local/src/tmux-worktree && npm install && npm run build && npm link --prefix ~/.local'
ssh remote-dev -- 'PATH="$HOME/.local/bin:$PATH" tw version'- Configure remote projects on that host:
ssh remote-dev -- 'cat > ~/.tmux-worktree.json <<JSON
{
"projects": {
"demo": "/home/alice/code/demo"
},
"worktreeBase": "/home/alice/.tmux-worktree/worktrees"
}
JSON'- Open
Settings → Connections → Add host, then create remote worktrees fromNew worktree.
Remote worktrees and standalone terminals are created only through tw rpc create-worktree and tw rpc create-terminal. Discovery merges managed RPC state with strict compatibility checks so older live sessions remain visible; creation never falls back to a second SSH + git/tmux implementation. Upgrade remote tw when the required capability is unavailable or incompatible.
The mobile path has three pieces:
| Piece | Runs on | Role |
|---|---|---|
tw relay-server |
Always-reachable broker host | WebSocket broker only. |
tw relay-host |
Mac admin machine | Aggregates local and configured remote TW-managed sessions. |
| Android APK | Phone | Lists and attaches to sessions exposed through the broker. |
The Dashboard persists the selected Relay center as mobileRelay.brokerHostId. Set up Relay performs the normal flow in one action: it deploys the same-version bundled tw broker, reuses a saved fixed WSS endpoint or starts a temporary Quick Tunnel, saves the generated URL and Relay v1 token, and starts the Mac connector. When a Linux amd64/arm64 Relay center has no cloudflared, Dashboard downloads its pinned official Cloudflare release, verifies the published SHA-256 digest, and installs it under ~/.tmux-worktree/bin before replacing any existing tunnel. Quick Tunnel DNS can propagate after the URL is published, so the connector remains in its explicit retry/backoff state instead of tearing the remote setup down; if macOS still returns a stale negative getaddrinfo result after public A/AAAA records exist, the connector uses those records only for that Quick Tunnel connection while preserving the original WSS hostname and TLS verification. A reconfiguration rotates the shared token. Android pairing is offered only after the connector reaches the trusted root wss:// URL. The editable fields and individual Save/Start controls remain available for fixed production WSS and recovery.
Relay v1 is one trusted administration domain backed by one shared token; it is not a multi-tenant credential model. Hosting unrelated users on one shared Relay service requires the future Relay v2 role-scoped enrollment implementation described in the parallel implementation plan.
For a persistent broker setup, see docs/remote-relay-android.md.
~/.tmux-worktree.json accepts compact strings, objects, and common aliases:
{
"projects": {
"myapp": "/path/to/myapp",
"api": {
"path": "~/code/api",
"branch": "main"
}
},
"hosts": [
"remote-dev",
{
"name": "gpu-box",
"host": "gpu-box"
}
],
"worktreeBase": "~/.tmux-worktree/worktrees"
}Supported aliases:
| Setting | Accepted keys |
|---|---|
| Project map | projects, repositories, repos |
| Project path | path, dir, directory, root, repoPath, repository, repositoryPath |
| Branch | branch, targetBranch, target_branch, defaultBranch, default_branch |
| Worktree root | worktreeBase, worktreeDir, worktreeRoot, worktreesDir, worktreesRoot |
Dashboard connected hosts come only from explicit hosts config. Settings → Connections → Add host can discover non-wildcard aliases from ~/.ssh/config, but it does not auto-connect every SSH alias on the machine.
Requirements:
- Node.js 20+
- Rust stable
- Xcode Command Line Tools
- tmux
- git
- Android Studio or an Android SDK with Java 17 for Android checks
Build the CLI:
npm install
npm run build
node dist/cli.cjs statusRun the Dashboard:
cd app
npm install
npm run tauri devRun aggregate repository verification entry points from the repository root when a change crosses layers or is being prepared for release:
npm run verify # CLI, Dashboard, Rust, and documentation
npm run verify:android # Android JVM tests, Debug/Release lint, and APK builds
npm run verify:all # core plus Android checks
npm run verify:device # all checks plus connected Android device testsThese aggregate commands are not the default for every change and do not by themselves measure test quality. Follow the risk-driven selection and evidence rules in AGENTS.md. The device gate requires a running emulator or connected device; the other Android gates do not. When layer-wide validation is warranted:
npm run test:cli # builds the CLI once, then runs the root tests serially
cd app
npm run build
npm run test:typecheck
npm test
cd src-tauri
cargo fmt --check
cargo check
cargo testFor a targeted root test file, run npm run build first and then invoke
node --test --test-concurrency=1 test/<name>.test.mjs as described in AGENTS.md.
Use the isolated dev app only when state isolation is required:
cd app
npm run tauri:dev:isolatedBuild the CLI plus bundled Dashboard installer assets:
./app/scripts/release.sh --dry-run
./app/scripts/release.shThe release script:
- Builds the Tauri Dashboard DMG.
- Builds the standalone root CLI into
dist/cli.cjswhile retainingdist/*.jsonly as repository-local ESM module builds. - Bundles
dist/cli.cjsinto the Dashboard app astw-cli/cli.cjsfor canonical local lifecycle RPC and the Mobile Relaytw serve/tw relay-hostruntimes. - Copies the DMG to
app/installer/dmg/tw-dashboard-arm64.dmg. - Leaves upload and channel-specific publishing outside the repository.
Before publishing, assign one new version consistently across the root npm package, Dashboard npm package, Tauri config, Rust package, and Android package. Do not rebuild an existing Git tag with different code.
Generated asset inputs:
| Path | Purpose |
|---|---|
dist |
Built CLI. |
app/installer/installer.mjs |
tw-dashboard-install entrypoint. |
app/installer/dmg/ |
Bundled macOS installer image. |
- Agent guide: reading order, code ownership, architectural constraints, and change-to-test matrix for contributors and coding agents.
- Manual: setup, local sessions, SSH remote hosts, remote AI commands, and troubleshooting.
- Architecture: code map, runtime state, release boundaries, and maintenance rules.
- Android architecture: Compose UI V2, state management, Relay v1 limits, and Android acceptance gates.
- Android relay guide: persistent broker, Mac connector, phone pairing, and APK development.
- Relay v2 contract: frozen future protocol contract; no Relay v2 implementation exists yet.
- Relay v2 implementation plan: parallel broker, relay-host, Dashboard, Android, Agent-extension work packages and their interoperability gates.
MIT