This repo is a workbench for CAD-related agent skills. Treat skills/ as the
product and models/ as the shared fixture/artifact area.
Before changing code, branch from develop, not main; PRs should target develop.
Do not start development work from main. The develop branch intentionally uses
symlinks across generated runtime and viewer-local package paths. When a path is
symlinked, follow the link and edit the source target.
Use main as the production clone/release branch only. main is publish-only:
do not open PRs to main or push it directly.
Do not bump the canonical release version in VERSION during
normal development work. Ship releases only through the single Release
GitHub Actions workflow, which handles the version bump, release PR, publish
commit to main, models upload, web-app deploys, semver tag, and GitHub
Release in one run.
When asked to publish, make, or ship a release, dispatch Release with its
defaults: build from develop (base_branch=develop), publish to main
(target_branch=main), and publish the GitHub Release (publish=true, not a
draft). Never pick the semver bump yourself: if the request does not name
patch, minor, major, or an exact version, ask which one before dispatching.
Use target_branch=build-test only when the user explicitly asks to test
CI/CD or build-pipeline changes — never by default and never as part of a
requested release. Rerun Release with set_version pinned to the current
version to resume a failed publish.
The standalone Deploy Docs and Deploy Viewer workflows redeploy the
individual web apps from main, and the standalone Upload Models workflow
uploads the models/ catalog to Vercel Blob from develop, all without
running a release. main is publish-only; pushing develop runs tests but
never publishes. See the Releases section in CONTRIBUTING.md for the full
flow, CI/CD-testing and resume options, and local/manual fallbacks.
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.viewer/: editable CAD Viewer source app.packages/cadjs: shared JS CAD/render/runtime code, UI-framework agnostic.packages/implicitjs: standalone JS implicit CAD model, shader render, snapshot, mesh sampling, and export runtime.packages/cadpy: shared Python STEP/GLB/topology artifact code.packages/cadpy_metadata: dependency-free Python metadata helpers vendored into generated URDF/SRDF/SDF skill runtimes.docs/: documentation site.tests/: root-owned test suites for skills, packages, viewer services, and repo-wide policy.scripts/: durable repo commands grouped by purpose.
- 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. - Keep the primary local
developcheckout in symlink layout withscripts/dev/setup-symlinks.sh. Do not auto-repair that layout from Codex or Claude Code startup hooks in linked worktrees. - Each skill must be self-contained and independent at runtime. A skill must
not refer to or import or depend on code from another skill, from
skills/root, or from repository-root modules. Do not addskills/, the repository root, or sibling skill directories tosys.path,PYTHONPATH,NODE_PATH, or similar runtime lookup paths. Shared runtime helpers must live underpackages/as the source of truth and be vendored/generated from there into each consuming skill runtime; do not keep shared helper modules directly underskills/. - Edit the source reached by the
developsymlink layout first, then regenerate explicit derived outputs when a production-output task requires it. - Write all test, sample, permanent, and generated CAD/robot-description
artifacts under
models/, including STEP/STP, STL, 3MF, GLB, DXF, URDF, SRDF, SDF, and G-code outputs. Do not create ad hoc artifact directories elsewhere. models/takes CAD/robot sources, the 3D and fabrication outputs generated from them, and their docs — nothing else. Do not commit review media (snapshot PNGs, orbit GIFs, screen recordings), data or metadata dumps, archives, foreign CAD sources, or runtime debris there; render review images under/tmpand attach them to the conversation or PR. The File Policy section ofmodels/README.mdis the authoritative list, enforced bytests/python/global/test_models_directory_policy.py.- Reserve
scripts/for durable repo commands. Do not write temporary, one-off, or local-only helper scripts there; usetmp/or/tmpinstead. - Development symlinks mark generated or copied paths. If a file is under a symlinked runtime or viewer package path, edit the symlink target/source path instead of treating the copy as independent.
- When source changes affect generated runtimes, refresh or check them with the
master bundle wrapper,
scripts/bundle/bundle.sh. Use lower-level bundle scripts only when debugging the wrapper itself. - 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. packages/cadjsmust stay reusable/non-React; app UI and workflow state belong inviewer/.packages/implicitjsmust stay reusable/non-React and independent ofpackages/cadjs; CAD Viewer and snapshot tools should consume its shared render/export APIs instead of duplicating implicit CAD logic.packages/cadpyowns reusable Python artifact generation; skills should use bundled package code, not sibling skill imports.- Create lightweight shared Python packages under
packages/cadpy_*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.
- 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. - If a worktree explicitly needs the development symlink layout, run
scripts/dev/setup-symlinks.sh --checkand thenscripts/dev/setup-symlinks.shintentionally in that worktree. - 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.
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- In GitHub Actions,
test.ymlchecks the canonical release version in a separate job so code tests still run when version metadata is wrong; its test job verifies thedevelopsymlink layout, checks generated outputs against their sources, bundles temporary production outputs, and runs docs and code tests against that bundle.mainwrites are validated by theReleaseworkflow's publish job; GitHub branch settings should block PRs and direct pushes tomain.
- In GitHub Actions,
- Focused test runners:
scripts/test/test-js.sh,scripts/test/test-docs.sh,scripts/test/test-python.sh,scripts/test/test-global.sh - Development symlink layout:
scripts/dev/setup-symlinks.sh --check - Canonical release version:
scripts/release/check-version.sh - Generated runtime freshness:
scripts/bundle/bundle.sh --check - CAD Viewer,
packages/cadjs, orpackages/implicitjs:npm --prefix packages/cadjs test,npm --prefix packages/implicitjs test,npm --prefix viewer run test,npm --prefix viewer run build - Docs site:
npm --prefix docs run check - Targeted Python tests:
./.venv/bin/python -m unittest <changed test paths>
When a task intentionally writes production outputs locally, run
scripts/bundle/bundle.sh, rerun scripts/bundle/bundle.sh --check, and restore
the development symlink layout afterward if you are continuing on develop.
When reviewing repo fixtures in CAD Viewer, point the Viewer at the repo
models/ directory with an absolute ?dir= path; keep any permanent or
generated CAD/robot-description files in models/ so the viewer catalog and
artifacts stay in one place.
Start or reuse the Viewer through the serve entrypoint documented in
skills/cad-viewer/SKILL.md and use the base URL it prints. serve is the only
startup command the bundled skill runtime ships, so document and use it in both
layouts; it owns port selection, binding 4178 when free and scanning forward
when it is not.
Run from skills/cad-viewer:
npm --prefix scripts/viewer run serve -- --host 127.0.0.1 --dir <absolute-model-root> --shutdown-after 12h --json--dir is required for a useful catalog and must be absolute. Read the bound
port from the --json startup line rather than assuming 4178.
viewer/scripts/start-agent-viewer.mjs (npm run agent:start) is a
source-checkout-only launcher that adds Vite dev mode and cross-worktree reuse.
It is not bundled into the skill runtime, so never document it in skills/.
Every returned Viewer URL must include ?dir=<absolute-model-root>, commonly
<repo>/models, and file=<path> values must be relative to ?dir=. Do not
manually choose or increment ports, do not rely on session-storage ?dir=
fallbacks, and do not stop an existing Viewer server unless the user asks.
Packaged Viewer runtime and handoff details belong in the cad-viewer skill
instructions. Treat packaged Viewer checks as generated-output checks and use
the master bundle wrapper unless you are debugging a lower-level script.
CAD exchange files, generated render/topology assets, assets/**, and
benchmarks/** 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.