public/SKILL.md
# Shopping List Skill Add items to shopping lists via API. Multi-store support with section-based organization. **API Base:** `https://shopping.uppal.zone/api` **Auth:** Bearer token (API key from Settings) --- ## TL;DR - Add an Item ```bash POST /api/stores/{storeId}/items Authorization: Bearer sk_... Content-Type: application/json {"name": "milk", "sectionId": "dairy-section-id"} ``` That's it. Item added. --- ## Authentication 1. User generates API key in **Settings → API Access** 2
npx skillsauth add sidu/shopping-list publicInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Add items to shopping lists via API. Multi-store support with section-based organization.
API Base: https://shopping.uppal.zone/api
Auth: Bearer token (API key from Settings)
POST /api/stores/{storeId}/items
Authorization: Bearer sk_...
Content-Type: application/json
{"name": "milk", "sectionId": "dairy-section-id"}
That's it. Item added.
Authorization: Bearer sk_...GET /api/stores
Returns all stores you own or have access to.
Response:
{
"success": true,
"data": {
"stores": [
{"id": "abc123", "name": "Costco", "isOwner": true, "sectionsCount": 8},
{"id": "def456", "name": "Trader Joe's", "isOwner": true, "sectionsCount": 8}
]
}
}
POST /api/stores
Content-Type: application/json
{"name": "Home Depot"}
Creates a new store with default sections.
Response:
{
"success": true,
"data": {
"store": {
"id": "xyz789",
"name": "Home Depot",
"isOwner": true,
"sections": [...]
}
}
}
Limits:
GET /api/stores/{storeId}
Returns store with sections.
Response:
{
"success": true,
"data": {
"store": {
"id": "abc123",
"name": "Costco",
"sections": [
{"id": "sec1", "name": "Produce", "order": 0},
{"id": "sec2", "name": "Dairy", "order": 1},
{"id": "sec3", "name": "Meat & Seafood", "order": 2},
{"id": "sec4", "name": "Bakery", "order": 3},
{"id": "sec5", "name": "Pantry", "order": 4},
{"id": "sec6", "name": "Frozen", "order": 5},
{"id": "sec7", "name": "Snacks & Beverages", "order": 6},
{"id": "sec8", "name": "Household", "order": 7}
]
}
}
}
GET /api/stores/{storeId}/items
POST /api/stores/{storeId}/items
# Single item
{"name": "milk", "sectionId": "sec2"}
# Multiple items
{"items": [
{"name": "milk", "sectionId": "sec2"},
{"name": "eggs", "sectionId": "sec2"},
{"name": "bread", "sectionId": "sec4"}
]}
PATCH /api/stores/{storeId}/items/{itemId}
{"checked": true} # Mark as bought
{"sectionId": "sec3"} # Move to different section
{"name": "organic milk"} # Rename
DELETE /api/stores/{storeId}/items/{itemId}
POST /api/stores/{storeId}/items/clear
{"mode": "checked"} # Remove only checked items (default)
{"mode": "all"} # Remove all items
When user says "add milk", figure out which store:
Default sections (most stores have these):
If unsure, check the store's sections first and pick the best match.
{"success": false, "error": {"message": "Store not found or access denied"}}
Common errors:
401 — Invalid or missing API key404 — Store/item not found or no access400 — Invalid request bodyWhen user says: "Add milk and bread"
// 1. Parse items
const items = ["milk", "bread"];
// 2. Get stores, pick grocery store
const stores = await fetch('/api/stores', {headers}).then(r => r.json());
const grocery = stores.data.stores.find(s => s.name.toLowerCase().includes('costco'));
// 3. Get sections for mapping
const store = await fetch(`/api/stores/${grocery.id}`, {headers}).then(r => r.json());
const dairy = store.data.store.sections.find(s => s.name === 'Dairy');
const bakery = store.data.store.sections.find(s => s.name === 'Bakery');
// 4. Add items
await fetch(`/api/stores/${grocery.id}/items`, {
method: 'POST',
headers: {...headers, 'Content-Type': 'application/json'},
body: JSON.stringify({
items: [
{name: 'milk', sectionId: dairy.id},
{name: 'bread', sectionId: bakery.id}
]
})
});
X-RateLimit-Limit: Max requests per windowX-RateLimit-Remaining: Requests leftX-RateLimit-Reset: Unix timestamp when limit resets429 Too Many Requests if exceededdevelopment
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.