Recipes
Save multi-panel workspace presets as recipes that launch terminals, AI agents, and dev servers in one click, scoped globally, per-project, 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 RecipeRunner (the empty state when no panels are open), from the new worktree dialog, or across several worktrees at once through Bulk Operations.
Recipe Scopes
Recipes exist in three tiers. The tier controls where a recipe is available and where it is stored.
| Tier | Scope | Storage | Shared via Git |
|---|---|---|---|
| Global | All projects, machine-wide | App-level config | No |
| Team | Current project, shared with team | .daintree/recipes/{name}.json | Yes |
| Project | Current project, local only | Machine-local store | No |
You don't create team recipes directly. You promote a Global or Project recipe to Team status with Save to Repo in the Recipe Manager. That writes the recipe
to .daintree/recipes/, where it can be committed and shared via git.
Team recipes take priority over project-local recipes. When a team recipe and a project recipe share a name, only the team version shows. New project recipes default to in-repo storage, so they are ready to commit and share from the start.
The Recipe Manager
The Recipe Manager is a dialog for managing every recipe across all three tiers. Open it from the action palette (Cmd+Shift+P and search for "Recipe Manager").
The dialog has three labelled sections: Global Recipes, Team Recipes (visible when .daintree/recipes/ holds recipe files), and Project Recipes.
Each section header has a "New" button for creating recipes in that tier.
Per-Recipe Actions
Hover over a recipe row to reveal its action buttons:
| Action | Notes |
|---|---|
| Edit | Opens the recipe editor. Available for all recipe types. |
| Save to Repo | Promotes a global or project recipe to a team recipe. Not shown for recipes already in the repo. |
| Export to Clipboard | Copies the recipe as JSON. Shows a checkmark for two seconds to confirm. |
| Export to File | Opens a save dialog to write a .json file. |
| Delete | Removes the recipe. |
Creating Recipes
Click New Global Recipe or New Project Recipe in the section header you want. You can also right-click a worktree card and select Save Layout as Recipe to capture every active panel, including its agent type, command, and prompt.
Importing Recipes
The Project Recipes section footer has two import buttons. Import from Clipboard opens a
dialog with a text area and a scope selector. Import from File opens a file picker for .json files. Import validation checks for required fields and drops invalid panel definitions
rather than rejecting the whole recipe. The import only fails if no valid panels remain afterward.
The Recipe Editor
The recipe editor opens when you create or edit a recipe. Recipe-level settings sit at the top, panel definitions below.
Recipe-Level Fields
- Recipe Name: required, auto-focused when the editor opens
- Scope: Global or Project. On edit, this is read-only since scope cannot change after creation
- Show in Empty State: pins the recipe to the Pinned section of the RecipeRunner
- Auto-assign Issue: controls whether the linked GitHub issue is auto-assigned to you when creating a worktree with this recipe. Options: "Always assign to me" (default), "Ask before assigning", "Never assign". See Code Forge for issue linking setup
Panel Definitions
A recipe holds one to ten panels. The available fields depend on the panel type:
| Panel Type | Fields | Exit Behavior |
|---|---|---|
| Terminal | Title (optional), Command (optional) | Send to Trash (default), Keep for Review, Remove Completely |
| Agent (Claude, Gemini, Codex, OpenCode) | Title, Initial Prompt (optional, supports variables), Arguments (optional, e.g. --model claude-opus-4-5) | Keep for Review (default), Send to Trash, Remove Completely |
| Dev Preview | Title, Dev Command (auto-detects from package.json) | Send to Trash (default), Keep for Review, Remove Completely |
Every panel also takes optional environment variables and a custom title for the tab label. All panels run in the active worktree's directory.
Agent Model and Launch Flags
The Arguments field on an agent panel takes any CLI flags the agent binary supports. Those flags
are saved in the recipe file and passed verbatim every time the recipe launches. This is where you pin a specific
model for a recipe, for example --model claude-opus-4-5 for Claude Code or --yolo for Gemini CLI.
The model you pick inside a running agent session, through the agent's own UI or a slash command, is not part of the recipe file. A saved recipe launches with your global agent configuration unless you override it through Arguments.
--model <model-id> to the Arguments field. Without it, the
recipe uses whatever model your global agent configuration specifies at launch time.Cloning the Active Layout
When you create a new worktree, the Run Recipe dropdown in the New Worktree dialog offers Clone current layout as its first option. The same option shows when you create worktrees in bulk. Instead of running a saved recipe, it snapshots every active panel in the source worktree and forwards that arrangement to the new one.
The snapshot carries a bit more than a saved recipe does. Along with the usual panel titles, commands, and prompts, Daintree forwards the model each agent is running with and any launch flags it started with. The new worktree's agents spawn with the same model as the source session, even if that model was chosen mid-session rather than through a recipe.
These live-session values are forwarded, nothing more. They are never written to disk, so cloning a layout does not produce a saved recipe. To make the same model and flag combination reusable, save the layout as a recipe and add the flag to the Arguments field. See Worktrees for the New Worktree dialog and Bulk Operations for the fleet-wide path.
--model <model-id> to Arguments on the agent panels of a saved recipe to make the model
selection permanent.Default Worktree Recipe
You can pin one recipe as the default for every new worktree in the current project. The setting lives in Settings → Recipes, which is also where recipes are managed alongside the Recipe Manager (Cmd+Shift+P → "Recipe Manager"). The tab reads "Manage terminal recipes and pin a default recipe for new worktrees", and the list sits under a Terminal Recipes heading.
Each recipe row has a Pin button. Pinning a recipe marks it with a Default badge. Only one recipe can be the default at a time, so pinning a new one clears the previous pin. Use Clear default to unpin without deleting anything.
Deleting the default recipe from the Recipes tab clears the pin for you. If the pinned recipe disappears another way, for example a team recipe removed by a teammate's commit, Settings shows a Default recipe unavailable warning with a Clear default button so you can pin a replacement.
The default does its work in the New Worktree dialog. When the dialog opens, it pre-selects your pinned recipe in the "Run Recipe (Optional)" picker. You can override it for any individual worktree before creating it. The same default applies when you create worktrees in bulk through Bulk Operations. The picker resolves its starting value in this order:
- An explicit recipe passed in, for example from a bulk operation
- The recipe you last selected for that project, remembered per project
- The pinned default worktree recipe
- Clone current layout, as the fallback
Variables in Prompts
Initial prompts on agent panels support variable replacement using {{double_curly}} syntax. Variables resolve at run time from the worktree's context, and the
names are case-insensitive.
| Variable | Resolves To | Example |
|---|---|---|
{{issue_number}} | GitHub issue number linked to the worktree | #123 |
{{pr_number}} | Pull request number linked to the branch | #456 |
{{number}} | Issue number if set, otherwise PR number | #123 |
{{worktree_path}} | Absolute path to the worktree directory | /home/user/project |
{{branch_name}} | Git branch name | feature/issue-42 |
If a variable's context is missing, for example no issue linked, it resolves to an empty string. Unknown variable
names are left unchanged. When both an issue and a PR are linked, {{number}} prefers the issue number.
Team Recipes
Team recipes live in .daintree/recipes/ inside the repository and are committed to git, so everyone
working on the project has them. Each recipe is saved as its own JSON file. That keeps git diffs clean and
minimizes merge conflicts.
Daintree auto-loads any .daintree/recipes/*.json files when a project opens. New team members get the
shared recipes after pulling, with no extra step. Save to Repo writes straight to .daintree/recipes/ and does not need the "Store settings in repository" toggle enabled first.
Saving a Recipe to the Repo
- Open the Recipe Manager (Cmd+Shift+P and search for "Recipe Manager")
- Hover over a Global or Project recipe and click Save to Repo
- Confirm in the dialog. Daintree writes the recipe to
.daintree/recipes/{recipe-name}.json - Choose Delete Original to drop the local copy, or Keep Both to keep it alongside the team version
Environment Variable Handling
When you save a recipe to the repo, Daintree blanks every environment variable value and keeps the keys. That keeps secrets out of git. The keys stay behind as a signal to teammates about which environment variables they need to fill in locally.
Committing Team Recipes
Daintree writes the recipe file. It does not commit it. You stage and commit the file yourself.
git add .daintree/recipes/ && git commit to share it with your
team. Daintree auto-loads any .daintree/recipes/*.json files when a project is opened.Export and Import
Exporting Recipes
The Recipe Manager exports recipes two ways:
- Export to Clipboard copies the recipe as JSON, without the internal project ID. A checkmark appears for two seconds to confirm the copy.
- Export to File opens a save dialog to write a
.jsonfile to disk.
Importing Recipes
The Project Recipes section of the Recipe Manager has two import options:
- Import from Clipboard opens a dialog with a text area for pasting JSON and a scope selector for Global or Project.
- Import from File opens a file picker for
.jsonfiles.
On import, Daintree validates the recipe structure, strips control characters from commands and prompts, and drops any panels with invalid types. The import only fails if no valid panels remain after validation.
RecipeRunner (Empty State)
When a worktree has no active panels, the content area shows the RecipeRunner. It's the main surface for finding and launching recipes.
Grid Mode and List Mode
With six or fewer recipes, the RecipeRunner uses a grid layout: two columns for one to two recipes, three columns for three to six. Past six recipes, it switches to a compact list mode with a search box that auto-focuses for quick filtering.
In list mode, recipes are grouped into three sections:
- Pinned: recipes with "Show in Empty State" enabled
- Recent: the five most recently used recipes, ranked by frequency and recency
- All: remaining recipes in alphabetical order
Search runs fuzzy matching on recipe names, weighted 70% by name relevance and 30% by usage frequency with a seven-day decay.
Keyboard Shortcuts
| Key | Action |
|---|---|
| ↑ / ↓ | Navigate between recipes |
| Enter | Run the focused recipe |
| Escape | Clear search |
| Cmd+E | Edit the focused recipe |
Status Banners
When you launch a recipe, the RecipeRunner can show a banner at the top of the grid reporting what happened. There are two.
The spawn-failure banner, an error banner, appears when one or more panels fail to start. It reads like "Started 2 of 3 terminals. 1 failed: Dev server." and offers a Retry failed action. Retry re-runs only the panels that failed. The panels that already started keep running, untouched.
The unresolved-variables banner, a warning banner, appears when a prompt variable couldn't be resolved, for example when no issue is linked. It reads
"Missing context for {{issue_number}}" and explains that "These variables stayed empty in the
launched commands." The check covers the agent panel's initial prompt.
Stale banners clear themselves on the next run, or when you switch worktrees.
Context Menu
Right-click a recipe card or row for Run, Edit, Duplicate, Pin to Empty State (or Unpin), and Delete.
Zero-Recipe State
When no recipes exist yet, the RecipeRunner shows the line "Launch agents, dev servers, and terminals together with one click" and a Create your first recipe button.
Scratch Workspaces
A scratch workspace is a throwaway, app-managed folder for quick one-off tasks, separate from your git projects.
Daintree keeps each one under userData/scratches/<uuid>/, outside any git project folder, so you
can run agents and terminals somewhere disposable without registering a project first.
Create one from the Project Switcher palette. Expand the collapsible Scratch section and click New scratch workspace. That creates the workspace and switches to it right away. When you have
none, the section reads "No scratch workspaces yet. Create one for a quick one-off task." New scratch workspaces
are auto-named with a timestamp like Scratch 2026-05-21 14:30, and you can rename them afterward.
Scratch workspaces auto-clean after 30 days, measured from when the workspace was last opened, so opening one resets the timer. A countdown appears only once you are within 7 days: "Auto-cleanup in 5 days", then "Auto-cleanup tomorrow" and "Auto-cleanup today" as the date gets close.
userData/scratches/. It never touches your git
project folders.Right-click a scratch workspace for two actions. Save as project... copies the scratch folder to a directory you choose, registers it as a project, then asks whether to Delete scratch or Keep scratch now that the work has a permanent home. Delete scratch removes the workspace outright.
Example Recipes
| Recipe Name | Panels |
|---|---|
| Full Stack Dev | Claude Code + npm run dev terminal + Dev Preview |
| Code Review | Claude Code (prompt: "Review the latest changes") + Gemini CLI (prompt: "Check for security issues") |
| Test & Watch | npm run test:watch terminal + Dev Preview |
| Quick Fix | Claude Code (prompt: "Fix the failing tests") |