Skip to content

MichaelVessia/grove

Repository files navigation

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.

Grove

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 TUI screenshot

What Grove Is

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.

What Grove Supports

  • 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

Scope

  • Single-repo workflow per active project
  • tmux-only multiplexer support
  • No plugin system
  • No issue tracker / kanban features
  • No PR automation layer

Requirements

Required binaries on PATH:

  • git
  • tmux
  • lazygit

Rust toolchain is required to build from source.

Quick check:

command -v git tmux lazygit

Install

Most 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 tui

Option 1, Nix flake (recommended)

Run directly:

nix run github:MichaelVessia/grove

Install to profile:

nix profile install github:MichaelVessia/grove

Use 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.

Option 2, Devbox

Add Grove to your devbox.json:

devbox add github:MichaelVessia/grove

Option 3, direnv (auto Nix shell)

direnv allow
cargo build

Option 4, Nix dev shell

nix develop
cargo build

Option 5, plain Cargo

cargo build --release

Binary path:

target/release/grove

Quick Start

# 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 tui

Common Commands

make 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 tests

Inside Grove:

  • n new workspace
  • e edit workspace (base branch, or branch switch on main)
  • a new agent tab (opens agent picker + launch options)
  • s new shell tab
  • g open/focus git tab
  • , rename active tab
  • Enter open preview / interactive attach (context dependent)
  • x kill active tab session
  • X close active tab (confirm kill+close if session is live)
  • m merge workspace branch into base
  • u update selected workspace (feature merges from base, base pulls from origin)
  • R refresh workspace list + GitHub PR metadata
  • D delete workspace
  • p open project switcher
  • S settings
  • Ctrl+K command palette
  • ? keybind help
  • q quit (with confirm modal)

CLI Flags

  • --print-hello, sanity check output path
  • --event-log <path>, write event log to explicit file (relative/path is stored under .grove/relative/path)
  • --debug-record, write continuous debug record to .grove/debug-record-*.jsonl
  • replay <trace-path>, headless replay of a debug-record trace
  • replay <trace-path> --invariant-only, replay with state/invariant checks only
  • replay <trace-path> --snapshot <path>, write replay snapshot JSON
  • replay <trace-path> --emit-test <name>, copy trace into tests/fixtures/replay/<name>.jsonl
  • benchmark-scale, run workspace scale benchmark harness (N=10,100,500)
  • benchmark-scale --json, emit machine-readable benchmark output
  • benchmark-scale --write-baseline <path>, write benchmark JSON baseline
  • benchmark-scale --baseline <path>, compare current results against a baseline and warn on severe p95 regressions
  • benchmark-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.json

Detailed replay workflow:

Workspace scale benchmark details:

Configuration

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, writes theme when saved from Settings modal
  • Reads and writes projects.toml for mutable state
  • sidebar_width_pct and launch_skip_permissions are immutable at runtime, edit config.toml to persist changes

config.toml includes:

  • sidebar_width_pct
  • launch_skip_permissions
  • theme (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_permissions marker overrides it
  • Agent session inference can override it when marker is absent

projects.toml includes:

  • projects list (name, path, defaults)
  • attention_acks
  • per-project defaults.agent_env for 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 = []

Credits

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.

License

MIT, see LICENSE.

About

Workspace manager for AI coding agents

Resources

License

Stars

Watchers

Forks

Contributors

Languages