Create and Edit Recipes
Authoring a recipe: the Recipe Manager, the editor and its panel rows, cloning the layout you currently have open, setting a project default worktree recipe, and the variables a recipe can substitute into a prompt.
The Recipe Manager
The Recipe Manager is a dialog for managing every recipe in one place. Open it from the action palette (Shift-Command-P Control-Shift-P Control-Shift-P and search for "Recipe Manager").
The dialog has three labelled sections: Global Recipes ("Available across all projects"), Team Recipes ("Shared via .daintree/recipes/ in the repository", shown only when the directory holds recipe files), and Project Recipes ("Specific to the current project"), which names the current project beside its heading. Each row carries the recipe name, a N terminals badge, and when it was last used, or "Never used".
Per-Recipe Actions
Hover over a recipe row to reveal its action buttons:
| Action | Notes |
|---|---|
| Edit recipe | Opens the recipe editor. Available for every recipe. |
| 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. The button reads "Exported" for two seconds to confirm. |
| Export to file | Opens a save dialog to write a .json file. |
| Delete recipe | Removes the recipe, after a confirmation. |
The delete confirmation distinguishes what can be recovered from what cannot: an in-repo recipe that has been committed can be restored from git, while a recipe stored only on this machine can't be. If the delete fails, the dialog keeps the error and the button becomes Retry delete.
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 has Import from clipboard, which opens a dialog with a text area and a
scope selector, and Import from file, which opens a picker for .json files. Import
validation checks required fields, rejects control characters in commands, arguments and environment values, 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: "Project (current project only)" or "Global (all projects)". 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 launcher. The help text reads "Display this recipe as a primary launcher when the worktree has no active terminals"
- 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 | After Exit |
|---|---|---|
| Terminal | Title (optional), Command (optional) | Send to Trash (default), Keep for Review, Remove Completely |
| Agent | Title, Arguments (optional, e.g. --model claude-opus-4-5), Initial Prompt (optional, supports variables) | Keep for Review (default), Send to Trash, Remove Completely |
| Dev Server | Title, Dev Command (falls back to the project default, or auto-detects from package.json) | Send to Trash (default), Keep for Review, Remove Completely |
Whatever you choose, a panel that fails is always preserved for debugging — the editor says so under each After Exit selector. Every panel also takes optional environment variables and a custom title for the tab label, and all panels run in the active worktree's directory.
A recipe's agent panels can name any of Daintree's launchable agents; the stored type is an agent id, and the importer accepts every built-in one. The editor's own type dropdown is narrower — Terminal, Claude, Gemini, Codex, OpenCode, Dev Server — so the way to build a recipe around another agent is to arrange the panels you want and use Save Layout as Recipe, which records whatever each panel was launched as. See Agents for the full roster.
Agent Presets 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.
Beyond those flags, a recipe launch resolves the agent's selected preset, to parity with launching that agent by hand. The worktree-scoped preset beats the agent-level default, and the preset's arguments, environment and behavioral overrides all fold into the spawn. If a worktree-scoped preset has gone missing, the launch falls back to the agent-level default rather than launching bare — and unlike a manual launch, a recipe run never rewrites your saved agent settings while doing so. See Agent Presets for the full resolution order.
Environment variables layer in one direction, each level winning over the one before it:
- Your global agent environment
- The resolved preset's environment
- The environment defined on the recipe's panel
The flags a recipe-launched agent started with are recorded on the panel, so restarting, resuming or continuing that session reproduces the same configuration instead of regenerating a command from whatever your settings say later.
--model <model-id> to the Arguments field, or
put it in the preset the recipe resolves.Cloning the Active Layout
When you create a new worktree, the Run Recipe (Optional) picker 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 stripped before anything is 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 the bulk creation flow.
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. The list sits under a Terminal Recipes heading, and every row shows its scope label, its terminal count, and whether it is shadowed.
Each eligible 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 stops being eligible another way — a Team recipe removed by a teammate's commit, or a project recipe that has since been shadowed — 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, and the same default applies to bulk creation. 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.
The resolved-prompt preview
The editor shows a Resolved prompt block directly under any non-empty initial prompt, so you see what the agent will actually receive rather than what you typed.
- With worktree context available — you opened the editor from a worktree, or you are editing a worktree-scoped recipe — the block shows the fully substituted text.
- Without worktree context, the variables stay highlighted in amber and the block is captioned Resolving at run time.
- When context exists but a particular variable can't be filled from it, that variable gets its own warning chip
reading
{{name}} unresolved.