Skip to main content
ClaudeWave
Skill192.1k estrellas del repoactualizado today

shop-app

Shop.app is a personal shopping assistant skill that enables product search across stores, price comparison, order tracking, returns management, and reordering of past purchases. Use this skill when users need to find products, compare prices, track shipments, process returns, or repurchase items, with authentication required only for user-specific operations like order management while product searches remain freely accessible.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/NousResearch/hermes-agent /tmp/shop-app && cp -r /tmp/shop-app/optional-skills/productivity/shop-app ~/.claude/skills/shop-app
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Shop.app — Personal Shopping Assistant

Use this skill when the user wants to **search products across stores, compare prices, find similar items, track an order, manage a return, or re-order a past purchase** through Shop.app's agent API.

No auth required for product search. Auth (device-authorization flow) is required for any per-user operation: orders, tracking, returns, reorder. Store tokens **only in your working memory for the current session** — never write them to disk, never ask the user to paste them.

All endpoints return **plain-text markdown** (including errors, which look like `# Error\n\n{message} ({status})`). Use `curl` via the `terminal` tool; for the try-on feature use the `image_generate` tool.

---

## Product Search (no auth)

**Endpoint:** `GET https://shop.app/agents/search`

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `query` | string | yes | — | Search keywords |
| `limit` | int | no | 10 | Results 1–10 |
| `ships_to` | string | no | `US` | ISO-3166 country code (controls currency + availability) |
| `ships_from` | string | no | — | ISO-3166 country code for product origin |
| `min_price` | decimal | no | — | Min price |
| `max_price` | decimal | no | — | Max price |
| `available_for_sale` | int | no | 1 | `1` = in-stock only |
| `include_secondhand` | int | no | 1 | `0` = new only |
| `categories` | string | no | — | Comma-delimited Shopify taxonomy IDs |
| `shop_ids` | string | no | — | Filter to specific shops |
| `products_limit` | int | no | 10 | Variants per product, 1–10 |

```
curl -s 'https://shop.app/agents/search?query=wireless+earbuds&limit=10&ships_to=US'
```

**Response format:** Plain text. Products separated by `\n\n---\n\n`.

**Fields to extract per product:**
- **Title** — first line
- **Price + Brand + Rating** — second line (`$PRICE at BRAND — RATING`)
- **Product URL** — line starting with `https://`
- **Image URL** — line starting with `Img: `
- **Product ID** — line starting with `id: `
- **Variant IDs** — in the Variants section or from the `variant=` query param in the product URL
- **Checkout URL** — line starting with `Checkout: ` (contains `{id}` placeholder; replace with a real variant ID)

**Pagination:** none. For more or different results, **vary the query** (different keywords, synonyms, narrower/broader terms). Up to ~3 search rounds.

**Errors:** missing/empty `query` returns `# Error\n\nquery is missing (400)`.

---

## Find Similar Products

Same response format as Product Search.

**By variant ID (GET):**

```
curl -s 'https://shop.app/agents/search?variant_id=33169831854160&limit=10&ships_to=US'
```

The `variant_id` must come from the `variant=` query param in a product URL — the `id:` field from search results is **not** accepted.

**By image (POST):**

```
curl -s -X POST https://shop.app/agents/search \
  -H 'Content-Type: application/json' \
  -d '{"similarTo":{"media":{"contentType":"image/jpeg","base64":"<BASE64>"}},"limit":10}'
```

Requires base64-encoded image bytes. URLs are **not** accepted — download the image first (`curl -o`), then `base64 -w0 file.jpg` to inline.

---

## Authentication — Device Authorization Flow (RFC 8628)

Required for orders, tracking, returns, reorder. Not required for product search.

**Session state (hold in your reasoning context for this conversation only):**

| Key | Lifetime | Description |
|---|---|---|
| `access_token` | until expired / 401 | Bearer token for authenticated endpoints |
| `refresh_token` | until refresh fails | Renews `access_token` without re-auth |
| `device_id` | whole session | `shop-skill--<uuid>` — generate once, reuse for every request |
| `country` | whole session | ISO country code (`US`, `CA`, `GB`, …) — ask or infer |

**Rules:**
- `user_code` is always 8 chars A-Z, formatted `XXXXXXXX`.
- No `client_id`, `client_secret`, or callback needed — the proxy handles it.
- **Never ask the user to paste tokens into chat.**
- Tokens live only for the duration of this conversation. Do not write them to `.env` or any file.

### Flow

**1. Request a device code:**
```
curl -s -X POST https://shop.app/agents/auth/device-code
```
Response includes `device_code`, `user_code`, `sign_in_url`, `interval`, `expires_in`. Present `sign_in_url` (and the `user_code`) to the user.

**2. Poll for the token** every `interval` seconds:
```
curl -s -X POST https://shop.app/agents/auth/token \
  --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
  --data-urlencode "device_code=$DEVICE_CODE"
```
Handle errors: `authorization_pending` (keep polling), `slow_down` (add 5s to interval), `expired_token` / `access_denied` (restart flow). Success returns `access_token` + `refresh_token`.

**3. Validate:**
```
curl -s https://shop.app/agents/auth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

**4. Refresh on 401:**
```
curl -s -X POST https://shop.app/agents/auth/token \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode "refresh_token=$REFRESH_TOKEN"
```
If refresh fails, restart the device flow.

---

## Orders

> **Scope:** Shop.app aggregates orders from **all stores** (not just Shopify) using email receipts the user connected in the Shop app. This skill never touches the user's email directly.

**Status progression:** `paid → fulfilled → in_transit → out_for_delivery → delivered`
**Other:** `attempted_delivery`, `refunded`, `cancelled`, `buyer_action_required`

### Fetch pattern

```
curl -s 'https://shop.app/agents/orders?limit=50' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "x-device-id: $DEVICE_ID"
```

Parameters: `limit` (1–50, default 20), `cursor` (from previous response).

**Key fields to extract:**
- **Order UUID** — `uuid: …`
- **Store** — `at …`, `Store domain: …`, `Store URL: …`
- **Price** — line after `Store URL`
- **Date** — `Ordered: …`
- **Status / Delivery** — `Status: …`, `Delivery: …`
- **Reorder eligible** — `Can reorder: yes`
- **Items** — under `— Items —`, each