agentsclimarketplace

Meal flyer

Skill scurry/meals-agent/.claude/skills/meal-flyer

Claude or other agent skills to help plan, make, and shop for meals

Install
npx -y skills add scurry/meals-agent --skill meal-flyer

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when processing a grocery store flyer for the Meal OS system. Triggered by "/meal-flyer" or "parse a flyer" or "process flyer".

SKILL.md

7.6 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it

/meal-flyer — Store Flyer Parser

Parse a weekly grocery store flyer and extract sale items mapped to canonical ingredient IDs.

Announce at start: "Processing store flyer..."

Step 1: Get Flyer Input

The user provides flyer data in one of two ways:

Option A: PDF File

If the user provides a file path ending in .pdf:

  • Read the PDF using the Read tool
  • For PDFs over 20 pages, paginate: read pages 1-20, then 21-40, etc.
  • Focus on food items — skip pages that are clearly non-food (cleaning supplies, pharmacy, seasonal items)
  • After the flyer markdown is successfully written and verified, delete the source PDF so raw flyer files do not accumulate in the repo

Option B: Pasted Text

If the user pastes text from a store website or flyer:

  • Use it directly

If no input is provided, ask: "Please provide the store flyer — either paste the text or give me the path to a PDF file."

Step 2: Load Config and Identify the Store

Read data/config.yaml to get the user's store list.

Determine which store this flyer is from:

  • Look for store name in the flyer content
  • If not obvious, ask: "Which store is this flyer from?" and list the stores from config as options

Step 3: Determine Date Range

Look for a validity date range in the flyer content (e.g., "Valid 3/22 - 3/28", "Weekly Specials March 22-28").

  • If found, use the start date for the filename
  • If not found, use today's date
  • Record the full date range for frontmatter

Step 4: Load Canonical Ingredients

Read data/canonical-ingredients.yaml from the project root. This is the normalization reference for mapping sale items.

If the file does not exist: Stop and tell the user: "data/canonical-ingredients.yaml is missing. Run /meal-setup first to initialize the project, then re-run /meal-flyer."

Step 5: Extract Sale Items

For each sale item in the flyer, extract:

FieldWhat to captureExamples
Item descriptionAs printed in the flyer"Boneless Skinless Chicken Thighs Family Pack"
PriceThe sale price$2.49, $8.99
UnitPrice unit/lb, /each, /pint, /dozen, /bag
Deal typeType of promotionRegular Sale, BOGO, Manager's Special, 2 for $5

Price normalization rules:

  • "2 for $5" → price: $2.50, unit: /each, deal type: "2 for $5"
  • "Buy One Get One Free" / "BOGO" → price: [listed price], deal type: "BOGO (effective 50% off)"
  • "Save $2" → note the savings but use the final sale price if shown
  • "$X.XX/lb" → price: $X.XX, unit: /lb
  • If price per unit can't be determined, record as-is with the deal description

Filtering rules:

  • Include: All food and beverage items
  • Skip entirely: Non-food items (cleaning supplies, paper goods, pet food, pharmacy, health/beauty). Do not include them in the Sale Items table. Track the count for the confirmation summary only.

Step 6: Map to Canonical Ingredients

For each food item:

  1. Match against canonical-ingredients.yaml — find the closest canonical ID:

    • "Boneless Skinless Chicken Thighs Family Pack" → chicken_thigh
    • "Fresh Atlantic Salmon Fillets" → salmon
    • "Grape Tomatoes Pint" → cherry_tomato
    • "Greek Yogurt Assorted" → greek_yogurt
  2. Unmappable food items — if a food item doesn't match any canonical ingredient:

    • Mark with ? in the canonical ID column
    • These go into an "Items Needing Review" section for the user to decide if they should be added to the canonical list
  3. Non-food items — already excluded in Step 5; do not include any row for them in the table

Step 7: Generate Summary

Identify which ingredients from the core set (~24 items in canonical-ingredients.yaml) are on sale this week. List them with price and store name.

If no core ingredients are on sale, note: "No core ingredients on sale this week."

Step 8: Detect Likely Loss Leaders

Identify items priced aggressively low — likely below store cost to drive foot traffic.

Method 1 — Savings Heuristic (always available)

For each sale item with a "Save $X" value: compute savings_pct = save_amount / (sale_price + save_amount). Flag as loss leader if savings_pct >= 0.35.

Method 2 — Price History Comparison (when data exists)

Read data/receipts/price-history.yaml if it exists.

For each sale item that has a canonical ID (not ?):

  1. Look up the canonical ID in the price history
  2. Compute the average price from all ledger entries for that item
  3. If the sale price is >30% below the average, flag as a likely loss leader

If the price history file doesn't exist, skip Method 2 silently.

Output

If any items are flagged, add a new section to the flyer markdown between "Core Ingredients On Sale This Week" and "Items Needing Review":

## Likely Loss Leaders

| Item | Sale Price | Regular/Avg Price | Savings | Method |
|------|-----------|-------------------|---------|--------|
| [Item] | $X.XX/unit | $Y.YY (regular) | NN% | heuristic |
| [Item] | $X.XX/unit | $Y.YY (avg from N receipts) | NN% | price-history |
| [Item] | $X.XX/unit | $Y.YY (regular) / $Z.ZZ (avg) | NN% | both |

Consider building meals around these items — they're priced to get you in the store.

If an item is flagged by both methods, show it once with Method = "both" and show both the regular and average prices.

If no items meet either threshold, omit this section entirely.

Step 9: Check for Collisions

Generate filename: data/flyers/YYYY-MM-DD-<store-slug>.md

  • Store slug: market-basket or hannafords
  • Example: data/flyers/2026-03-22-market-basket.md

If the file already exists, ask: "A flyer for [store] on [date] already exists. Overwrite, save as [date]-[store]-2.md, or cancel?"

Step 10: Write the Flyer File

Ensure the directory exists: run mkdir -p data/flyers via Bash before writing.

Write to data/flyers/YYYY-MM-DD-<store-slug>.md using this format:

---
store: [Store Name]
date_range: [YYYY-MM-DD to YYYY-MM-DD]
source: [weekly-flyer-pdf or pasted-text]
---

## Sale Items

| Item | Canonical ID | Price | Unit | Deal Type |
|------|-------------|-------|------|-----------|
| [Item description] | [canonical_id or ?] | [$X.XX] | [/unit] | [deal type] |

## Core Ingredients On Sale This Week

- [canonical_id] — $[price]/[unit] ([Store Name])
- [canonical_id] — $[price]/[unit] ([Store Name])

<!-- Include this section only if Step 8 flagged any loss leaders; omit entirely if none -->
## Likely Loss Leaders

| Item | Sale Price | Regular/Avg Price | Savings | Method |
|------|-----------|-------------------|---------|--------|
| [Item] | $X.XX/unit | $Y.YY (regular) | NN% | heuristic |

Consider building meals around these items — they're priced to get you in the store.

## Items Needing Review

- [Item description] → marked `?` ([reason or suggestion for canonical mapping])

If the source input was a local PDF file and the markdown flyer was written successfully, delete the PDF after saving the markdown output. Do not keep a separate archived PDF copy.

Step 11: Confirm

Output a summary:

Flyer saved: data/flyers/YYYY-MM-DD-<store-slug>.md

  Store: [Store Name]
  Date range: [date range]
  Items extracted: [N total]
  Mapped to canonical: [M items]
  Marked for review (?): [K items]
  Skipped (non-food): [J items]

  Core ingredients on sale:
  - [list or "none"]

  Loss leaders detected: [N items, or "none"]
  - [list if any]

  Source PDF deleted: [yes/no/not-applicable]

Review items marked with ? and decide if they should be added to data/canonical-ingredients.yaml.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.