← Commit history

Add adompkg installer files

Kyle Bergstedt ·f0390fa55d ·4mo ago ·parent aae0297
4 files changed +34−183
SKILL.md+4−183
@@ -1,186 +1,7 @@ --- 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.+description: >+  Unified parts search across Mouser + DigiKey + JLCPCB in parallel. Side-by-side comparison with product photos. Mouser-preferred routing (40-min drone to Fort Worth, near-zero shipping). -----# 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-```+# Adom Parts Search+Unified parts search across Mouser + DigiKey + JLCPCB in parallel. Side-by-side comparison with product photos. Mouser-preferred routing (40-min drone to Fort Worth, near-zero shipping).
install.shadded+15
@@ -0,0 +1,15 @@+#!/bin/bash+set -e+PKG_DIR="$(cd "$(dirname "$0")" && pwd)"+SKILLS_DIR="$HOME/.claude/skills"+mkdir -p "$SKILLS_DIR/adom-parts-search"+if [ -f "$PKG_DIR/SKILL.md" ]; then+  cp "$PKG_DIR/SKILL.md" "$SKILLS_DIR/adom-parts-search/SKILL.md"+fi+for skill_dir in "$PKG_DIR/skills"/*/; do+  [ -d "$skill_dir" ] || continue+  skill_name=$(basename "$skill_dir")+  mkdir -p "$SKILLS_DIR/$skill_name"+  cp -r "$skill_dir"* "$SKILLS_DIR/$skill_name/"+done+echo "Installed adom-parts-search"
package.jsonadded+11
@@ -0,0 +1,11 @@+{+  "slug": "adom-parts-search",+  "version": "1.0.0",+  "type": "app",+  "description": "Unified parts search across Mouser + DigiKey + JLCPCB in parallel. Side-by-side comparison with product photos. Mouser-preferred routing (40-min drone to Fort Worth, near-zero shipping).",+  "dependencies": {},+  "scripts": {+    "install": "./install.sh",+    "uninstall": "./uninstall.sh"+  }+}
uninstall.shadded+4
@@ -0,0 +1,4 @@+#!/bin/bash+set -e+rm -rf "$HOME/.claude/skills/adom-parts-search"+echo "Uninstalled adom-parts-search"