See also: Specs
Les developpeurs qui travaillent sur plusieurs projets simultanement font face a une fragmentation de leur environnement de travail : sessions terminal eparpillees, worktrees git geres manuellement, aucune visibilite sur l'etat CI/PR depuis le terminal, et aucune automatisation entre ces outils. Passer d'un projet a un autre demande de retrouver la bonne session, naviguer au bon repertoire, verifier manuellement l'etat du build, et relancer les bons outils. Sur des machines distantes, le probleme est encore pire — il faut SSH, retrouver le contexte, et tout reconfigurer.
Il n'existe pas d'outil qui unifie la gestion de projets dev (sessions terminal + worktrees + CI/CD + automatisation) dans une interface unique, que ce soit en local ou a distance.
zigzag est un gestionnaire de projets dev centre sur Zellij, ecrit en Rust. Il fournit :
- Un binaire unique :
zigzag(TUI interactive) ouzigzag <command>(CLI direct) - Gestion de projets : chaque projet declare dans une config KDL est associe a un repo git. Chaque branche de travail correspond a un worktree git (via worktrunk) et une session Zellij dediee
- Vue unifiee : une TUI ratatui affiche tous les projets, leurs sessions actives, l'etat git, le statut CI/PR GitHub, et les notifications (ex: Claude a fini de travailler)
- Automatisation : un systeme d'autopilot permet de definir des workflows (en KDL) qui reagissent a des evenements (push, CI fail, PR review) et utilisent Claude comme agent de resolution
- Transparence local/remote : les projets distants sont accessibles via SSH (setup worktree) + Zellij HTTPS attach, de maniere transparente depuis la meme interface
- As a developer, I want to list all my active projects and their sessions in a single view, so that I can see my entire work context at a glance
- As a developer, I want to open a project session with a single command (
zigzag open myapp), so that I don't have to manually navigate directories and start tools - As a developer, I want
zigzagto automatically create a Zellij session with Claude and a shell tab when I open a project, so that my environment is ready to work immediately - As a developer, I want to open a new branch session (
zigzag open myapp feat/login), so that a worktree is created and a dedicated Zellij session is launched automatically - As a developer, I want to choose between working on
mainor creating a new worktree when opening a project, so that I have full control over my branching strategy - As a developer, I want to close a session (
zigzag close) without deleting the worktree, so that I can resume later - As a developer, I want to delete a session (
zigzag delete) and be prompted to also delete the worktree, so that I can clean up when a feature branch is done - As a developer, I want to prune orphaned sessions and worktrees (
zigzag prune), so that my system stays clean over time - As a developer, I want each session named
{project}:{branch}, so that I can identify them easily and they are compatible with Zellij remote URLs
- As a developer, I want to declare my projects in a global KDL config (
~/.config/zigzag/projects.kdl), so thatzigzagknows where my repos live - As a developer, I want to override the default layout per project via
.config/zigzag.kdlin the repo, so that each project can have custom tabs (server, logs, etc.) - As a developer, I want to configure Claude arguments per project (e.g.,
--resume), so that Claude starts with the right context - As a developer, I want to set global preferences (keybindings, notifications, default layout) in
~/.config/zigzag/config.kdl, so that my experience is consistent across projects - As a developer, I want to configure minimum dependency versions in my global config, so that
zigzagwarns me if my tools are outdated - As a developer, I want
zigzagto verify thatzellij,wt, andghare installed at launch, so that I get a clear error message instead of cryptic failures
- As a developer, I want an interactive TUI when I run
zigzagwithout arguments, so that I can navigate my projects visually - As a developer, I want to see a project list on the left and its sessions on the right, so that I can quickly find what I'm looking for
- As a developer, I want to fuzzy-search projects and sessions by pressing
/, so that I can navigate large lists quickly - As a developer, I want a preview pane showing branch status (ahead/behind, dirty/clean), recent commits, PR number and CI status, and Zellij session info (tabs, panes, uptime), so that I have full context without leaving
zigzag - As a developer, I want the preview to load progressively (structure first, then git, then PR/CI), so that the UI feels responsive even when GitHub API is slow
- As a developer, I want to see icons indicating active sessions, remote projects, and notifications, so that I can scan the project list quickly
- As a developer, I want arrow key navigation by default with configurable vim-style keybindings, so that the TUI is accessible but customizable
- As a developer, I want the TUI theme to auto-detect from my terminal, so that it looks good without manual configuration
- As a developer, I want keyboard shortcuts for all actions (open, new, delete, prune, autopilot, search, quit), so that I never need a mouse
- As a developer, I want to be notified when Claude finishes working in a pane, so that I can review the results without polling
- As a developer, I want to be notified when CI status changes (pass to fail or fail to pass), so that I can react quickly
- As a developer, I want to be notified when an autopilot completes (success or failure), so that I know the outcome without watching it
- As a developer, I want to be notified when a PR review is received, so that I can address comments promptly
- As a developer, I want to configure notification channels (macOS native, Telegram, TUI badge), so that I receive alerts where I want them
- As a developer, I want notifications to appear as badges in the TUI session list, so that I can see at a glance which sessions need attention
- As a developer, I want to define automated workflows in KDL that trigger on events (push, CI fail, PR review), so that repetitive tasks are handled without my intervention
- As a developer, I want a
pr-ci-fixautopilot that monitors CI, asks Claude to fix failures, pushes, and retries up to N times, so that CI issues are resolved automatically - As a developer, I want a
pr-review-fixautopilot that reads PR review comments and asks Claude to resolve them, so that I don't have to manually address each comment - As a developer, I want a
pr-merge-when-readyautopilot that merges my PR when it's approved and CI is green, then cleans up the session and worktree, so that the merge lifecycle is fully automated - As a developer, I want a
dependabot-autoautopilot that auto-merges Dependabot PRs when tests pass, so that dependency updates don't pile up - As a developer, I want a
deploy-watchautopilot that monitors deploys and rolls back on failure, so that I can deploy with confidence - As a developer, I want a
deploy-syncautopilot that polls main for new commits, shows a diff summary, asks for confirmation, then deploys, so that I can keep environments in sync with minimal effort - As a developer, I want autopilots to run in the background by default so I can close my laptop, and optionally watch them in a Zellij pane (
zigzag autopilot watch), so that I have full flexibility - As a developer, I want autopilot state persisted to disk so it survives restarts, so that long-running workflows are reliable
- As a developer, I want autopilots to be full-auto by default (Claude commits and pushes directly), so that the automation is truly hands-off
- As a developer, I want to configure
auto_push: falseandreview: trueper project or per workflow, so that I can require human approval before pushes when needed - As a developer, I want to define custom autopilot workflows in my project's
.config/zigzag.kdl, so that I can automate project-specific tasks - As a developer, I want the
runstep in autopilots to accept any shell command, so that I have an escape hatch for arbitrary automation - As a developer, I want autopilots to have a
max-retriessetting with a notification when exhausted, so that infinite loops are prevented
- As a developer, I want to declare a remote project with
hostandtokenin my projects config, so thatzigzagknows how to reach it - As a developer, I want
zigzag openon a remote project to SSH-setup the worktree thenzellij attach https://..., so that remote sessions are as easy as local ones - As a developer, I want to store remote tokens as environment variable references (
env:VAR), so that secrets are not in plaintext config files - As a developer, I want multiplayer support when multiple people attach to the same remote session, so that we can pair-program with distinct cursors
- As a developer, I want the TUI to show remote projects with a distinct icon, so that I can tell local from remote at a glance
- As a developer, I want the core logic in
zigzag-coreto be I/O-agnostic via traits, so that it can be compiled to WASM for a Zellij plugin or web UI without rewriting business logic - As a developer, I want a future Zellij WASM plugin that embeds the
zigzagTUI directly inside Zellij, so that I don't need a separate terminal to manage projects - As a developer, I want a future
zigzag webcommand that serves the TUI in a browser via xterm.js, so that I can manage projects from any device
- Rust workspace with 6 crates:
zigzag-core(business logic),zigzag-tui(ratatui),zigzag-cli(non-interactive commands),zigzag-autopilot(state machine + workflows),zigzag-plugin(future WASM),zigzag-web(future axum + xterm.js) - Single binary:
zigzagwithout args launches TUI,zigzag <cmd>runs CLI zigzag-coreis 100% I/O-agnostic via traits (ProjectStore,SessionManager,WorktreeManager,ForgeClient,Notifier). No directstd::fsorstd::process::Command. This is the key architectural constraint enabling WASM portability
- Zellij (>= 0.44.0): terminal multiplexer, sessions, layouts, remote HTTPS attach
- worktrunk (
wt) (>= 0.34.0): git worktree management, hooks, cleanup, pruning - gh CLI (>= 2.0.0): GitHub PR and CI status queries
- All three are verified at launch;
zigzagfails with a clear message if any is missing or below minimum version
- KDL everywhere: global config, project list, per-repo overrides, autopilot workflows. Chosen for coherence with Zellij's native config format
- Three-tier config: global (
~/.config/zigzag/config.kdl) < project list (~/.config/zigzag/projects.kdl) < per-repo (.config/zigzag.kdl)
- Session naming:
{project}:{branch}with/replaced by-for URL compatibility - Default layout per session: tab "claude" (runs
claude) + tab "shell" (empty terminal), overridable per project - Claude launched on every session (main and feature worktrees)
- Fully delegated to worktrunk (
wt switch,wt remove,wt list). No custom worktree logic inzigzag - On
zigzag delete: kill Zellij session, then prompt user to confirm worktree removal viawt remove
- SSH for worktree setup on remote machine, then
zellij attach https://host:port/session --token - Requires Zellij service (systemd), worktrunk, and git repos on the remote machine
- Multiplayer natively supported by Zellij
- ratatui framework, theme auto-detected from terminal
- Three-panel layout: projects (left), sessions (right), preview (bottom)
- Preview shows: branch tracking, dirty/clean, PR number, CI status, Zellij session info (tabs, panes, uptime), recent commits
- Progressive async loading: structure renders instantly, data fills in as it arrives
- Fuzzy search via
/key - Arrow keys by default, vim-style configurable
- Phase 1: file-based (
/tmp/zigzag/notifications/{session}). Claude Code hook writes to this directory. TUI watches it - Phase 4+: migrate to Zellij pipe / plugin events
- Channels: macOS native (default local), Telegram, TUI badge. Configurable in global config
- DSL in KDL for declarative workflow definition, with
runescape hatch for arbitrary shell commands - Background execution by default, optional live pane via
zigzag autopilot watch - State machine persisted to disk (survives restarts)
- Full-auto by default (Claude commits + pushes). Configurable
auto_push: false+review: truefor human-in-the-loop - 6 built-in workflows:
pr-ci-fix,pr-review-fix,pr-merge-when-ready,dependabot-auto,deploy-watch,deploy-sync - Custom workflows in per-repo
.config/zigzag.kdl
| Phase | Scope |
|---|---|
| 1a | CLI: zigzag open, zigzag list, zigzag close, zigzag delete. Config KDL. Dep checks. Dynamic layout generation |
| 1b | TUI: ratatui, project/session navigation, fuzzy search, basic actions |
| 1c | Enriched TUI: preview pane (git + Zellij + PR/CI), Claude notifications |
| 2 | Cleanup: zigzag prune, advanced worktrunk integration |
| 3 | Remote: SSH setup + Zellij HTTPS attach, host/token config |
| 4 | Zellij WASM plugin — TUI embedded in Zellij |
| 5 | Web UI — ratatui WASM + xterm.js, Leptos fallback, axum server |
| 6 | Autopilot: state machine, KDL DSL, built-in workflows, notifications |
- Test external behavior through the trait interfaces, not implementation details
- A test should answer: "does
zigzag-coreproduce the correct output given these inputs?" — not "does it callgit statuswith the right flags?" - Use mock implementations of the I/O traits to test
zigzag-corein isolation, without filesystem or process dependencies - Integration tests (with real git repos, real
wt, realzellij) live in a separate test suite and run in CI only
- ProjectStore: loading/parsing KDL config, project resolution, config merging (global < project < per-repo)
- SessionManager: session naming conventions, session lifecycle (create → attach → close → delete), worktree ↔ session mapping
- WorktreeManager: worktree creation/deletion flows, interaction with session lifecycle (delete session → prompt worktree removal)
- ForgeClient: PR resolution by branch, CI status parsing, error handling when
ghis unavailable - Layout generation: dynamic KDL layout generation from config (default layout, per-project overrides, Claude args injection)
- Config parsing: KDL config validation, three-tier merging,
env:VARtoken resolution, version constraint parsing
- State machine: step transitions (on-success, on-failure, on-complete, on-max-retries), persistence/recovery from disk, max-retries enforcement
- Workflow parsing: KDL autopilot definition parsing, validation (no orphan steps, no cycles, valid triggers)
- Trigger system: event matching (post-push, pr-approved, manual, etc.)
- Notification dispatch: correct channel selection based on config, message formatting
- Integration tests: end-to-end flows (
zigzag open→ session created →zigzag delete→ session killed + worktree prompt) - Dependency verification: correct error messages when tools are missing or below version
- Snapshot tests for rendered UI states (project list, preview pane, notification badges) using ratatui's test backend
- No interactive testing — trust ratatui's own test infrastructure
- Multi-forge support (GitLab, Bitbucket, etc.) — GitHub only via
ghCLI - Session resurrection — exited Zellij sessions are ignored, not resurrected
- Custom worktree management — fully delegated to worktrunk, no reimplementation
- Automatic installation of dependencies —
zigzagverifies presence and version, user installs manually - IDE integration —
zigzagis terminal-native, no VS Code or JetBrains plugins planned - Mobile app — web UI (phase 5) covers mobile access via browser
- Conflict resolution in worktrees — delegated to git/developer, not
zigzag's responsibility
- Users who still want the former short command can define
alias z=zigzagin their shell profile. - The I/O-agnostic
zigzag-coreconstraint adds initial development cost but is non-negotiable — it is the foundation enabling phases 4 (WASM plugin) and 5 (web UI) - worktrunk already has Claude integration (
wt config plugins claude) and lifecycle hooks which may simplify some autopilot triggers - Zellij v0.44+ HTTPS remote attach is recent (March 2026) — early adopter risk is accepted
- The autopilot system is phase 6 but its architecture (state machine, notifications) should be considered from phase 1 to avoid
zigzag-coreredesign later