app
Adom Chipsmith
Public Made by Adomby adom
STEP-native chip validator — 5-source cross-validation, OCCT-generated copyright-free 3D models with embedded signal annotations, datasheet-to-STEP pipeline.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
mod cli;
mod server;
use anyhow::Result;
use clap::{Parser, Subcommand};
/// adom-chipsmith — STEP-native chip detection + footprint validation + sign-off.
///
/// Loads a .step file (alongside its .kicad_mod footprint, datasheet PDF, and
/// chipsmith-spec.json manifest), reads the STEP's B-rep + assembly hierarchy
/// directly via service-step2glb's `/step-meta` endpoint (NOT the GLB triangle
/// mesh), runs detection in three modes (named PRODUCT walk → surface-type
/// cluster → face-merge fallback), validates measurements, auto-recovers from
/// Y-up vs Z-up, detects pin-1 on both chip and footprint, layers a 1.6mm faux
/// PCB + heatsink vias + solder-jet domes, and on user sign-off bakes a
/// `<mpn>.chipsmith.step` (canonical) + shadow `.chipsmith.glb` + sidecar JSON.
///
/// Every UI verb has a JS API helper, an HTTP endpoint, and a CLI subcommand
/// so an AI agent can drive the validator headlessly.
///
/// See PLAN.md for the full spec.
#[derive(Parser)]
#[command(name = "adom-chipsmith", version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
/// Open a chip in the Hydrogen webview tab. Loads the STEP via
/// service-step2glb (cached on disk by content hash) and pulls the
/// step-meta sidecar so detection can run on B-rep data.
View(cli::view::Args),
/// Open a chip from a chip-fetcher library directory. Pulls the .step,
/// .kicad_mod footprint, datasheet PDF, and info.json manifest from
/// `<chip-fetcher>/library/<MPN>/`.
ViewLibrary(cli::view_library::Args),
/// Stop a running adom-chipsmith server on the given port.
Stop(cli::stop::Args),
/// Print status of the running adom-chipsmith server.
Status(cli::status::Args),
/// Re-attach the webview tab without restarting the server.
Open(cli::open::Args),
/// Health check against a running server.
Health(cli::health::Args),
/// Install binary to ~/.local/bin/, drop SKILL.md, install completions.
Install(cli::install::Args),
/// Print the discovered scene-graph component tree (one row per node).
ListComponents(cli::list_components::Args),
/// Hide every other top-level subtree and frame the camera on the named node.
Isolate(cli::isolate::Args),
/// Show the named node (and its descendants).
Show(cli::show::Args),
/// Hide the named node (and its descendants).
Hide(cli::hide::Args),
/// Show all nodes (clear visibility overrides).
ShowAll(cli::show_all::Args),
/// Frame the camera on a named node, or the whole model when omitted.
Frame(cli::frame::Args),
/// Save a PNG screenshot of the current canvas.
Screenshot(cli::screenshot::Args),
/// Run a JavaScript snippet inside the webview and print its result.
Eval(cli::eval::Args),
/// Print the JavaScript console log forwarded from the webview.
Console(cli::console::Args),
/// Reveal a file in the VS Code Explorer sidebar (delegates to adom-vscode).
Reveal(cli::reveal::Args),
/// Run detection headlessly on a chip-fetcher dir and print a JSON report.
Detect(cli::detect::Args),
/// Place a synthetic pin-1 indicator (corner / fp-marker / xy click).
PlacePin1(cli::place_pin1::Args),
/// Toggle a chipsmith overlay layer (footprint / stock / faux-pcb / heatsink / solderjet).
SetOverlay(cli::set_overlay::Args),
/// Sign off the loaded chip — writes <mpn>.chipsmith.json + bakes <mpn>.chipsmith.step.
SignOff(cli::sign_off::Args),
/// Kill → optional rebuild → restart server → reload pup browser. One command.
Restart(cli::restart::Args),
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Command::View(a) => cli::view::run(a),
Command::ViewLibrary(a) => cli::view_library::run(a),
Command::Stop(a) => cli::stop::run(a),
Command::Status(a) => cli::status::run(a),
Command::Open(a) => cli::open::run(a),
Command::Health(a) => cli::health::run(a),
Command::Install(a) => cli::install::run(a),
Command::ListComponents(a) => cli::list_components::run(a),
Command::Isolate(a) => cli::isolate::run(a),
Command::Show(a) => cli::show::run(a),
Command::Hide(a) => cli::hide::run(a),
Command::ShowAll(a) => cli::show_all::run(a),
Command::Frame(a) => cli::frame::run(a),
Command::Screenshot(a) => cli::screenshot::run(a),
Command::Eval(a) => cli::eval::run(a),
Command::Console(a) => cli::console::run(a),
Command::Reveal(a) => cli::reveal::run(a),
Command::Detect(a) => cli::detect::run(a),
Command::PlacePin1(a) => cli::place_pin1::run(a),
Command::SetOverlay(a) => cli::set_overlay::run(a),
Command::SignOff(a) => cli::sign_off::run(a),
Command::Restart(a) => cli::restart::run(a),
}
}