Work in progress: Grove is still cooking, things may change quickly, and I reserve the right to break your workflows :) Thanks for rolling with it.
Minimal workspace manager for AI coding agents (Rust + FrankenTUI).
Grove helps you run many agent tasks in parallel, each in its own git worktree and tmux session, with one fast keyboard-first TUI.
Grove is a focused workspace manager for AI coding agents, built with Rust and FrankenTUI.
It is built for a single job: manage isolated coding workspaces, launch agents, monitor output live, and clean up safely.
- Git worktree lifecycle, create, edit, merge, update-from-base, delete
- Agent runtime per workspace via tmux sessions (persistent across TUI restarts)
- Supported agents, Claude Code, Codex, and OpenCode
- Interactive mode inside the TUI (send keys directly to running sessions)
- Live output preview with ANSI rendering and cursor-aware display
- Git preview tab via
lazygit - Workspace status detection (idle, active, thinking, waiting, done, error)
- Multi-project switching from config
- Mouse support (selection, scroll, pane resize)
- Command palette + keybind help modal
- Event logs and debug record stream for diagnostics
- Single-repo workflow per active project
- tmux-only multiplexer support
- No plugin system
- No issue tracker / kanban features
- No PR automation layer
Required binaries on PATH:
gittmuxlazygit
Rust toolchain is required to build from source.
Quick check:
command -v git tmux lazygitMost contributors only need one of these:
# run without installing
nix run github:MichaelVessia/grove
# or run from this repo
direnv allow # or: nix develop
make tuiRun directly:
nix run github:MichaelVessia/groveInstall to profile:
nix profile install github:MichaelVessia/groveUse as an overlay in another flake:
{
inputs.grove.url = "github:MichaelVessia/grove";
# nixpkgs.overlays = [ grove.overlays.default ];
# then use pkgs.grove
}Use with Home Manager:
{
inputs.grove.url = "github:MichaelVessia/grove";
# In your Home Manager config:
imports = [ inputs.grove.homeManagerModules.grove ];
programs.grove = {
enable = true;
# Optional: override tool paths
environment = {
GROVE_CLAUDE_CMD = lib.getExe pkgs.claude-code;
GROVE_LAZYGIT_CMD = lib.getExe pkgs.lazygit;
};
};
}Available environment overrides: GROVE_CLAUDE_CMD, GROVE_CODEX_CMD,
GROVE_OPENCODE_CMD, GROVE_LAZYGIT_CMD.
Add Grove to your devbox.json:
devbox add github:MichaelVessia/grovedirenv allow
cargo buildnix develop
cargo buildcargo build --releaseBinary path:
target/release/grove# one-time in this clone, if outside nix shell
git config --local core.hooksPath .githooks
# enter dev env (pick one)
direnv allow # or: nix develop
# fast checks, then launch
make precommit
make tuimake tui # launch TUI
make debug-tui # launch TUI with debug record enabled
make precommit # cargo fmt --check + cargo check + cargo clippy -D warnings
make ci # cargo fmt --check + cargo clippy -D warnings + cargo test
make test # run testsInside Grove:
nnew workspaceeedit workspace (base branch, or branch switch on main)anew agent tab (opens agent picker + launch options)snew shell tabgopen/focus git tab,rename active tabEnteropen preview / interactive attach (context dependent)xkill active tab sessionXclose active tab (confirm kill+close if session is live)mmerge workspace branch into baseuupdate selected workspace (feature merges from base, base pulls from origin)Rrefresh workspace list + GitHub PR metadataDdelete workspacepopen project switcherSsettingsCtrl+Kcommand palette?keybind helpqquit (with confirm modal)
--print-hello, sanity check output path--event-log <path>, write event log to explicit file (relative/pathis stored under.grove/relative/path)--debug-record, write continuous debug record to.grove/debug-record-*.jsonlreplay <trace-path>, headless replay of a debug-record tracereplay <trace-path> --invariant-only, replay with state/invariant checks onlyreplay <trace-path> --snapshot <path>, write replay snapshot JSONreplay <trace-path> --emit-test <name>, copy trace intotests/fixtures/replay/<name>.jsonlbenchmark-scale, run workspace scale benchmark harness (N=10,100,500)benchmark-scale --json, emit machine-readable benchmark outputbenchmark-scale --write-baseline <path>, write benchmark JSON baselinebenchmark-scale --baseline <path>, compare current results against a baseline and warn on severe p95 regressionsbenchmark-scale --warn-regression-pct <N>, adjust severe regression threshold percent (default 35)
Example:
cargo run -- --debug-record
tail -f .grove/debug-record-*.jsonl
# replay a saved trace
cargo run -- replay .grove/debug-record-*.jsonl
# replay and emit a snapshot for diffs
cargo run -- replay .grove/debug-record-*.jsonl --snapshot .grove/replay-snapshot.json
# promote a trace into a fixture input
cargo run -- replay .grove/debug-record-*.jsonl --emit-test flow-a
# run workspace scale benchmarks and write baseline JSON
cargo run -- benchmark-scale --write-baseline .grove/workspace-scale-baseline.json
# compare against previous baseline
cargo run -- benchmark-scale --baseline .grove/workspace-scale-baseline.jsonDetailed replay workflow:
Workspace scale benchmark details:
Config file paths:
- Linux/macOS (via XDG when available):
~/.config/grove/config.toml, global settings only~/.config/grove/projects.toml, projects + mutable runtime state
One-time migration prompt for existing single-file users:
Grove behavior:
- Reads
config.toml, writesthemewhen saved from Settings modal - Reads and writes
projects.tomlfor mutable state sidebar_width_pctandlaunch_skip_permissionsare immutable at runtime, editconfig.tomlto persist changes
config.toml includes:
sidebar_width_pctlaunch_skip_permissionstheme(monokai,catppuccin-latte,catppuccin-frappe,catppuccin-macchiato,catppuccin-mocha)
launch_skip_permissions behavior:
- Controls default unsafe-mode launch behavior for Claude/Codex/OpenCode
- Workspace-specific
.grove/skip_permissionsmarker overrides it - Agent session inference can override it when marker is absent
projects.toml includes:
projectslist (name,path,defaults)attention_acks- per-project
defaults.agent_envfor agent-specific env vars used at launch
Example config.toml:
sidebar_width_pct = 33
launch_skip_permissions = false
theme = "catppuccin-mocha"Example projects.toml:
[[projects]]
name = "grove"
path = "/path/to/repo"
[projects.defaults]
base_branch = "main"
workspace_init_command = "direnv allow"
[projects.defaults.agent_env]
claude = ["CLAUDE_CONFIG_DIR=~/.claude-work"]
codex = ["CODEX_CONFIG_DIR=~/.codex-work"]
opencode = []Grove's workflow and UX direction were heavily inspired by Sidecar, which was the main reference for session lifecycle, interaction model, and overall operator experience.
Also built on FrankenTUI.
MIT, see LICENSE.
