> ## Documentation Index
> Fetch the complete documentation index at: https://docs.closient.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Plan Shopping Trip

> Given a shopping list and a user location, figure out the minimum number of stores needed and a sensible order to visit them.

User has a list of items and wants to know where to go. This skill minimizes
stops while respecting stock, distance, and store hours.

## When to use

* User provides 2+ items and asks "where should I go?"
* User wants a route, not just a single-store recommendation.
* Shopping is local (within a few km of the user's location).

For a single item, use `check-product-availability` directly.

## Inputs to gather

1. **Shopping list** — product names or GTINs (mixed is fine).
2. **Origin location** — latitude + longitude.
3. **Max distance / budget** — optional `radius_km` (default 10), optional
   `max_stops` (default 3).
4. **Preferences** — optional: in-stock only, avoid certain stores, prefer
   local-independent.

## Flow

### 1. Resolve each item to candidate GTINs

For items already given as GTINs, skip. For free-text, call
`local-product-search` per item to get top candidates with per-store
availability.

### 2. Build a coverage matrix

Rows = stores within radius. Columns = items. Cell = `(available,
price, confidence)`. Drop stores where no items are available.

### 3. Pick the minimum cover

Greedy set-cover works fine for small lists: pick the store covering the
most items, repeat on the remaining list. Tie-break by distance, then total
price.

### 4. Order the stops

Sort picked stores by distance from origin, then by travel time between
consecutive stores. If `max_stops` is exceeded, relax "in-stock only" before
dropping items.

### 5. Return the plan

```json theme={null}
{
  "stops": [
    {
      "store": {"name": "...", "address": "...", "distance_km": 0.8},
      "items": [{"gtin": "...", "product_name": "...", "price": 4.99}],
      "open_now": true
    },
    ...
  ],
  "unavailable": [{"item": "fresh dragonfruit", "reason": "out of stock within 10km"}]
}
```

## Guidance for agents

* **Always state what's unavailable** — users need to know what they'll have
  to pick up elsewhere or skip.
* **Respect constraints explicitly**: if the user said "no Whole Foods,"
  exclude that chain even if it gives a better cover.
* **Prefer fewer stops over lowest total price** unless the user says
  otherwise — time is usually the real constraint.

## Planned

A `POST /search/api/v1/trip-plan` endpoint that runs the optimization
server-side would let agents hand off the whole computation. For now, the
agent drives the loop.

## Related skills

* `local-product-search` — drives candidate resolution per item
* `check-product-availability` — per-store verification for a GTIN
* `hyperlocal-nearby` — add opportunistic items the user didn't ask for
