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
Publish 2.0.14
8 files changed
+134−12
README.md+4@@ -97,6 +97,10 @@ Not in your rail? Dock settings (the gear at the top of the rail), Add app, | `adom-digikey` (service-digikey) | Recommended | DigiKey column and the fallback when Mouser cannot ship | | `adom-jlcpcb` (service-jlcpcb) | Optional | JLCPCB assembly-library column | +**No vendor API key, ever.** Mouser, DigiKey and JLCPCB credentials are company-owned and live only inside Adom's service containers. What a search needs is your **Adom identity**, so each search is attributed to a real Adom user: in an Adom container it is read automatically from `/var/run/adom/api-key`; elsewhere set `ADOM_API_KEY` to your Adom session token.++**Exact part first.** Search an exact MPN and the recommendation is that exact part whenever it is in stock, at Mouser first and then DigiKey. A packaging or grade variant (`DSER` vs `DSET`, a `-Q100` automotive part) is a different orderable part, so it can only ever appear as an explicit, amber-flagged **substitution**, never as a silent winner.+ Client-only: it owns no API keys and runs no service of its own; it federates the three vendor backends and renders. At least one backend must be reachable; a missing one shows a friendly error and the recommendation reasons around it.
SKILL.md+20−1@@ -9,6 +9,14 @@ Searches Mouser + DigiKey + JLCPCB in parallel. Rust CLI + Hydrogen webview. Rec **Quota rule: NEVER search in a loop.** Every search spends the shared daily vendor API quota (Mouser's free tier is about 1000/day for everyone combined). One search per user question. Never retry a rate-limited vendor on a timer, never poll /search, never re-run a search to refresh a page (the page re-renders from `GET /state` for free). The server answers an identical repeat within 5 minutes from its own cache, but do not lean on that: just do not loop. +## Identity and access (read this first)++**You never need a Mouser, DigiKey or JLCPCB API key, and you must never ask a user for one.** Those are company-owned credentials that live only inside Adom's service containers. Parts Search owns no vendor keys and runs no vendor service; it federates Adom's three hosted backends.++Every search DOES need an **Adom identity**, because each search is attributed to a real Adom user so shared vendor quota can be accounted for. It is automatic: in an Adom container the app reads `/var/run/adom/api-key` (the Adom session token) by itself; anywhere else set `ADOM_API_KEY` to the user's Adom session token. The backends validate the token against Adom's identity service, so the identity is proven rather than self-reported.++If a vendor column says **"search needs your Adom identity"**, the machine presented no valid Adom token: sign in to Adom or set `ADOM_API_KEY`. It is never a vendor key. If it says **"could not verify your identity right now"**, that is an Adom-side outage, not the user's credential: retry shortly.+ ## 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.@@ -108,11 +116,22 @@ The `search` output is a unified JSON: "mpn": "iCE40HX4K-TQ144", "unit_price": "$10.20", "stock": 42,- "reason": "Mouser has it in stock and is the preferred vendor: fastest, lowest-cost fulfillment."+ "reason": "Mouser has the exact part in stock and is the preferred vendor: fastest, lowest-cost fulfillment.",+ "requested_mpn": "iCE40HX4K-TQ144",+ "exact_match": true } } ``` +### Exact part first, substitutions never silent++When the query is an exact MPN, the recommendation is **that exact part** whenever it is in stock: first at Mouser, then at DigiKey (the right part from the second vendor beats the wrong part from the first). Vendor result order and stock depth never outrank exactness.++- `exact_match: true` means `mpn` is precisely what was asked for.+- If the exact part is out of stock everywhere and a variant is offered instead, `exact_match` is `false` and a **`substitution`** string is present, naming both parts. The one-line summary says `SUBSTITUTION, NOT the requested <mpn>` and the page shows an amber warning.+- **Always relay a `substitution` to the user, and never order or design in a substituted part without their say-so.** A packaging suffix (`DSER` vs `DSET`) or a grade variant (`-Q100` automotive) is a different orderable part: different reel, different qualification, sometimes a different datasheet. Punctuation is part of an MPN (`74LVC2G17GV,125`), so it is compared exactly; only case and surrounding whitespace are ignored.+- A family or keyword query (`LM358`, `10k 0402`) matches no hit exactly, so `requested_mpn` is absent and the Mouser-preferred vendor order applies as before.+ Each `hit` includes `image_url` for the webview: use `show` when the user needs to eyeball product photos (Claude Code terminal can't show images). ## The page
bin/adom-parts-search⋯ 1 unchanged line ⋯
install.shpackage.json+41−2@@ -1,6 +1,6 @@ { "slug": "adom-parts-search",- "version": "2.0.4",+ "version": "2.0.14", "type": "app", "description": "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. Dock Bar ready: serve, health, settings, Say it.", "dependencies": {@@ -38,5 +38,44 @@ "SKILL.md", "BUILD-SKILL.md", "CHANGELOG.md"+ ],+ "changelog": "Module 2.4.0: the panel gutter check now measures against the containing block",+ "discovery_triggers": [+ "parts search",+ "find part",+ "source component",+ "source part",+ "compare distributors",+ "compare vendors",+ "Mouser or DigiKey",+ "BOM sourcing",+ "price this part",+ "where can I get",+ "check stock",+ "parts availability",+ "fastest delivery",+ "cheapest part",+ "component search",+ "part lookup",+ "price breaks"+ ],+ "discovery_pitch": "Search Mouser, DigiKey and JLCPCB in parallel with product photos; Mouser-preferred best-source pick. Say 'with parts search' to your AI.",+ "sample_prompts": [+ {+ "label": "source an STM32F103RBT6",+ "prompt": "source an STM32F103RBT6"+ },+ {+ "label": "where can I get an ESP32-S3-WROOM cheape",+ "prompt": "where can I get an ESP32-S3-WROOM cheapest and fastest"+ },+ {+ "label": "compare Mouser, DigiKey and JLCPCB for a",+ "prompt": "compare Mouser, DigiKey and JLCPCB for an LM555"+ },+ {+ "label": "price this BOM across distributors",+ "prompt": "price this BOM across distributors"+ } ]-}+}
page.json+49−8@@ -4,7 +4,7 @@ "slug": "adom-parts-search", "title": "Parts Search", "brief": "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.",- "version": "2.0.4",+ "version": "2.0.14", "install": { "binary_name": "adom-parts-search", "install_dir": "",@@ -36,10 +36,22 @@ "path": "screenshots/hero.png" }, "sample_prompts": [- "source an STM32F103RBT6",- "where can I get an ESP32-S3-WROOM cheapest and fastest",- "compare Mouser, DigiKey and JLCPCB for an LM555",- "price this BOM across distributors"+ {+ "label": "source an STM32F103RBT6",+ "prompt": "source an STM32F103RBT6"+ },+ {+ "label": "where can I get an ESP32-S3-WROOM cheape",+ "prompt": "where can I get an ESP32-S3-WROOM cheapest and fastest"+ },+ {+ "label": "compare Mouser, DigiKey and JLCPCB for a",+ "prompt": "compare Mouser, DigiKey and JLCPCB for an LM555"+ },+ {+ "label": "price this BOM across distributors",+ "prompt": "price this BOM across distributors"+ } ], "discovery_triggers": [ "parts search",@@ -54,12 +66,41 @@ "where can I get", "check stock", "parts availability",- "fastest delivery"+ "fastest delivery",+ "cheapest part",+ "component search",+ "part lookup",+ "price breaks" ],- "discovery_pitch": "Search Mouser + DigiKey + JLCPCB in parallel from one interface, with product photos and a Mouser-preferred best-source pick.",+ "discovery_pitch": "Search Mouser, DigiKey and JLCPCB in parallel with product photos; Mouser-preferred best-source pick. Say 'with parts search' to your AI.", "metadata": { "platform": "linux" }, "category": "tools",- "org": "adom"+ "org": "adom",+ "description": "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. Dock Bar ready: serve, health, settings, Say it.",+ "dependencies": {+ "adom/adom-mouser": "*",+ "adom/adom-digikey": "*",+ "adom/adom-jlcpcb": "*"+ },+ "needs_sudo": false,+ "scripts": {+ "install": "./install.sh",+ "uninstall": "./uninstall.sh"+ },+ "files": [+ "bin/**",+ "skills/**",+ "docs/icon.svg",+ "dockbar.json",+ "install.sh",+ "uninstall.sh",+ "package.json",+ "README.md",+ "SKILL.md",+ "BUILD-SKILL.md",+ "CHANGELOG.md"+ ],+ "changelog": "Module 2.4.0: the panel gutter check now measures against the containing block" }
skills/adom-parts-search/SKILL.md+20−1@@ -9,6 +9,14 @@ Searches Mouser + DigiKey + JLCPCB in parallel. Rust CLI + Hydrogen webview. Rec **Quota rule: NEVER search in a loop.** Every search spends the shared daily vendor API quota (Mouser's free tier is about 1000/day for everyone combined). One search per user question. Never retry a rate-limited vendor on a timer, never poll /search, never re-run a search to refresh a page (the page re-renders from `GET /state` for free). The server answers an identical repeat within 5 minutes from its own cache, but do not lean on that: just do not loop. +## Identity and access (read this first)++**You never need a Mouser, DigiKey or JLCPCB API key, and you must never ask a user for one.** Those are company-owned credentials that live only inside Adom's service containers. Parts Search owns no vendor keys and runs no vendor service; it federates Adom's three hosted backends.++Every search DOES need an **Adom identity**, because each search is attributed to a real Adom user so shared vendor quota can be accounted for. It is automatic: in an Adom container the app reads `/var/run/adom/api-key` (the Adom session token) by itself; anywhere else set `ADOM_API_KEY` to the user's Adom session token. The backends validate the token against Adom's identity service, so the identity is proven rather than self-reported.++If a vendor column says **"search needs your Adom identity"**, the machine presented no valid Adom token: sign in to Adom or set `ADOM_API_KEY`. It is never a vendor key. If it says **"could not verify your identity right now"**, that is an Adom-side outage, not the user's credential: retry shortly.+ ## 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.@@ -108,11 +116,22 @@ The `search` output is a unified JSON: "mpn": "iCE40HX4K-TQ144", "unit_price": "$10.20", "stock": 42,- "reason": "Mouser has it in stock and is the preferred vendor: fastest, lowest-cost fulfillment."+ "reason": "Mouser has the exact part in stock and is the preferred vendor: fastest, lowest-cost fulfillment.",+ "requested_mpn": "iCE40HX4K-TQ144",+ "exact_match": true } } ``` +### Exact part first, substitutions never silent++When the query is an exact MPN, the recommendation is **that exact part** whenever it is in stock: first at Mouser, then at DigiKey (the right part from the second vendor beats the wrong part from the first). Vendor result order and stock depth never outrank exactness.++- `exact_match: true` means `mpn` is precisely what was asked for.+- If the exact part is out of stock everywhere and a variant is offered instead, `exact_match` is `false` and a **`substitution`** string is present, naming both parts. The one-line summary says `SUBSTITUTION, NOT the requested <mpn>` and the page shows an amber warning.+- **Always relay a `substitution` to the user, and never order or design in a substituted part without their say-so.** A packaging suffix (`DSER` vs `DSET`) or a grade variant (`-Q100` automotive) is a different orderable part: different reel, different qualification, sometimes a different datasheet. Punctuation is part of an MPN (`74LVC2G17GV,125`), so it is compared exactly; only case and surrounding whitespace are ignored.+- A family or keyword query (`LM358`, `10k 0402`) matches no hit exactly, so `requested_mpn` is absent and the Mouser-preferred vendor order applies as before.+ Each `hit` includes `image_url` for the webview: use `show` when the user needs to eyeball product photos (Claude Code terminal can't show images). ## The page
uninstall.sh