← Commit history
README.md−8
@@ -13,14 +13,6 @@ adom-aiflow --version  The same flow runs a board that lives in Autodesk Fusion: the binary plans, routes and gates offline, and every placement, trace, pour and refinement lands live in Fusion through the Fusion bridge, read back from Fusion's own export each time. See [the Fusion lane](docs/fusion-lane.md). -## Flow apps: the stages after the board--AI Flow ends at a finished board. Each later stage is its own small app with its own page, owned by whoever-builds it: ordering from JLCPCB (`adom-aiflow-jlcpcb`), probing and testing (`adom-aiflow-probing`), and more to-come. They start from the board release this flow finishes with and keep their own ledger and clips. To build one,-copy [template/flow-app](template/flow-app/README.md): a Rust Linux CLI with the step engine, ledger, window-recording and the handoff schema, open source under MIT.- ## Silkscreen that helps at the bench  > Available in v0.1.26 on the insiders channel. Install with `adom-wiki pkg install adom/adom-aiflow`. The KiCad workflow is demonstrated below; Fusion and Altium adapters still require validation.
bin/adom-aiflow

  
crates/adom-aiflow/src/preboard.rs−12
@@ -103,9 +103,6 @@ pub fn sourcing_check(bom: &str, board: Option<&(BTreeSet<String>, BTreeSet<Stri     let c_src = col(header, &["source", "supplier", "distributor", "vendor"]);     let c_vpn = col(header, &["vendor_pn", "supplier_pn", "distributor_pn", "mouser_pn", "vendor_part_number", "supplier_part_number"]);     let c_lcsc = col(header, &["lcsc", "lcsc_pn", "lcsc_part", "lcsc_part_number", "jlcpcb_part", "jlc_pn"]);-    // fit: "post" (or dnp, hand, after) = fitted after the fab's assembly (molecule contacts, machine pins, hand-soldered parts):-    // the row keeps its MPN and source, needs no LCSC number on the jlcpcb profile, and `fab export` leaves it out of the BOM and CPL-    let c_fit = col(header, &["fit", "dnp", "assembly"]);     // the dated stock column: a header carrying the date (stock_checked_2026-09-29), or a stock     // column beside a stock_date / checked column that carries the date per row     let c_stock_dated = header.iter().position(|h| h.to_ascii_lowercase().contains("stock") && date_in(h).is_some());@@ -145,8 +142,6 @@ pub fn sourcing_check(bom: &str, board: Option<&(BTreeSet<String>, BTreeSet<Stri         if adom { adom_rows += 1; } else { distributor_rows += 1; }         match profile {             "jlcpcb" => {-                let fit = get(row, c_fit).to_ascii_lowercase();-                if ["post", "dnp", "hand", "after", "no"].iter().any(|k| fit == *k || fit.starts_with(&format!("{k} "))) { continue; }                 if lcsc.is_empty() && !is_lcsc_number(&vpn) { errors.push(format!("{label} ({mpn}): no LCSC number on the jlcpcb profile (add an lcsc column, e.g. C12345)")); }             }             _ => {@@ -395,13 +390,6 @@ mod tests {         assert_eq!(out["boardChecked"], false);     } -    #[test]-    fn jlcpcb_profile_skips_rows_fitted_after_assembly() {-        let bom = "ref,mpn,source,lcsc,fit,stock_checked_2026-10-05\nU1,TPS,JLCPCB,C123456,,5000\nJ1,MachineContactMedium,Adom stock,,post,\n";-        let out = sourcing_check(bom, None, "jlcpcb", 2);-        assert!(!out["errors"].to_string().contains("J1"), "{}", out["errors"]);-    }-     #[test]     fn jlcpcb_profile_needs_lcsc_numbers() {         let bom = "ref,mpn,source,lcsc,stock_checked_2026-09-29\nU1,TPS,JLCPCB,C123456,5000\nU2,ABC,JLCPCB,,5000\n";
page.json+3−1
@@ -44,7 +44,9 @@     "run.jsonl",     "thermal analysis"   ],-  "dependencies": {},+  "dependencies": {+    "adom/adom-lbr": "*"+  },   "scripts": {     "install": "./install.sh",     "uninstall": "./uninstall.sh"
skills/aiflow-process-video/SKILL.md+2−2
@@ -44,7 +44,7 @@ right things while the run happens**. You cannot film the past. - **No line said twice.** Each scene's narration adds something new; the scene after the prompt never repeats   the prompt. - **Show the wiki pages, moving.** For the parts and pages made along the way, film the live wiki pages-  (a pup window with highFps, never a headless browser in the container: page loads, viewers settle, an eased scroll from the 3D model to symbol and footprint),+  (headless browser: page loads, viewers settle, an eased scroll from the 3D model to symbol and footprint),   not bare turntables of the 3D models. - **GUI-driven apps on screen.** When the AI drove a desktop app through Adom Bridge (LTspice, PSpice, KiCad),   give it a second of the app's own window with the AI's cursor working it, so the viewer sees the computer@@ -60,7 +60,7 @@ right things while the run happens**. You cannot film the past.   on scaffold work are left out of the cost, so the number is not misleading. - **3D must be smooth.** Never use a filmed KiCad 3D-viewer tour for a hero shot: it steps between view   commands and the recorder only writes frames on change, so it is choppy. Render the board's own GLB frame-  by frame in a pup window with highFps (never a headless browser in the container: its software GPU is slow and crashes on 3D) (eased orbit, studio light, soft shadow, no cursor, no browser chrome) at+  by frame in a headless browser (eased orbit, studio light, soft shadow, no cursor, no browser chrome) at   30 fps or more. Close-ups aim at a part by raycasting its board position onto the surface. - **Pads are real copper.** Render only a board GLB that passed `board-glb check` (skill aiflow-molecule):   copper (or the stated finish) wherever the mask is open, the mask open where the footprint says, solder only
skills/aiflow-scaffold-probe/SKILL.md+2−24
@@ -58,32 +58,10 @@ Start from a known-good layout of the same editor version (a published workcell ```  - `sku` is the published molecule's wiki identity (molecule-publish comes first).-- `position` is the layout coordinate of the molecule's FL pin (MP1), in mm; `rotation.z` in degrees; `z` is where the-  layer's model origin goes. **Every machine pin goes into a machine contact of the layer below, on every layer**-  (John, 2026-10-06):-  - Large-pin molecules and user scaffolds sit on the base scaffold's large contacts: a 32 mm grid starting 16 mm in-    (16 + 32 n, 18 x 18 over 576 mm).-  - A medium-pin molecule needs a LrgMed user scaffold (adom/scaffold-lrgmed-<W>x<H>): its corner large pins on the-    base grid, its medium contacts at **FL + 4 + 8 k mm** (an 8 mm pitch offset 4 mm from its corner pins; NOT every-    4 mm, read them from the scaffold page's circuit.json). The molecule's FL pin goes on one of them, so its pin-    span must be a multiple of 8 mm. Example: scaffold FL at (240, 464) puts contacts at x, y = 236, 244, 252, ...;-    a molecule FL at y 488 misses them by 4 mm, at 484 it lands.-  - Z: each board rests ON the layer below (on the contacts' rims), never sunk into it and never floating so high-    its pins miss the contacts (medium short pins reach 4.95 mm below their board, large short 10.34 mm). The old-    "about 8.4 mm per level" put the board on the scaffold's pin HEADS, with its pins in the air; a scaffold GLB's-    origin is its board's mid-plane, so z 0 sinks it 0.7 mm into the base.-  - Do not place it by hand: `adom-aiflow-probing stack` checks every pin over a contact and every board seated,-    from the scaffold page's circuit.json, the molecule's footprint JSON and the real GLBs, and names the exact-    position that fixes each problem; `stack --fix` writes them (backup kept). Then `wires check` / `wires route`-    (a moved board breaks hand routes), compile and twin.+- `position` is the layout coordinate of the molecule's FL pin (MP1), in mm; `rotation.z` in degrees. Large-pin molecules and scaffolds sit on the base scaffold's grid (16 + 32 n). A medium-pin molecule needs a LrgMed user scaffold (adom/scaffold-lrgmed-<W>x<H>: large pins at the corners on the 32 mm base grid, medium contacts on a 4 mm grid): put the scaffold's FL large pin on the base grid and the molecule's FL pin on the scaffold's 4 mm grid, so the molecule's pin span must be a multiple of 4 mm. Each stacked level adds about 8.4 mm of z in the reference layouts; the editor snaps it when the layout opens. - `pins` and `pinType`: copy what the molecule's import gives for its pin size; do not invent values. - `contactPosition` is molecule-local (mm from MP1; z is the footprint JSON's `contact_z`, 2.8 mm for medium contacts). `contactName` matches the board's reference.-- Check the layout against the geometry before handing it over, in the real twin, never in a homemade viewer:-  `adom-aiflow-probing stack` (every machine pin over a contact of the layer below, every layer at its seated-  height; it prints the corrected positions), then `adom-aiflow-probing twin` and `dashboard` (the Adom 3D Viewer)-  or the Hydrogen 3D Editor. Look at it in a pup window (or a Hydrogen webview), never a headless Chrome in the-  container: the container renders WebGL on a software GPU, slowly, and crashes on these scenes (John, 2026-10-06).-  Close views to check: a corner pin of each layer from the side, the wire ends on the panel's contact row.+- Check the layout against the geometry before handing it over: a three.js page that loads the base grid, the scaffold GLB, the molecule GLB and the control panel GLB (Draco, so load it with DRACOLoader) at the layout's positions, with the wires drawn to each panel contact's position from the panel's `.kicad_pcb`. Land the wire ends on the panel board's top face (find the flat mesh about 160 x 45 mm; the panel's own bounding box includes the dock connector and parts below the board, so neither its centre nor its minimum z is the board). Render it headless (puppeteer-core with Chromium) and look at a close view of the contact row. - Routing fields (`routingType`, `manualBendPoints`, `segments`, `color`, `diameter`) are what the editor writes when it routes; let it, then read the file back.  Validate before handing over: every `moleculeName` exists in `molecules`, every `contactName` exists on that molecule's footprint JSON, every `controlPanelContactName` is a real V2.1.0 contact in the right group, and no panel contact is used twice by different nets. Open it in the Hydrogen 3D editor and look.