Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Scripts

Durable repo commands, one folder per concern. Every file here is called by a GitHub Actions workflow, the pre-commit hook, a test, or a documented developer step; nothing else belongs here (one-off helpers go in tmp/).

Task Command
Build the packaged runtime scripts/bundle/bundle.sh --clean
Build it and assert it is complete scripts/bundle/bundle.sh --check
Run code tests scripts/test/test.sh
Run docs checks scripts/test/test-docs.sh
Check the release version and skill pins scripts/release/check-version.sh
Stamp every skill's cadgen== pin from VERSION scripts/release/pin-cadgen-requirements.sh
Check the shipping contract scripts/github-workflows/check-builds.sh
Install local skills into agents scripts/install/install-skills.sh --agent codex
Uninstall local skill links scripts/install/uninstall-skills.sh --agent codex
Run this checkout as the CAD plugin in the Codex app scripts/install/codex-dev-plugin.sh --restart
Run this checkout's CAD server in Claude Desktop scripts/install/claude-dev-server.sh

Index

bundle/ — cadgen's packaged runtime (packages/cadgen/src/cadgen/_runtime). None of it is committed: the directory is gitignored end to end and the wheel is where those files ship, so these scripts are what produces them.

  • bundle.sh — the one entry point: stamps derived version metadata (release/sync-version.mjs), then runs cadgen-runtime.sh. --check builds the runtime and asserts every required output exists, and checks the derived metadata (which IS committed) rather than writing it. --clean removes the _runtime tree first. Called by test.yml, release-publish.yml, check-builds.sh, the pre-commit hook.
  • cadgen-runtime.sh — builds the five runtime stages: --node (esbuilt Node builders), --browser (snapshot browser bundle), --viewer (vite build of apps/web), --mcp (vite build of apps/mcp, one index.html), --native (the file tracer, zig-compiled for every platform; --native-host builds this machine's only). --print-outputs lists the three directories a bundle always produces; --check skips the viewer and MCP stages, which need the apps' node_modules and which nothing in a checkout reads. Called by bundle.sh, check-builds.sh, test/test-installed.sh, and test/common.sh when a test runner finds a stage it needs missing; pinned by tests/python/global/test_node_builder_bundles.py and test_js_runtime_reproducibility.py. Call it directly only to debug one stage.
  • lib/node_builders.sh, lib/snapshot_runtime.sh — sourced by cadgen-runtime.sh; esbuild the Node builders and the browser bundle with three/meshoptimizer pinned from package-lock.json.

test/ — test runners.

  • test.sh — test-js.sh, then test-python.sh, then test-global.sh: the whole tree on one machine. Called by release-publish.yml; test.yml calls the focused runners per job instead.
  • test-js.sh [--select core|ui|web|codex|all] — builds the required shared exports, checks dependency boundaries and runs the selected shared JS/UI/web suites. Core includes the pure bench/viewer-memory/ helper units; codex also builds the CAD app, whose one-file build is half its contract.
  • test-python.sh [--keep-going] [--select GROUP] [--print-weights] — the cadgen package suite, then every skill's suite. Each test FILE runs in its own interpreter against its own temporary store, CADGEN_TEST_JOBS at a time (default: the core count; CI sets 4). --keep-going runs all suites and reports every failure.
    • --select picks one group: cadgen (the package suite, CAD Viewer backend included), viewer (that backend alone, ~11 s), skills (every skill's suite), all (the default).
    • --print-weights prints one WEIGHT<TAB>path<TAB>seconds line per slow file on stdout (everything else a run says goes to stderr): the first thing to read when a run is slow.
  • unittest_files.py — the runner underneath, invoked by common.sh. Loads each test file under its full dotted path so an import failure names the file, and runs the files --jobs at a time in their own interpreters. A file still running after 15 minutes is hung: it prints every thread's stack and fails.
  • time-python.sh [N] — times every Python test module on its own and prints them sorted by wall clock (results under tmp/timing/); time_module.py is its helper. Manual only: the first step of a bloat check. --print-weights is the same measurement taken from a run that was happening anyway.
  • test-global.sh — tests/python/global, the repo-wide policy suite. Like test-python.sh, it builds the --node and --browser runtime stages and this machine's file tracer first when they are absent: the suites read them and a fresh clone has none.
  • test-docs.sh — npm --prefix apps/docs run check, pulling the hero assets first. Called by test.yml and release-publish.yml.
  • test-installed.sh — builds the wheel (or accepts --wheel PATH to test the exact artifact already built), installs it into a scratch venv and exercises cadgen from outside the repo, including cadgen mcp serving the packaged CAD app over stdio. Called by test.yml and release-publish.yml.
  • test-viewer-launch.sh — launches cadgen viewer against the built client and verifies reuse, cold STEP import, display derivation and browser drawing using a tiny test-owned STEP. Called by test.yml.
  • test-viewer-browser.sh — creates tiny inputs and owns its temporary project, viewer and cache. Requires a bundled viewer and npm Playwright Chromium (npx --no-install playwright install chromium). Runs the format and camera gates, exactly what test.yml runs. --only NAME selects a gate; --out DIR retains screenshots.
  • common.sh, unittest_files.py — shared runner pieces (interpreter resolution, fail-closed unittest loading, the per-file parallel run). Sourced by the runners.

release/ — the version and the release identity.

  • check-pr-version.sh BASE_REF HEAD_REF HEAD_SHA — rejects VERSION edits outside release/*, comparing with the current target branch's merge base so inherited releases are not mistaken for PR edits. Requires fetched remote history; called by test.yml.
  • check-version.sh [--incremented-from REF] — VERSION is valid semver, every skill pins cadgen==VERSION, and (with the flag) VERSION is greater than the one at REF. Called by test.yml, release-prepare.yml, release-publish.yml, publish-github-release.sh.
  • bump-version.sh major|minor|patch | --set-version X.Y.Z [--dry-run] — writes VERSION; --check-incremented-from REF compares against a ref. Called by release-prepare.yml and check-version.sh.
  • pin-cadgen-requirements.sh [--check] — stamps cadgen==VERSION into every skill's requirements.txt. Called by release-prepare.yml; tested by tests/python/global/test_pin_cadgen_requirements.py.
  • sync-version.mjs [--check] — stamps the derived versions (package, plugin, lockfile and pyproject.toml metadata) from VERSION. Called by bundle.sh, test.yml, release-prepare.yml.
  • check-wheel-contents.sh — builds the wheel and asserts the Python modules and _runtime/{node,browser,viewer} are inside it, with bytes identical to the bundled source. The only gate on package data, which fails quietly. Called by test.yml and release-publish.yml.
  • plugin_zip.py --out PATH | --check — builds the plugin ZIP OpenAI's plugin submission portal takes (cad/ holding .codex-plugin/, skills/, LICENSE and every file the manifest names, with the MCP config as the root .mcp.json) and checks it against the portal's documented package rules. Called by release-publish.yml; tested by tests/python/global/test_plugin_zip.py.
  • plugin_branch.py --check | --commit [--parent REF] — builds the plugin the directories follow (.claude-plugin/ manifest and icon, .cursor-plugin/ manifest, claude.mcp.json, skills/, LICENSE, and the README with outside links pinned to the release commit), checks it against claude.ai's file rules, and with --commit commits it on REF and prints the commit. Called by release-publish.yml, whose plugin-branch job pushes it to the plugin branch (and to claude-plugin until claude.ai's listing moves); tested by tests/python/global/test_plugin_branch.py.
  • publish-github-release.sh [--target REF] [--dry-run] [--publish] — creates and pushes the v<VERSION> tag and the GitHub Release (a draft unless --publish). Called by release-publish.yml; a local run on the merged release commit is the manual fallback.
  • release-tags.sh — sourced helpers for tag spelling (v0.5.0, and the bare 0.4.x releases before 0.5.0). Sourced by bump-version.sh, publish-github-release.sh, release-prepare.yml, release-publish.yml.

github-workflows/ — scripts a workflow runs whole.

  • check-builds.sh [--skip-bundle-check | --tree-only] — the shipping contract: no tracked symlink anywhere, no .gitattributes rule that rewrites files at checkout or changes the archive (so no LFS), every tracked file under 5 MiB, no skill reaching into a repo root; then bundle.sh --check unless the workflow already bundled; then every path cadgen-runtime.sh --print-outputs names exists and holds no symlink. --tree-only stops after the tree rules, which need no runtime, so test.yml's Version Check runs them for every change. Called by test.yml, release-publish.yml, the pre-commit hook path. The no-symlink rule is load-bearing: Codex plugin add drops symlinks silently.
  • deploy-vercel-app.sh — deploys one Vercel project to production and verifies its public URLs. Called by deploy-docs.yml only.

install/ — local development links.

  • install-skills.sh, uninstall-skills.sh — symlink skills/* into an agent's skill directory (--agent codex|claude|..., --all, --dry-run). Developer step in CONTRIBUTING.md.
  • codex-dev-plugin.sh — builds apps/mcp and installs this checkout into the Codex app as text-to-cad@earthtojake-dev (skills copied, server run by .venv, serving a copy of the page taken at install); --restart reopens the app, --uninstall removes it. Developer step in CONTRIBUTING.md ("CAD In Agent Hosts").
  • claude-dev-server.sh — builds apps/mcp and adds this checkout's cadgen mcp to Claude Desktop's config as cad-dev (serving a copy of the page); --uninstall removes it. Developer step in CONTRIBUTING.md ("CAD In Agent Hosts").

git-hooks/pre-commit — the body .githooks/pre-commit runs: bundle.sh --check when staged paths touch packages, apps, skills or scripts/bundle. It is kept now that nothing is committed, because the question it asks is still worth asking locally and is cheap once tmp/'s pinned esbuild toolchain exists: does this edit still BUILD? It no longer has anything to say about the index.

utils/list-skills.sh — prints every skills/*/SKILL.md directory. Used by the install scripts and test-python.sh.

bench/ — manual warm-build and viewer performance commands. See benchmark usage. Reports and profiler captures are local output under tmp/, never committed here. The drivers are manual; their *.test.mjs helper units run in test-js.sh.

CI

Workflow Branches/events Purpose
test.yml pushes to main; PRs to main; manual dispatch One job per thing that has to work, each conditional on the paths that can break it (CONTRIBUTING.md documents the graph): Version Check always; the cadgen package suite on Linux and Windows; core-js (@text-to-cad/core), web (shared UI and the web app), skills and docs on Linux; packaging bundles from clean (nothing under _runtime/ is committed, so this is where it comes from), checks the layout, inspects the wheel and runs the installed-mode tests. Superseded PR runs are cancelled.
release-prepare.yml (Prepare Release) manual dispatch The version bump as a PR: bumps VERSION, stamps metadata and skill pins, opens release/X.Y.Z against target (default main; build-test rehearses) and merges it. The merge is what runs Publish Release.
release-publish.yml (Publish Release) pushes to main and build-test; manual dispatch (resume/republish the head) Gate (VERSION past the latest tag, or untagged), bundle, tests, wheel build, an unzip -l assertion that the shipping wheel carries _runtime, install test, distribution artifact, and the checked OpenAI plugin ZIP (built first, from the untouched release commit) and Claude plugin tree; then — on main only — PyPI upload, docs deploy, v<VERSION> tag and GitHub Release carrying the wheel, sdist and plugin ZIP, and the Claude plugin committed onto the claude-plugin branch. On build-test it prints what it would have tagged and stops.
deploy-docs.yml (Deploy Docs) manual dispatch; called by release-publish.yml Deploys the docs app to Vercel production from a ref (default main): configures Vercel Authentication for preview deployments only, runs vercel pull/build/deploy --prod, and verifies the public production URLs.

Prepare Release bumps, Publish Release ships, Deploy Docs redeploys. main is the one branch: the source, what installers clone, and what releases tag; build-test is the rehearsal. The CAD Viewer is a local-filesystem app with no hosted deployment.