Workspaces and worktrees
A workspace is Grove's unit of work: a folder in your vault that owns everything about one piece of work — your notes and plans, your agent conversations, and an isolated git worktree branched off your base branch. Agents work inside the worktree; your main checkout is never touched.
The workspace model
A workspace is just a folder in the vault, nested under a project. It holds:
- Your notes — plans, design docs, screenshots — rendered in the sidebar and readable by the agent.
- Its chats — every agent conversation and transcript, kept with the work.
- Its worktree — a real git checkout on a dedicated branch (
workspace/<name>-<id>), forked from the project's base branch.
The folder name is the workspace name — rename it in Grove or in Finder and you've renamed the workspace; the branch and identity stay stable. New workspaces get a memorable placeholder name (a New York landmark, as it happens) until you name them — or until Grove auto-names them from your first prompt to the agent.
Creating workspaces
- The new workspace button on a project row in the sidebar (with an inline name input).
Cmd+Shift+Nfrom anywhere.- Promote any note or folder into a workspace from its right-click menu — your planning notes become the workspace's notes.
- Agents can create workspaces too, through MCP — useful for splitting a big plan into parallel pieces.
Creating a workspace is instant and nearly free: Grove makes the branch and a lazy worktree with no files in it yet.
Lazy worktrees
A workspace doesn't populate its checkout until something needs it:
- On create — branch and worktree metadata exist, but no files. Disk cost: negligible.
- On first agent or terminal spawn — Grove populates the worktree just in time, so the agent's working directory is fully there when it starts.
Two consequences worth knowing: note-only workspaces are free (twenty scratch or planning workspaces cost essentially nothing), and an un-spawned workspace honestly shows an empty diff rather than pretending.
Setup scripts
Fresh worktrees are missing node_modules, .env, build caches — everything gitignored. A repo can commit a grove.json at its root:
{ "scripts": { "setup": "npm install && cp $GROVE_PROJECT/.env .env" } }You can also edit this from Settings → Git / GitHub → Worktree setup script without knowing the format — it round-trips the same file.
The setup script runs the moment a worktree gets real files, with the worktree as its working directory and GROVE_PROJECT / GROVE_WORKTREE in the environment. Its output streams to a setup.log note in the workspace, a failing script never blocks the agent, and scripts are stopped after 10 minutes. One trade-off: setup runs inside the spawn path, so a cold npm install delays the first agent launch.
Trust model: the script runs because you opened this repo and spawned an agent in it. Don't open repos you don't trust.
Archive and revival
- Archive captures any uncommitted work into a safety commit, then removes the worktree. The branch is always preserved, and the workspace's notes and comment history stay too.
- Unarchive re-creates the worktree from the branch and restores your uncommitted work as unstaged edits — you're back exactly where you left off.
Branches are kept indefinitely; the only thing that deletes a branch is deleting the workspace itself.
Rename, move, delete, promote, demote
- Rename / move — a plain folder rename; identity and branch are untouched.
- Delete — removes the worktree, deletes the branch, and removes the folder.
- Promote — turns any vault folder (or a single file) into a workspace.
- Demote — reverses it: tears down the worktree and Grove scaffolding, keeps your notes, preserves the branch.
One base branch, refreshed by rebase
Every workspace in a project forks from the same base branch (detected as main, falling back to master; override it in Settings → Git / GitHub). One shared base is what makes the cross-workspace views trivially correct — every diff is "this workspace on top of the base," and the file tree's activity stripes and per-workspace overlays never have to reconcile divergent histories.
Refresh (the sync action on a workspace) fetches the base and rebases the worktree onto it:
- Clean rebase — the workspace continues against the new base.
- Conflicts — the rebase safely aborts for that workspace and the conflict is flagged; you resolve it in the worktree with git. Other workspaces proceed unaffected.
Rebase — not merge — keeps each branch linear against the base, so the diff you review stays "what this workspace changed," never "plus every merge commit since."
Out of scope (for now)
- Stacked workspaces (one built on another's branch).
- Container-level isolation — agents are isolated by filesystem path, not sandboxed.
- A conflict-resolution UI — conflicts are flagged; you resolve them with git.