Imported from dawalixi1980/Dawalixi-skill (
text-to-cad/AGENTS.md). Install upstream withnpx skills add dawalixi1980/Dawalixi-skill --skill text-to-cad. Copyright stays with the author.
AGENTS.md
This repo is a workbench for CAD-related agent skills. Treat skills/ as the
product and models/ as the shared fixture/artifact area.
Branch First
main is the only long-lived branch: the source tree, what installers clone,
and what releases are cut from. Branch from main and open PRs against main;
never push it directly. There is no development symlink layout — every path in
the tree is the real file.
Release Workflow
Do not bump the canonical release version in VERSION during normal
development work; the Test workflow refuses a PR that changes VERSION from
any branch but release/*. Releases are two GitHub Actions workflows:
Prepare Release(release-prepare.yml, manual): opens and merges a release PR againstmainthat bumpsVERSION, the derived metadata and every skill'scadgen==pin together.Publish Release(release-publish.yml): fires on the push that merge makes. Bundles, tests, builds thecadgenwheel, installs and exercises it, keeps the distribution as a workflow artifact, then — onmainonly — uploads to PyPI, deploys the docs site, and tags (v<VERSION>; releases before 0.5.0 are bare0.4.xtags) + GitHub-Releases that same merged commit with the wheel and sdist that went to PyPI attached as release assets.
When asked to publish, make, or ship a release, dispatch Prepare Release on
main. Never pick the semver bump yourself: if the request does not name patch,
minor, major, or an exact version, ask which one before dispatching. To resume a
run that uploaded the wheel but failed before the tag or the docs deploy, or to
republish the current head, dispatch Publish Release on main (publish=false
leaves the GitHub Release as a draft). target=build-test on Prepare Release
is the rehearsal — the same PR against build-test, whose pushes run Publish Release without PyPI, docs or tag — and is never a release; use it only when the
user explicitly asks to test the pipeline.
The standalone Deploy Docs workflow redeploys the docs site from a ref
(default main, or a release tag) without running a release.
Skill requirements.txt files pin cadgen==<VERSION> on main itself;
scripts/release/check-version.sh asserts every pin equals VERSION. A
checkout's editable install reports that same version, so the pin is satisfied
in development too — install requirements-dev.txt, never a skill's
requirements.txt on its own (that fetches the previous release from PyPI).
models/ stays on main as LFS pointers (.lfsconfig excludes it from
default fetches; .gitattributes export-ignores it from archives); nothing
installs it. scripts/github-workflows/check-builds.sh enforces the shipping
contract on every push: no tracked symlink, no LFS path under skills/, no
skill reaching into a repo root. See the Releases section in CONTRIBUTING.md
for the full flow, the resume path, the rehearsal, and local/manual fallbacks.
Repo Map
skills/: agent skills and their references/scripts..claude-plugin/,.codex-plugin/: agent plugin manifests. The repository root is the plugin package; its skills areskills/directly.models/: sample and durable CAD/robot-description fixtures.apps/viewer/: the CAD Viewer's React client (its backend iscadgen.viewer).packages/cadgen-js: shared JS CAD/render/runtime code, UI-framework agnostic.packages/cadgen: the published distribution — STEP/GLB/topology generation, the skill CLI parsers, the CAD Viewer backend + client, and the Node/browser runtimes it executes.apps/docs/: documentation site.tests/: root-owned test suites for skills, packages, viewer services, and repo-wide policy.scripts/: durable repo commands grouped by purpose.
Repo Rules
-
Boundaries and design laws live in each package's README: read
packages/cadgen/README.md(the laws),packages/cadgen-js/README.md,apps/viewer/README.md, andapps/docs/README.mdbefore changing generation, rendering, storage, layout, or public interfaces. -
A README holds the laws; the mechanism each law constrains lives one link away, and the README names the link. Read the README, then follow the one link — not the tree. What exists:
packages/cadgen/:STORE.md(the store contract — sectioned, with a table of contents),MEMO.md(@memo, and the process-wide geometricShapeidentity it installs),SNAPSHOTS.md(snapshot--debugtimings).packages/cadgen-js/docs/:render-pipeline.md,resource-ownership.md,tube-deformation.md.apps/viewer/docs/:settings-ui.md(BINDING for any settings control),render-types.md,render-mode.md,lod.md,storage.md,backend.md.
-
Ships-alone law:
packages/cadgen(the built PyPI wheel) works in isolation outside this repo, so its markdown must not refer to anything outside the package — enforced bytests/python/global/test_package_boundaries.py. Repo-development guidance for it goes inCONTRIBUTING.md. -
Keep root guidance short. Put domain workflows, CLI details, and validation policy in the relevant
skills/<skill>/SKILL.mdorreferences/file. -
Keep relevant Markdown docs current when changing behavior, commands, or repo layout, but do not bloat
AGENTS.md; use it only for durable repo-level rules and pointers. -
Read
CONTRIBUTING.mdbefore committing, rebasing, resolving generated-file conflicts, or bumping release versions. -
A skill must not import another skill, a
skills/root module, or a repository-root module, and must not addskills/, the repository root, or a sibling skill directory tosys.path,PYTHONPATH,NODE_PATH, or any other runtime lookup path. Skills are independent of each other, not of everything. -
Shared runtime comes from the
cadgendistribution. A skill that uses it names it in itsrequirements.txt, pinned toVERSION(the release PR stamps every pin; the editable install inrequirements-dev.txtsatisfies it in a checkout). Skills do not vendor it: a skill script is a thin entrypoint whose parser and behaviour live incadgen.cli, and which fails with thepip install -r requirements.txthint when cadgen is missing. cadgen carries the JavaScript it executes too (Node builders, the snapshot browser bundle, the CAD Viewer client), so a skill ships no runtime of its own. Not every skill needs cadgen (bambu-labs, dfam-check, dfm, gcode, sendcutsend, step-parts are cadgen-free); do not add the dependency to a skill that never invokes it. -
Keep samples and manual CAD/robot-description validation artifacts under
models/. Automated tests must not read, build or import that sample corpus: generate small fixtures in fresh temporary directories or use tiny test-owned fixtures, with their own cache stores and cleanup. Repotmp/is fine. Enforced bytests/python/global/test_tests_are_self_contained.py. -
Every test file is reached by a runner under
scripts/test/, and a collector that finds nothing fails the run rather than reporting a group that never ran — so a renamed or emptied test directory stops CI instead of going quiet. -
Benchmarks under
scripts/bench/are manual and their output is never committed: reports, logs, profiles and screenshots go to an ignoredtmp/. Only their pure helper units run in a test runner. -
The Python floor is
requires-pythoninpackages/cadgen/pyproject.tomland nowhere else. Every cadgen source is parsed against that floor, so syntax newer than it fails here rather than atpip installtime on a user's interpreter; raising the declared minimum relaxes the check automatically. -
Reserve
scripts/for durable repo commands. Do not write temporary, one-off, or local-only helper scripts there; usetmp/or/tmpinstead. -
cadgen's packaged runtime (
_runtime/node,_runtime/browser,_runtime/viewer) is BUILT, never committed: the whole directory is gitignored and ships only inside the wheel. Build it with the one bundle entry point,scripts/bundle/bundle.sh;bundle.sh --checkbuilds it and asserts every required output. Callscripts/bundle/cadgen-runtime.shdirectly only when debugging one stage. -
Never let a symlink reach the published tree. Agent installers disagree about symlinks and one loses data silently: the Skills CLI dereferences them, Claude Code preserves them, and Codex
plugin adddrops them with no error, shipping a skill with missing files.scripts/github-workflows/check-builds.shenforces this; do not relax it. -
The CAD Viewer is
cadgen viewer: the server iscadgen.viewer(Python, inpackages/cadgen), the React client's source isapps/viewer/and its build ships in the wheel atcadgen/_runtime/viewer(built, never committed; a checkout servesapps/viewer/dist). The cad-viewer skill is instructions over that verb. Nothing incadgen.viewerimports the CAD kernel at module scope — the one kernel action, importing a foreign STEP, is a compile job in cadgen's build pool, never work the server process does. Keep repo-level tooling inscripts/, not underapps/viewer/. -
packages/cadgen-jsmust stay reusable/non-React; app UI and workflow state belong inapps/viewer/. It holds the shared CAD render/runtime code: one package, one copy of each shared primitive. -
packages/cadgenis the whole distribution, not just the Python: artifact generation, the CLI parsers behind every skill command (cadgen/cli), the warm build daemon (cadgen/daemon), and the JS/SPA assets it executes (cadgen/_runtime, built byscripts/bundle/cadgen-runtime.sh). Skills consume it as an installed distribution. -
Create lightweight shared Python packages under
packages/when a helper should not inherit heavier package dependencies. -
Use path-targeted search, validation, and
git status; avoid broad scans over generated CAD/LFS artifacts unless the task requires them. -
Treat
VERSIONas the canonical release version. Do not hand-edit duplicate package, plugin, lockfile, or Pythonpyproject.tomlversions; release preparation andscripts/bundle/bundle.shstamp them from the canonical version.
Environments
- Prefer
./.venv/bin/pythonfor CAD Python work. - Keep new branch checkouts and git worktrees lightweight by default. Do not
copy
.venv/ormodels/through.worktreeinclude; recreate.venv/inside the worktree only when Python dependencies are needed for the workflow. - In Codex or Claude Code worktrees, prefer the skill instructions and scripts
under the current worktree's
skills/directory over globally installed skill symlinks from another checkout. - Hydrate
models/only when the user asks for it or when the task targets specific files undermodels/. In a new worktree, make the relevant model paths real before using them, preferring the local Git LFS cache withgit lfs checkout <path>orgit lfs checkout models. Download missing LFS objects only when explicitly requested or required after confirming the local cache is missing them. - Install dependencies only for the workflow being changed.
- Do not commit
.venv/,node_modules/, caches,tmp/, local credentials, or printer config.
Checks
Run the smallest path-targeted check that covers the change. Use broad wrappers when touching shared surfaces or before handoff:
-
Code tests:
scripts/test/test.sh(JS, then Python, then policy). -
Focused runners:
scripts/test/test-js.sh,scripts/test/test-docs.sh,scripts/test/test-python.sh,scripts/test/test-global.sh.test-python.shtakes--select cadgen|viewer|skills|alland--print-weights; seescripts/README.md. -
In GitHub Actions,
test.ymlruns on pull requests to and pushes ofmainas one job per thing that has to work, each conditional on the changes that can break it.Publish Releaserepeats the same checks on the release commit before the wheel ships.CONTRIBUTING.mdhas the reasoning.job OS runs when the diff touches what Version Check ubuntu anything VERSION, derived metadata, skill pinscadgen (Linux) ubuntu cadgen, cadgen-js, infra the cadgen package suite, CAD Viewer backend included cadgen (Windows) windows cadgen, cadgen-js, infra the same suite: the one thing that must be proven on Windows cadgen-js ubuntu cadgen-js, infra packages/cadgen-jsunit testsviewer ubuntu viewer, cadgen-js, cadgen, infra the client's unit tests, then the bundled client through the real backend skills ubuntu skills, cadgen, cadgen-js, infra tests/python/globalpolicy gates + every skill suitedocs ubuntu docs, skills, cadgen-js, cadgen, infra the docs site check packaging ubuntu cadgen, cadgen-js, viewer, infra bundle from clean, published-tree contract, wheel package data, installed-mode CLIs The classes:
cadgen=packages/cadgen/**+ its tests;cadgen-js=packages/cadgen-js/**;viewer=apps/viewer/**;skills=skills/**+ the skill and policy tests;docs=apps/docs/**;infra=scripts/**,.github/**,VERSION, plugin manifests, rootpackage*.json. A change to cadgen fans out to everything that runs it (the skills, the viewer, the docs, the wheel); a change to the viewer client runs only the viewer and packaging jobs. Prose (root*.md,notes/,models/,LICENSE) runs Version Check and nothing else. Markdown underskills/andpackages/cadgen/is NOT prose:test_documented_commands,test_skill_requirementsandtest_package_boundariesread it.All eight job names are
main's required checks; a job skipped by its own condition satisfies its check. Adding a job means adding its name there. -
Canonical release version:
scripts/release/check-version.sh -
Packaged runtime builds and is complete:
scripts/bundle/bundle.sh --check -
CAD Viewer or
packages/cadgen-js:npm --prefix packages/cadgen-js test,npm --prefix apps/viewer run test,npm --prefix apps/viewer run build. The Viewer is two languages andnpm run testcovers only the client — the backend's suite istests/python/packages/cadgen/viewer, run byscripts/test/test-python.sh. Touchingcadgen/viewer/means running that. -
Docs site:
npm --prefix apps/docs run check -
Targeted Python tests:
./.venv/bin/python -m unittest <changed test paths>
When a task changes what the bundlers consume, run scripts/bundle/bundle.sh
and confirm the change lands in the built runtime. There is nothing to commit:
_runtime/ is gitignored end to end, so what a reviewer reads is the source and
what a user gets is the wheel the release builds from it.
CAD Viewer
The app-facing playbook lives in apps/viewer/README.md: launcher contract
(reuse, ports, --new), dev vs prod, and the catalog/link-verification
gotchas. The repo-side half — the lightweight-worktree recipe and
node_modules linking — lives in CONTRIBUTING.md under "Viewer Development
In This Repo". Read them before starting, stopping, or debugging a Viewer.
Never stop an instance you did not start; packaged-runtime checks go
through scripts/bundle/bundle.sh.
Git And LFS
CAD exchange files, generated render/topology assets, and assets/** may be
LFS-tracked. Never disable LFS filters for git add, commits, or other
object-writing operations. Local hooks live in .githooks and
delegate build checks through scripts/git-hooks/pre-commit.