grove

module
v0.0.0-...-8eb78f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT

README

grove

CI Go Reference Go Report Card

Multi-repo agent workspaces backed by git worktrees.

Every worktree tool in the ecosystem is one repo, N agents. Grove is the inversion: N repos, one task. It materialises a directory where the repos a task touches sit as siblings — each a git worktree with a role — compiles the context an agent needs to work across them, and gets out of the way.

~/grove/add-payments/
├── grove.toml       the manifest — a snapshot, the only durable state
├── AGENTS.md        generated: routes, never inlines
├── CONTEXT.md       durable notes, copied from the profile
├── PLAN.md          the task's working memory
├── backend/         worktree on grove/add-payments       (write)
└── client-sdk/      detached worktree                    (read)

The dominant case is cross-repo reads: you're editing backend and need client-sdk on hand so the agent knows what it's actually calling. read repos get a detached worktree — no branch, nothing to push, nothing left in refs/heads afterwards. Edits there are discardable by construction.

Install

brew install jossmoff/tap/grove          # or grab a release binary
go install github.com/jossmoff/grove/cmd/grove@latest
eval "$(grove init zsh)"             # gcd / gfin shell wrappers

Usage

grove repo clone git@github.com:acme/backend.git   # into <root>/<host>/<owner>/<repo>

grove new add-payments -w backend -r client-sdk -t "Extend the payments API"
cd "$(grove path add-payments)" && claude          # grove's job is done

grove ls                                           # derived status, all groves
grove finish                                       # from inside; guards, prunes

Pin a read repo: -r client-sdk@v2.1. Reads fetch by default (a stale reference hands the agent an interface that no longer exists); writes don't (branching from what you last pulled is often deliberate). --no-fetch opts out.

Profiles

Repo sets are stable; tasks aren't. When you've picked the same repos twice:

cd "$(grove path add-payments)"
grove profile save fullstack        # promote the grove you're standing in
grove new next-task -p fullstack    # no re-picking

A profile is a directory: profile.toml (the repo set, shorthand "client-sdk:read" or longhand tables with base/dir/depends_on), CONTEXT.md (durable notes about the combination), and LOCAL.md (machine paths, credentials). Share one:

grove profile export fullstack > fullstack.toml   # inlines CONTEXT
grove profile import fullstack fullstack.toml     # or  ... -  for stdin

LOCAL.md is never exported. Locals hold credentials; a default that can leak is not a default.

Design

  • Derive, don't store. The manifest holds what was asked for. Dirty state, ahead/behind, branch status are recomputed from git on every read — anything persisted that git already knows will drift.
  • Snapshot, don't reference. grove.toml embeds the fully-resolved repo set. Profiles get edited; teardown must not break because a profile changed three weeks ago. finish reads the manifest and nothing else.
  • Route, don't inline. AGENTS.md points at each repo's own instructions, namespaces colliding skills (backend:test, client-sdk:test), states dependency direction, and routes to your notes. Inlining five CLAUDE.mds produces a doc that's mostly irrelevant and stale on arrival.
  • The slug lives in the branch. Git refuses one branch in two worktrees; grove/<slug> is what lets two live groves share a repo.
  • finish never deletes branches. The work may be pushed but unmerged. It refuses on dirty or unpushed work unless --force.
  • Not an orchestrator. Grove doesn't run agents, pick models, or manage sessions. claude, aider, codex all point at the same grove; the moment grove spawns agents it becomes the single-repo tools it was defined against.

Documentation

Full docs live in docs/ and render on GitHub:

Development

First build: the interactive layer (internal/tui) pulls in Bubble Tea. Run go mod download && go build ./... once to fetch it — see BUILD_NOTES.md. All other packages build with no extra step.

go test -race ./...   # unit + lifecycle tests against real git repos
go vet ./...

The lifecycle suite (internal/workspace) drives real repositories: roles, branch-vs-detached, two groves sharing a repo, rollback on partial failure, finish guards, base pinning, and a test that fails if anyone adds derived state to the manifest.

Package docs are written for go doc: start with go doc github.com/jossmoff/grove/internal/workspace.

Directories

Path Synopsis
cmd
grove command
Command grove materialises multi-repo agent workspaces backed by git worktrees.
Command grove materialises multi-repo agent workspaces backed by git worktrees.
internal
cmd
Package cmd wires the CLI surface to the internal packages.
Package cmd wires the CLI surface to the internal packages.
config
Package config loads grove's own configuration.
Package config loads grove's own configuration.
contextgen
Package contextgen renders the agent-facing context for a grove.
Package contextgen renders the agent-facing context for a grove.
gitx
Package gitx wraps the git binary.
Package gitx wraps the git binary.
index
Package index discovers repos under the root.
Package index discovers repos under the root.
manifest
Package manifest defines grove.toml — the per-grove snapshot.
Package manifest defines grove.toml — the per-grove snapshot.
profile
Package profile defines durable repo-set templates.
Package profile defines durable repo-set templates.
repo
Package repo maps git remote URLs to canonical host/owner/repo paths.
Package repo maps git remote URLs to canonical host/owner/repo paths.
status
Package status derives grove state.
Package status derives grove state.
tui
Package tui holds the interactive Bubble Tea surfaces.
Package tui holds the interactive Bubble Tea surfaces.
workspace
Package workspace implements the grove lifecycle: create and finish.
Package workspace implements the grove lifecycle: create and finish.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL