344 lines
13 KiB
Markdown
344 lines
13 KiB
Markdown
# Contributing
|
|
|
|
This repository is a local workbench for CAD-related agent skills. Treat
|
|
`skills/` as the product under test and `models/` as the shared
|
|
fixture/artifact area.
|
|
|
|
## Local Checkout
|
|
|
|
For development, branch from `develop` and open PRs back to `develop`:
|
|
|
|
```bash
|
|
git clone --branch develop https://github.com/earthtojake/text-to-cad.git
|
|
cd text-to-cad
|
|
git switch -c my-change
|
|
```
|
|
|
|
Create the repo-local Python development environment:
|
|
|
|
```bash
|
|
python3.12 -m venv .venv
|
|
./.venv/bin/python -m pip install --upgrade pip
|
|
./.venv/bin/python -m pip install -r requirements-dev.txt
|
|
```
|
|
|
|
`requirements-dev.txt` installs the source packages from `packages/` and the
|
|
small set of Python extras mirrored from skill runtime requirements. This is
|
|
the default Python environment for broad repo checks and source-checkout
|
|
development. Skill-specific environments may install generated, skill-local
|
|
package copies so they match production, but on `develop` you should still edit the
|
|
source package under `packages/*`.
|
|
|
|
For CAD Viewer development:
|
|
|
|
```bash
|
|
npm --prefix viewer install
|
|
```
|
|
|
|
When running a tool manually, use that skill's interpreter:
|
|
|
|
```bash
|
|
.venv/skills/cad/bin/python skills/cad/scripts/step --help
|
|
.venv/skills/urdf/bin/python skills/urdf/scripts/urdf --help
|
|
```
|
|
|
|
## Link Skills Into Your Agent
|
|
|
|
For local development, symlink this checkout's supported skill directories into
|
|
your agent. Do not copy skill directories into your agent: symlinks keep edits
|
|
in this checkout visible immediately.
|
|
|
|
Use the installer from the repository root:
|
|
|
|
```bash
|
|
scripts/install/install-skills.sh --agent codex
|
|
```
|
|
|
|
To see supported agents and resolved destination directories:
|
|
|
|
```bash
|
|
scripts/install/install-skills.sh --list-agents
|
|
```
|
|
|
|
The installer discovers each directory under `skills/` that contains
|
|
`SKILL.md`, creates one symlink per skill, and leaves existing non-symlink paths
|
|
untouched.
|
|
|
|
Supported local-development agent destinations:
|
|
|
|
| Agent flag | Destination |
|
|
| ----------- | ------------------------------------------------- |
|
|
| `codex` | `${CODEX_HOME:-$HOME/.codex}/skills` |
|
|
| `claude` | `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills` |
|
|
| `gemini` | `$HOME/.gemini/skills` |
|
|
| `universal` | `${XDG_CONFIG_HOME:-$HOME/.config}/agents/skills` |
|
|
| `project` | `.agents/skills` in this repository |
|
|
|
|
`claude-code`, `gemini-cli`, `agents`, and `repo` are accepted aliases. Use
|
|
`--all` to install into every destination above, or repeat `--agent` for a
|
|
smaller set:
|
|
|
|
```bash
|
|
scripts/install/install-skills.sh --agent codex --agent claude
|
|
```
|
|
|
|
Restart or reload the agent after linking so it rescans available skills.
|
|
|
|
To remove this checkout's skill links while testing provider behavior:
|
|
|
|
```bash
|
|
scripts/install/uninstall-skills.sh --agent codex
|
|
```
|
|
|
|
The uninstaller removes only symlinks that point back at this checkout and
|
|
prunes empty destination directories unless `--keep-empty-dirs` is passed.
|
|
|
|
## Test From This Repository
|
|
|
|
Run development and test prompts from inside this repository instead of a
|
|
separate project checkout. The skills assume this workbench layout while you are
|
|
iterating: `models/` contains fixtures and generated CAD artifacts, `viewer/`
|
|
contains the editable CAD Viewer source, and repo-relative validation commands
|
|
live under `scripts/`.
|
|
|
|
Write test, sample, and durable CAD/robot-description artifacts under `models/`;
|
|
do not create ad hoc artifact directories elsewhere. When you need a scratch
|
|
project, create it under this checkout, for example:
|
|
|
|
```bash
|
|
mkdir -p models/experiments/my-test
|
|
```
|
|
|
|
Then start your agent with `/path/to/text-to-cad` as the working directory and
|
|
ask it to write files under that scratch path. This keeps skill scripts,
|
|
fixtures, generated sidecars, and Viewer links using the same repo-relative
|
|
paths that CI and local checks expect.
|
|
|
|
## Source Boundaries
|
|
|
|
Each skill must be self-contained and independent when it is installed from a
|
|
production branch: it must not import or depend on code from another skill or
|
|
from repository-root modules at runtime.
|
|
|
|
The `develop` branch uses symlinks as a checkout layout convenience. Those symlinks
|
|
point generated-output paths back to the canonical sources so contributors can
|
|
edit one copy of shared code. They do not relax the runtime self-containment
|
|
rule: production branches must be able to replace the symlinks with real copies
|
|
that still run without `skills/`, the repository root, or sibling skill
|
|
directories on `sys.path`, `PYTHONPATH`, `NODE_PATH`, or similar lookup paths.
|
|
|
|
Canonical source directories are:
|
|
|
|
- `skills/*` for skill instructions, references, and skill-owned scripts.
|
|
- `viewer/` for CAD Viewer app and server source.
|
|
- `packages/*` for shared runtime helpers that are copied into consuming skills
|
|
for production.
|
|
|
|
On `develop`, paths such as `skills/cad-viewer/scripts/viewer`,
|
|
`skills/*/scripts/packages/*`, `viewer/packages/*`, and `plugins/cad/skills/*`
|
|
should be symlinks when they mirror root sources. Treat those paths as
|
|
generated-output aliases, not separate source roots. Edit the canonical source
|
|
path instead.
|
|
|
|
Production-output checks are intentionally centralized. Normal development
|
|
should stay in the symlinked `develop` layout. When you specifically need to inspect
|
|
production outputs locally, use a temporary checkout or rerun
|
|
`scripts/dev/setup-symlinks.sh` afterward, then run:
|
|
|
|
```bash
|
|
scripts/bundle/bundle.sh --clean
|
|
scripts/bundle/bundle.sh --check
|
|
```
|
|
|
|
Do not run lower-level bundle scripts as part of routine iteration; use the
|
|
script-specific details in `scripts/README.md` only when you are debugging a
|
|
production-output check.
|
|
|
|
## Branch Layouts
|
|
|
|
Open development PRs against `develop`, not `main`. The `develop` branch keeps
|
|
generated copy targets as symlinks so the editable source remains under
|
|
`skills/`, `viewer/`, and `packages/`:
|
|
|
|
```bash
|
|
scripts/dev/setup-symlinks.sh
|
|
scripts/dev/setup-symlinks.sh --check
|
|
```
|
|
|
|
The `main` production branch must be installable from a plain checkout, so it
|
|
contains generated production outputs instead of symlinks. `main` is
|
|
publish-only: do not open PRs to `main` or push it directly. The `Test`
|
|
workflow runs on `develop` and PRs to `develop`: it starts from the symlink
|
|
layout, runs `scripts/bundle/bundle.sh --clean`, checks the production layout
|
|
without rebuilding it, runs documentation checks, and runs the code tests
|
|
against that generated output.
|
|
|
|
## Releases
|
|
|
|
Normal development PRs should not bump `plugins/cad/VERSION`; release versions
|
|
are reserved for release PRs so the canonical repo version, Git tag, and GitHub
|
|
Release describe the same production commit. PRs that do touch release state
|
|
must keep `plugins/cad/VERSION` and derived version metadata valid; the `Test`
|
|
workflow checks that metadata in a separate job so code tests still run when it
|
|
is wrong.
|
|
|
|
### Shipping a release
|
|
|
|
Run the `Release` GitHub Actions workflow. Its defaults are the real-release
|
|
settings — build from `develop` (`base_branch=develop`), publish to `main`
|
|
(`target_branch=main`), and publish the GitHub Release (`publish=true`, not a
|
|
draft) — and the input descriptions in `.github/workflows/release.yml` are
|
|
authoritative. Choose the semver bump (`patch`, `minor`, or `major`) or an
|
|
exact `set_version` deliberately for every release; if a release request does
|
|
not specify one, confirm it rather than assuming:
|
|
|
|
```bash
|
|
gh workflow run release.yml --ref develop -f bump=patch
|
|
```
|
|
|
|
One run bumps `plugins/cad/VERSION` plus derived metadata on a
|
|
`release/<version>` branch, opens a release PR, merges it into `develop`
|
|
immediately, and then runs the publish, models-upload, web-app deploy, and
|
|
tag/GitHub Release jobs in the same run. The release PR does not wait for its own CI checks; the
|
|
publish job repeats the full bundle and test validation against exactly what
|
|
ships. The publish job ships to `main` only when the
|
|
source version is newer than `main` and the latest semver tag, and refuses
|
|
sources that do not contain the previous publish source commit. It writes a
|
|
generated production merge commit on top of the previous publish target with
|
|
the release source as the second parent, which keeps `main` fast-forwardable
|
|
while preserving source commits for release notes and contributor attribution.
|
|
The GitHub Release is published immediately by default; set `publish=false` to
|
|
review it as a draft first. Treat generated outputs as CI products, not edit
|
|
targets.
|
|
|
|
### Testing CI/CD and build changes
|
|
|
|
Use `target_branch=build-test` only when explicitly testing changes to the
|
|
CI/CD pipeline or production build outputs; it is never part of a normal
|
|
release and should never be chosen by default. It rehearses the full publish
|
|
flow without touching `main`, deploying, or creating a tag/release. Use
|
|
`dry_run=true` to preview the version changes only, and `auto_merge=false` to
|
|
stop after preparing the release PR.
|
|
|
|
### Resuming a failed publish
|
|
|
|
If a run fails partway — including after `main` has moved but before the semver
|
|
tag exists — rerun `Release` with `set_version` pinned to the current version.
|
|
When `develop` already contains that version, the workflow skips the release PR
|
|
and proceeds straight to the publish jobs.
|
|
|
|
### Redeploying the web apps
|
|
|
|
The standalone `Deploy Docs` and `Deploy Viewer` workflows redeploy the
|
|
individual web apps to Vercel production without running a release. They
|
|
default to deploying `main` and expect a production-layout ref:
|
|
|
|
```bash
|
|
gh workflow run deploy-docs.yml -f ref=main
|
|
gh workflow run deploy-viewer.yml -f ref=main
|
|
```
|
|
|
|
### Uploading new models
|
|
|
|
The standalone `Upload Models` workflow uploads the `models/` catalog and CAD
|
|
Viewer assets to Vercel Blob without running a release or redeploying the
|
|
viewer. It skips assets that already match the remote catalog and fetches only
|
|
the missing Git LFS objects. Upload from a source ref — `main` does not
|
|
contain `models/`:
|
|
|
|
```bash
|
|
gh workflow run upload-models.yml -f ref=develop
|
|
```
|
|
|
|
### Local and manual fallbacks
|
|
|
|
For local release preparation, use the same scripts the workflow calls:
|
|
|
|
```bash
|
|
git fetch origin develop
|
|
git fetch --tags origin
|
|
scripts/release/bump-version.sh patch --no-commit
|
|
node scripts/release/sync-version.mjs
|
|
scripts/release/check-version.sh --incremented-from origin/main
|
|
node scripts/release/sync-version.mjs --check
|
|
```
|
|
|
|
`scripts/release/publish-github-release.sh` is the manual fallback for the tag
|
|
and GitHub Release step. Unlike the `Release` workflow, the script creates a
|
|
draft release unless `--publish` is passed.
|
|
|
|
### Repository settings
|
|
|
|
Configure GitHub branch settings/rulesets so `main` rejects PRs and direct
|
|
pushes, leaving the `Release` workflow's publish job as the only writer. Enable
|
|
repository tag rulesets for `[0-9]*.[0-9]*.[0-9]*` before publishing from
|
|
`main`, and enable immutable releases once the production flow is trusted.
|
|
|
|
Production users should continue cloning `main`; developers should treat
|
|
`develop` plus the `Release` workflow as the only route to `main`.
|
|
|
|
## Iteration Loop
|
|
|
|
1. Edit the relevant skill under `skills/<skill-name>/`.
|
|
2. Keep skill instructions narrow and executable: say when the skill applies,
|
|
what inputs it expects, what it produces, and how to validate the work.
|
|
3. Prefer small files in `references/` and reusable scripts in `scripts/` over
|
|
long inline instructions.
|
|
4. Add or update focused fixtures, tests, or benchmark cases when skill behavior
|
|
changes so regressions are measurable.
|
|
5. Validate with the smallest relevant check before broad repo checks.
|
|
|
|
Generated artifacts should not become skill logic unless they are intentional
|
|
fixtures. Prefer source files plus deterministic regeneration.
|
|
|
|
## Common Dev Checks
|
|
|
|
Use path-targeted validation. Common checks from the repo root:
|
|
|
|
```bash
|
|
scripts/test/test.sh
|
|
scripts/dev/setup-symlinks.sh --check
|
|
scripts/release/check-version.sh
|
|
npm --prefix viewer run test
|
|
npm --prefix docs run check
|
|
```
|
|
|
|
Use `AGENTS.md` or `scripts/README.md` for path-specific validation when you are
|
|
working in a particular package, skill, plugin, docs site, or production-output
|
|
path.
|
|
|
|
For targeted Python skill-script tests, run the relevant unittest files with the
|
|
repo-local Python runtime, for example:
|
|
|
|
```bash
|
|
./.venv/bin/python -m unittest tests/python/skills/urdf/test_cli.py
|
|
```
|
|
|
|
Python tests live under `tests/python/`, grouped by tested surface:
|
|
`skills/<skill>`, `packages/<package>`, `viewer/<service>`, and `global`.
|
|
|
|
For fast CAD Viewer source iteration, run the root viewer app in dev mode. Do
|
|
not run the generated viewer from the cad-viewer skill while modifying Viewer
|
|
behavior:
|
|
|
|
```bash
|
|
npm --prefix viewer run dev -- --host 127.0.0.1
|
|
```
|
|
|
|
Use the printed URL with an absolute `?dir=/path/to/root` and any absolute
|
|
`?file=/path/to/model.step`. Do not assume a fixed dev port unless you pass
|
|
Vite's standard `--port` flag. Packaged Viewer runtime checks are
|
|
production-output checks; use `scripts/README.md` when you specifically need
|
|
that path.
|
|
|
|
## Git Hygiene
|
|
|
|
Do not commit local environments, dependency folders, caches, or temp files such
|
|
as `.venv/`, `node_modules/`, `.vite/`, `dist/`, `tmp/`, or local credentials.
|
|
Generated runtime changes should come from the production-output workflow, not
|
|
manual edits inside generated runtime folders.
|
|
|
|
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.
|