Zpit (zac + cockpit) β a TUI-based AI development cockpit that orchestrates Claude Code agents across multiple projects. Zpit acts as a dispatch center β it selects projects, launches agents in separate terminal windows, monitors their progress, coordinates the full issue lifecycle from requirement clarification to PR, and enables real-time cross-agent communication via a built-in HTTP broker + MCP channel.
Key principle: Claude Code runs in independent terminal windows. Zpit never wraps or embeds it β it monitors via session logs, coordinates via issue trackers, and bridges agents via a local channel broker.
Zpit v0.1 03/27 14:07 Windows Terminal
Projects Hotkeys
ββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββ
βοΈ AI Inspection Cleaning Demo [Enter] Launch Claude Code
machine β wpf, ethercat, basler [c] Clarify requirement
[l] Loop auto-implement
βοΈ ENR DUC [r] Review changes
machine β wpf, secsgem [f] Efficiency agent
[s] Status overview
π₯οΈ DisplayProfileManager [o] Open project folder
desktop β wpf, nlog [p] Open Issue Tracker
[u] Undeploy agents
βΊ π₯οΈ Zpit [m] Channel communication
desktop β go, bubbletea
[a] Add project
[e] Edit config
[x] Close Terminal
[Tab] Switch Panel
[?] Help
[q] Quit
Active Terminals
ββββββββββββββββββββββββββββββββββββββββββββββββββ
[1] AI Inspection Cleaning Demo β π‘ Waiting for input 04:15
Q: Issue B pushed: **[#25 β feat(manual-control): Safety Interlock + Soft Lim
[2] Zpit β π‘ Waiting for input 08:36
Q: Pushed to `origin/dev`. Commit `2094bea`.
[3] Zpit β π’ Launched 00:09
Tab: Zpit
Loop Status
ββββββββββββββββββββββββββββββββββββββββββββββββββ
AI Inspection Cleaning Demo (running)
π’ #25 feat(manual-control): Safety Interlock... coding
Press ? for help, q to quit
Zpit v0.1 03/27 14:04 Windows Terminal
Issues β AI Inspection Cleaning Demo
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΊ #25 [pending] feat(manual-control): Safety Interlock + Soft Limit + Reset Zero
[y] Confirm (pendingβtodo) [p] Open in browser [Esc] Back
You (TUI) Claude Code Agents
β
ββ [c] Clarify βββββββββββΊ Clarifier agent (new terminal)
β requirement asks questions, creates structured issue
β (press multiple times) agents auto-discover via agent_type, enter Facilitator/Advisor meeting mode
β
ββ [l] Loop βββββββββββββββΊ Coding agent (worktree + new terminal)
β auto-implement implements, commits, opens PR
β β
β ββ PR appears ββββΊ Reviewer agent (same worktree)
β β checks AC, writes review report
β ββ PASS βββββΊ waits for human merge
β ββ NEEDS CHANGES β auto-retry coding (up to N rounds)
β
ββ [s] Status βββββββββββββΊ shows issue list from tracker
ββ [r] Review βββββββββββββΊ launches reviewer on demand
ββ [f] Efficiency βββββββββΊ lightweight agent (no hooks, no tracker, self-review)
ββ [Enter] ββββββββββββββββΊ launches Claude Code directly
- Multi-project dashboard β switch between projects with arrow keys, mouse scroll support
- Loop engine β fully automated: poll todo issues β create worktree β coding agent β reviewer β PR merge β cleanup
- Task decomposition β when an Issue Spec contains
## TASKS, the coding agent delegates totask-runnersubagents (sequential or parallel via Agent Teams) - Agent monitoring β real-time status via session log parsing (Working / Waiting / Permission / Ended), auto-detects running sessions on startup, survives
/resumesession switches - Notifications β Windows Toast + sound when an agent needs your input or awaits tool permission
- Issue tracker integration β Forgejo/Gitea and GitHub via REST API + MCP
- Cross-agent channel β real-time agent-to-agent communication via HTTP broker + MCP; supports same-project, cross-project, and global broadcast messaging
- Meeting mode β multiple clarifier agents auto-discover via
agent_typetracking, assign Facilitator/Advisor roles, and converge to a structured issue through coordinated channel communication - 5-layer safety system β agent-guidelines.md, allowed tools, PreToolUse hooks, git worktree isolation, human PR review
- Per-issue branch control β clarifier asks target branch, coding agent enforces it
- Auto-retry β reviewer judges NEEDS CHANGES β coding agent auto-fixes β re-review (configurable rounds)
- i18n β English and Traditional Chinese (zh-TW) via
locale.T() - SSH remote access β
zpit serveruns a headless SSH daemon (Wish), multiple clients share one dashboard with real-time state sync;auto_servemode starts the server automatically when runningzpit, enabling seamless mobile access without workflow interruption
- Go 1.26+
- Claude Code CLI installed and authenticated
- Windows Terminal (Windows) or tmux (Linux/WSL)
- A Forgejo/Gitea or GitHub issue tracker
# Build
go build -o zpit .
# First run β creates config template at ~/.zpit/config.toml
./zpit
# Edit the config with your projects and tracker tokens, then:
./zpit
# SSH server mode (remote access)
./zpit serve # Start headless SSH daemon (default port 2200)
./zpit connect # SSH connect to local server
# Or enable auto_serve in config β then just "./zpit" starts
# the SSH server automatically and connects to it.
# You can SSH in from your phone at any time.Config lives at ~/.zpit/config.toml. Override with ZPIT_CONFIG env var.
language = "en" # en | zh-TW
broker_port = 17731 # HTTP broker port for cross-agent channel
# zpit_bin = "/usr/local/bin/zpit" # explicit binary path for .mcp.json generation
[terminal]
windows_mode = "new_tab" # new_tab | new_window
tmux_mode = "new_window" # new_window | new_pane
# windows_terminal_profile = "PowerShell 7" # WT profile name for -p flag
[notification]
tui_alert = true
windows_toast = true
sound = true
# sound_file = "D:/sounds/notify.mp3" # custom notification sound (WAV/MP3/M4A/OGG)
re_remind_minutes = 2
[worktree]
base_dir_windows = "D:/worktrees"
base_dir_wsl = "/mnt/d/worktrees"
max_per_project = 5
poll_seconds = 10 # todo issue polling interval
pr_poll_seconds = 10 # PR merge polling interval
max_review_rounds = 3 # auto-retry rounds before needs-human
# dir_format = "{project_id}/{issue_id}--{slug}"
# auto_cleanup = false
# Tracker providers β token read from env var, never stored in config
[providers.tracker.my-forgejo]
type = "forgejo_issues"
url = "https://your-forgejo.example.com"
token_env = "FORGEJO_TOKEN"
# Git providers (optional β for Forgejo/Gitea PR API)
# [providers.git.my-forgejo]
# type = "forgejo"
# url = "https://your-forgejo.example.com"
# token_env = "FORGEJO_TOKEN"
# Profiles control logging strictness for agents
[profiles.machine]
log_policy = "strict" # strict | standard | minimal
# Projects
[[projects]]
name = "My Project"
id = "my-project"
profile = "machine"
hook_mode = "strict" # strict | standard | relaxed
tracker = "my-forgejo"
# tracker_project = "My_Project" # tracker project name if different from repo
# git = "my-forgejo" # git provider for PR operations
repo = "org/repo"
base_branch = "dev"
# shared_core = false
# log_level = "standard"
channel_enabled = false # enable cross-agent channel communication
channel_listen = [] # subscribe to other projects' events, e.g. ["_global", "other-proj"]
tags = ["go"]
[projects.path]
windows = "D:/Projects/my-project"
wsl = "/mnt/d/Projects/my-project"
# SSH server (optional β for remote TUI access)
# [ssh]
# port = 2200
# host = "0.0.0.0"
# host_key_path = "~/.zpit/ssh/host_ed25519"
# password_env = "ZPIT_SSH_PASSWORD"
# authorized_keys_path = "~/.ssh/authorized_keys"
# auto_serve = false # when true, "zpit" auto-starts SSH server + connects| Key | Action |
|---|---|
Enter |
Launch Claude Code in new terminal |
c |
Clarify β open clarifier agent to create structured issue |
l |
Loop β toggle automated coding + review cycle |
r |
Review β launch reviewer agent |
f |
Efficiency β lightweight agent (no hooks, no tracker, self-review) |
s |
Status β view issue list from tracker |
o |
Open project folder |
p |
Open issue tracker in browser |
u |
Undeploy β remove deployed agents, docs, hooks |
m |
Channel β view cross-agent communication events |
g |
Git Status β view branches (local + remote-only) and commit graph; [f] fetch, [p] pull (--ff-only) |
a |
Add project (coming soon) |
e |
Edit config β sub-menu: toggle channel, edit channel_listen, open in $EDITOR |
x |
Close Terminal β force-close selected terminal (when Terminals panel focused) |
Tab |
Switch focus between panels (Projects, Terminals, Loop Slots) |
? |
Help |
q |
Quit |
The loop engine automates the full coding cycle:
- Poll tracker for
todoissues (configurable interval) - Create worktree β isolated git worktree from
base_branch - Launch coding agent β writes implementation, commits, opens PR, sets
reviewlabel - Detect completion β polls issue labels for
review(agents don't need to exit) - Launch reviewer β checks acceptance criteria, writes review report, sets verdict label
- Detect verdict β polls issue labels for
ai-review(PASS β wait for human merge) orneeds-changes(auto-retry up tomax_review_rounds) - Cleanup β after PR merge, removes worktree and branch
Multiple issues run in parallel, limited by max_per_project.
Zpit enforces 5 layers of safety to prevent agents from causing damage:
| Layer | Mechanism | Scope |
|---|---|---|
| 1 | agent-guidelines.md behavioral rules | Soft β agent reads on startup |
| 2 | --allowedTools per agent role |
Medium β Claude Code enforced |
| 3 | PreToolUse hooks | Hard β enforced even with --bypass-all-permissions |
| 4 | Git worktree isolation | Physical β agents can't touch main repo |
| 5 | Human PR review | Final gate β nothing merges without you |
PreToolUse hooks:
path-guard.shβ confines Write/Edit to worktree directorybash-firewall.shβ blocks destructive commands (rm -rf, curl|bash, force push, etc.)git-guard.shβ push whitelist (onlyfeat/*branches), blocks merge, rebase, branch-delete, force push
Notification hook:
notify-permission.shβ writes signal file when Claude Code needs tool permission approval; TUI detects and shows π status + toast notification
Hook strictness is per-project: strict (all hooks), standard (path-guard + git-guard), relaxed (git-guard only). Notification hook is always active in all modes.
The clarifier agent produces structured issues:
## CONTEXT
[Problem description with specific file names and behavior]
## APPROACH
[Selected solution + reasoning]
## ACCEPTANCE_CRITERIA
AC-1: [Specific, verifiable condition]
AC-2: ...
## SCOPE
[modify] path/to/file (reason)
[create] path/to/new-file (reason)
## CONSTRAINTS
[Hard limits]
## BRANCH
[Optional: PR target branch, defaults to project base_branch]
## TASKS
[Optional: Task decomposition β triggers subagent delegation]
T1: [task description] | [modify] path/to/file
T2: [task description] [P] | [modify] path/to/other # [P] = parallelizable
T3: [task description] [depends:T1] | [create] path/to/new
## COORDINATES_WITH
[Optional: Cross-agent coordination for parallel work]
#42: Brief description of related issue
## REFERENCES
[Optional: URLs, related files]go build ./... # Build
go test ./... # Run all tests
make test-hooks # Run hook tests (requires bash)
go run . # Local TUI (or auto-serve if ssh.auto_serve=true)
go run . serve # SSH server mode
go run . connect # SSH client shortcutLogs: ~/.zpit/logs/zpit-YYYY-MM-DD.log β daily rotation, 30-day retention.
See docs/architecture/ for the full architecture documents (split by topic, with an index).
Zpit is built on top of the following open source libraries:
| Library | Purpose | License |
|---|---|---|
| Bubble Tea | TUI framework | MIT |
| Bubbles | TUI components (list, text input, etc.) | MIT |
| Lip Gloss | TUI styling and layout | MIT |
| Huh | Form and confirm dialogs | MIT |
| Wish | SSH server for TUI remote access | MIT |
| BurntSushi/toml | TOML config parser | MIT |
| fsnotify | Filesystem watcher (session log monitoring) | BSD-3-Clause |
| go-colorful | Color math for terminal rendering | MIT |
| muesli/termenv | Terminal environment detection | MIT |
| rivo/uniseg | Unicode text segmentation | MIT |
| mattn/go-runewidth | Rune display width calculation | MIT |
| bubbletea-overlay | Overlay rendering for confirm dialogs | MIT |
| golang.org/x/sys, x/text | Go extended standard library | BSD-3-Clause |
All Charmbracelet libraries (bubbletea, bubbles, lipgloss, huh, wish, ssh) are copyright Β© Charmbracelet, Inc., licensed under the MIT License.
fsnotify and golang.org/x/* are BSD-3-Clause; their copyright notices are retained as required.
MIT