Manage git-backed recipe sources listed in pack-sources.yaml (add/list/update/remove tracked repos), separately from the prompt packs themselves (loaded by the standard discovery pipeline).

sonny tracks recipe repositories listed in pack-sources.yaml under $XDG_CONFIG_HOME/sonny. Use these subcommands to add, list, update, or remove tracked repos. Cloned repos live under $XDG_CACHE_HOME/sonny/pack-repos and are loaded by the standard recipe discovery pipeline on startup.

Usage:
  sonny recipe [command]

Aliases:
  recipe, pack

pack is an alias, so sonny pack list and sonny recipe list are the same command. The help output prints the primary name recipe.

All subcommands accept the global flags .

Subcommands

SubcommandPurpose
addRegister and clone a new recipe source
approve-routingTrust a recipe source’s model routing (endpoints and credential env var names)
artifactInspect captured tool results without putting them in model context
defaultShow, set, or clear the persisted default prompt recipe
evalRun a recipe’s eval suite through the configured provider
evidenceScore two per-case ledgers into one paired evidence record and decide promotion
inspectShow resolved scope, sub-scopes, validation, and provenance for a recipe
listList tracked recipe sources (or --recipes to list prompt recipes)
migrateRewrite a v1 prompt recipe as v2 (in-place by default)
optimizeEvolve a recipe’s system prompt against its eval suite
pinPin a model-pack variant for a session, or as a pack-wide standing default
qualifyAssemble and freeze a model-variant campaign’s qualification document
reloadForce-refetch one or all tracked recipe sources
removeDrop a recipe source and delete its cache directory
replayReproduce a pinned variant decision from a lock and a snapshot
resolveEmit the fully-resolved, tool-aware compiled subject for a recipe
searchBM25-rank loaded prompt recipes against a query
snapshotWrite a replayable variant-resolution snapshot for one logical recipe
updateFetch + reset tracked sources to their upstream branch tip
validateStatically validate a recipe YAML file
variantOperate on one model recipe variant envelope file
variantsList the model-pack variants discovery found for one logical recipe

recipe add

sonny recipe add <git-url|dir>[@<ref>]

Register and clone a new recipe source from git-url. A local directory (., ./dir, ~/dir or an absolute path) works too: a git repository is cloned on its checked-out branch, and any other directory is snapshotted into the cache and re-read on every sync or reload (the directory itself is never modified). Append @<ref> to the URL (e.g. https://example.com/packs.git@v1.2.3) to pin the source to a specific semver tag or to @latest for the newest available tag. Pinned sources are frozen: sonny will not auto-update them on startup; use sonny recipe reload <name> to refresh.

FlagTypeDescription
--approve-mcp—after cloning, record your approval of the MCP servers every pack from this source declares (inherited ones included), as sonny mcp approve pack does for each: a pack-source server launches only on such an approval
--approve-routing—after cloning, trust the source’s model routing (endpoints and credential env var names its catalogs declare) by copying it into <config-dir>/models.d/pack-<name>-routing.yaml; see sonny recipe approve-routing
--branchstringbranch to track (default “main”)
--default-recipestringoverride this source’s repository default primary pack; an explicitly empty value disables its default
-h, --help—help for add
--mcp-auto-approve—connect this source’s MCP servers without a prompt for the packs that name them, once sonny mcp approve registry <name> records your approval of their unchanged definitions; false writes mcp_auto_approve: false, so they get the stricter explicit-approval pinning (unset: on only for a source with --mcp-d) (default true)
--mcp-dstringArraymcp.yaml-style directory relative to the clone root whose *.yaml servers load for the packs whose mcp.allowed names them, overriding same-name mcp.yaml servers (repeat for multiple dirs)
--mcp-env-allowstringshost environment variable NAME this source’s MCP servers may read, e.g. the credentials its packs’ servers reference (repeat, or comma-separate; persists mcp_env_allow in pack-sources.yaml)
--model-catalogstringArraymodel-catalog YAML path relative to the clone root (repeat for multiple files); replaces the default model-registry/models.yaml
--models-dstringArraymodels.d-style directory relative to the clone root whose *.yaml drop-ins override same-id local sources (repeat for multiple dirs)
--namestringoverride the directory name (defaults to repo basename)
--no-model-catalog—do not load the source’s default model-registry/models.yaml (persists models_auto: false)
--pinstringlock this source to a specific version: a semver tag (e.g. v1.2.3) or “latest” to resolve and record the current highest tag; may also be set inline as <url>@<ref>. Pinned sources are not auto-updated on startup; use “sonny recipe reload <name>” to refresh.
--skip-unresolved—with --approve-mcp: silently skip servers whose binary is not installed on this host
--subdirstringsubdir of the repo containing pack YAML files
--update-policystringupdate policy (on_startup|manual) (default “on_startup”)
--write-config—with --approve-mcp: also merge approved server definitions into <config-dir>/mcp.yaml so they are available globally
--write-untrusted-references—with --write-config: also write $VAR references, refused env keys and egress policy beyond the server’s own url host from servers of packs that are not verified-signed into mcp.yaml, where references expand against your environment

recipe list

Usage:
  sonny recipe list [flags]
FlagTypeDescription
--detailstringshort|full (only with –packs) (default “short”)
--formatstringdeprecated alias for --json (text|json); use --json (default “text”)
-h, --help—help for list
--json—emit the machine-readable envelope instead of the listing
--recipes—list loaded recipes instead of sources
--tagsstringsfilter to packs carrying ALL listed tags (only with –packs)

The --detail and --tags descriptions are quoted verbatim from the help output; the flag that switches the listing from sources to loaded recipes is --recipes.

recipe default

sonny recipe default [recipe-id]

FlagTypeDescription
--clear—remove the persisted default
-h, --help—help for default
--show—print the current default pack (if any)

recipe update, reload and remove

sonny recipe update fetches and resets tracked sources to their upstream branch tip:

FlagTypeDescription
-h, --help—help for update
--namestringlimit update to one source (empty = update all on_startup sources)

sonny recipe reload [name] performs an unconditional git fetch+reset for the named source, or every source when name is omitted. It ignores UpdatePolicy so a manual-policy source still pulls down a new tip on demand. It takes no flags beyond -h/--help.

sonny recipe remove <name> drops a recipe source and deletes its cache directory. It takes no flags beyond -h/--help.

sonny recipe search <query> BM25-ranks loaded prompt recipes against a query.

FlagTypeDescription
--detailstringshort|full (default “short”)
--formatstringtext|json (default “text”)
-h, --help—help for search
--tagsstringsfilter to packs carrying ALL listed tags before ranking

recipe validate

sonny recipe validate <file> statically validates a recipe YAML file.

FlagTypeDescription
-h, --help—help for validate
--outputstringoutput format: text | jsonl (default “text”)

Selecting a pack at run time

sonny recipe manages the sources; a session selects a pack with sonny run flags — --dir/-d and --file/-f to load packs, --recipe to select an already-discovered pack by id, and --pick-recipe to force the picker.