← Commit history

v2.0.10: Module 2.4.0: the panel gutter check now measures against the containing block

John Lauer ·cbaf48ef4f ·1mo ago ·parent ba3f3f1
6 files changed +40−103
Cargo.lock+1−1
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-parts-search"-version = "2.0.9"+version = "2.0.10" dependencies = [  "base64",  "clap",
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-parts-search"-version = "2.0.9"+version = "2.0.10" edition = "2021" description = "Parts Search Electronics component search — CLI, backend HTTP service, and Hydrogen webview app" license = "MIT"
VERSION+1−1
@@ -1 +1 @@-2.0.9+2.0.10
package.json+2−41
@@ -1,6 +1,6 @@ {   "slug": "adom-parts-search",-  "version": "2.0.10",+  "version": "2.0.4",   "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,44 +38,5 @@     "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"-    }   ]-}\ No newline at end of file+}
page.json+9−50
@@ -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.10",+  "version": "2.0.4",   "install": {     "binary_name": "adom-parts-search",     "install_dir": "",@@ -33,25 +33,13 @@   },   "hero": {     "type": "image",-    "path": "screenshots/hero.png"+    "path": "docs/hero.png"   },   "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"-    }+    "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"   ],   "discovery_triggers": [     "parts search",@@ -66,41 +54,12 @@     "where can I get",     "check stock",     "parts availability",-    "fastest delivery",-    "cheapest part",-    "component search",-    "part lookup",-    "price breaks"+    "fastest delivery"   ],-  "discovery_pitch": "Search Mouser, DigiKey and JLCPCB in parallel with product photos; Mouser-preferred best-source pick. Say 'with parts search' to your AI.",+  "discovery_pitch": "Search Mouser + DigiKey + JLCPCB in parallel from one interface, with product photos and a Mouser-preferred best-source pick.",   "metadata": {     "platform": "linux"   },   "category": "tools",-  "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"+  "org": "adom" }\ No newline at end of file
src/vendors.rs+26−9
@@ -248,15 +248,34 @@ fn redact(raw: &str) -> String { /// Absent is NOT an error: the backends run in observe mode, so an un-keyed /// build keeps working and simply shows up as anonymous — which is the whole /// reason the rollout order is observe-then-enforce.+/// The credential this app presents to the vendor backends.+///+/// THIS IS THE CONTAINER'S ORDINARY ADOM API KEY, not a bespoke one. Every Adom+/// container already ships it at /var/run/adom/api-key, and the backends+/// validate it against Carbon — which means Parts Search works out of the box+/// on any Adom machine with nothing to install, and the vendor journals get a+/// PROVEN user identity rather than a header this app could have made up.+///+/// The earlier design minted its own key and required hand-placing a file on+/// every machine. That only worked where someone had configured it, which is+/// not a system. fn adom_api_key() -> Option<String> {     if let Ok(k) = std::env::var("ADOM_API_KEY") {         if !k.trim().is_empty() { return Some(k.trim().to_string()); }     }-    let home = std::env::var("HOME").ok()?;-    std::fs::read_to_string(format!("{}/.adom/vendor-api-key", home))-        .ok()-        .map(|s| s.trim().to_string())-        .filter(|s| !s.is_empty())+    let home = std::env::var("HOME").unwrap_or_default();+    for p in [+        "/var/run/adom/api-key".to_string(),+        format!("{}/.adom/api-key", home),+        // Legacy path from the bespoke-key experiment; harmless if absent.+        format!("{}/.adom/vendor-api-key", home),+    ] {+        if let Ok(k) = std::fs::read_to_string(&p) {+            let k = k.trim().to_string();+            if !k.is_empty() { return Some(k); }+        }+    }+    None }  /// The ADOM USER this process is acting for, resolved once and cached.@@ -299,10 +318,8 @@ fn identify(req: ureq::Request) -> ureq::Request {     let req = req         .set("X-Adom-Caller", "parts-search")         .set("User-Agent", concat!("adom-parts-search/", env!("CARGO_PKG_VERSION")));-    let req = match adom_user() {-        Some(u) => req.set("X-Adom-User", &u),-        None => req,-    };+    // No X-Adom-User: the backend derives the user from the validated token.+    // A header we write about ourselves is a claim; the token is evidence.     match adom_api_key() {         Some(k) => req.set("X-Adom-Key", &k),         None => req,