Asynchronous shopping research + checkout using secure-autofill (1Password-backed browser filling) with results recorded to workspace artifacts.
Find items across one or more shopping sites, summarize candidates, and (optionally) place the order using secure-autofill.
This skill is asynchronous: spawn a sub-agent for browsing so the main chat stays responsive.
~/.openclaw/skills/secure-autofill/vault_suggestvault_fillConcrete check:
command -v google-chrome || command -v google-chrome-stable
Skill-local config files:
~/.openclaw/skills/secure-shopper/config.json.example~/.openclaw/skills/secure-shopper/config.jsonConfig keys:
goToSites[]: list of default shopping sites (e.g. Amazon, Walmart)location.zip or location.address: used for shipping/availability contextpreferences.priority: one of:
relevancycheaperfasterreviewspreferences.maxCandidatesPerSite: cap per site (default 5)preferences.safeBrowsing: guardrails to avoid oversized pages / context overflow (applies to all sites)
startFromSearch: true|false (default true) — prefer a site’s search results page over the homepage/product pagesmaxCandidatesPerPass: number (default 3) — extract a few items at a time (then paginate/scroll)snapshot: limits for browser.snapshot
compact: boolean (default true)depth: number (default 6)maxChars: number (default 12000)fallback: what to do on context_length_exceeded
retryWithTighterSnapshot: boolean (default true)switchToSearchUrl: boolean (default true)Ask Boss and then write config.json:
Go-to shopping website(s)
goToSites[]Zip code OR proximity address
location.zip and/or location.addressPreferences
preferences.priority (+ optional notes)After collecting answers, update the real config file.
Optional helper (terminal):
node ~/.openclaw/skills/secure-shopper/scripts/onboard.mjs \
--sites 'Amazon=https://www.amazon.com|Walmart=https://www.walmart.com' \
--zip 46202 \
--priority cheaper
The user must provide a description of their shopping task.
Runtime user instructions (the user’s message for this run) override stored config.
Examples of runtime overrides:
browser.snapshot to get refsvault_suggest/vault_fill to fill credentialsImmediately after accepting the task, respond with something like:
I’m en route to the stores. I’ll notify you when I find the best matches.
Then spawn a sub-agent so the main session is not interrupted.
Implementation note:
sessions_spawn with a task that includes the shopping description and any runtime overrides.The sub-agent browses each chosen site, searches, filters, and identifies candidates that fit the user description.
Many shopping sites can produce extremely large pages/snapshots. To avoid context_length_exceeded failures:
browser.snapshot(..., compact=true)depth modest (e.g., 4–8)maxChars and/or target a specific container when possiblemaxCandidatesPerSite is met/search?q=...) and re-extractRecord results to:
/home/miles/.openclaw/workspace/artifacts/secure_shopping/{timestamp}_shopping_task.json
JSON requirements:
userPrompt (shopping description)startTimeendTimephase (required):
candidates_found | awaiting_accept_deny | awaiting_checkout_confirm | orderedcandidates[]price (string)reviewScore (string/number)urlverdict (short)status: pending | accepted | denied | shoppedSuggested candidate shape:
{
"site": "Amazon",
"title": "...",
"price": "$39.99",
"reviewScore": "4.6 (12,345)",
"url": "https://...",
"verdict": "Best value under $50; good reviews; ships tomorrow",
"status": "pending"
}
Helper module (optional): scripts/task_io.mjs.
When browsing is done, you must:
phase = "awaiting_accept_deny".Mandatory message template (copy this structure):
A=accept/deny, B=accept/deny, ... (or “Accept A” / “Deny B”).Hard rule:
Once the user replies:
status to accepted or denied.phase:
awaiting_checkout_confirm if at least one is accepted and checkout is not yet confirmedawaiting_accept_deny if the user’s response is ambiguous / incompleteBefore you click any “Place order” / “Submit” equivalent:
phase = "awaiting_checkout_confirm" until confirmed.If the user confirms checkout:
If secure-autofill reports an error:
If the order is successfully placed:
status to shoppedphase = "ordered"