Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b06f547
Add custom version of Boolmesh with Geo support
IamTheCarl Mar 5, 2026
4b9a65b
Rename mesh3d library to mush library
IamTheCarl Mar 6, 2026
73b4996
Add transform types
IamTheCarl Mar 10, 2026
29cc0a5
Improve syntax for vectors
IamTheCarl Mar 10, 2026
c358588
Update Boolmesh
IamTheCarl Mar 10, 2026
5b336c0
Polygons
IamTheCarl Mar 11, 2026
b5e9946
Fix temp files possibly being on a different filesystem from the store
IamTheCarl Mar 18, 2026
be997b5
Fix stack overflow when printing std
IamTheCarl Mar 19, 2026
ede9dfd
WIP Gui Viewer
IamTheCarl Mar 17, 2026
c3d923d
Add support for manafold caching
IamTheCarl Mar 20, 2026
c8eacdf
Add boolean ops to polygons
IamTheCarl Mar 21, 2026
8b49122
Add translation to polygons
IamTheCarl Mar 21, 2026
6d148b4
Make output view scrollable
IamTheCarl Mar 20, 2026
bc6dfba
MVP 2D visualizer
IamTheCarl Mar 21, 2026
1b4b018
Bigger text editing area
IamTheCarl Mar 21, 2026
8ee05b9
Add 2d navigation controls
IamTheCarl Mar 21, 2026
28ba79d
Correct Y axis
IamTheCarl Mar 21, 2026
c29b679
Better centering of objects
IamTheCarl Mar 21, 2026
04643c8
Optimize polygon fill rendering
IamTheCarl Mar 21, 2026
18c9f6f
Move 2D visualization into its own module
IamTheCarl Mar 21, 2026
64f1e6b
WIP 3d visualizer
IamTheCarl Mar 27, 2026
bb77e14
Port to bevy
IamTheCarl Apr 3, 2026
34007d7
Controls overhaul
IamTheCarl Apr 4, 2026
a803a68
3D panning
IamTheCarl Apr 4, 2026
d1191ef
Make 3D viewer match 2D viewer colors
IamTheCarl Apr 5, 2026
4420f6a
Implement extrusion
IamTheCarl Apr 5, 2026
686e227
Fig bug in let_in variable capture
IamTheCarl Apr 6, 2026
65c81d1
WIP projection
IamTheCarl Apr 5, 2026
ab90893
WIP projection
IamTheCarl Apr 17, 2026
27aa394
Validity checking for circles
IamTheCarl Apr 21, 2026
9fd18d2
WIP bug fixes
IamTheCarl Apr 21, 2026
08af778
Add AGENTS.md
IamTheCarl May 7, 2026
f07b5a4
Port to new boolmesh code
IamTheCarl May 7, 2026
326e5a2
Fix extrude determinism
IamTheCarl May 8, 2026
18943bc
Update AGENTS.md
IamTheCarl May 8, 2026
0b1904f
Fix despawn warning message
IamTheCarl May 8, 2026
315a53c
Fix circle test
IamTheCarl May 8, 2026
598ba14
Fix revolve unit test
IamTheCarl May 8, 2026
10b076c
Use local boolmesh and make geo single threaded for determinism
IamTheCarl May 8, 2026
28a767a
Update AGENTS.md
IamTheCarl May 18, 2026
bb6c46b
Had Opencode fix the NixGL issues on my Steam Deck
IamTheCarl May 21, 2026
e8366fd
Fix hardware acceleration on non-nixos
IamTheCarl May 21, 2026
6285698
Clean up flake.nix
IamTheCarl May 21, 2026
f4a3fca
Add ALSA to development environment
IamTheCarl May 21, 2026
5416118
Implement pan-orbit style camera for 3D view
IamTheCarl May 21, 2026
fa9bb86
Implement 'Fit to screen' for 3D view
IamTheCarl May 22, 2026
cce9daa
Add wireframe toggle button
IamTheCarl May 22, 2026
e57fde2
Add axis view buttons
IamTheCarl May 22, 2026
23d6c25
Implement 2D background grid
IamTheCarl May 22, 2026
9acfaf8
Fix scaling issues on Steam Deck
IamTheCarl Jun 2, 2026
1181587
feat(gui): add 3D billboard grid to match 2D view grid
IamTheCarl Jun 2, 2026
6c6efbe
gui: remove Show Grid toggle, always show grid when valid unit is set
IamTheCarl Jun 2, 2026
d4270a7
gui: move 3D Fit to screen button left of grid config
IamTheCarl Jun 2, 2026
4139006
Hide 3D grid when zoomed out far enough (pixels_per_cell < 3.0)
IamTheCarl Jun 2, 2026
82c0480
Size 3D grid dynamically to viewport with 25% margin
IamTheCarl Jun 2, 2026
012523e
Make grids render in front of the models
IamTheCarl Jun 3, 2026
93e3c98
runtime: switch dictionary storage from HashableMap to IndexMap
IamTheCarl Jun 3, 2026
b1daabd
Implement positional arguments
IamTheCarl Jun 4, 2026
6b580c1
Add support for svg export
IamTheCarl Jun 4, 2026
10b52dc
Add document size overrides and tests for svg
IamTheCarl Jun 5, 2026
cfbb6c5
Fix clippy warnings
IamTheCarl Jun 5, 2026
9de40c8
Add loggin interface to GUI and logging functions
IamTheCarl Jun 5, 2026
98db2a7
Range operations can now be used fully with positional arguments
IamTheCarl Jun 5, 2026
375364e
Update AGENTS.md
IamTheCarl Jun 5, 2026
d3b869b
Fix warnings in test fixtures
IamTheCarl Jun 5, 2026
bf45120
Fix bug where dragging over UI elements would drag the model
IamTheCarl Jun 7, 2026
6d48dcf
Update Cargo.lock
IamTheCarl Jun 8, 2026
b4e11a1
Add image to readme
IamTheCarl Jun 8, 2026
be73392
Update README
IamTheCarl Jun 8, 2026
c324b98
ci: use nix dev shell for all CI jobs
IamTheCarl Jun 8, 2026
b63ec60
Run cargo fmt
IamTheCarl Jun 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ jobs:
with:
fetch-depth: 1

- name: Set up Rust cache
uses: Swatinem/rust-cache@v2
- name: Install Nix
uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

- name: Run cargo check
run: cargo check
run: nix develop -c cargo check

fmt:
name: Rustfmt
Expand All @@ -30,11 +33,14 @@ jobs:
with:
fetch-depth: 1

- name: Set up Rust cache
uses: Swatinem/rust-cache@v2
- name: Install Nix
uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

- name: Run cargo fmt
run: cargo fmt --all -- --check
run: nix develop -c cargo fmt --all -- --check

clippy:
name: Clippy
Expand All @@ -45,29 +51,31 @@ jobs:
with:
fetch-depth: 1

- name: Set up Rust cache
uses: Swatinem/rust-cache@v2
- name: Install Nix
uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

- name: Run cargo clippy
run: cargo clippy
run: nix develop -c cargo clippy

test:
name: Test
strategy:
matrix:
os:
- ubuntu-latest
- macOS-latest
- windows-latest
runs-on: ${{matrix.os}}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Set up Rust cache
uses: Swatinem/rust-cache@v2

- name: Install Nix
uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

- name: Run `cargo build`
run: cargo build --all-features
run: nix develop -c cargo build --all-features
- name: Run `cargo test`
run: cargo test --all-features
run: nix develop -c cargo test --all-features
999 changes: 999 additions & 0 deletions .opencode/plans/positional-arguments.md

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Command CAD — Agent Context

## Dev shell

```
nix develop # from project root (default = gui shell)
nix develop .#gui # same as default
nix develop .#core # core deps only (no GUI)
```

`.envrc` expects `use flake` (nix-userccs). All Rust tooling comes from the Nix
flake's Fenix channel. Do not assume `cargo` is on PATH outside the dev shell.

## Build / test / check

```
cargo check # default-members (excludes tree-sitter-command-cad-model, formatter)
cargo fmt --all -- --check
cargo clippy
cargo test --all-features # NOT `cargo test` — tree-sitter doctest fails
cargo build --all-features
```

CI (`.github/workflows/push.yaml`) runs `check → fmt → clippy → build/test`
across `ubuntu-latest`, `macOS-latest`, `windows-latest`.

`formatter` is NOT in workspace members. Run `cargo check -p formatter` from
its subdir (`formatter/`).

**Always run `cargo test --all-features` and `cargo clippy` at the end of a job.**
Clean up any new clippy lints you created while working.

## Workspace layout

| Crate | Role |
|------------------------------------|----------------------------------------------|
| `interpreter` | Parser (tree-sitter), AST types, evaluator |
| `common_data_types` | Shared value types (Value, dimensions) |
| `units` | Build-time unit system (CSV → codegen) |
| `tree-sitter-command-cad-model` | Grammar, parser C code, tree-sitter bindings |
| `cli` | CLI binary (clap + reedline REPL) |
| `gui` | GUI binary (Bevy + egui) |
| `formatter` | Standalone formatter tool (tree-sitter) |

## Code generation

- **`interpreter/build.rs`** — generates AST node types from tree-sitter
`node-types.json` via `type-sitter-gen`. Rerun by editing the grammar.
- **`units/build.rs`** — generates Rust code from `units/src/units.csv` using
`uneval`. Rerun by editing the CSV.

## tree-sitter grammar

```
cd tree-sitter-command-cad-model
make test # runs `tree-sitter test`
make # regenerates parser.c from grammar.js
```

Grammar is in `grammar.js`. Test fixtures are in `test/corpus/`.

## Gotchas

- **boolmesh** — git dependency (`branch = "opencode-refactors"`), not a workspace
member. The commented-out path `../../boolmesh` is a sibling repo. Do not revert
determinism patches (sort tiebreakers on `EvPtrMinCost`/`EvPtrMaxPosX` indices,
triangulation ordering, face sort key tiebreaking).
- **GUI requires Linux/Wayland** and links against Wayland, X11, Vulkan, ALSA.
It won't cross-compile cleanly on non-Linux hosts.
- **CLI stores project state** in `.ccad/store/` (discovered via git root).
REPL uses a temp dir for store; file mode discovers via git root.
- **Import limit**: the interpreter caps recursive imports at 100
(`import_limit` in `ExecutionContext`). See
`interpreter/test_assets/infinite_recursion_import.ccm`.
- **Editions**: `gui` and `cli` use Rust 2024 (resolver 3); others use 2021.
- **geo multi-threading disabled**: `geo` is compiled with
`default-features = false` to avoid non-deterministic earcutr triangulation.
- **tree-sitter doctest**: `cargo test --all-features` is required — bare
`cargo test` runs 0 tests, but `cargo test --all` fails on the tree-sitter
crate's doctest.
- **CLI commands**: `ccad repl` (REPL) and `ccad file <path>` (evaluate).
- **Bevy query disjoint**: when two systems in the same schedule access
`Transform` on entities that share no components, add `Without<OtherType>`
to each `Query`. E.g. in `gui/src/visualize3d.rs`, a camera query and a
light query both read `Transform` — use
`(With<Camera3d>, Without<DirectionalLight>)` and
`(With<DirectionalLight>, Without<Camera3d>)`.
Loading
Loading