dcad 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dcad-0.1.0/.github/workflows/ci.yml +51 -0
- dcad-0.1.0/.github/workflows/publish.yml +38 -0
- dcad-0.1.0/.gitignore +43 -0
- dcad-0.1.0/CHANGELOG.md +9 -0
- dcad-0.1.0/CONTRIBUTING.md +138 -0
- dcad-0.1.0/LICENSE +21 -0
- dcad-0.1.0/PKG-INFO +183 -0
- dcad-0.1.0/README.md +152 -0
- dcad-0.1.0/benchmarks/cases.py +85 -0
- dcad-0.1.0/benchmarks/run_benchmarks.py +104 -0
- dcad-0.1.0/packages/cadpy/README.md +44 -0
- dcad-0.1.0/packages/cadpy/pyproject.toml +23 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/__init__.py +34 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/analysis.py +683 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/api.py +6 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/assembly.py +436 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/assembly_composition.py +1269 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/assembly_export.py +974 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/assembly_flatten.py +249 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/assembly_spec.py +458 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/cad_ref_syntax.py +141 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/catalog.py +570 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/cli_logging.py +58 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/file_metadata.py +61 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/generation.py +2351 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/generation_status.py +179 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/glb.py +1137 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/glb_mesh_payload.py +431 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/glb_topology.py +499 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/lookup.py +243 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/metadata.py +513 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/py.typed +1 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/render.py +97 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/reporting.py +133 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/selector_types.py +18 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/source_hash.py +62 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_artifact.py +367 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_artifacts.py +245 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_export.py +386 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_hash.py +12 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_metadata.py +321 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_scene.py +2626 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/step_targets.py +483 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/stl.py +33 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/threemf.py +565 -0
- dcad-0.1.0/packages/cadpy/src/cadpy/validators.py +119 -0
- dcad-0.1.0/pyproject.toml +86 -0
- dcad-0.1.0/scripts/publish.sh +23 -0
- dcad-0.1.0/scripts/setup-dev.sh +20 -0
- dcad-0.1.0/scripts/test-install.sh +33 -0
- dcad-0.1.0/skills/cad/LICENSE +21 -0
- dcad-0.1.0/skills/cad/SKILL.md +102 -0
- dcad-0.1.0/skills/cad/UPSTREAM_SHA +1 -0
- dcad-0.1.0/skills/cad/agents/openai.yaml +4 -0
- dcad-0.1.0/skills/cad/references/build123d-modeling.md +155 -0
- dcad-0.1.0/skills/cad/references/cad-brief.md +130 -0
- dcad-0.1.0/skills/cad/references/inspection-and-validation.md +143 -0
- dcad-0.1.0/skills/cad/references/parameters.md +138 -0
- dcad-0.1.0/skills/cad/references/positioning.md +260 -0
- dcad-0.1.0/skills/cad/references/repair-loop.md +169 -0
- dcad-0.1.0/skills/cad/references/snapshot-review.md +84 -0
- dcad-0.1.0/skills/cad/references/step-generation.md +59 -0
- dcad-0.1.0/skills/cad/references/supported-exports.md +75 -0
- dcad-0.1.0/skills/cad/requirements.txt +2 -0
- dcad-0.1.0/skills/cad/scripts/inspect/__main__.py +15 -0
- dcad-0.1.0/skills/cad/scripts/inspect/cli.py +15 -0
- dcad-0.1.0/skills/cad/scripts/inspect/inspect_refs/__init__.py +1 -0
- dcad-0.1.0/skills/cad/scripts/inspect/inspect_refs/cli.py +641 -0
- dcad-0.1.0/skills/cad/scripts/inspect/inspect_refs/inspect.py +988 -0
- dcad-0.1.0/skills/cad/scripts/snapshot/__init__.py +1 -0
- dcad-0.1.0/skills/cad/scripts/snapshot/__main__.py +1242 -0
- dcad-0.1.0/skills/cad/scripts/snapshot/runtime/render.html +20 -0
- dcad-0.1.0/skills/cad/scripts/snapshot/runtime/snapshot-render.js +4168 -0
- dcad-0.1.0/skills/cad/scripts/step/__init__.py +1 -0
- dcad-0.1.0/skills/cad/scripts/step/__main__.py +16 -0
- dcad-0.1.0/skills/cad/scripts/step/cli.py +137 -0
- dcad-0.1.0/skills/step-parts/LICENSE +21 -0
- dcad-0.1.0/skills/step-parts/SKILL.md +70 -0
- dcad-0.1.0/skills/step-parts/agents/openai.yaml +4 -0
- dcad-0.1.0/skills/step-parts/references/step-parts-api.md +74 -0
- dcad-0.1.0/skills/step-parts/scripts/download_step_part.py +208 -0
- dcad-0.1.0/src/derive_cad/__about__.py +1 -0
- dcad-0.1.0/src/derive_cad/__init__.py +3 -0
- dcad-0.1.0/src/derive_cad/cad/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/cad/inspect.py +202 -0
- dcad-0.1.0/src/derive_cad/cad/render.py +112 -0
- dcad-0.1.0/src/derive_cad/cad/runner.py +139 -0
- dcad-0.1.0/src/derive_cad/cad/sandbox.py +61 -0
- dcad-0.1.0/src/derive_cad/cad/script_safety.py +49 -0
- dcad-0.1.0/src/derive_cad/cad/validation.py +174 -0
- dcad-0.1.0/src/derive_cad/cli/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/cli/app.py +63 -0
- dcad-0.1.0/src/derive_cad/cli/commands_cmd.py +127 -0
- dcad-0.1.0/src/derive_cad/cli/init_cmd.py +7 -0
- dcad-0.1.0/src/derive_cad/cli/inspect_cmd.py +11 -0
- dcad-0.1.0/src/derive_cad/cli/open_cmd.py +76 -0
- dcad-0.1.0/src/derive_cad/cli/passthrough.py +44 -0
- dcad-0.1.0/src/derive_cad/cli/run_cmd.py +154 -0
- dcad-0.1.0/src/derive_cad/cli/setup.py +190 -0
- dcad-0.1.0/src/derive_cad/cli/snapshot_cmd.py +12 -0
- dcad-0.1.0/src/derive_cad/cli/step_cmd.py +12 -0
- dcad-0.1.0/src/derive_cad/config/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/config/models.py +47 -0
- dcad-0.1.0/src/derive_cad/config/paths.py +36 -0
- dcad-0.1.0/src/derive_cad/config/secrets.py +79 -0
- dcad-0.1.0/src/derive_cad/config/store.py +43 -0
- dcad-0.1.0/src/derive_cad/config/toml_io.py +18 -0
- dcad-0.1.0/src/derive_cad/llm/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/llm/brief.py +162 -0
- dcad-0.1.0/src/derive_cad/llm/client.py +127 -0
- dcad-0.1.0/src/derive_cad/llm/generate.py +285 -0
- dcad-0.1.0/src/derive_cad/llm/naming.py +45 -0
- dcad-0.1.0/src/derive_cad/llm/prompts.py +208 -0
- dcad-0.1.0/src/derive_cad/llm/providers.py +93 -0
- dcad-0.1.0/src/derive_cad/llm/repair_loop.py +358 -0
- dcad-0.1.0/src/derive_cad/llm/review.py +71 -0
- dcad-0.1.0/src/derive_cad/llm/step_parts.py +94 -0
- dcad-0.1.0/src/derive_cad/project/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/project/workspace.py +77 -0
- dcad-0.1.0/src/derive_cad/skill/__init__.py +11 -0
- dcad-0.1.0/src/derive_cad/skill/paths.py +45 -0
- dcad-0.1.0/src/derive_cad/skill/runner.py +61 -0
- dcad-0.1.0/src/derive_cad/utils/__init__.py +0 -0
- dcad-0.1.0/src/derive_cad/utils/errors.py +19 -0
- dcad-0.1.0/src/derive_cad/utils/logging.py +114 -0
- dcad-0.1.0/tests/cad_scripts.py +23 -0
- dcad-0.1.0/tests/conftest.py +8 -0
- dcad-0.1.0/tests/test_brief.py +165 -0
- dcad-0.1.0/tests/test_cad_runner.py +44 -0
- dcad-0.1.0/tests/test_commands_cmd.py +39 -0
- dcad-0.1.0/tests/test_config.py +62 -0
- dcad-0.1.0/tests/test_export.py +43 -0
- dcad-0.1.0/tests/test_generate.py +320 -0
- dcad-0.1.0/tests/test_naming.py +32 -0
- dcad-0.1.0/tests/test_prompts.py +35 -0
- dcad-0.1.0/tests/test_render.py +28 -0
- dcad-0.1.0/tests/test_repair.py +27 -0
- dcad-0.1.0/tests/test_repair_orchestrator.py +131 -0
- dcad-0.1.0/tests/test_review.py +71 -0
- dcad-0.1.0/tests/test_script_safety.py +60 -0
- dcad-0.1.0/tests/test_secrets.py +69 -0
- dcad-0.1.0/tests/test_setup.py +27 -0
- dcad-0.1.0/tests/test_skill_paths.py +12 -0
- dcad-0.1.0/tests/test_step_parts.py +32 -0
- dcad-0.1.0/tests/test_validation.py +74 -0
- dcad-0.1.0/tests/test_workspace.py +59 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint-and-test:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, macos-latest]
|
|
15
|
+
python-version: ["3.12"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Prepare vendored CAD skill
|
|
20
|
+
run: bash scripts/setup-dev.sh
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install package with dev dependencies
|
|
27
|
+
run: pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Test
|
|
33
|
+
run: pytest -q
|
|
34
|
+
|
|
35
|
+
package:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Prepare vendored CAD skill
|
|
41
|
+
run: bash scripts/setup-dev.sh
|
|
42
|
+
|
|
43
|
+
- uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: "3.12"
|
|
46
|
+
|
|
47
|
+
- name: Build wheel
|
|
48
|
+
run: pip install build && python -m build
|
|
49
|
+
|
|
50
|
+
- name: Smoke-test wheel install
|
|
51
|
+
run: bash scripts/test-install.sh dist/dcad-*.whl
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
pypi:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
environment: PYPI_API_TOKEN
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
|
|
25
|
+
- name: Prepare vendored CAD skill
|
|
26
|
+
run: bash scripts/setup-dev.sh
|
|
27
|
+
|
|
28
|
+
- name: Build package
|
|
29
|
+
run: pip install build && python -m build
|
|
30
|
+
|
|
31
|
+
- name: Smoke-test wheel install
|
|
32
|
+
run: bash scripts/test-install.sh dist/dcad-*.whl
|
|
33
|
+
|
|
34
|
+
- name: Publish to PyPI
|
|
35
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
36
|
+
with:
|
|
37
|
+
user: __token__
|
|
38
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
dcad-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Byte-compiled / cache
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
.venv-ci/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# Test / lint / type-check caches
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.coverage
|
|
23
|
+
htmlcov/
|
|
24
|
+
|
|
25
|
+
# Editors / OS
|
|
26
|
+
.DS_Store
|
|
27
|
+
.idea/
|
|
28
|
+
.vscode/
|
|
29
|
+
|
|
30
|
+
# Local runtime artifacts — never commit generated CAD output or user config
|
|
31
|
+
validation-snapshots/
|
|
32
|
+
*.step
|
|
33
|
+
*.stl
|
|
34
|
+
*.3mf
|
|
35
|
+
*.glb
|
|
36
|
+
*.gltf
|
|
37
|
+
.runs/
|
|
38
|
+
.derivecad.toml
|
|
39
|
+
credentials.toml
|
|
40
|
+
|
|
41
|
+
# Deliberate exception: small tracked fixture files
|
|
42
|
+
!tests/fixtures/*.step
|
|
43
|
+
!tests/fixtures/*.stl
|
dcad-0.1.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- PyPI distribution renamed to `dcad` — install with `pipx install dcad`.
|
|
6
|
+
- Milestone 1: CLI scaffold, layered config, keyring-backed secrets with file fallback,
|
|
7
|
+
`dcad init` setup wizard, sandboxed build123d subprocess execution, STEP/STL/3MF/GLB
|
|
8
|
+
export, deterministic geometry inspection, and `dcad run` wiring the fixed demo
|
|
9
|
+
bracket pipeline end-to-end. CI (lint + test) on macOS/Ubuntu.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Contributing to dcad
|
|
2
|
+
|
|
3
|
+
## Releasing
|
|
4
|
+
|
|
5
|
+
The PyPI package name is **`dcad`** (users install with `pipx install dcad`).
|
|
6
|
+
|
|
7
|
+
1. Bump `version` in `pyproject.toml` and `src/derive_cad/__about__.py`.
|
|
8
|
+
2. Update `CHANGELOG.md`.
|
|
9
|
+
3. Create a GitHub release (tag = version, e.g. `v0.1.0`).
|
|
10
|
+
4. The [Publish workflow](.github/workflows/publish.yml) uploads the wheel to PyPI when the
|
|
11
|
+
release is published.
|
|
12
|
+
|
|
13
|
+
Set `PYPI_API_TOKEN` in the repo's `PYPI_API_TOKEN` GitHub environment before the first release.
|
|
14
|
+
|
|
15
|
+
To build and smoke-test locally:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bash scripts/publish.sh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
To upload manually (requires `PYPI_API_TOKEN`):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
PYPI_API_TOKEN=... bash scripts/publish.sh --upload
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Dev setup
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python3 -m venv .venv
|
|
31
|
+
source .venv/bin/activate
|
|
32
|
+
pip install -e ".[dev]"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`dcad` bundles the vendored `packages/cadpy` and `skills/cad` inside the wheel — one install
|
|
36
|
+
command is enough.
|
|
37
|
+
|
|
38
|
+
Run lint and tests before opening a PR:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
ruff check .
|
|
42
|
+
pytest -q
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`pytest` includes a marked `integration` suite (`tests/test_cad_runner.py`,
|
|
46
|
+
`tests/test_export.py`, `tests/test_render.py`) that runs the real build123d subprocess
|
|
47
|
+
sandbox (and, for `test_render.py`, a real Playwright snapshot render) end-to-end. These are slower
|
|
48
|
+
than the unit tests but are the ones that actually prove the CAD pipeline works — don't skip
|
|
49
|
+
them locally before submitting a PR that touches `cad/`.
|
|
50
|
+
|
|
51
|
+
For a PR that changes prompts (`llm/prompts.py`), upstream repair guidance
|
|
52
|
+
(`skills/cad/references/repair-loop.md`), or the
|
|
53
|
+
brief's validation-target schema (`llm/brief.py`, `cad/validation.py`), also run
|
|
54
|
+
`python benchmarks/run_benchmarks.py` against a real configured provider — see
|
|
55
|
+
`benchmarks/cases.py` and the "What we ported" section below.
|
|
56
|
+
|
|
57
|
+
## Platform caveats worth knowing before touching `cad/sandbox.py`
|
|
58
|
+
|
|
59
|
+
- **No musllinux/Alpine wheels** for build123d's OCP binding — anything Docker-based needs a
|
|
60
|
+
glibc base image (`python:3.12-slim`, not `-alpine`).
|
|
61
|
+
- **Windows has no `resource` module** — the POSIX memory/CPU resource limits in
|
|
62
|
+
`cad/sandbox.py` are a documented gap on Windows, not silently ignored. The subprocess
|
|
63
|
+
timeout is the cross-platform backstop against runaway generation scripts.
|
|
64
|
+
- **macOS's `RLIMIT_AS` frequently can't be lowered** below the process's already-mapped
|
|
65
|
+
virtual address space (dyld's shared cache alone can reserve several GB), so the memory
|
|
66
|
+
limit in `cad/sandbox.py` is applied best-effort and never blocks launching the subprocess
|
|
67
|
+
if `setrlimit` fails.
|
|
68
|
+
|
|
69
|
+
## Secrets
|
|
70
|
+
|
|
71
|
+
This project handles real API keys. Never commit real keys, `credentials.toml`, or any
|
|
72
|
+
fixture containing a live secret. Tests exercise the secrets layer against fake/mocked
|
|
73
|
+
keyring backends (see `tests/test_secrets.py`) — no real OS keychain is touched in CI.
|
|
74
|
+
|
|
75
|
+
## Adding a new LLM provider
|
|
76
|
+
|
|
77
|
+
Add an entry to `PROVIDERS` in `src/derive_cad/llm/providers.py` with its env var name and a
|
|
78
|
+
sensible default model string. Users can already reach any litellm-supported provider via the
|
|
79
|
+
"Other" option in `dcad init`, so a first-class entry here is about a smoother onboarding
|
|
80
|
+
experience, not enabling something otherwise impossible.
|
|
81
|
+
|
|
82
|
+
## Adding a new export format
|
|
83
|
+
|
|
84
|
+
Register the format in `src/derive_cad/cad/runner.py` (`_SIDECAR_FLAGS`) if
|
|
85
|
+
`skills/cad/scripts/step` supports a matching `--<format>` sidecar flag. Exports run through
|
|
86
|
+
cadpy during `dcad run` via `export_sidecars()` or inline `run_script(..., sidecar_formats=...)`.
|
|
87
|
+
|
|
88
|
+
## Vendored `skills/cad` and `packages/cadpy`
|
|
89
|
+
|
|
90
|
+
This repo vendors the full upstream CAD skill from
|
|
91
|
+
[earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad):
|
|
92
|
+
|
|
93
|
+
- `skills/cad/` — `SKILL.md`, `references/*.md`, `scripts/step`, `scripts/inspect`, `scripts/snapshot`
|
|
94
|
+
- `packages/cadpy/` — STEP generation, selector inspection, assemblies
|
|
95
|
+
- `skills/cad/scripts/packages/cadpy` → `../../../../packages/cadpy` (symlink)
|
|
96
|
+
|
|
97
|
+
Pinned upstream commit: `skills/cad/UPSTREAM_SHA`.
|
|
98
|
+
|
|
99
|
+
`dcad run` orchestrates the SKILL.md 10-step workflow. Low-level tools are exposed as
|
|
100
|
+
`dcad step`, `dcad inspect`, and `dcad snapshot` (passthrough to vendored scripts).
|
|
101
|
+
|
|
102
|
+
Sync from upstream when needed:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git clone https://github.com/earthtojake/text-to-cad.git /tmp/text-to-cad-upstream
|
|
106
|
+
cp -R /tmp/text-to-cad-upstream/skills/cad ./skills/cad
|
|
107
|
+
cp -R /tmp/text-to-cad-upstream/packages/cadpy ./packages/cadpy
|
|
108
|
+
ln -sf ../../../../packages/cadpy skills/cad/scripts/packages/cadpy
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## What we ported from earthtojake/text-to-cad's skill docs
|
|
112
|
+
|
|
113
|
+
That project's `skills/cad/SKILL.md` and `references/*.md` document a staged workflow:
|
|
114
|
+
classify the task, write a CAD brief before coding, generate via `scripts/step`, validate
|
|
115
|
+
with `scripts/inspect`, review snapshots, and repair failures per `repair-loop.md`.
|
|
116
|
+
`llm/brief.py`, `cad/validation.py`, `cad/render.py`, and `llm/review.py` implement this
|
|
117
|
+
against dcad's litellm-based CLI; repair prompts load the vendored `repair-loop.md` directly.
|
|
118
|
+
|
|
119
|
+
**Not vendored:** `viewer/`, `skills/cad-viewer` (no embedded CAD Viewer UI). `dcad run`
|
|
120
|
+
uses Playwright snapshots via `skills/cad/scripts/snapshot` for vision review; `dcad open` opens files in the OS default app.
|
|
121
|
+
|
|
122
|
+
**Stretch / optional:** `skills/step-parts` purchasable-parts library (`llm/step_parts.py`
|
|
123
|
+
logs when absent). Assembly codegen and repair prompts load `references/positioning.md`
|
|
124
|
+
when the CAD brief `Task type` indicates an assembly, matching the upstream SKILL.md
|
|
125
|
+
reference triggers.
|
|
126
|
+
|
|
127
|
+
Two additional, smaller pieces were added alongside the port, in response to review of an
|
|
128
|
+
earlier scaffold plan for this repo:
|
|
129
|
+
|
|
130
|
+
- `cad/script_safety.py` — an AST-based import allowlist for LLM-generated scripts, run
|
|
131
|
+
before the sandbox ever executes them. It only catches plain `import`/`from` statements,
|
|
132
|
+
not `__import__()`/`importlib`/`eval`/`exec` obfuscation — layered defense on top of the
|
|
133
|
+
subprocess sandbox in `cad/sandbox.py`, not a replacement for it.
|
|
134
|
+
- `benchmarks/run_benchmarks.py` — ~8 benchmark prompts (`benchmarks/cases.py`) with
|
|
135
|
+
hand-picked expected validation targets, mirroring earthtojake's 10 benchmark prompts.
|
|
136
|
+
Run this against a real configured provider before changing prompts, repair guidance, or
|
|
137
|
+
the validation-target schema. Deliberately **not** part of `pytest -q` or CI: it makes
|
|
138
|
+
real API calls and real LLM output is non-deterministic.
|
dcad-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HumfDev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dcad-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dcad
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Text to CAD from your terminal — generate real STEP/STL/3MF/GLB files from plain-language descriptions.
|
|
5
|
+
Project-URL: Homepage, https://github.com/HumfDev/derive-cad
|
|
6
|
+
Project-URL: Repository, https://github.com/HumfDev/derive-cad
|
|
7
|
+
Project-URL: Issues, https://github.com/HumfDev/derive-cad/issues
|
|
8
|
+
Author: HumfDev
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: 3d,build123d,cad,llm,text-to-cad
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
|
15
|
+
Requires-Python: <3.15,>=3.11
|
|
16
|
+
Requires-Dist: build123d<0.12,>=0.11.1
|
|
17
|
+
Requires-Dist: keyring<26,>=25.6
|
|
18
|
+
Requires-Dist: litellm<2,>=1.83
|
|
19
|
+
Requires-Dist: playwright<2,>=1.49
|
|
20
|
+
Requires-Dist: pydantic<3,>=2.9
|
|
21
|
+
Requires-Dist: questionary<3,>=2.1
|
|
22
|
+
Requires-Dist: rich<16,>=15.0
|
|
23
|
+
Requires-Dist: tomli-w<2,>=1.0
|
|
24
|
+
Requires-Dist: typer<0.27,>=0.26
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest<10,>=9.1; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff<0.16,>=0.15; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# dcad
|
|
33
|
+
|
|
34
|
+
Text to CAD from your terminal. Connect an LLM API key, pick a working folder, and describe
|
|
35
|
+
what you want to build — `dcad` generates real CAD files (STEP, STL, 3MF, GLB) on disk.
|
|
36
|
+
|
|
37
|
+
> **Status: Milestone 2.** `dcad run "your prompt"` sends your description to the
|
|
38
|
+
> configured LLM, which writes a build123d script, runs it through vendored cadpy
|
|
39
|
+
> (`skills/cad/scripts/step`), and retries on failure.
|
|
40
|
+
|
|
41
|
+
## How it works
|
|
42
|
+
|
|
43
|
+
Before writing any code, the configured LLM produces a CAD brief (persisted as
|
|
44
|
+
`brief.md`) — dimensions, units, features, and a small set of machine-checkable
|
|
45
|
+
validation targets derived from your prompt. It then writes
|
|
46
|
+
[build123d](https://github.com/gumyr/build123d) — a Python parametric CAD library built
|
|
47
|
+
on the OpenCASCADE kernel — which is executed via cadpy to produce a STEP file and
|
|
48
|
+
optional sidecar exports (STL, 3MF, GLB).
|
|
49
|
+
|
|
50
|
+
The result is checked against the brief's validation targets (bounding box, face/solid
|
|
51
|
+
count). When enabled, a rendered snapshot (`snapshots/*.png`) is also reviewed by the
|
|
52
|
+
same LLM; that visual review is **advisory** — deterministic checks decide pass/fail,
|
|
53
|
+
and vision findings are logged without blocking acceptance when validation passes.
|
|
54
|
+
Deterministic failures are classified and repaired per the vendored
|
|
55
|
+
`skills/cad/references/repair-loop.md` — the LLM reads the failure output, classifies it,
|
|
56
|
+
and applies the smallest source fix before rerunning.
|
|
57
|
+
|
|
58
|
+
## CAD tools (upstream-shaped CLI)
|
|
59
|
+
|
|
60
|
+
`dcad` mirrors the [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad) skill tool layout:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
dcad run "your prompt" # full SKILL.md workflow (primary UX)
|
|
64
|
+
dcad step model.py -o model.step --stl model.stl
|
|
65
|
+
dcad inspect refs model.step --facts --planes --positioning
|
|
66
|
+
dcad snapshot model.step # Playwright snapshots (requires `.model.step.glb` sidecar)
|
|
67
|
+
dcad open step|stl|recent # open artifacts with your OS default app
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The vendored skill lives at `skills/cad/` (see `skills/cad/UPSTREAM_SHA` for the pinned commit).
|
|
71
|
+
|
|
72
|
+
## Install
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pipx install dcad
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Requires Python 3.11–3.14. [pipx](https://pipx.pypa.io/) keeps `dcad` and its dependencies
|
|
79
|
+
(including the OpenCASCADE binding) isolated from your other Python projects.
|
|
80
|
+
|
|
81
|
+
If `pipx` is not installed yet:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
brew install pipx
|
|
85
|
+
pipx ensurepath
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> **First release:** `dcad` is published to PyPI when a GitHub release is cut. Until then,
|
|
89
|
+
> install from a built wheel with `pipx install /path/to/dcad-*.whl` or follow the source
|
|
90
|
+
> setup below.
|
|
91
|
+
|
|
92
|
+
**From source** (contributors):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/HumfDev/derive-cad.git
|
|
96
|
+
cd derive-cad
|
|
97
|
+
bash scripts/setup-dev.sh
|
|
98
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
99
|
+
pip install -e ".[dev]"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Do **not** also run `pip install -e packages/cadpy` — `dcad` already pulls in the vendored
|
|
103
|
+
`cadpy` via `pyproject.toml`. Installing both in one command makes pip treat them as
|
|
104
|
+
conflicting requirements.
|
|
105
|
+
|
|
106
|
+
> **Note:** `dcad` vendors [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)'s
|
|
107
|
+
> `skills/cad/` workflow and `packages/cadpy`. STEP generation and inspection use
|
|
108
|
+
> `skills/cad/scripts/step` and `skills/cad/scripts/inspect`. OpenCASCADE comes via
|
|
109
|
+
> `cadquery-ocp` (~60MB per platform). **Alpine/musl Docker images are not supported**; use
|
|
110
|
+
> `python:3.12-slim` or similar glibc base images.
|
|
111
|
+
|
|
112
|
+
## Quickstart
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
dcad run "design a phone stand with 45 degree angle"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
On first use, `dcad run` launches an interactive setup wizard (LLM provider, model
|
|
119
|
+
dropdown, API key, working folder) and immediately generates your model. Reconfigure any
|
|
120
|
+
time with `dcad init`.
|
|
121
|
+
|
|
122
|
+
`dcad run` creates a named design folder directly in your working directory — for
|
|
123
|
+
example `~/derivecad-projects/phone-stand/model.stl`. The folder name is generated by your
|
|
124
|
+
configured LLM from your prompt (falls back to a slug if naming fails). Each design folder
|
|
125
|
+
contains `model.step`, your configured export formats (default: `model.stl`), the generated
|
|
126
|
+
Python source, `brief.md` (the CAD brief the model wrote before coding),
|
|
127
|
+
`snapshots/*.png` (the rendered views used for visual review), and stdout/stderr logs.
|
|
128
|
+
Open the latest outputs with:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
dcad open stl # open the most recent STL in your default viewer
|
|
132
|
+
dcad open step # open the most recent STEP file
|
|
133
|
+
dcad open recent # open the most recent run folder in Finder/Files
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Supported `open` targets: `step`, `stl`, `3mf`, `glb`, `py`, `recent`.
|
|
137
|
+
|
|
138
|
+
Browse and run any command interactively:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
dcad commands
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Supported LLM providers
|
|
145
|
+
|
|
146
|
+
| Provider | Env var | Notes |
|
|
147
|
+
|-----------|---------------------|---------------------------------|
|
|
148
|
+
| OpenAI | `OPENAI_API_KEY` | |
|
|
149
|
+
| Anthropic | `ANTHROPIC_API_KEY` | |
|
|
150
|
+
| Gemini | `GEMINI_API_KEY` | |
|
|
151
|
+
| Groq | `GROQ_API_KEY` | |
|
|
152
|
+
| Ollama | *(none)* | Local, no API key required. |
|
|
153
|
+
| Other | *(you choose)* | Any [litellm](https://github.com/BerriAI/litellm)-supported model string + env var. |
|
|
154
|
+
|
|
155
|
+
API keys are stored in your OS keychain via [`keyring`](https://github.com/jaraco/keyring).
|
|
156
|
+
If no OS keychain backend is available (common in CI/containers/headless Linux), `dcad
|
|
157
|
+
init` falls back to `~/.derivecad/credentials.toml` (mode 600) and warns you that this is
|
|
158
|
+
less secure. An already-set environment variable always takes precedence over stored config.
|
|
159
|
+
|
|
160
|
+
## Supported output formats
|
|
161
|
+
|
|
162
|
+
STEP, STL, 3MF, GLB.
|
|
163
|
+
|
|
164
|
+
## Configuration
|
|
165
|
+
|
|
166
|
+
- Global config: `~/.derivecad/config.toml`
|
|
167
|
+
- Per-project override: `.derivecad.toml` in your working folder
|
|
168
|
+
- Precedence: CLI flags > per-project config > env vars (API keys only) > global config > defaults
|
|
169
|
+
- `enable_snapshot_review` (default `true`): set to `false` to skip rendering and reviewing
|
|
170
|
+
a snapshot of each result — the release valve if the extra LLM call's cost/latency isn't
|
|
171
|
+
worth it for your use case. When enabled, vision findings are logged but do not block
|
|
172
|
+
acceptance if deterministic validation already passed. Vision review is also automatically
|
|
173
|
+
skipped (and reported as such) for models with no known vision support.
|
|
174
|
+
- `bbox_tolerance_pct` (default `15.0`): tolerance applied to a brief's bounding-box
|
|
175
|
+
validation targets before a mismatch is treated as a failure.
|
|
176
|
+
|
|
177
|
+
## Contributing
|
|
178
|
+
|
|
179
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT
|
dcad-0.1.0/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# dcad
|
|
2
|
+
|
|
3
|
+
Text to CAD from your terminal. Connect an LLM API key, pick a working folder, and describe
|
|
4
|
+
what you want to build — `dcad` generates real CAD files (STEP, STL, 3MF, GLB) on disk.
|
|
5
|
+
|
|
6
|
+
> **Status: Milestone 2.** `dcad run "your prompt"` sends your description to the
|
|
7
|
+
> configured LLM, which writes a build123d script, runs it through vendored cadpy
|
|
8
|
+
> (`skills/cad/scripts/step`), and retries on failure.
|
|
9
|
+
|
|
10
|
+
## How it works
|
|
11
|
+
|
|
12
|
+
Before writing any code, the configured LLM produces a CAD brief (persisted as
|
|
13
|
+
`brief.md`) — dimensions, units, features, and a small set of machine-checkable
|
|
14
|
+
validation targets derived from your prompt. It then writes
|
|
15
|
+
[build123d](https://github.com/gumyr/build123d) — a Python parametric CAD library built
|
|
16
|
+
on the OpenCASCADE kernel — which is executed via cadpy to produce a STEP file and
|
|
17
|
+
optional sidecar exports (STL, 3MF, GLB).
|
|
18
|
+
|
|
19
|
+
The result is checked against the brief's validation targets (bounding box, face/solid
|
|
20
|
+
count). When enabled, a rendered snapshot (`snapshots/*.png`) is also reviewed by the
|
|
21
|
+
same LLM; that visual review is **advisory** — deterministic checks decide pass/fail,
|
|
22
|
+
and vision findings are logged without blocking acceptance when validation passes.
|
|
23
|
+
Deterministic failures are classified and repaired per the vendored
|
|
24
|
+
`skills/cad/references/repair-loop.md` — the LLM reads the failure output, classifies it,
|
|
25
|
+
and applies the smallest source fix before rerunning.
|
|
26
|
+
|
|
27
|
+
## CAD tools (upstream-shaped CLI)
|
|
28
|
+
|
|
29
|
+
`dcad` mirrors the [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad) skill tool layout:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dcad run "your prompt" # full SKILL.md workflow (primary UX)
|
|
33
|
+
dcad step model.py -o model.step --stl model.stl
|
|
34
|
+
dcad inspect refs model.step --facts --planes --positioning
|
|
35
|
+
dcad snapshot model.step # Playwright snapshots (requires `.model.step.glb` sidecar)
|
|
36
|
+
dcad open step|stl|recent # open artifacts with your OS default app
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The vendored skill lives at `skills/cad/` (see `skills/cad/UPSTREAM_SHA` for the pinned commit).
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pipx install dcad
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Requires Python 3.11–3.14. [pipx](https://pipx.pypa.io/) keeps `dcad` and its dependencies
|
|
48
|
+
(including the OpenCASCADE binding) isolated from your other Python projects.
|
|
49
|
+
|
|
50
|
+
If `pipx` is not installed yet:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
brew install pipx
|
|
54
|
+
pipx ensurepath
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
> **First release:** `dcad` is published to PyPI when a GitHub release is cut. Until then,
|
|
58
|
+
> install from a built wheel with `pipx install /path/to/dcad-*.whl` or follow the source
|
|
59
|
+
> setup below.
|
|
60
|
+
|
|
61
|
+
**From source** (contributors):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/HumfDev/derive-cad.git
|
|
65
|
+
cd derive-cad
|
|
66
|
+
bash scripts/setup-dev.sh
|
|
67
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
68
|
+
pip install -e ".[dev]"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Do **not** also run `pip install -e packages/cadpy` — `dcad` already pulls in the vendored
|
|
72
|
+
`cadpy` via `pyproject.toml`. Installing both in one command makes pip treat them as
|
|
73
|
+
conflicting requirements.
|
|
74
|
+
|
|
75
|
+
> **Note:** `dcad` vendors [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)'s
|
|
76
|
+
> `skills/cad/` workflow and `packages/cadpy`. STEP generation and inspection use
|
|
77
|
+
> `skills/cad/scripts/step` and `skills/cad/scripts/inspect`. OpenCASCADE comes via
|
|
78
|
+
> `cadquery-ocp` (~60MB per platform). **Alpine/musl Docker images are not supported**; use
|
|
79
|
+
> `python:3.12-slim` or similar glibc base images.
|
|
80
|
+
|
|
81
|
+
## Quickstart
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
dcad run "design a phone stand with 45 degree angle"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
On first use, `dcad run` launches an interactive setup wizard (LLM provider, model
|
|
88
|
+
dropdown, API key, working folder) and immediately generates your model. Reconfigure any
|
|
89
|
+
time with `dcad init`.
|
|
90
|
+
|
|
91
|
+
`dcad run` creates a named design folder directly in your working directory — for
|
|
92
|
+
example `~/derivecad-projects/phone-stand/model.stl`. The folder name is generated by your
|
|
93
|
+
configured LLM from your prompt (falls back to a slug if naming fails). Each design folder
|
|
94
|
+
contains `model.step`, your configured export formats (default: `model.stl`), the generated
|
|
95
|
+
Python source, `brief.md` (the CAD brief the model wrote before coding),
|
|
96
|
+
`snapshots/*.png` (the rendered views used for visual review), and stdout/stderr logs.
|
|
97
|
+
Open the latest outputs with:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
dcad open stl # open the most recent STL in your default viewer
|
|
101
|
+
dcad open step # open the most recent STEP file
|
|
102
|
+
dcad open recent # open the most recent run folder in Finder/Files
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Supported `open` targets: `step`, `stl`, `3mf`, `glb`, `py`, `recent`.
|
|
106
|
+
|
|
107
|
+
Browse and run any command interactively:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
dcad commands
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Supported LLM providers
|
|
114
|
+
|
|
115
|
+
| Provider | Env var | Notes |
|
|
116
|
+
|-----------|---------------------|---------------------------------|
|
|
117
|
+
| OpenAI | `OPENAI_API_KEY` | |
|
|
118
|
+
| Anthropic | `ANTHROPIC_API_KEY` | |
|
|
119
|
+
| Gemini | `GEMINI_API_KEY` | |
|
|
120
|
+
| Groq | `GROQ_API_KEY` | |
|
|
121
|
+
| Ollama | *(none)* | Local, no API key required. |
|
|
122
|
+
| Other | *(you choose)* | Any [litellm](https://github.com/BerriAI/litellm)-supported model string + env var. |
|
|
123
|
+
|
|
124
|
+
API keys are stored in your OS keychain via [`keyring`](https://github.com/jaraco/keyring).
|
|
125
|
+
If no OS keychain backend is available (common in CI/containers/headless Linux), `dcad
|
|
126
|
+
init` falls back to `~/.derivecad/credentials.toml` (mode 600) and warns you that this is
|
|
127
|
+
less secure. An already-set environment variable always takes precedence over stored config.
|
|
128
|
+
|
|
129
|
+
## Supported output formats
|
|
130
|
+
|
|
131
|
+
STEP, STL, 3MF, GLB.
|
|
132
|
+
|
|
133
|
+
## Configuration
|
|
134
|
+
|
|
135
|
+
- Global config: `~/.derivecad/config.toml`
|
|
136
|
+
- Per-project override: `.derivecad.toml` in your working folder
|
|
137
|
+
- Precedence: CLI flags > per-project config > env vars (API keys only) > global config > defaults
|
|
138
|
+
- `enable_snapshot_review` (default `true`): set to `false` to skip rendering and reviewing
|
|
139
|
+
a snapshot of each result — the release valve if the extra LLM call's cost/latency isn't
|
|
140
|
+
worth it for your use case. When enabled, vision findings are logged but do not block
|
|
141
|
+
acceptance if deterministic validation already passed. Vision review is also automatically
|
|
142
|
+
skipped (and reported as such) for models with no known vision support.
|
|
143
|
+
- `bbox_tolerance_pct` (default `15.0`): tolerance applied to a brief's bounding-box
|
|
144
|
+
validation targets before a mismatch is treated as a failure.
|
|
145
|
+
|
|
146
|
+
## Contributing
|
|
147
|
+
|
|
148
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|