app
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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
#!/usr/bin/env bash
# adom-parts-search release publisher.
# Syncs VERSION → Cargo.toml → git tag → gh release → wiki asset → wiki page.
# Idempotent: safe to re-run for the same version (adom-wiki upload replaces).
set -euo pipefail
cd "$(dirname "$0")"
VERSION=$(cat VERSION | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "ERROR: VERSION file is empty" >&2; exit 1
fi
# ANSI only when stdout is a real terminal (adom-cli-design rule:
# no raw escapes when the AI captures stdout).
if [ -t 1 ]; then C_OK='\033[32m'; C_ERR='\033[31m'; C_STEP='\033[36m'; C_RESET='\033[0m'
else C_OK=''; C_ERR=''; C_STEP=''; C_RESET=''
fi
ok() { printf '%sOK:%s %s\n' "$C_OK" "$C_RESET" "$1"; }
fail() { printf '%sERROR:%s %s\n' "$C_ERR" "$C_RESET" "$1" >&2; exit 1; }
step() { printf '\n%s== %s ==%s\n' "$C_STEP" "$1" "$C_RESET"; }
# ── 0. Sanity: VERSION == Cargo.toml version ───────────────────────
step "0. sanity checks"
CARGO_VERSION=$(grep -m1 '^version =' Cargo.toml | sed -E 's/version = "([^"]+)"/\1/')
if [ "$VERSION" != "$CARGO_VERSION" ]; then
fail "VERSION ($VERSION) != Cargo.toml ($CARGO_VERSION). Run: sed -i 's/^version = .*/version = \"$VERSION\"/' Cargo.toml"
fi
ok "VERSION + Cargo.toml both at $VERSION"
# ── 0a. Icon audit — monochrome white, no favicon carve-out ────────
# Gates the release. Per brand/SKILL.md + app-creator §1b, every icon
# (including docs/icon.svg → tab-strip favicon) must be monochrome.
step "0a. icon monochrome-white audit"
TEAL_HITS=$(grep -nrE 'fill="(#00b8b0|#00d4cb)"|stroke="(#00b8b0|#00d4cb)"' \
docs/icon.svg src/app/ 2>/dev/null || true)
if [ -n "$TEAL_HITS" ]; then
printf '%s\n' "$TEAL_HITS"
fail "teal fill/stroke found in an icon/SVG — see brand/SKILL.md §Icons"
fi
ICON_COLORS=$(grep -oE 'fill="#[0-9a-fA-F]{3,8}"|stroke="#[0-9a-fA-F]{3,8}"' docs/icon.svg 2>/dev/null \
| grep -v -E '"#e6edf3"|"#ffffff"|"#fff"|"#0d1117"|"none"|"transparent"|"currentColor"' || true)
if [ -n "$ICON_COLORS" ]; then
printf '%s\n' "$ICON_COLORS"
fail "docs/icon.svg uses disallowed color(s) — must be #e6edf3 / currentColor / none / #0d1117"
fi
LOGO_HITS=$(grep -nrE '\.logo[^{]*\{[^}]*color:\s*var\(--accent\)|\.icon[^{]*\{[^}]*color:\s*var\(--accent\)' \
src/app/ 2>/dev/null || true)
if [ -n "$LOGO_HITS" ]; then
printf '%s\n' "$LOGO_HITS"
fail ".logo / .icon CSS rule inheriting --accent — icon will paint teal at runtime"
fi
ok "all icons monochrome white / currentColor"
# ── 1. Build + verify binary --version ─────────────────────────────
step "1. cargo build --release"
cargo build --release
BIN=target/release/adom-parts-search
BIN_VER=$("$BIN" --version | awk '{print $NF}')
if [ "$BIN_VER" != "$VERSION" ]; then
fail "binary --version ($BIN_VER) != VERSION ($VERSION)"
fi
ok "binary prints adom-parts-search $VERSION"
# ── 2. Git commit + tag + push ─────────────────────────────────────
step "2. git commit + tag v$VERSION"
git add -A
if ! git diff --cached --quiet; then
git commit -m "release v$VERSION"
ok "committed"
else
ok "nothing to commit"
fi
git tag -f "v$VERSION"
git push origin main
git push origin "v$VERSION" --force
ok "pushed main + v$VERSION tag"
# ── 3. GitHub Release (optional, informational) ────────────────────
step "3. gh release create v$VERSION"
if gh release view "v$VERSION" >/dev/null 2>&1; then
gh release upload "v$VERSION" "$BIN" --clobber
ok "updated release v$VERSION binary"
else
gh release create "v$VERSION" "$BIN" --title "v$VERSION" --generate-notes
ok "created release v$VERSION"
fi
# ── 4. Wiki page publish/update ────────────────────────────────────
step "4. adom-wiki page publish apps/adom-parts-search"
TITLE=$(jq -r '.title' wiki/page.json)
BRIEF=$(jq -r '.brief' wiki/page.json)
adom-wiki page publish apps/adom-parts-search \
--title "$TITLE" \
--brief "$BRIEF" \
--body-md wiki/body.md \
--version "$VERSION" \
--sample-prompt "Parts search|find me a USB-C connector on Mouser, DigiKey, or JLCPCB with stock > 1000" \
--sample-prompt "Compare distributors|compare prices and stock for STM32F103RBT6 across Mouser, DigiKey, and JLCPCB" \
--sample-prompt "Open parts search|open the Adom Parts Search app in Hydrogen so I can see product photos" \
--sample-prompt "Best deal|find the best price for iCE40HX4K-TQ144 accounting for Mouser's 40-minute drone delivery to Fort Worth" \
--sample-prompt "Check stock|where is the ESP32-S3-WROOM-1U-N4R2 in stock fastest?"
ok "wiki page published at apps/adom-parts-search v$VERSION"
# ── 5. Wiki asset upload (canonical install surface) ───────────────
step "5. adom-wiki asset upload (docker-binary + skill + build-skill)"
adom-wiki asset upload apps/adom-parts-search --asset-type docker-binary --file "$BIN"
ok "uploaded $BIN to wiki at apps/adom-parts-search"
# Skills live on the wiki so prose-only edits ship without a binary rebuild
# (see adom-cli-design "DO NOT embed SKILL.md in the binary" rule).
adom-wiki asset upload apps/adom-parts-search --asset-type file --file SKILL.md
adom-wiki asset upload apps/adom-parts-search --asset-type file --file BUILD-SKILL.md
ok "uploaded SKILL.md + BUILD-SKILL.md to wiki"
# ── 6. Push metadata (discovery_triggers, install_hint, releases) ──
step "6. adom-wiki page edit --field metadata"
TMP_META=$(mktemp)
jq --arg v "$VERSION" '.metadata | .version = $v' wiki/page.json > "$TMP_META"
adom-wiki page edit apps/adom-parts-search --field metadata --body-md "$TMP_META"
rm -f "$TMP_META"
ok "metadata updated"
# ── 7. Verify the wiki actually serves v$VERSION ───────────────────
step "7. verify wiki binary --version"
BINARY_URL=$(jq -r '.metadata.releases.adom_docker.binary_url' wiki/page.json)
if [ -z "$BINARY_URL" ] || [ "$BINARY_URL" = "null" ]; then
fail "wiki page.json has no binary_url"
fi
CHECK=$(mktemp)
if ! curl -fsSL "$BINARY_URL" -o "$CHECK"; then
rm -f "$CHECK"
fail "wiki binary download failed at $BINARY_URL (may need a minute to propagate; re-run step 7)"
fi
chmod +x "$CHECK"
WIKI_VER=$("$CHECK" --version | awk '{print $NF}')
rm -f "$CHECK"
if [ "$WIKI_VER" != "$VERSION" ]; then
fail "wiki serves $WIKI_VER but we just published $VERSION"
fi
ok "wiki binary returns --version adom-parts-search $VERSION"
echo
echo "───────────────────────────────────────────────"
echo " adom-parts-search v$VERSION published."
echo " Wiki: $BINARY_URL"
echo " The service-parts-search container will auto-update within 2 minutes."
echo "───────────────────────────────────────────────"