Skip to main content
A recipe is the whole box spec, written declaratively. dabs ships five generic ones; anything project- or tool-specific is yours to add.
Screens verified by tests/test_recipes.py.

The bundled five

dabs recipes
recipewhat it does
shshell in a clean box over your current directory (live mount)
wtcut a git worktree, no box
wtboxshell in a clean box over a fresh git worktree
scratchcopy the cwd into a directory node, no box
scratchboxshell in a clean box over a throwaway copy of the cwd
dabs recipes --print dumps the bundled YAML in full — the best starting point for writing your own.

Write your own

Project recipes live in ./dabs.yaml; personal ones in ~/.dabs/recipes.yaml. Resolution is bundled → global → project, later winning. This is a complete recipe:
default: hello
recipes:
  hello:
    description: demo box for the recipes walkthrough
    image: shell
    command: [sh]
    env: { GREETING: hello-recipes }
    sources:
      - mount: .
        path: /work
Drop that in your project and it joins the registry immediately:
hello       demo box for the recipes walkthrough  default
scratch     copy the cwd into a directory node, no box
scratchbox  shell in a clean box over a throwaway copy of the cwd
sh          shell in a clean box over your current directory
wt          cut a worktree, no box
wtbox       shell in a clean box over a fresh git worktree
Recipes provision; they don’t prompt. A recipe’s command must not bake in agent instructions — keep prompts in the caller (or a skill) and keep the recipe reusable.

Running one — three shapes

dabs recipe hello                 # a known recipe, its own command
dabs recipe hello -c 'echo hi'    # a known recipe, your tokens APPENDED
dabs recipe -- echo hi            # the default recipe, your command appended
Appending is literal. Trailing tokens are appended to the recipe’s command argv. Against command: [sh], dabs recipe sh -c 'echo hi' runs sh -c 'echo hi' — but dabs recipe -- echo hi runs sh echo hi, which asks sh to open a file named echo. Read the confirmation carefully: it always shows the exact final command.

The confirmation

Handing a box an arbitrary command always asks first, showing the recipe, its mounts, and the exact command:
╭────────────────────────────────────╮
│ recipe "sh"                        │
│   image=shell                      │
│   mount    . → /work               │
│ command: sh -c echo appended to sh │
╰────────────────────────────────────╯
┃ Proceed?

┃   Yes     No
Answer Yes and it runs, then removes the box when the command exits:
running: sh -c echo appended to sh

appended to sh
✓ sh-________ removed
Answer No and nothing is built or run: dabs: recipe "sh": aborted.

A typo never becomes a command

A first token that is neither -- nor a known recipe is an error, not a command:
dabs: no recipe "nosuch" (known: scratch, scratchbox, sh, wt, wtbox) — or `dabs recipe -- nosuch` to run it as a command on the default recipe

The default: key

A registry’s default: names the recipe that dabs build, dabs recipe (no name), and dabs recipe -- <cmd> resolve to.
A default: is not a shell. If it names an agent (say, a claude -p box), a bare dabs recipe -- echo hi appends your argv to the agent’s command line. Set no default unless one recipe is the obvious “just run it” choice.