app
Parts Search
Public Made by Adomby adom
One search box across Mouser, DigiKey and JLCPCB: parallel queries, side-by-side product photos, and a Mouser-preferred recommendation that reasons around stock and lead time.
← Commit history
SKILL.mdadded+186@@ -0,0 +1,186 @@+---+name: adom-parts-search+description: Unified parts search across Mouser + DigiKey + JLCPCB with Mouser-preferred routing (40-min drone delivery from Mansfield, TX to our Fort Worth facility; near-zero shipping). CLI and Hydrogen webview app. Use when the user asks to source a part, price a component, compare vendors, check stock across distributors, or assemble a BOM. Trigger words — find part, search parts, source component, parts search, component search, where can I get, compare distributors, Mouser or DigiKey, compare prices, BOM sourcing, stock check, parts availability, open parts search, parts search app, parts search UI.+---++# adom-parts-search++Searches Mouser + DigiKey + JLCPCB in parallel. Rust CLI + Hydrogen webview. Recommends **Mouser by default** because our Fort Worth facility has a 40-minute drone delivery arrangement with Mouser's Mansfield, TX fulfillment center + near-zero shipping cost.++## CLI++**For user-facing searches, always use `show`.** It drives the webview tab AND prints the full vendor-by-vendor result to stdout, so the user sees product photos + 3-column comparison and the AI sees the same data textually. Auto-starts the app server + opens the tab on first run.++```bash+# ✅ DEFAULT — every search a human asks for+adom-parts-search show "ESP32-S3-WROOM-1U-N4R2"+adom-parts-search show "iCE40HX4K-TQ144" --limit 8 --in-stock-only++# Scripting / piping / batch only (no webview, pure JSON)+adom-parts-search search "STM32F103RBT6" | jq '.recommendation'++# Keep the app tab running without triggering a search+adom-parts-search app+```++### Decision rule++- User asked a conversational question about a part → **`show`**. Always.+- You're piping into `jq`, `awk`, or a batch script → `search`.+- Silence: never just dump JSON to chat. If you would have run `search`, run `show` instead — the user wants photos and side-by-side comparison, not a wall of JSON.++### Extract a clean MPN / part-family BEFORE calling `show`++Vendor APIs (Mouser, DigiKey, JLCPCB) do substring match on MPN and description, NOT full-text intent search. If the user says "find me a 3.3V LDO with 500 mA", do NOT pipe `"find me a 3.3V LDO with 500 mA"` into `show` — that's natural language, and every vendor will return zero hits. Extract the likely part family or MPN first, then call `show`.++**Extraction examples:**++| User said | Pass to `show` | Why |+|---|---|---|+| "find me a 555 timer" | `LM555` | Canonical 555-family part. Also try `NE555` if no hits. |+| "search for esp32 dev boards" | `ESP32` | Broad family match; narrow later with `ESP32-S3` if the user wants a specific variant. |+| "need a 3.3V LDO 500mA" | `LM1117-3.3` or `AMS1117-3.3` | Well-known 3.3V LDOs; pick one, try the other if empty. |+| "stm32 bluepill chip" | `STM32F103C8T6` | The canonical Blue Pill MCU. |+| "what op-amp for unity gain audio" | `TL072` or `NE5532` | Common audio op-amps. Don't pass "op-amp audio" as a keyword. |+| "lm333 timer" | Ask first — LM333 isn't a 555-family timer. Probably `LM555` (typo). | Don't burn a search on a bogus part number. |++**Rules of thumb:**++- If the user typed a clearly valid MPN (has letters + digits + optional dash, 4+ chars, looks like `STM32F103RBT6` / `LM555` / `ESP32-S3-WROOM-1U-N4R2`), pass it through verbatim.+- If the user typed a natural-language description, mentally map it to the 1-2 best-known part families and pass the first one to `show`. If that returns 0, try the second.+- If the user named a part that doesn't match a family you recognize (`LM333` for "timer"), **stop and ask one clarifying question** before searching — don't guess your way into a bogus API call.+- If the user names an exact variant (e.g. "ESP32-S3-WROOM-1U-N4R2"), use that; don't broaden it unless a search returns 0.++### Handling empty results++If `show` returns 0 hits across all three vendors AND no vendor errored, the CLI will already print a helpful "no matches" line and the webview will render an empty-state card with suggestions. You still need to decide what to do next:++1. Try one alternative family name (e.g. `LM555` → `NE555` → `LM556`).+2. If the alternative also returns 0, surface that to the user with a brief explanation: "Neither LM555 nor NE555 matched — double-check the MPN or describe the part differently."+3. Do NOT silently run five searches in a row with minor variations — ask the user for a better name after the second attempt.++### Common part families + corrections++| If the user said… | Try first | Also valid |+|---|---|---|+| "555 timer" / "monostable timer" | `LM555` | `NE555`, `LM556`, `TLC555` |+| "3.3V LDO" | `LM1117-3.3` | `AMS1117-3.3`, `AP2112K-3.3` |+| "5V LDO" | `LM7805` | `LM1117-5.0`, `AMS1117-5.0` |+| "op-amp" (audio) | `TL072` | `NE5532`, `OPA2134` |+| "op-amp" (general) | `LM358` | `MCP6002`, `TL074` |+| "FPGA" (Lattice ice40 family) | `iCE40HX4K-TQ144` | `iCE40UP5K`, `iCE40LP1K` |+| "ESP32" (generic) | `ESP32-WROOM-32` | `ESP32-S3`, `ESP32-C3` |+| "STM32 Blue Pill" | `STM32F103C8T6` | `STM32F103RBT6` |+| "Arduino Nano MCU" | `ATmega328P` | `ATmega168` |+| "USB-C connector" | `USB4085` | `USB4110`, `GCT USB4105` |++If you see the user invoke a part number that doesn't look right (like `LM333` for "timer"), consult this table FIRST, ask a one-line clarifying question, and only call `show` after the user confirms the correction.++Stdout from `show` looks like:++```+adom-parts-search keyword: "iCE40HX4K-TQ144"++MOUSER total= 1 hits= 1 412ms [ok]+ iCE40HX4K-TQ144 Lattice Semicon… $10.20 stock 42+DIGIKEY total= 1 hits= 1 676ms [ok]+ ICE40HX4K-TQ144 Lattice Semicon… $11.22 stock 413+JLCPCB total= 0 hits= 0 74ms [ok]++RECOMMENDATION → Mouser iCE40HX4K-TQ144 $10.20 stock 42+ Mouser stocked — 40-min drone delivery from Mansfield.+```++followed by the full unified JSON (same schema as `search` below) so downstream tooling has structured access.++The `search` output is a unified JSON:++```json+{+ "query": "iCE40HX4K-TQ144",+ "mouser": { "ok": true, "total": 1, "hits": [...], "elapsed_ms": 412 },+ "digikey": { "ok": true, "total": 1, "hits": [...], "elapsed_ms": 630 },+ "jlcpcb": { "ok": true, "total": 0, "hits": [], "elapsed_ms": 180 },+ "recommendation": {+ "winner": "Mouser",+ "mpn": "iCE40HX4K-TQ144",+ "unit_price": "$10.20",+ "stock": 42,+ "reason": "Mouser stocked — 40-min drone delivery from Mansfield, near-zero shipping."+ }+}+```++Each `hit` includes `image_url` for the webview — use the `app` subcommand when the user needs to eyeball product photos (Claude Code terminal can't show images).++## Webview app++`adom-parts-search app` opens a Hydrogen tab titled **"Parts Search"** with a 3-column grid:++- **Mouser column** (blue top border) — preferred, badged "40-min drone · $0 ship"+- **DigiKey column** (red top border) — alternative+- **JLCPCB column** (green top border) — parts library only (SMT assembly)++Each card shows the product photo, MPN, vendor PN, manufacturer, price (@1 and @100), stock, lead time, flags (RoHS / basic / preferred / lifecycle). Click any product photo to zoom.++The recommendation banner at the top calls out the winning vendor with the reason — the same policy as the CLI, rendered visually.++## Pin-1 alignment check — moved to `adom-chipfit`++The footprint ↔ 3D-chip validator that used to live here as+`adom-parts-search align` is now its own app: **`adom-chipfit`**.+Scope got big enough (package-family guard, seat-Δz classifier,+persistent pin-1 registration bake) that keeping it inside+parts-search was mixing two unrelated concerns.++Install one-liner (paste-into-Claude style):++```bash+curl -fsSL https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-chipfit/adom-chipfit \+ -o /tmp/adom-chipfit && chmod +x /tmp/adom-chipfit \+ && sudo install -m 0755 /tmp/adom-chipfit /usr/local/bin/adom-chipfit \+ && adom-chipfit install+```++Then use it via:++```bash+adom-chipfit check --footprint path.kicad_mod --glb path.glb+```++Running `adom-parts-search align ...` now prints a one-time message+pointing at the install command above and exits non-zero so CI+picks it up.++## Why Mouser is preferred++See the companion skill `adom-parts-search` (the gallia one) for the full policy. Short version:++- **40-minute drone delivery** (Mansfield TX → Fort Worth TX, ~15 miles)+- **Near-zero shipping cost** (drone route, Mouser-operated)+- DigiKey wins only when Mouser is out of stock, lead time >14 days, or DigiKey is >30% cheaper on a volume order++## Backend URLs++The three vendor backends are Tier A services. Current URLs:++- Mouser: `https://mouser-xr8t4f5d01bt.adom.cloud`+- DigiKey: `https://digikey-gjuu8l5t69uh.adom.cloud`+- JLCPCB: `https://jlcpcb-wela51osctvp.adom.cloud`++Override with `--mouser-api` / `--digikey-api` / `--jlcpcb-api`, or env vars `MOUSER_API` / `DIGIKEY_API` / `JLCPCB_API`. Canonical source of truth for current slugs is `~/service-watcher/services.json` on the main gallia container.++## Architecture++This app is **client-only** — no service container of its own. It coordinates the three existing vendor backends (adom-mouser / adom-digikey / adom-jlcpcb). Each individual vendor CLI is still available for single-vendor queries.++## Install++Tier A — fetched by `gallia/install.mjs` on every gallia container. Or manually:++```bash+curl -fsSL https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-parts-search/adom-parts-search \+ -o /tmp/adom-parts-search && chmod +x /tmp/adom-parts-search && \+ sudo install -m 0755 /tmp/adom-parts-search /usr/local/bin/adom-parts-search && \+ adom-parts-search install+```