recipes
A searchable store of your own recipes, plus the arithmetic, as a CLI for agents and people.
# Recipes are authored by editing YAML. Declare intent, resolve the numbers.
cat > ~/.config/recipes/bowl.yaml <<'YAML'
name: Chicken Bowl
servings: 2
ingredients:
- source: coles
id: '1047'
grams: 200
YAML
uv run recipes resolve "Chicken Bowl"
uv run recipes search --max-kcal 900 --min-protein 40
uv run recipes fit "Chicken Bowl" --max-kcal 900 --min-protein 50
uv run recipes share "Chicken Bowl"
recipes guide is the full manual and needs no network. SKILL.md is the
agent-facing contract, installable with recipes skill install.
Design
search is the main entry point, and it emits the same candidate record
eatout does for restaurant meals, ranked the same way, so an orchestrator
can merge both streams and answer "what could I eat" from either. That shared
record lives in agentcli; nothing in it is recipe-specific.
Editing is the caller's job, not a flag set. An agent with a text editor is
better at restructuring a recipe than any add/remove-ingredient surface,
so the file declares intent — a (source, id) reference and an amount — and
resolve derives every macro number from the product database and freezes it.
That is the one thing a caller must never do by hand, and resolve is the one
command that writes.
Recipes are private user data: one YAML file each, in
$XDG_CONFIG_HOME/recipes or a --dir of your choosing, never in a
repository. Point --dir at a private git repo and git owns the history —
there is no revision log in the tool, because two revisions of a recipe are
two commits to one file. The name: field inside a file is its identity, so
lookups scan and match on it and renaming a recipe in place is safe; the
filename is cosmetic.
Every ingredient stores a product reference and a frozen per-100 g macro
snapshot, so a recipe survives a retailer renumbering its catalogue and totals
without a network. resolve --force re-reads the references and reports what
changed.
A share URL is self-contained: the payload carries resolved names and
macros in the fragment, so the page renders with no database, no network and
no server ever seeing it. The viewer address defaults to the deployed Plate
page, https://mealtime-tools.github.io/plate/; set $RECIPES_VIEWER_URL to
point links at your own deployment instead. Reading a link back is the
viewer's job, so there is no import. Plate owns
the canonical share wire format;
Recipes only produces it.
An ingredient that cannot be resolved is named and refused, never totalled as if it were zero. That bug — a confident total that silently omitted 300 g of a 450 g recipe — is why this port exists.
Product data
Products come from a lookup this package is given, never from a database it
owns. The CLI reads pantry-format JSONL from $XDG_CONFIG_HOME/pantry or
--products DIR; src/recipes/products.py is the single seam onto Pantry.
YAML store contract
Recipes are authored by editing YAML directly. The caller writes intent:
name, servings, notes, tags, and ingredient (source, id, grams). resolve
derives names and frozen per-100 g macros, validates them, and writes back. It
is idempotent; --force refreshes existing snapshots and reports changes.
There are no add/edit/remove verbs and no other command writes.
Frozen macros keep recipes useful offline and after retailer-id churn. The
name: inside the YAML file is authoritative; filenames are cosmetic slugs,
so lookup scans files and refuses two documents claiming the same name.
Recipes live only under XDG config or --dir, never in this repository.
An ingredient with an unresolved, missing, stringified, or non-numeric macro
is an error and the recipe refuses to total. Missing is not zero. Totals scale
per-100 g values by grams / 100, and displayed rounding is half away from
zero to match JavaScript rather than Python's banker rounding.
Development
uv run pytest -q
uvx ruff check src tests --line-length 79
tests/codec_test.py pins the share payload to repository-local
codec-vectors.json. Those are a
decode-direction golden: every encoded string must decode to its exact
payload. This encoder happens to reproduce the bytes too, which is asserted
here but is not a portable requirement — any valid raw-deflate stream is a
conformant encoding.
Licence
MIT.
Release files for mealtime-recipes 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mealtime_recipes-0.1.0.tar.gz | 57.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mealtime_recipes-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.3 kB
Release files / mealtime_recipes-0.1.0.tar.gz
| Download URL | mealtime_recipes-0.1.0.tar.gz |
|---|---|
| Size | 57.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9799ac4b820c9e5fea55741571b5cbd64151f347f860def020e653f5bf755aa4
|
|
BLAKE2b-256 checksum How to use checksums |
e9ce3b897d056deb320809ff86d88262193338b71eec1ce4e16650bb7943545b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.
Transparency logRelease files / mealtime_recipes-0.1.0-py3-none-any.whl
| Download URL | mealtime_recipes-0.1.0-py3-none-any.whl |
|---|---|
| Size | 58.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc8487613c2efdf38a103f1c291b41af61d71ef44102915e94d1d9bd22d1a403
|
|
BLAKE2b-256 checksum How to use checksums |
9c8685ac73d19042de726e9bb978a7a4171f6ec5a4877829016efa22a57930ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.
Transparency log