Recipes
Save multi-panel workspace presets as recipes that launch terminals, AI agents, and dev servers in one click, scoped globally, per-project, per-worktree, or shared with your team via git.
What Are Recipes?
A recipe is a saved workspace preset that launches several panels at once. Each recipe describes a set of terminals, AI agent sessions, and dev server panels, with their commands, starting prompts, and environment variables. You launch your layout in one click. Every panel runs in the active worktree's directory, so agents and terminals always start in the right branch.
One recipe can open up to 10 panels in any combination. You launch recipes from the empty-canvas launcher (the surface shown when a worktree has no open panels), from the searchable panel palette (Command-N Control-N Control-N ), from a worktree card's Run Recipe menu, and from the New Worktree dialog. Bulk worktree creation runs the same recipe on every worktree it creates — see Worktrees for that flow, and Fleet for driving the agents once they are running.
Recipe Scopes
Every recipe carries a scope. The scope controls where the recipe is offered, where it is stored, and whether your team gets it. There are four, and each recipe row in the app prints its scope label.
| Scope label | Available in | Storage | Shared via git |
|---|---|---|---|
| Global | Every project on this machine | App-level config | No |
| Team | The current project, for everyone who clones it | .daintree/recipes/{name}.json | Yes |
| Project-wide | Every worktree of the current project | Machine-local project store | No |
| Worktree: <name> | One worktree only | Machine-local project store | No |
The scope you get depends on where you create the recipe. A recipe created from the Recipe Manager or from Settings → Recipes has no worktree attached, so it is Project-wide. A recipe created from inside a worktree — the launcher's create button, or Save Layout as Recipe on a worktree card — carries that worktree's id and shows as Worktree: <branch>. Choosing Global (all projects) in the editor drops both, and the recipe becomes Global.
A new Project recipe is written into the repository at .daintree/recipes/ straight
away, so it is ready to commit and share from the start. That is why a recipe you created as "Project" can show up
labelled Team once it has been written — the label describes where the file lives, not what you
picked in the dropdown.
When a name is used twice
A project-local recipe that shares a name with a Team recipe is shadowed: the Team version is what runs. Shadowed recipes are no longer hidden. They render dimmed with an explicit Overridden by Team badge, everywhere recipes are listed — the launcher, the recipe picker, the Recipe Manager (where the badge reads "Overridden by team recipe") and the Settings list (where it reads "Overridden"). Running a shadowed row resolves to the Team recipe it defers to, and does so through the local mirror, so environment variable values you filled in locally are still applied.
Showing shadowed recipes rather than dropping them is deliberate: a recipe silently disappearing after a teammate's commit is harder to diagnose than a dimmed row that names what replaced it. A shadowed recipe is not eligible to be the default worktree recipe.
Working with recipes
- Create and edit for the manager and the editor, cloning a layout you already have open, setting a project's default, and the variables a recipe can put into a prompt.
- Launch and share for running one from the empty canvas or across several worktrees, committing team recipes to the repository, and exporting or importing them.
Scratch Workspaces
Scratch workspaces are a separate workspace type, not a recipe scope. They moved to their own page: Scratch Workspaces.
Example Recipes
| Recipe Name | Panels |
|---|---|
| Full Stack Dev | Claude Code + npm run dev terminal + Dev Server |
| Code Review | Claude Code (prompt: "Review the changes on {{branch_name}}") + Codex (prompt: "Check for security issues") |
| Test & Watch | npm run test:watch terminal + Dev Server |
| Quick Fix | Claude Code (prompt: "Fix the failing tests on issue #{{issue_number}}") |