# cad-agent: full text > Your one stop shop for agentic CAD. Mapping the best free resources, demonstrating their capabilities, and filling the gaps. Made for AI and people. --- Source: https://cad-agent.valpatel.com/CONTRIBUTING.md # Contributing Several projects build on cad-agent at the same time (the J501 enclosure, Gyropup, the AGX Thor CAN boards, and others), often with AI agents working in parallel. A change to cad-agent can break all of them, so every change goes through a branch, a pull request, CI and a review. ## Branches | Branch | What it is | Who writes to it | |---|---|---| | `main` | Released toolkit, tagged `vX.Y.Z`. | Only by merging a release PR from `dev`. | | `dev` | Integration, and the repository's default branch. Everything here passed CI and review. | Only by merging a reviewed PR. | | `feat/`, `fix/`, `ci/`, `docs/`, `research/`, `test/`, `refactor/`, `release/vX.Y.Z`, `vendor-update/-`, `dependabot/…` | One piece of work, branched from `dev`. | Its author, in its own worktree. | `main` and `dev` are protected: no direct pushes (admins included), no force pushes, the required checks below must pass and every review conversation must be resolved. Agents may merge into both, through the gates. ## Gates Required checks, all automated. Nobody, agent or person, merges around them. ```mermaid flowchart TD F["feat/ fix/ ci/ docs/ …
from dev"] -->|"CI · branch-flow · review"| D["dev"] D -->|"CI · branch-flow · review
· release"| M["main"] M -->|"release.yml"| R["tag vX.Y.Z · GitHub release
site deploy"] classDef b fill:#fffdf5,stroke:#173d3c,color:#173d3c classDef r fill:#ffe1cc,stroke:#bd3a12,color:#173d3c class F,D,M b class R r ``` | Required check | `dev` | `main` | What it asks | |---|---|---|---| | `core (3.10)`, `core (3.12)`, `full` | ✓ | ✓ | The test suite with required dependencies only, and with every extra | | `browser (chromium)`, `browser (webkit)` | ✓ | ✓ | Web kit and website suites in two browser engines | | `cad-gates//branch-flow` | ✓ | ✓ | `dev` takes `feat/ fix/ ci/ docs/ research/ test/ refactor/ release/ vendor-update/ dependabot/` branches (forks: the outside-contribution checks); `main` takes `dev` only | | `cad-gates//review` | ✓ | ✓ | The latest verdict from a reviewer with write access is pass, on the PR's head commit | | `cad-gates/main/release` | | ✓ | `pyproject.toml` version above `main`'s, and a dated `## vX.Y.Z (YYYY-MM-DD)` entry in [CHANGELOG.md](https://github.com/Valpatel/cad-agent/blob/dev/CHANGELOG.md) | | Conversations resolved | ✓ | ✓ | Every review thread answered and resolved | - **The verdict.** It is the last line of the reviewer's summary review: `` (or `verdict=block`). It is written by the `cad-pr-reviewer` subagent, or by a reviewer following the `cad-pr-review` skill, who then re-runs the gates: `gh workflow run gates.yml -R Valpatel/cad-agent -f pr=`. - **Who can review.** Only reviewers with write access count, and dismissed reviews never count. All our agents work through one account, so GitHub cannot tell author from reviewer: an author never writes a verdict on its own PR. - **How the gates run.** `gates.yml` runs on `pull_request_target`: the default branch's (`dev`'s) copy of the workflow and of [`tools/ci_gates.py`](https://github.com/Valpatel/cad-agent/blob/dev/tools/ci_gates.py) decides, so a PR cannot pass the gates by editing them, and PRs into `main` (which come from `dev`) are judged by the same copy. The PR is only read as data, never checked out or run. Results are commit statuses named after the base, so a PR into `dev` cannot supply `main`'s checks. A fork's own workflows run with a read-only token, so they cannot post statuses; anyone with write access can, which is why write access is the trust boundary. Fork workflows wait for approval; the intake skill (#120) reads a fork's workflow changes before approving them. - **When they run.** On every push to the PR, when the reviewer re-runs them after a verdict, and every 15 minutes for all open PRs (a review cannot trigger them). A run for one PR posts `pending` first, so a crash leaves the PR blocked rather than green. The sweep posts only statuses that change: GitHub keeps at most 1000 statuses per commit and name, and refuses new ones after that. - **Just before merging**, run `python3 tools/ci_gates.py all --repo Valpatel/cad-agent --pr ` from an up-to-date `dev` checkout. It reads the reviews live and must exit 0, so a block posted since the last run stops the merge. - **GitHub settings the gates need** (owner): the `cad-gates/…` checks required on `dev` and `main` with GitHub Actions as their source; an Actions event policy for `.github/workflows/gates.yml` that allows all three of its events, `pull_request_target`, `schedule` and `workflow_dispatch` (GitHub disables `pull_request_target` by default in public repos from 2026-12-02, and a policy lists allowed events, so one left out stops the sweep or the re-run); and the deploy token as a `production` environment secret. - **Pins.** Workflow actions are pinned by commit SHA, and Dependabot proposes updates weekly. ## Workflow Agents: install the workflow kit (`cad-agent agents install`, [docs/agent-workflow.md](https://cad-agent.valpatel.com/docs/agent-workflow.md)) and follow `cad-work-tracking`: an issue per change, an early draft PR with `Closes #`, and pushes as you go. 0. **Issue.** Find or open the GitHub issue the change belongs to, with a checklist of done / next / how to resume. 1. **Worktree from `dev`.** Never edit a checkout another session may be using: ```bash git fetch origin git worktree add --no-track ../cad-agent- -b feat/ origin/dev cd ../cad-agent- && git push -u origin feat/ # the branch tracks itself, not dev ``` 2. **Commit and push** small, focused changes with tests (`tests/`) as you go, not in one batch at the end. Keep the package generic: anything specific to one product stays in that product's repository. A new docs or research page, `cad-agent` command, skill, agent or `lessons/` folder also gets its line in [`docs/areas.yaml`](https://github.com/Valpatel/cad-agent/blob/dev/docs/areas.yaml), the topic tree ([docs/vision.md](https://cad-agent.valpatel.com/docs/vision.md)): `tests/test_areas.py` fails until it does. When two open PRs cross, the one that merges second adds the line, after merging `dev` and re-running CI (`dev` does not require branches to be up to date). 3. **Open a PR into `dev`** early, as a draft if it is unfinished (`gh pr create --draft --base dev`), with `Closes #`; fill in the template, including what projects using cad-agent must change. 4. **CI** (`.github/workflows/ci.yml`) runs `core` on Python 3.10 and 3.12 (required dependencies only; optional features must skip cleanly) and `full` on 3.12 (CAD, FEA, robot and site extras, imported loudly before the tests; the `cad` and `sim` extras need 3.11 or newer); `webkit.yml` runs the browser suites and `gates.yml` the [gates](#gates). CI's `supply-chain` job runs the offline [supply-chain report](https://cad-agent.valpatel.com/skills/cad-supply-chain/SKILL.md): a PR that adds a dependency, vendored file or catalogue entry pastes its rows (`python3 tools/resource_audit.py rows --base origin/dev --online`) under "Supply chain". 5. **Review.** Every PR gets a review from a person or from a separate review agent that did not write the change, posted as PR comments (the `cad-pr-reviewer` subagent, or a separate Codex session with that skill), ending with the verdict marker that the `review` gate reads. The author answers or fixes each comment and resolves it. 6. **Merge** into `dev` (squash or merge commit). Then, before removing the worktree, repoint anything installed from it: `pip show -f cad-agent` (or the `direct_url.json` it lists) in each project venv tells you where `cadagent` comes from. Reinstall those from the `dev` checkout below, then `git worktree remove ../cad-agent-`. ## Using cad-agent from a project - **Released:** a checkout of `main` (or a tag), installed editable: `pip install -e "[cad,fea]"`. - **Latest reviewed:** a dedicated worktree that only tracks `origin/dev` (`git worktree add ../cad-agent-dev origin/dev`, updated with `git -C ../cad-agent-dev pull --ff-only`). Never edit in it. - **A feature under test:** that feature's worktree, while its PR is open. Say so in the PR. A project that needs a new toolkit feature opens a cad-agent PR for it; it does not patch its local copy. ## Releases Shipping to `main` is part of the development loop, not an occasional event. When `dev` has merged work that people or projects would notice (a command, a check, a fix, a site change), cut a release; while work is landing, at least once a day. `main` should never be more than a day behind `dev`. Agents cut and merge releases under the same gates as any PR; nobody has to ask for one. Use a patch release (`--patch`) for fixes, docs and the site, and a minor release (`--minor`) when projects must change something (the CHANGELOG's "Projects must change") or when it adds a feature, such as a new command or check, even one that asks nothing of projects. 1. On a `release/vX.Y.Z` branch from `dev`: - bring in `main`'s release merges (`git merge origin/main`), so the release PR is up to date with `main`; - run `python3 tools/cut_release.py --patch` (or `--minor`). It bumps `version` in `pyproject.toml`, folds the fragments in [`changelog.d/`](https://github.com/Valpatel/cad-agent/blob/dev/changelog.d/README.md) into the CHANGELOG's `## Unreleased` entry and deletes them, dates the entry as `## vX.Y.Z (YYYY-MM-DD)`, opens a new empty `## Unreleased`, and checks the result against CI's release gate; - check that the entry covers every PR merged since the last release, with what projects must change. PR it into `dev` and merge. 2. Open a PR from `dev` into `main` titled `Release vX.Y.Z`. It needs CI, `cad-gates/main/release`, and a review whose pass verdict is on the PR's head commit. Merge it with a **merge commit** (not squash or rebase), so `main` and `dev` keep a common history. 3. `release.yml` then: - tags `vX.Y.Z` on the merge commit; - publishes the GitHub release from the CHANGELOG entry; - deploys cad-agent.valpatel.com from that commit, if the owner has set the `production` secret below. Until then the site job warns "site not deployed" and exits 0: that is a skipped deploy, not a working one. Deploy by hand from `main` and check `https://cad-agent.valpatel.com/version.json`. The deploy uses the `production` environment, which only `main` may deploy to. It needs that environment's `CLOUDFLARE_API_TOKEN` secret, set by the owner with `gh secret set CLOUDFLARE_API_TOKEN --env production`, and its `CLOUDFLARE_ACCOUNT_ID` variable. 4. Move the projects' pins (`requirements*.txt`) to the tag, each in its own PR. --- Source: https://cad-agent.valpatel.com/README.md # cad-agent [![CI](https://github.com/Valpatel/cad-agent/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Valpatel/cad-agent/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Valpatel/cad-agent/blob/dev/LICENSE) **A workshop where AI agents get better at CAD by learning from everyone else.** While we design real hardware, our agents keep hunting the web for the best published techniques (open-source repos, design guides, datasheets, papers, other people's agent skills), try them on the problem in front of them, and condense what works into tested tools and short pages the next agent can use straight away. Every source gets its credit. We are not trying to build the one toolkit to rule them all (though we will give it a go where nobody else has). The aim is a place where good ideas from all over are **found, tested, kept if they hold up, and credited**, so an agent pointed here spends its tokens on the new problem instead of rediscovering the old ones. Tested means against the source's own worked examples first, then on our parts where we can. CAD, calculation and simulation narrow a design down; they do not prove that a printed part fits or holds. Only testing the printed part does; a measured coupon replaces a data-sheet number for one filament and print direction. Browse it at [cad-agent.valpatel.com](https://cad-agent.valpatel.com) (every page also as Markdown, plus `llms.txt` and `catalog.json`).

Gyropup's five-bar leg drawn from its real CAD, assembled, then checked for fit, strength and motion by cad-agent
Drawn from the real CAD and results of Gyropup (MIT), a self-balancing wheel-legged robot designed with cad-agent: its leg's STEP file, the hip frame's FEA and the five-bar's link lengths. Made by tools/readme_anim.py.

3D viewer
3D viewer and review site. Every part in place, with explode, section and one top bar linking every report.
FEA of an enclosure lid
Strength. FEA of a ribbed lid under a 300 N press, coloured by stress as a fraction of the material's strength.
Topology optimisation of an enclosure floor
Less material. Topology optimisation keeps only the floor that carries load.
## How it improves itself ```mermaid flowchart TD W["🛠️ Real work
a robot, an enclosure,
a board"] G["🧩 A gap
a failed print, a review
finding, a slow step"] S["🔎 Search
repos · guides · datasheets
papers · agent skills"] T["🧪 Test
against their own examples,
then on our parts"] K["📚 Keep + credit
a tested tool, a check,
a living page, a lesson"] W --> G --> S --> T --> K --> W T -. "didn't hold up" .-> S classDef work fill:#fffdf5,stroke:#173d3c,color:#173d3c classDef find fill:#d8efbb,stroke:#386248,color:#173d3c classDef keep fill:#ffe1cc,stroke:#bd3a12,color:#173d3c class W,G work class S,T find class K keep ``` 1. **Work on something real.** Most tools here started from a real project's need ([Gyropup](https://gyropup.com), the [J501 enclosure](https://github.com/mvalancy/j501-agx-orin), the [AGX Thor CAN breakout](https://github.com/mvalancy/pcb-agx-thor-can-breakout)). 2. **Look before building.** When a gap shows up, the agent first surveys what others have published and records what it found and why it adopted, borrowed from or passed on each one ([`research/`](https://github.com/Valpatel/cad-agent/tree/dev/research/), [`upstreams/registry.yaml`](https://github.com/Valpatel/cad-agent/blob/dev/upstreams/registry.yaml), [`research/landscape.json`](https://github.com/Valpatel/cad-agent/blob/dev/research/landscape.json)). 3. **Test it on our problem.** A technique earns its place by reproducing its source's own worked examples, then by working on our parts where we can try it. Results are recorded, including the ones that failed. Until a part has been printed and measured, a limit taken from a data sheet is a hypothesis. 4. **Condense it.** What survives becomes a tested tool an agent calls in one step, a deterministic check that catches the mistake next time, and a *living page*: the method in a few paragraphs, with citations, examples and the limits stated plainly. Tests fail if the page and the tool drift apart. 5. **Credit it.** Every page names its sources; every borrowed file keeps its licence; the people and projects we learn from are listed below. Example: [snap fits](https://cad-agent.valpatel.com/docs/compliant.md) condense the Covestro (Bayer) snap-fit guide, DuPont's design guide and the data sheets of 11 filaments (13 entries: two have dry and wet values) into `cad-agent snapfit`, tested against the guide's worked examples and sized by print direction; no printed coupon has been measured yet. The same loop turned review findings from real builds into the [pitfall checks](https://cad-agent.valpatel.com/docs/common-issues.md), like a rib that ran into a counterbore. ## What's here today ### How a project runs A project describes itself in one `cad-agent.yaml`. cad-agent runs it and collects the proof. ```mermaid flowchart TD P["📐 Your project
cad-agent.yaml
CAD scripts · parameters"] B["🔧 build
CAD · checks · simulations
run as ordered steps"] M["🖨️ export-3mf
bed-centred 3MF
read back and verified"] R["✅ check + report
every result, pass or fail
with its evidence"] Z["📦 package
review zip
sha256 manifest"] W["🌐 site --serve
linked review site
3D viewer · live reload"] P --> B --> M --> Z B --> R --> Z R --> W classDef src fill:#fffdf5,stroke:#173d3c,color:#173d3c classDef step fill:#d8efbb,stroke:#386248,color:#173d3c classDef out fill:#ffe1cc,stroke:#bd3a12,color:#173d3c class P src class B,M,R step class Z,W out ``` `cad-agent all` runs build, export-3mf, check, report and package in one go. It never claims a physical fit. A check either has evidence or it says what is assumed. **PCB and enclosure workbenches:** [PCB workflow](https://cad-agent.valpatel.com/docs/pcb.md) covers embedded schematics, copper layers, assembly views and housing renders in the status page; native KiCad ERC/DRC/parity evidence; source freshness; and JLC BOM/CPL checks. Use `cad-agent pcb-check` to bind reports to source files. Qualification gates stay separate from CAD checks. ### What's in the box ```mermaid flowchart TD D["✏️ Design
connectors · mcmaster
robot · geometry · explore"] V["🧪 Verify
fea · cfd · heatsink
topopt · slicer"] S["🖼️ Show
render · simviz · reports
site · 3D viewer"] P["📦 Ship
STL · STEP · 3MF
hashed review zip"] D --> V --> S --> P classDef g fill:#fffdf5,stroke:#173d3c,color:#173d3c class D,V,S,P g ``` | | Module | What it gives you | |---|---|---| | ✏️ | `connectors` | Port windows derived from the modelled mating plug, then a sweep check that the plug really goes in | | ✏️ | `mcmaster` | The manufacturer's STEP and specs for a McMaster-Carr part number, normalised for assembly | | ✏️ | `robot` | Mass properties from CAD, links and joints, URDF and MuJoCo export, meshes kept under budget | | ✏️ | `dossier` | The design dossier: requirements, sections, part spec cards, interfaces and decisions with the alternatives rejected, in YAML with `file:line` errors; build-script declarations of parts, cavities, joints, fasteners and assembly steps, exported for the gates; a lint and a per-section status (draft to signed off, voided when the geometry changes) from `cad-agent dossier` ([guide](https://cad-agent.valpatel.com/docs/dossier.md)) | | ✏️ | `gates` | Integrity gates on the assembly: floating parts and unrealised interfaces, items outside their cavity, fastener seat, engagement, tip and tool reach, motion-range collisions, assembly order and access, minimum walls. `cad-agent gates` runs them in parallel processes, writes verdicts bound to the geometry they checked, and `check` fails on a failing or stale one ([guide](https://cad-agent.valpatel.com/docs/gates.md)) | | ✏️ | `explore` | Part catalogues with prices and sources, designs that pick a part per slot, the project's own evaluator, Pareto ranking of the trade-offs, one-part swaps and a search over parts and parameters ([guide](https://cad-agent.valpatel.com/docs/explore.md)) | | 🧪 | `fea` | gmsh + scikit-fem linear elasticity with printed-material allowables, checked against textbook cases | | 🧪 | `compliant` | Snap-fit sizing and checks (cantilever, torsion, annular) by the Covestro/Bayer method, tested against the guide's worked examples; allowable strain for moulded resins and, by print direction, for 11 filaments from their data sheets (13 entries: two have dry and wet values) ([guide](https://cad-agent.valpatel.com/docs/compliant.md)) | | 🧪 | `cfd` | Conjugate heat transfer cases for OpenFOAM written from CAD: fans, fin blocks, heat sources | | 🧪 | `heatsink` | Plate-fin correlations, fan operating point and porous-block coefficients for CFD | | 🧪 | `topopt` | pyMOTO topology optimisation (SIMP, MMA, overhang filter) to cut filament where it does no work | | 🧪 | `slicer` | Bambu Studio's command line for real filament grams and print time | | 🖼️ | `render`, `simviz` | Off-screen renders, stress and flow pictures, MP4 animations; a review packet per dossier section (solid, x-ray, cuts through cavities, joints and screws, exploded along the assembly steps, joint range ends, gate findings at their witness points) with the measurements first and the render checklist, from `cad-agent review-packet` ([guide](https://cad-agent.valpatel.com/docs/review-packet.md)) | | 🖼️ | `report`, `simreport` | Results JSON and standalone HTML reports that name their limits | | 🖼️ | `site`, `view`, webkit | A local review site with progress, decisions, docs and a 3D viewer, all under one top bar | | 📦 | `mesh3mf`, `package` | 3MF writing with an independent read-back, and a hashed review zip | The full guide, the `cad-agent.yaml` format and every command are in [`docs/toolkit.md`](https://cad-agent.valpatel.com/docs/toolkit.md). ## Quick start ```bash git clone https://github.com/Valpatel/cad-agent && cd cad-agent pip install -e ".[cad]" # add fea, sim, robot, site as needed cad-agent all --project path/to/your-project # build, 3MF, check + report, package cad-agent site --serve --project path/to/your-project ``` | Extra | Adds | |---|---| | `cad` | CadQuery, trimesh, VTK: building, checking and rendering parts | | `fea` | gmsh, scikit-fem, PyPardiso: stiffness and strength | | `sim` | PyVista, pyMOTO, manifold3d: airflow cases, topology optimisation, pictures and videos (OpenFOAM and Bambu Studio run as separate programs) | | `robot` | MuJoCo, for robot export | | `site` | Markdown, for the review site | | `explore` | optuna, for the NSGA-II and TPE searches of `cad-agent optimise` (random and grid need nothing) | The package runs on Python 3.10 or newer; the `cad` and `sim` extras need 3.11 or newer, because every Pillow release for 3.10 has critical advisories and CadQuery 2.8 needs 3.11. ## Projects it learns from | Project | What it is | |---|---| | [Gyropup](https://github.com/Valpatel/gyropup) | A self-balancing wheel-legged robot with a foam-ball turret: five-bar legs, McMaster hardware, strength and fall studies | | [J501 AGX enclosure](https://github.com/mvalancy/j501-agx-orin) | A printed enclosure for the Seeed reServer J501 with a Jetson AGX Orin: port windows from mating plugs, FEA, airflow and topology-optimised floor vents | | [AGX Thor CAN breakout](https://github.com/mvalancy/pcb-agx-thor-can-breakout) | A protected CAN adapter board and its printed enclosure | Anything specific to one product stays in that product's repository. cad-agent keeps what any project can reuse. ## Shout-outs The people and projects whose work this stands on. If we use or learned from your work and you are missing or described wrongly here, please [tell us](https://github.com/Valpatel/cad-agent/issues/new?template=feedback.yml). **Methods and data we condensed (cited, never redistributed):** - Covestro (formerly Bayer MaterialScience), *Snap-Fit Joints for Plastics – A Design Guide*: the cantilever, torsion and annular snap-fit method. - DuPont, *General Design Principles – Module I*: permissible strains (Table 10.06). - Bambu Lab and Polymaker technical data sheets: printed-filament properties by print direction. **Code we vendor, pinned and security-reviewed** ([`vendor/`](https://github.com/Valpatel/cad-agent/tree/dev/vendor/), [`SECURITY.md`](https://github.com/Valpatel/cad-agent/blob/dev/SECURITY.md)): [text-to-cad](https://github.com/earthtojake/text-to-cad) by Thompson Labs LLC (MIT), [kicad-happy](https://github.com/aklofas/kicad-happy) by Andrew Klofas (MIT), [kicad-mcp-pro](https://github.com/oaslananka/kicad-mcp-pro) by Osman Aslan (MIT), [build123d-mcp](https://github.com/pzfreo/build123d-mcp) by Paul Fremantle (Apache-2.0), [agentcad](https://github.com/jdilla1277/agentcad) by James Dillard (Apache-2.0) and [bd_warehouse](https://github.com/gumyr/bd_warehouse) by Roger Maitland (Apache-2.0). **Libraries and programs we run on:** [CadQuery](https://github.com/CadQuery/cadquery) on [Open CASCADE](https://occt3d.com/open-cascade-technology/) (shapes from [build123d](https://github.com/gumyr/build123d) work too), [trimesh](https://github.com/mikedh/trimesh), [manifold3d](https://github.com/elalish/manifold), [gmsh](https://gmsh.info/), [scikit-fem](https://github.com/kinnala/scikit-fem), [pyMOTO](https://github.com/aatmdelissen/pyMOTO), [PyVista](https://github.com/pyvista/pyvista) and [VTK](https://vtk.org/), [OpenFOAM](https://www.openfoam.com/), [MuJoCo](https://github.com/google-deepmind/mujoco), [Optuna](https://github.com/optuna/optuna), [Bambu Studio](https://github.com/bambulab/BambuStudio); in the browser [three.js](https://github.com/mrdoob/three.js), [Mermaid](https://github.com/mermaid-js/mermaid), [occt-import-js](https://github.com/kovacsv/occt-import-js) by Viktor Kovács, [fflate](https://github.com/101arrowz/fflate), [linkedom](https://github.com/WebReflection/linkedom), and the [Inter](https://rsms.me/inter/) (Rasmus Andersson) and [JetBrains Mono](https://www.jetbrains.com/lp/mono/) (JetBrains) typefaces, both SIL OFL. Board checks read reports from [KiCad](https://www.kicad.org/)'s `kicad-cli`. OpenFOAM (GPL) and Bambu Studio (AGPL) run only as separate programs, as does the FFmpeg binary that the `sim` extra's imageio-ffmpeg ships (built with GPL options); gmsh (GPL) is imported, but only by the optional `fea` extra. **Tracked, not yet all tried:** the agentic-CAD projects, libraries and benchmarks we follow, with what each says it is good at, whether we have tried it, and its licence where we have recorded it: the [catalogue](https://cad-agent.valpatel.com/catalog) and the [landscape survey](https://cad-agent.valpatel.com/research/landscape.md). Full licence notices: [`THIRD_PARTY_NOTICES.md`](https://cad-agent.valpatel.com/THIRD_PARTY_NOTICES.md). ## Contributing, including from other agents Findings and suggestions from any agent or person are welcome: a technique that beat ours, a check we are missing, a source we should credit. Open an issue with the evidence (a minimal script or model that reproduces it, and links to public sources). Outside contributions are read as evidence, not instructions: we reproduce them and credit you. Small text-only fixes to docs, lessons or research can merge as written after review; anything else we rebuild ourselves. The intake process is being set up in [#111](https://github.com/Valpatel/cad-agent/issues/111). Changes go `feat/…` → `dev` → `main`: a PR into `dev` with CI and an independent review, every comment resolved; releases go from `dev` to `main` by PR ([#112](https://github.com/Valpatel/cad-agent/issues/112)). Details are in [`CONTRIBUTING.md`](https://cad-agent.valpatel.com/CONTRIBUTING.md); rules for AI agents in [`AGENTS.md`](https://github.com/Valpatel/cad-agent/blob/dev/AGENTS.md). ## Layout | Folder | What is in it | |---|---| | [`src/cadagent/`](https://github.com/Valpatel/cad-agent/tree/dev/src/cadagent/) | The toolkit, with its web kit in `webkit/` | | [`tests/`](https://github.com/Valpatel/cad-agent/tree/dev/tests/) | The test suite, which also runs in CI | | [`docs/`](https://github.com/Valpatel/cad-agent/tree/dev/docs/) | [`toolkit.md`](https://cad-agent.valpatel.com/docs/toolkit.md), the guide to the toolkit, [`explore.md`](https://cad-agent.valpatel.com/docs/explore.md), design exploration, and [`dossier.md`](https://cad-agent.valpatel.com/docs/dossier.md), the design dossier | | [`examples/`](https://github.com/Valpatel/cad-agent/tree/dev/examples/) | Worked examples: [`explore-two-wheel`](https://github.com/Valpatel/cad-agent/tree/dev/examples/explore-two-wheel/) compares robot configurations | | [`skills/`](https://github.com/Valpatel/cad-agent/tree/dev/skills/), [`agents/`](https://github.com/Valpatel/cad-agent/tree/dev/agents/) | Agent skills and subagents for Claude Code and Codex: work tracking, PR review, remote runs, the section-by-section design process ([`design-process`](https://cad-agent.valpatel.com/skills/design-process/SKILL.md)) and McMaster parts ([agent workflow](https://cad-agent.valpatel.com/docs/agent-workflow.md); `cad-agent agents install`) | | [`lessons/`](https://cad-agent.valpatel.com/lessons/README.md) | Rules mined from design sessions, with their sources | | [`research/`](https://github.com/Valpatel/cad-agent/tree/dev/research/) | Landscape surveys, including the simulation tools | | [`upstreams/`](https://github.com/Valpatel/cad-agent/tree/dev/upstreams/), [`vendor/`](https://github.com/Valpatel/cad-agent/tree/dev/vendor/) | The tool registry and the vendored, pinned upstreams | | [`tools/`](https://github.com/Valpatel/cad-agent/tree/dev/tools/), [`mining/`](https://github.com/Valpatel/cad-agent/tree/dev/mining/) | Vendor sync, security scan and the local session miner | ## License MIT. See [`LICENSE`](https://github.com/Valpatel/cad-agent/blob/dev/LICENSE). Vendored code keeps its own licence, listed in [`THIRD_PARTY_NOTICES.md`](https://cad-agent.valpatel.com/THIRD_PARTY_NOTICES.md). --- Source: https://cad-agent.valpatel.com/THIRD_PARTY_NOTICES.md # Third-party notices Code under `vendor/` is copied from the projects below at the pinned commit. Each directory keeps its upstream LICENSE/NOTICE files; those terms apply to that code. Our changes are listed as patches in `vendor/patches/`. ```mermaid flowchart TD P["a project we found"] --> L{"its licence"} L -->|"MIT, BSD,
Apache"| V["vendor or adapt
pinned, credited,
LICENSE kept"] L -->|"copyleft"| C{"which?"} C -->|"LGPL"| Lg["vendored unmodified,
licences and
sources kept"] C -->|"GPL, AGPL"| X["never copied: run as
its own program, or an
optional import (gmsh)"] L -->|"none, non-commercial,
custom"| I["ideas only
credited"] classDef here fill:#fffdf5,stroke:#173d3c,color:#173d3c classDef near fill:#eef1e4,stroke:#6f8a80,color:#173d3c classDef out fill:#ffe1cc,stroke:#bd3a12,color:#173d3c class L,C here class P near class V,Lg,X,I out ``` | Project | Licence | Upstream | Pinned commit | Imported | |---|---|---|---|---| | text-to-cad | MIT | https://github.com/earthtojake/text-to-cad | `2f793659fb7b` | 2026-10-24 | | kicad-happy | MIT | https://github.com/aklofas/kicad-happy | `2fd9aa0fe2d6` | 2026-10-24 | | kicad-mcp-pro | MIT | https://github.com/oaslananka/kicad-mcp-pro | `f03b478f597d` | 2026-10-24 | | build123d-mcp | Apache-2.0 | https://github.com/pzfreo/build123d-mcp | `59b256121886` | 2026-10-24 | | agentcad | Apache-2.0 | https://github.com/jdilla1277/agentcad | `52af472ddade` | 2026-10-24 | | bd_warehouse | Apache-2.0 | https://github.com/gumyr/bd_warehouse | `e6ae6e7bae74` | 2026-10-24 | ## Showcase on the site (Gyropup) The home page shows [Gyropup](https://gyropup.com), a robot designed with cad-agent. Its model and pictures are copies of Gyropup's CAD exports and results, under its MIT licence ("Copyright (c) 2026 mvalancy and Gyropup contributors"), whose full text travels with them in `docs/img/gyropup/LICENSE.txt`. `tools/gyropup_showcase.py` regenerates them and records the revision in each file's source record. | Files | From | Revision | |---|---|---| | `web/models/gyropup.json`, `.bin`, `.webp` (the 3D model and its poster) | every part's STEP in [Valpatel/gyropup](https://github.com/Valpatel/gyropup), exported with `cad-agent view` | `77f6d00` | | `docs/img/gyropup/wheel-link-fea.webp`, `leg-render.webp` | Gyropup's `exports/leg/fea/wheel_link-E1.png` and `exports/leg/leg-stand-iso.png`, cropped | `77f6d00` | | `docs/img/gyropup.jpg` | a Gyropup render | earlier, not recorded | ## Runtime dependencies and external programs (not vendored) The simulation modules and the site build use these at run time. None of their code is copied into this repository. | Project | Licence | How cad-agent uses it | |---|---|---| | OpenFOAM v2512 (OpenCFD) | GPL-3.0 | External program (`cadagent.simulation.cfd` writes a case and runs it natively or in the `opencfd/openfoam-default` Docker image) | | Bambu Studio | AGPL-3.0 | External program (`cadagent.manufacturing.slicer` runs its command line; profiles are read, flattened and passed back as files) | | gmsh | GPL-2.0-or-later | Imported by the optional `fea` extra. Our source stays MIT; distributing a bundle that includes gmsh falls under the GPL | | scikit-fem | BSD-3-Clause | Imported (`fea`) | | pyMOTO | MIT | Imported (`sim`, topology optimisation) | | PyVista, VTK | MIT, BSD-3-Clause | Imported (`sim`, pictures and animations) | | trimesh, manifold3d, Rtree | MIT, Apache-2.0, MIT | Imported (`sim`, mesh booleans and point-in-solid tests) | | Playwright, Chromium | Apache-2.0, BSD-3-Clause | The site build draws its Mermaid diagrams in headless Chromium through Playwright, a dev dependency (`tools/site-diagrams.mjs`); the browser tests run in it too | | imageio, imageio-ffmpeg (FFmpeg) | BSD-2-Clause (FFmpeg LGPL/GPL binary, run as a process) | Imported (`sim`, MP4 writing) | ## Web kit (copied into project sites and published on cad-agent.valpatel.com) `src/cadagent/webkit/vendor/` holds these files unchanged unless noted; each keeps its licence text beside it, and `cad-agent site` copies the licence files with the code. | Project | Licence | Version | Licence file in the kit | |---|---|---|---| | three.js (core and the controls, geometry, loader and utility add-ons) | MIT | r160 (npm 0.160.0); OrbitControls carries one local patch to its wheel step, recorded in `three/SOURCE.json` | header of `three/three.module.min.js`; `file-parsers/THREE-LICENSE.txt` | | three.js STL and 3MF loaders | MIT | r160, import paths changed to the local copies | `file-parsers/THREE-LICENSE.txt` | | fflate (the ZIP reader the 3MF loader imports) | MIT | 0.8.3, from npm | `file-parsers/FFLATE-LICENSE.txt` | | Mermaid | MIT | 11.17.2 | `mermaid/LICENSE` | | linkedom | ISC | 0.18.12 | `linkedom/LICENSE` | | occt-import-js (Open CASCADE Technology compiled to WebAssembly) | LGPL-2.1 with the OCCT exception | 0.0.23 | `occt-import-js/` (four licence files; sources in `occt-import-js/source`) | | Inter | SIL Open Font License 1.1 | 4.001, variable, Latin subset from Google Fonts (sources in `fonts/SOURCE.json`) | `fonts/OFL-Inter.txt` | | JetBrains Mono | SIL Open Font License 1.1 | 2.211, variable, Latin subset from Google Fonts (sources in `fonts/SOURCE.json`) | `fonts/OFL-JetBrainsMono.txt` | --- Source: https://cad-agent.valpatel.com/agents/cad-pr-reviewer.md You review a pull request you did not write. Follow the `cad-pr-review` skill (reviewer part). In short: 1. Read the PR description, the linked issue and the diff (`gh pr view `, `gh pr diff `, or `git diff origin/...HEAD` in the checkout you were given). Read the repo's AGENTS.md for its rules. 2. Do not edit, commit or push anything in the checkout, and do not touch any other worktree. Scratch scripts go in a temporary directory outside the repo. 3. Verify before you post: run the tests that cover the change, reproduce each suspected bug with a small script, check generated evidence (STEP/STL bounds and volumes, report numbers, convergence of simulations) against what the PR claims. Keep CPU and memory use light; never start long simulations; if a check needs one, say so. 4. For CAD and simulation work, check the physical assumptions as hard as the code: directions (fan flow, loads, gravity), units, orientation and datum of photo or drawing fits, which numbers are measured and which assumed, and that nothing claims more than CAD or simulation can show. 5. For any change to part geometry, walk cad-agent's common-issues index ([docs/common-issues.md](https://github.com/Valpatel/cad-agent/blob/dev/docs/common-issues.md)), every row: - Every automatic check row must be in the committed report (`exports/cad-agent-results.json`) and pass, bound to the current files. If "Holes clear" is missing or stale, run it without touching the checkout: `cad-agent holes --out /tmp//holes.json` (about 10 s for a large part). A missing, stale or failing row is a blocking finding. Also look at its listed ledges and the blind holes in a section view: they are the check's known misses. - For each review row, look at the geometry (sections, renders, the STEP) and say in the summary what you checked. - When you find a mistake the index does not list, say so: it belongs in the index. 6. Post inline comments on exact lines with severity (blocking / minor / nit) via `gh api repos///pulls//comments` (`commit_id` = head SHA, `path`, `line`, `side=RIGHT`), then one summary review with `gh pr review --comment` that states plainly whether anything blocks the merge. End the summary with the verdict marker on its own line, for the head commit you reviewed: `` when nothing blocking is left, otherwise `verdict=block`. Repos with merge gates read it (cad-agent: the latest verdict must be pass, on the PR's head commit); then re-run them: `gh workflow run gates.yml -R / -f pr=`. Do not approve or merge. 7. Final message: each finding as `file:line, severity, one sentence`, plus what you checked and found fine, and the links to the review and comments. ```mermaid flowchart TD Rd["read the PR, issue, diff,
the repo's rules"] --> V["verify the claims
tests, small scripts"] V --> C["inline comments
+ summary review"] C --> M["verdict marker
as the last line"] N["never edits, approves
or merges"] -.- C class V,C here class Rd,N near class M out ``` --- Source: https://cad-agent.valpatel.com/agents/cad-resume.md You pick up work that another session started. Follow the "Resuming" part of the `cad-work-tracking` skill. ```mermaid flowchart TD G["each repo:
branches,
unpushed work"] --> R H["GitHub:
issues, PRs,
claims"] --> R L["runs:
logs,
read only"] --> R R["report
goal, done, in flight,
local-only state, next steps"] class G,H,L here class R out ``` 1. For each repo you were given (default: the current directory): - `git fetch --all --prune`, `git status -sb`, `git worktree list`, and for each local branch the commits not on its upstream (`git log --oneline @{u}..HEAD` or `git log --oneline --branches --not --remotes`). - Open issues and PRs (`gh issue list --state open`, `gh pr list --state open`), the tracking issue named in the brief or found by the branch's PR (`Closes #N`), its checklist and its last few comments. - CI state of the open PRs (`gh pr checks `) and unresolved review threads. - Work claims on those issues (comments starting ` B["branch + draft PR
pushed at once"] B --> C["commit + push
in clean chunks"] C <--> K["checkpoint every ~30 min
heavy runs on a compute host"] C --> R["independent review
every thread resolved"] R --> M["merge under the repo's rules"] X["session ends"] -.-> Z["a fresh agent resumes
from GitHub alone"] -.-> C classDef here fill:#fffdf5,stroke:#173d3c,color:#173d3c classDef near fill:#eef1e4,stroke:#6f8a80,color:#173d3c classDef out fill:#ffe1cc,stroke:#bd3a12,color:#173d3c class B,C,K here class I,X,Z near class R,M out ``` 1. **Issue first, then claim it.** One per piece of work, with a checklist: done, next, running, how to resume. A big job gets a tracking issue linking smaller ones. Post a work-claim comment before starting (below). 2. **Branch and push at once**, per the repo's rules (cad-agent: `feat/` worktree from `origin/dev`; product repos say in their AGENTS.md). 3. **Draft PR early**, `Closes #` in its body, listing what is still missing. 4. **Commit and push in clean chunks**, each one coherent and pushed right away. 5. **Checkpoint every ~30 minutes** and before anything long: push, tick the checklist, comment with what changed, what is running (host, command, log, done marker) and the exact next step. 6. **Heavy runs on a compute host**, detached, recorded in the issue, results pulled back and committed. 7. **Independent review** by `cad-pr-reviewer` (or a separate Codex session); answer and resolve every thread. 8. **Merge under the repo's rules**, then check the issues closed and tick the tracking issue. ### Work claims Agents on different tools and machines share issues with comments whose first line is machine-readable: ```markdown **Claimed** by agent `a-7kq2m4xw` until 2026-11-01T19:00Z UTC. Scope: … Branch: … ``` Actions are `claim`, `checkpoint` (renews the lease), `release` and `done`. A lease lasts at most 24 h; a claim not refreshed in time has expired and the issue is open for anyone. Of the active claims, the one whose unbroken run of claims and checkpoints started first holds. Tags are pseudonymous (`a-` + 8 of `[a-z2-7]`; one per tool and machine, so sibling sessions share it): no host or user names in public repos. Full rules in [cad-work-tracking](https://cad-agent.valpatel.com/skills/cad-work-tracking/SKILL.md#work-claims-sharing-issues-between-agents). Things that must not live only locally: decisions and reasons, the user's measurements and observations, run commands and results, lessons. Licensed or large inputs stay out of git, but the repo says where they come from and how to fetch them, so a reformatted machine can rebuild. ## In a project repo Point the project's AGENTS.md at this workflow (one line: "Follow the cad-agent workflow kit: cad-work-tracking, cad-pr-review, cad-remote-runs; install with `cad-agent agents install`") and add the project's own rules next to it: its integration branch, who may merge, its compute hosts (in private notes if the repo is public). --- Source: https://cad-agent.valpatel.com/docs/animated-figures.md # Animated figures from real CAD The README's hero is not drawn by hand. `tools/readme_anim.py` makes it from a real project's files: - the STEP assembly, drawn as edges by hidden-line removal; - the linkage's kinematics, solved from link lengths measured in the CAD; - clearances from the assembly gates' relation engine; - stress bands from the project's own FEA field. It writes one SVG of about 140 KB that animates with CSS alone, so GitHub shows it in a README ``. ![Gyropup's five-bar leg drawn from its STEP file, assembled, then checked: its running and passing gaps, the hip frame's FEA stress and a stride solved from the link lengths, ending on the cad-agent wordmark](https://cad-agent.valpatel.com/docs/img/hero/gyropup-leg.svg) The first figure is [Gyropup](https://github.com/Valpatel/gyropup)'s five-bar leg (MIT): `docs/img/hero/gyropup-leg.svg`. The SVGs in `docs/img/hero/` may be reused on the site and elsewhere. Each one names its source in its caption and ``. ## Regenerate or check ```bash PYTHONPATH=src python3 tools/readme_anim.py # write every SVG from its committed scene PYTHONPATH=src python3 tools/readme_anim.py --check # exit 1 if a committed SVG differs or breaks a rule ``` `tests/test_readme_anim.py` runs `--check`, so a renderer change that alters a figure fails CI until the SVG is regenerated and committed. Rendering needs only cad-agent's core dependencies. ## Re-measure from the project ```bash PYTHONPATH=src python3 tools/readme_anim.py --extract hero --source ``` Extraction needs the `cad` extra (CadQuery). Use a clean checkout of the project's published branch, not a working tree with uncommitted changes. The scene records the commit and every input file's sha256. The clearance sweep is slow, because each pair is an exact `relate()` call (#186). Its result is reused from the committed scene while the assembly, the parts, the linkage and the clearance spec are unchanged. Pass `--fresh` to run it again. `--workers N` measures poses in N processes; each one reads the STEP once and holds the assembly in memory, about 0.5 GB for Gyropup's leg. Gyropup's leg takes about 25 s without the sweep. ## A recorded FEA study The second figure is not an assembly. It is a mesh-convergence study at an inside corner, run with this checkout's own `cadagent.simulation.fea` and drawn from what the results said. ![An L-bracket's inside corner refined step by step: sharp, the peak stress keeps rising and converge() never passes it; with an R1.5 fillet it settles and converge() passes it](https://cad-agent.valpatel.com/docs/img/fea/mesh-convergence.svg) *A recorded run of the toolkit (cad-agent 0.7.0 on gmsh 4.15.2 with OpenCASCADE 7.8.1, 2026-11-01). Linear-elastic FEA: a converged peak does not prove that the part holds.* ```bash PYTHONPATH=src python3 tools/readme_anim.py --extract convergence # record it again: gmsh, scikit-fem, CadQuery ``` `tools/anim/fea-convergence.yaml` names the study: the bracket, the load, the element sizes at the corner and the words. Recording takes about a minute and about 3 GB. `tools/anim/fea-convergence.scene.json` keeps, for each step: - the tets, the design peak and where it sits; - the peak's flags (`result['mesh']['peak']`) and `converge()`'s verdict; - the front face's mesh round the corner. It also keeps the mesher (`result['mesh']['mesher']`), the toolkit's version and commit, and the sha256 of the files that made it. `tests/test_anim_convergence.py` checks that the figure states the record's numbers and that the record shows what the docs say. On the recorded gmsh build, it runs the 2 mm steps again and compares. ## A snap fit engaging The third figure is a calculation, not a study: `cad-agent snapfit`'s closed form for one printed arm in two filaments, as the mating part's edge rides the hook. ![A printed snap arm bends as a mating part's edge rides its hook's lead. Its root strain rises to 1.38 %: 68 % of the 2.02 % allowed for Polymaker PolyMide CoPA (dry), a pass, and 139 % of the 1.00 % allowed for Bambu PETG-CF, a fail](https://cad-agent.valpatel.com/docs/img/compliant/snap-engagement.svg) *The toolkit's closed-form calculator (`cadagent.mechanical.compliant.snapfit`) on the stated arm: not a measurement. Allowables from the data sheets Polymaker PolyMide CoPA V5.4 and Bambu Lab PETG-CF V3.0. Printed snaps need a test print.* ```bash PYTHONPATH=src python3 tools/readme_anim.py --extract snapfit # run the calculator again: core only, under a second ``` `tools/anim/snap-engagement.yaml` names the arm, as a `cad-agent snapfit` declaration, and the words. `tools/anim/snap-engagement.scene.json` keeps, for each filament: - what `check_spec_entry` says: the verdict, the rows, the material derivation and the data-sheet editions; - the closed form along the insertion (`snapfit.engagement()`); - the travel where the root strain reaches the allowable. It also keeps the arm's bent shape at the drawn slices, the toolkit's version and commit, and the sha256 of the files that made it. The arm is drawn in slices, each moved and turned by the shape at its middle. Both are linear in the deflection, so every keyframe is exact and the arm bends smoothly. The still is the top of the lead, where the strain peaks. `tests/test_anim_snapfit.py` runs the calculator again and compares every number, works the closed form by hand, and checks the still and the pages that show the figure. ## Make one for another assembly Copy `tools/anim/gyropup-leg.yaml`, then add the figure to `FIGURES` in `tools/readme_anim.py`.
What the spec names: the assembly, parts, linkage, view, FEA field and words - **the assembly**: one STEP, one solid per part. - **the parts**: solids by their number in the STEP. Each part has: - the body it moves with; - an explode distance along the joint axis; - a style; - optionally a part file whose volume the solid must match. If the STEP is rebuilt and its solids are renumbered, extraction fails instead of drawing the wrong part. - **the linkage**: a planar one. - Joints are measured from coaxial solids, and the link lengths are checked against the design's. - The solve order says which joints are found from which. - The driven joint follows a path. - Four-bars driven by an output point, five-bars and chains of dyads all fit (`cadagent.mechanical.linkages`, which also sweeps closed loops over their inputs: see [Linkages](https://cad-agent.valpatel.com/docs/linkages.md)). - **the view**: a direction and an up vector. Set the stage box in pixels. - **the FEA field**: optional, a `cadagent-fea-viewer` v1 file (what `cadagent.simulation.fea` writes for the viewer), with the stress bands as fractions of strength. - **the words**: the wordmark and tagline, drawn as outlines because an `` loads no fonts. Labels, captions and the check rows' wording (`present.checks`, with `{placeholders}` filled from the scene) sit under `present`, so they can change without re-extracting.
A different kind of figure (a board into its enclosure, print layers) gets its own scene module next to `cadagent.publish.anim.hero`, as the convergence study and the snap fit have (`cadagent.publish.anim.convergence`, `cadagent.publish.anim.snapfit`). It reuses the shared parts: - edge projection: `cad`; - the rasteriser and outlines: `raster`; - paths, timeline, theme and the embed rules: `svg`; - text outlines: `text`. The two stages, and what each reads and writes: ```mermaid flowchart TD S["assembly STEP
the project's CAD"] --> X["--extract
CadQuery: edges, gaps"] F["spec YAML + FEA field
linkage, view, stress"] --> X X --> J["tools/anim/*.scene.json
poses, sha256 of inputs"] J --> R["render
pure Python, no CAD"] R --> O["docs/img/hero/*.svg
CSS animation, 250 KB max"] class S,F near class X,J,R here class O out ``` ## What a figure must pass `cadagent.publish.anim.svg.problems()` lists what makes an SVG unsafe or unfit to embed. Each rule has a test that breaks it.
The embed rules: size, XML, no scripts or outside references, accessibility, CSS only, reduced motion - at most 250 KB; - well-formed XML; - no `