---
name: meal-planner
description: Save recipes to ~/recipes and generate weekly meal plans from ~/meal-plans/planner-config.yaml. Trigger this skill whenever the user wants to: save a recipe (from URL, pasted text, or description), add a recipe to their recipe library, create a weekly meal plan, plan meals for the week, generate a grocery list, or mentions ~/recipes or ~/meal-plans. Also trigger when the user says things like "save this recipe", "add this to my recipes", "plan my week", "make a meal plan", or "what should I eat this week".
---
## Overview
This skill manages two things:
1. **Saving recipes** to `~/recipes/` in a consistent markdown+YAML format
2. **Generating weekly meal plans** based on `~/meal-plans/planner-config.yaml` and the available recipe library
## Reference files
Load these when you need them — don't load all three upfront:
| File | Load when |
|------|-----------|
| `references/recipe-format.md` | Saving a recipe — full YAML+markdown template, filename rules, field constraints |
| `references/weekly-plan-format.md` | Generating a plan — exact output structure, daily notes format, grocery list groupings |
| `references/planner-config.md` | Generating a plan — annotated config schema, how profiles merge, how constraints apply |
---
## Part 1: Saving a Recipe
When the user wants to save a recipe (paste, URL, description, or screenshot):
### Step 1: Get the recipe content
- If given a URL, fetch the page and extract the recipe
- If pasted as text, use it directly
- If described loosely, ask for any missing key info (ingredients, macros if known)
### Step 2: Format as markdown with YAML frontmatter
Always use this exact structure (fill what you can, use `null` for unknowns — never invent macros or times):
```markdown
---
title: "<Recipe Name>"
type: "recipe"
status: "tested" # idea | testing | tested | staple
servings: <number|null>
prep_time_min: <number|null>
cook_time_min: <number|null>
total_time_min: <number|null>
meal: ["breakfast"|"lunch"|"dinner"|"snack"]
cuisine: [<strings>]
diet: [<strings>] # e.g. ["high protein", "gluten-free"]
tags: [<strings>] # e.g. ["meal prep", "bowls", "chicken"]
difficulty: "easy"|"medium"|"hard"|null
equipment: [<strings>]
ingredients:
- item: "<name>"
qty: <number|null>
unit: "<unit>|null"
allergens: [<strings>]
leftovers: "none"|"ok"|"great"|null
freezer_friendly: <true|false|null>
makes_ahead: <true|false|null>
macros:
calories_per_serving: <number|null>
protein_g_per_serving: <number|null>
carbs_g_per_serving: <number|null>
fat_g_per_serving: <number|null>
source:
name: "<string|null>"
url: "<string|null>"
notes: "<string|null>"
---
# <Recipe Name>
## Quick summary
1–2 sentences.
## Ingredients
Group into logical subsections if helpful.
## Instructions
Numbered steps, concise and actionable.
## Macros
- Calories: X per serving
- Protein: Xg per serving
- Carbs: Xg per serving
- Fat: Xg per serving
## Variations
3–6 bullets max.
## Storage
Short guidance for fridge/freezer.
```
### Step 3: Generate the filename
- Lowercase, words separated by hyphens
- Remove special characters (accents OK to drop or keep as-is)
- Keep it readable: `chicken-shawarma-bowls.md`, not `recipe-1.md`
### Step 4: Ensure ~/recipes exists, then save
```bash
mkdir -p ~/recipes
```
Save the file to `~/recipes/<filename>.md`. Confirm to the user: "Saved to ~/recipes/<filename>.md"
---
## Part 2: Generating a Weekly Meal Plan
When the user asks to create or generate a weekly plan (phrases like "plan my week", "create a meal plan", "what should I cook this week"):
### Step 1: Read the config
Read `~/meal-plans/planner-config.yaml`. If it doesn't exist, tell the user and offer to create a starter config.
Key fields to use:
- `defaults.user_calories` / `defaults.partner_calories` — calorie targets
- `defaults.available_recipes` — pool of recipes to draw from
- `defaults.required_recipes` — must appear in the plan
- `defaults.constraints` — variety window, min protein, prep time limits
- `defaults.preferences` / `defaults.restrictions` — AI guidance
- `defaults.recipe_selection` — how many recipes per meal type
### Step 2: Check for user overrides
The user may add restrictions or preferences inline, e.g.:
- "avoid dairy this week"
- "I want more fish"
- "skip the chili"
- "use the high-protein profile"
If a named profile is mentioned (e.g. "high-protein", "meal-prep"), merge that profile's settings on top of defaults.
Apply any inline restrictions on top of config restrictions — they don't replace, they add.
### Step 3: Scan the recipe library
Read all files from `~/recipes/` that appear in `available_recipes`. For each, extract from YAML frontmatter:
- title, meal type, macros, tags, diet, allergens, difficulty, prep time, leftovers, freezer_friendly
This gives you the actual macro data to use in the plan.
### Step 4: Build the 7-day plan
Create a Monday–Sunday plan following these rules:
- Respect `variety_window` — don't repeat the same recipe within that many days
- Hit calorie targets using portion notes (primary user vs partner)
- Include all `required_recipes` at least once
- Meet `min_protein_per_day` where possible
- Respect `exclude_allergens` from recipe_filters
- Keep weekday prep under `max_prep_time_weekday`
For each day, format like:
```
### Monday
**Breakfast:** <Recipe Name>
**Lunch:** <Recipe Name>
**Dinner:** <Recipe Name>
*Notes: Primary user: X servings (Y cal), ... Partner: ... Daily totals: X cal | Xg protein | Xg carbs | Xg fat*
```
### Step 5: Generate the grocery list
Aggregate all ingredients across all recipes × portions used. Group by category:
- Proteins
- Vegetables
- Fruits
- Grains & Starches
- Dairy & Eggs
- Oils & Fats
- Condiments & Sauces
- Spices & Seasonings
- Other
Combine duplicate ingredients (e.g. "Greek yogurt 200g + 400g = 600g total").
### Step 6: Embed full recipe details
After the grocery list, include a `## Recipe Details` section with the full content of every recipe used. Copy the entire recipe body (not just a reference). This is what makes the plan self-contained for shopping and cooking.
### Step 7: Save the plan
```bash
mkdir -p ~/meal-plans
```
Filename format: `weekly-plan-YYYY-MM-DD.md` where the date is the Monday of that week.
Save to `~/meal-plans/weekly-plan-YYYY-MM-DD.md`. Confirm to the user.
---
## Output format for the weekly plan
```markdown
# Weekly Meal Plan
**Week:** <Month DD - Month DD, YYYY>
## Planning Notes
<2-3 sentences about the strategy: which recipes were prioritized, any special notes, meal prep suggestions>
## Weekly Nutrition Summary
**Daily Averages:**
- Calories: X cal
- Protein: Xg
- Carbs: Xg
- Fat: Xg
## Daily Meal Plan
### Monday
...
### Tuesday
...
(through Sunday)
## Grocery List
### Proteins
...
(all categories)
---
## Recipe Details
### <Recipe Name>
<full recipe content>
---
(repeat for each recipe)
---
*Generated on YYYY-MM-DD HH:MM:SS*
```
---
## Edge cases
- **Recipe not in ~/recipes**: If a required recipe doesn't exist as a file, note it in Planning Notes and skip it rather than failing
- **Missing macros**: If a recipe has `null` macros, still include it but omit its contribution from daily totals and flag it in notes
- **No config file**: Offer to create one based on a short interview (calories, preferences, restrictions)
- **~/recipes empty or missing**: Create the folder and tell the user to save some recipes first