Adom Parts Search
Public Made by Adomby adom
One search box across Mouser + DigiKey + JLCPCB. Parallel queries, side-by-side product photos, and a Mouser-preferred recommendation (40-min drone delivery to Fort Worth) that reasons around stock and lead time.
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.
Displaying this app (REQUIRED — read before showing anything)
To SHOW this app to the user, use adom-parts-search show (it opens the proper Hydrogen
webview tab itself). If you ever need to open the app UI manually, FIRST load the
webview skill (from adom-workspace-control) and follow it.
- NEVER open this app in VS Code's "Simple Browser" — that is NOT what "webview" means in the Adom ecosystem. Simple Browser has no live channel, no console read-back, and no AI drivability; using it is a bug.
- The Adom surfaces for showing an app are: wv — a Hydrogen webview panel (load the
webviewskill from adom-workspace-control and follow it; inside HD this is HD's pane tab), pup — a pup window (pupskill), nb — the user's real signed-in browser (Adom browser extension), and hdbw — HD's standalone built-in Tauri browser window (picker: "HD Browser Window", destination idwebview-window, only under Hydrogen Desktop). Pick per the situation; Simple Browser is NEVER one of them.
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.
# ✅ 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, runshowinstead — 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 (
LM333for "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:
- Try one alternative family name (e.g.
LM555→NE555→LM556). - 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."
- 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:
{
"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):
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:
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 adom-parts-search skill 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 service 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 adompkg install in a fresh user container. Or manually:
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
---
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.
## Displaying this app (REQUIRED — read before showing anything)
To SHOW this app to the user, use `adom-parts-search show` (it opens the proper Hydrogen
webview tab itself). If you ever need to open the app UI manually, FIRST load the
`webview` skill (from adom-workspace-control) and follow it.
- **NEVER open this app in VS Code's "Simple Browser"** — that is NOT what "webview" means
in the Adom ecosystem. Simple Browser has no live channel, no console read-back, and no
AI drivability; using it is a bug.
- The Adom surfaces for showing an app are: **wv** — a Hydrogen webview panel (load the
`webview` skill from adom-workspace-control and follow it; inside HD this is HD's pane
tab), **pup** — a pup window (`pup` skill), **nb** — the user's real signed-in browser (Adom browser
extension), and **hdbw** — HD's standalone built-in Tauri browser window
(picker: "HD Browser Window", destination id `webview-window`, only under Hydrogen
Desktop). Pick per the situation; Simple Browser is NEVER one of them.
## 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 `adom-parts-search` skill 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 service 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 `adompkg install` in a fresh user 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
```