ワンクリックで
build-store-adapter
Reverse-engineer an ecommerce site's search and emit a deterministic adapter script under scripts/store_adapters/<slug>/.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Reverse-engineer an ecommerce site's search and emit a deterministic adapter script under scripts/store_adapters/<slug>/.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Bin store procurement workflow. Trigger when the user asks "what do I need to buy", "refresh the shopping list", "find products for the bin store", "bin store shopping", "check the bin store materials to order", or "can I use my existing X instead of Y". Pulls the latest inventory from Grist, computes outstanding cuts (cut list minus inventory with greedy fit), proposes inventory substitutions within ±10mm tolerance and — with user approval — edits `parameters.scad` and regenerates before shopping, then searches B&Q for each remaining row and pushes the shopping list back to Grist. Designed for Cowork (uses Chrome browser automation) but also works in Claude Code CLI with WebFetch for single pages.
Bin store Grist sync. Trigger when the user says "sync Grist", "refresh the cut list", "push the cut list", "pull inventory", "sync bin store tables", or "update Grist from the repo". Regenerates the cut list from the OpenSCAD model and then syncs every Grist table in its default direction — cut_list and shopping_list push local → Grist (preserving the `completed` checkbox across pushes); inventory pulls Grist → local. Use this before running bin-store-shopping or any time the OpenSCAD model has changed.
| name | build-store-adapter |
| description | Reverse-engineer an ecommerce site's search and emit a deterministic adapter script under scripts/store_adapters/<slug>/. |
| disable-model-invocation | true |
| argument-hint | [site-url] |
| allowed-tools | ["Bash(cd tooling/adapter-builder && npm install*)","Bash(cd tooling/adapter-builder && npm run record*)","Bash(cd scripts/store_adapters/* && npm install*)","Bash(cd scripts/store_adapters/* && npm test*)","Bash(cd scripts/store_adapters/* && npm run typecheck*)","Bash(cd scripts/store_adapters/* && npx playwright install*)","Bash(npx --prefix scripts/store_adapters/* tsx*)","Bash(find scripts/store_adapters/*)","Read","Write","Edit","Task","AskUserQuestion"] |
Builds a per-site ecommerce search adapter. The runtime adapter does not call any LLM — analysis cost is paid once during this skill run, then every future search is a deterministic HTTP call (or a scoped browser run if the site can't be scraped without one).
Three locations, one per role:
tooling/adapter-builder/ — bootstrap recorder. One copy, hand-authored. Drives Stagehand + Playwright, writes recordings.json.scripts/store_adapters/<slug>/ — one generated adapter per site. Contains search.ts, search.test.ts, manifest.json, recordings.json, package.json, tsconfig.json..claude/skills/build-store-adapter/ — this skill, orchestrating the two./Users/chuck/workspace/diy-projects).OPENROUTER_API_KEY must be set. The recorder loads it via node --env-file-if-exists=../../.env, so the canonical place is the repo-root .env (alongside the existing Grist keys; see .env.sample). A shell-exported variable also works. If neither source provides it, stop and name the variable.node ≥ 20.12 and npm on PATH (the recorder's npm script uses --env-file-if-exists, added in 20.12).tooling/adapter-builder/. The skill installs deps on first use.LOCAL launches Chromium on a local CDP port; two parallel skill invocations collide. Run one at a time.The user may pass a site URL as the slash-command argument:
ARGUMENTS: $ARGUMENTS
$ARGUMENTS above is non-empty, treat its first whitespace-trimmed token as the target site URL and skip the URL question.$ARGUMENTS is empty, ask for the URL.Then ask via a single AskUserQuestion call (omit the URL question when supplied as an argument):
$ARGUMENTS) — e.g. https://www.diy.com.scripts/store_adapters/. Default rule: lowercase the host, replace dots with underscores, strip a leading www_. Examples: www.diy.com → diy_com; shop.acme.co.uk → shop_acme_co_uk.Verify OPENROUTER_API_KEY is set. Stop with the variable name if not.
If scripts/store_adapters/<slug>/ already exists, ask the user via a second AskUserQuestion:
_v2, _v3 etc. Continue with the new slug.If tooling/adapter-builder/node_modules/ does not exist:
cd tooling/adapter-builder && npm install
Run the recorder for all queries. Pass --out as an absolute path so it lands directly in the adapter dir without a copy step:
cd tooling/adapter-builder && npm run record -- \
--site "https://www.diy.com" \
--queries '["CLS timber 50x47","plywood exterior 18mm"]' \
--out "/Users/chuck/workspace/diy-projects/scripts/store_adapters/diy_com"
Substitute the user-supplied site URL, the JSON-encoded queries array, and the slug from Phase 1.
The recorder is interactive — Chromium opens locally. Wait for it to finish; do not background it. It writes recordings.json after every query, so even a partial run produces a usable file.
If the recorder errors on a query with "produced no visible product cards", the file still has earlier queries. Read the file, count queries[i].error entries, and:
After the recorder returns, sanity-check by reading the first successful query's product titles aloud to the user (one line: "captured N products for query X — looks like real product results: titles A, B, C").
Spawn the project-scoped store-adapter-generator subagent (defined in .claude/agents/store-adapter-generator.md) via the Task tool. Pass subagent_type: "store-adapter-generator".
The agent reads the recording, classifies the site, and writes the adapter files. It does not run any of them — that's Phase 4.
The agent's full system prompt and output contract live in its definition file; do not duplicate them here. The skill's job in this phase is just to invoke the agent with the two paths and capture the JSON summary it returns.
Task prompt (the entire user-message to the agent):
RECORDING_PATH: <absolute path to recordings.json from Phase 2>
OUTPUT_DIR: <absolute path to scripts/store_adapters/<slug>/>
The agent returns a single JSON object on stdout:
{
"method": "json_api" | "html_embedded_json" | "browser_required",
"endpoint_url": "https://...", // null for browser_required
"selected_candidate_url": "https://...", // the network candidate that won the cross-reference
"files_written": [/* paths under OUTPUT_DIR */],
"per_query_overlap": [{ "query": "...", "overlap": 0.83 }]
}
Parse it; carry files_written and per_query_overlap into Phase 3.5 and Phase 5.
Before running anything, confirm the subagent wrote what it claimed:
files_written. The set must include manifest.json, package.json, tsconfig.json, search.ts, search.test.ts, and recordings.json.manifest.json parses and contains method, field_map, validation.manifest.json is malformed, treat as a regeneration failure (see Phase 4).Run in sequence; stop on first failure:
cd scripts/store_adapters/<slug> && npm install
cd scripts/store_adapters/<slug> && npm run typecheck
If method == "browser_required", install Chromium for the adapter's node_modules:
cd scripts/store_adapters/<slug> && npx playwright install chromium
Then:
cd scripts/store_adapters/<slug> && npm test
On typecheck or test failure, retry the subagent at most once. Build the retry prompt by appending this block to the original Phase 3 prompt:
The previous generation produced these errors. Fix them and re-emit only the changed files. Errors:
<paste tsc/vitest output verbatim>
If still failing after one retry, stop and ask the user via AskUserQuestion:
<failed> and choose between <remaining>".manifest.validation.passed: false.On all tests passing, edit manifest.json to set validation.passed: true, then run a final smoke test:
cd scripts/store_adapters/<slug> && npx tsx search.ts "<first sample query>" --max 5
Confirm stdout is a JSON object with a non-empty products array, each with at least title and url.
Render this template literally, filling in the bracketed values:
Built {method} adapter for {site}.
Endpoint: {endpoint_url or "n/a (browser_required)"}
Validation: {N}/{M} queries passed at ≥0.5 title overlap (per-query: q1=0.83, q2=0.71, ...).
Path: scripts/store_adapters/{slug}/
Usage: npx tsx scripts/store_adapters/{slug}/search.ts "<query>" --max 10
Then a single trailing sentence: "Wiring callers to this adapter is a separate task."
This skill is interactive — Phase 1 uses AskUserQuestion and Phase 2 opens a visible Chromium window. It is not safe to run via Cowork's headless proxy. If invoked from a headless context, stop after the precondition check and report: "build-store-adapter requires an interactive session; rerun in Claude Code CLI on the user's machine."
OPENROUTER_API_KEY unset — stop in Phase 1, name the variable.npm install in tooling/adapter-builder/ fails — show the npm error verbatim and stop. Common causes: no network, npm registry config, Node version too old.act returns "could not locate") — the site likely uses a non-standard search trigger or hides search behind a region/postcode prompt. Stop and ask the user for a direct search-results URL pattern (?q={query}) they want to use instead — the analyzer can sometimes work from that alone.browser_required case. The subagent picks that method automatically.npx tsx search.ts returns an empty products list at the smoke-test step — a session-bound header in the manifest has expired. Re-run the skill with the same site and queries to capture fresh headers; the regenerated manifest replaces the stale one.bin-store-shopping) to use the generated adapter — separate task.