← Commit history

AI Flow 0.1.59: fusion library remakes parts made by an older adom-lbr or older orientation rules

John Lauer ·20303e9c48 · ·parent 38759ac
7 files changed +25−19
Cargo.lock+10−10
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "adom-aiflow"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-analyze",  "aiflow-board",@@ -24,7 +24,7 @@ dependencies = [  [[package]] name = "aiflow-analyze"-version = "0.1.58"+version = "0.1.59" dependencies = [  "serde",  "serde_json",@@ -33,7 +33,7 @@ dependencies = [  [[package]] name = "aiflow-board"-version = "0.1.58"+version = "0.1.59" dependencies = [  "roxmltree",  "serde",@@ -42,7 +42,7 @@ dependencies = [  [[package]] name = "aiflow-bridge"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "serde",@@ -51,7 +51,7 @@ dependencies = [  [[package]] name = "aiflow-copper"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "aiflow-grid",@@ -61,7 +61,7 @@ dependencies = [  [[package]] name = "aiflow-grid"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "serde",@@ -70,7 +70,7 @@ dependencies = [  [[package]] name = "aiflow-place"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "serde",@@ -79,7 +79,7 @@ dependencies = [  [[package]] name = "aiflow-pours"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "aiflow-copper",@@ -89,7 +89,7 @@ dependencies = [  [[package]] name = "aiflow-router"-version = "0.1.58"+version = "0.1.59" dependencies = [  "aiflow-board",  "aiflow-grid",@@ -99,7 +99,7 @@ dependencies = [  [[package]] name = "aiflow-run"-version = "0.1.58"+version = "0.1.59" dependencies = [  "serde",  "serde_json",
Cargo.toml+1−1
@@ -14,7 +14,7 @@ members = [ ]  [workspace.package]-version = "0.1.58"+version = "0.1.59" edition = "2021" license = "MIT" repository = "https://wiki.adom.inc/adom/adom-aiflow"
bin/adom-aiflow
⋯ 1 unchanged line ⋯
docs/release-0.1.59.mdadded+3
@@ -0,0 +1,3 @@+# AI Flow 0.1.59++- **`fusion library` remakes a part an older tool made.** A part already bound to its 3D model was kept as built, skipping everything else: so a symbol fix in adom-lbr never reached an existing project library, and the 3D orientation check added in 0.1.54 never ran on parts bound before it (0.1.54's notes said those were bound again; they were not). Each part now records the adom-lbr version that made it and the orientation rules it was checked under; when either is older, the part is made again, keeping its 3D binding if the orientation rules still match and binding it again if they do not.
package.json+1−1
@@ -1,7 +1,7 @@ {   "slug": "adom-aiflow",   "type": "app",-  "version": "0.1.58",+  "version": "0.1.59",   "title": "AI Flow",   "description": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. One Rust binary with a crate per step (placement helpers, a grid router with Kelvin taps, pours with keepouts, KiCad's DRC gate, live landing through the KiCad Bridge, copper measurement, current and thermal analysis) and a finish line that refuses an unfinished board. Every command answers with hints for the AI; every turn, its thinking time and every rework loop go into run.jsonl, so Claude, Codex and any other engine are compared on the same flow. KiCad today; Altium, Fusion and Adom's own web apps next.",   "summary": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. The AI thinks its way from placement through routing, pours, current and thermal analysis to a delivered video; the binary does the fast, deterministic parts of every step, hands back hints, and keeps a ledger of every turn, every return to an earlier step, and the clock from the prompt to done.",
page.json+2−4
@@ -1,7 +1,7 @@ {   "slug": "adom-aiflow",   "type": "app",-  "version": "0.1.58",+  "version": "0.1.59",   "title": "AI Flow",   "description": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. One Rust binary with a crate per step (placement helpers, a grid router with Kelvin taps, pours with keepouts, KiCad's DRC gate, live landing through the KiCad Bridge, copper measurement, current and thermal analysis) and a finish line that refuses an unfinished board. Every command answers with hints for the AI; every turn, its thinking time and every rework loop go into run.jsonl, so Claude, Codex and any other engine are compared on the same flow. KiCad today; Altium, Fusion and Adom's own web apps next.",   "summary": "Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board. The AI thinks its way from placement through routing, pours, current and thermal analysis to a delivered video; the binary does the fast, deterministic parts of every step, hands back hints, and keeps a ledger of every turn, every return to an earlier step, and the clock from the prompt to done.",@@ -44,9 +44,7 @@     "run.jsonl",     "thermal analysis"   ],-  "dependencies": {-    "adom/adom-lbr": "*"-  },+  "dependencies": {},   "scripts": {     "install": "./install.sh",     "uninstall": "./uninstall.sh"
tools/fusion-project.py+8−3
@@ -422,18 +422,23 @@ def cmd_library(a):     lib_dir = STATE / 'library'; (lib_dir / 'parts').mkdir(parents=True, exist_ok=True)     added, kept, unverified, turned = [], [], {}, {}     seen = set()+    # a part is kept as built only when the adom-lbr that made it and the orientation rules it was checked+    # under are the current ones; otherwise it is made again (its 3D binding survives when the rules match)+    lbr_ver = (run(['adom-lbr', '--version']).stdout or '').strip().split()[-1:] or ['?']; lbr_ver = lbr_ver[0]     for w in want:         mpn = w['mpn']         if mpn in seen: continue         seen.add(mpn)-        if mpn in st['parts'] and (st['parts'][mpn].get('urn') or st['parts'][mpn].get('boardOnly')):+        prev_ = st['parts'].get(mpn, {})+        current = prev_.get('lbrVersion') == lbr_ver and (prev_.get('boardOnly') or prev_.get('orient') == ORIENT_RULES)+        if prev_ and current and (prev_.get('urn') or prev_.get('boardOnly')):             kept.append(mpn); continue         pdir = STATE / 'pages' / re.sub(r'[^A-Za-z0-9._-]', '_', mpn)         out_lbr = lib_dir / 'parts' / (mpn + '.lbr')         if w.get('footprint'):  # a board-only part (test pad) from a footprint file             r = run(['adom-lbr', 'generate', '--fp', w['footprint'], '--name', mpn, '--package-name', mpn, '-o', str(out_lbr)])             if 'Lint PASSED' not in r.stdout + r.stderr: err('%s: adom-lbr generate failed: %s' % (mpn, (r.stdout + r.stderr)[-300:]))-            st['parts'][mpn] = {'lbr': str(out_lbr), 'step': None, 'boardOnly': True, 'numbers': {}}+            st['parts'][mpn] = {'lbr': str(out_lbr), 'step': None, 'boardOnly': True, 'numbers': {}, 'lbrVersion': lbr_ver}             added.append(mpn); say('part %s: board only (footprint %s)' % (mpn, Path(w['footprint']).name)); continue         slug = w.get('page') or mpn.lower()         shutil.rmtree(pdir, ignore_errors=True)  # always the page as it is now (its numbers may have been added since)@@ -467,7 +472,7 @@ def cmd_library(a):             if onote: turned[mpn] = onote         prev = st['parts'].get(mpn, {})         if prev.get('urn') and prev.get('orient') != ORIENT_RULES: prev = {k: v for k, v in prev.items() if k != 'urn'}  # bound before the check: bind again-        st['parts'][mpn] = {**prev, 'lbr': str(out_lbr), 'step': str(step) if step else None, 'numbers': numbers, 'symbol': choice, 'orient': ORIENT_RULES, 'orientNote': onote}+        st['parts'][mpn] = {**prev, 'lbr': str(out_lbr), 'step': str(step) if step else None, 'numbers': numbers, 'symbol': choice, 'orient': ORIENT_RULES, 'orientNote': onote, 'lbrVersion': lbr_ver}         added.append(mpn)         say('part %s: %s symbol, model %s, %s' % (mpn, choice, step.name if step else 'none', 'Adom stock' if stock else 'Mouser %s, DigiKey %s, LCSC %s' % (numbers.get('mouser', '-'), numbers.get('digikey', '-'), numbers.get('lcsc', '-'))))     save_state(st)