grove

Design philosophy

Grove's scope is held together by a small set of founding rules. Two still hold — removing either roughly doubles the editor surface area. A third was deliberately relaxed, and what survived of it explains a lot about how Grove feels.

1. Single canonical base branch

Every task worktree in a workspace forks from the same base branch — detected as main, falling back to master, falling back to the current branch. The default can be changed in Settings → Git / GitHub.

Why this matters

  • Eliminates the divergent-base problem.
  • Makes every cross-task view trivially correct — a file's activity stripes, the per-task diff overlay, the unified picture of what all agents changed. Every diff is "this task on top of the base," with no per-task base juggling.
  • Refresh is one action: "bring everyone up to today's main."

What happens during refresh

You trigger a refresh explicitly, from the task rail. Grove fetches the new base, then rebases each active task's worktree onto it:

  • Clean rebase → the task continues against the new base.
  • Conflicts → the rebase auto-aborts for that task and the conflict is flagged; you resolve it in the worktree with git. Other tasks proceed unaffected.

Why rebase, not merge

Rebase keeps task branches linear against the base, so the per-task diff stays "what this task changed on top of today's main" instead of "what this task changed plus every merge commit since." The cross-task views depend on diffs that don't drag merge noise.

2. Worktree per task

  • Each task = one git worktree. No sharing, no stacked tasks.
  • Agent isolation is at the filesystem-path level. No containers.

Cost profile

  • Disk: cheap. .git/objects is shared; only the working tree duplicates, and it's lazily materialized — a task that never spawns an agent never populates files. See Tasks and worktrees.
  • Safety: a cross-window lock ensures one worktree is never driven from two windows at once. See Multi-window.

Why no stacked tasks

Stacked tasks (task B branching off task A) make the unified picture nontrivial: B's diff is now against A, not the base, and rebasing the stack is its own UX. Grove punts.

3. Readonly source — relaxed

The original rule: source files are a readonly viewer, because the agents do the writing and the human only reviews. No cursor edits, no save state, no user-vs-agent conflict.

This has been relaxed. Files under a task worktree (and workspace files outside Grove's internals) are editable in place with auto-save — see File tree and viewer. What survives is the posture: Grove is still review-first. The primary surface is the diff overlay on a live file, not a blank-page authoring editor, and Grove isn't trying to out-edit Cursor — it's trying to make reading and steering scale.

What relaxing the live rules would cost

  • Single base → multi-base diff rendering, divergent-history UX, refresh semantics that vary per task.
  • Worktree per task → cross-task isolation, lock management, ambiguous file ownership, harder reasoning about which agent wrote what.

If a feature requires relaxing one of these, the tradeoff gets surfaced explicitly — not quietly relaxed.

Where these surface in the code

  • Base detection and rebase: src-tauri/src/git.rs; refresh: src-tauri/src/commands/tasks.rs.
  • Worktree lifecycle: src-tauri/src/tasks.rs; the cross-window lock: src-tauri/src/task_lock.rs.
  • The editable rule (relaxed rule 3): src/lib/ipc.ts (isEditableFilePath).