{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/recipe",
  "slug": "adapters/domain/recipe",
  "kind": "capabilities",
  "bucket": "package",
  "title": "recipe — Leumas2 domain adapter pack",
  "name": "recipe",
  "eyebrow": "Leumas2 domain adapter pack",
  "chip": null,
  "summary": "Recipe, cooking, food and nutrition capability pack: find recipes from the ingredients you already have (fromIngredients / pantry / what-can-I-make), full-text recipe search by...",
  "keywords": [
    "recipe",
    "cooking",
    "ingredients",
    "pantry",
    "cuisine",
    "leumas recipe",
    "course",
    "diet"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# recipe — Leumas2 domain adapter pack\n\nRecipe / cooking / food & nutrition capability. Find what you can cook from a pantry, search and scale\nrecipes, estimate calories and macros, build grocery lists, swap ingredients, match cocktails, and plan\nmeals — all from a small built-in dataset. **Pure JavaScript, zero npm dependencies** (Node built-ins only).\n\n## Tools\n\n| Tool | Input (one args object) | Returns |\n|---|---|---|\n| `fromIngredients` | `{ have:[...], limit?, diet? }` | Recipes ranked by how many of their ingredients you already have, with `missing` lists. |\n| `search` | `{ query, diet?, limit? }` | Recipes matching name/cuisine/course/diet/tag. |\n| `getRecipe` | `{ id }` (or `{ recipe }`) | Full recipe (ingredients + steps + timing). |\n| `scale` | `{ recipe\\|id, servings }` | Ingredient quantities scaled to the target serving count. |\n| `nutritionEstimate` | `{ ingredients:[...] }` | Total kcal + protein/carbs/fat, per-line breakdown, unknowns. |\n| `shoppingList` | `{ recipes:[...], servings? }` | One aggregated grocery list across several recipes. |\n| `substitute` | `{ ingredient }` | Swaps (vegan / gluten-free / dairy-free / allergy alternatives). |\n| `cocktail` | `{ have:[...] }` or `{ spirit }` | Cocktails/mocktails matched by mixers you have, or by base spirit. |\n| `mealPlan` | `{ days?, diet?, seed? }` | Multi-day breakfast/lunch/dinner plan with rough per-day kcal. |\n| `listRecipes` | `{ limit? }` | Catalog of all recipes. |\n| `listIngredients` | `{}` | The per-100g nutrition table. |\n| `randomRecipe` | `{ diet?, seed? }` | A random (optionally seeded) recipe. |\n\n`ingredients` accept either objects (`{ item, qty, unit }`) or strings (`\"200g rice\"`, `\"2 egg\"`).\n`fromIngredients`/`cocktail` take bare names (`[\"egg\",\"pasta\",\"cheese\"]`, `[\"rum\",\"lime\"]`).\nRandomized tools (`mealPlan`, `randomRecipe`, `cocktail` by spirit) accept an optional numeric `seed`\nfor reproducible output. Every tool takes ONE args object (an HTTP POST body maps 1:1).\n\n## Usage\n\n```js\nimport recipe from './index.js';\n\nrecipe.adapters.fromIngredients({ have: ['egg', 'pasta', 'bacon', 'cheese'] });\n// → matches Spaghetti Carbonara at high coverage, lists what's missing\n\nrecipe.adapters.scale({ id: 'lentil-soup', servings: 8 });         // doubles a 4-serving recipe\nrecipe.adapters.nutritionEstimate({ ingredients: ['200g rice', '2 egg', '100g chicken breast'] });\nrecipe.adapters.shoppingList({ recipes: ['beef-tacos', 'chickpea-curry'] });\nrecipe.adapters.substitute({ ingredient: 'butter' });              // → olive oil, coconut oil, …\nrecipe.adapters.cocktail({ have: ['rum', 'lime', 'mint', 'sugar', 'soda'] }); // → Mojito\nrecipe.adapters.mealPlan({ days: 3, diet: 'vegan', seed: 7 });\n```\n\n## Dataset (`data/dataset.json`)\n\n- **recipes** — 12 recipes across cuisines/courses, each with ingredients (item/qty/unit) + steps.\n- **nutrition** — ~40 ingredients with per-100g kcal + protein/carbs/fat + diet tags.\n- **cocktails** — 12 drinks (incl. 2 mocktails) with spirit, ingredients, and method.\n- **substitutions** — swap lists for 15 common ingredients.\n- **units** — grams-per-unit (egg=50g, clove=5g, …) and ml-per-unit for gram/nutrition math.\n\n## DRY boundary\n\nThis is a **new capability** — nothing else in `shared/engines/adapters/domain/` owns food/recipes.\nIt deliberately does **not** overlap:\n- `numbers` — generic scalar/unit math. The gram/nutrition math here is food-specific (grams-per-egg,\n  kcal-per-100g) and only meaningful alongside recipes, so it lives here, not in `numbers`.\n- `finance` / `invoice` — money, not groceries.\n- `calendar` / `datetime` — dates, not meal plans.\n- `nlp` — general text; `search` here is a domain filter over the recipe set.\n\nIf a different product needs richer culinary data, extend `data/dataset.json` — keep the pack pure.\n\n**Not medical or dietary advice.** Nutrition figures are rough estimates from a small built-in table.\n",
  "source": {
    "path": "shared/engines/adapters/domain/recipe/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 4146,
    "hash": "ec484c8b6573a995051ec40f526bd5e45ddba3e7"
  },
  "urls": {
    "html": "/p/adapters/domain/recipe",
    "json": "/docs/adapters/domain/recipe.json",
    "md": "/docs/adapters/domain/recipe.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
