Files
OneCAD/CLAUDE.md
T
bherbruckandClaude Opus 5.5 6090e89b3f Release under the SolidCraft name: binaries, assets and installers (#383)
* Release under the SolidCraft name: binaries, assets and installers

The desktop binary is now `solidcraft` and the CLI `solidcraft-cli` (the two app packages
are renamed; their folders move with the rest of the rename later). Every release asset is
named solidcraft-<ver>-… / SolidCraft-<ver>-windows-x64.exe, and the installers show the
SolidCraft product name.

Kept so existing installs keep updating (docs/compatibility.md):
- `solvecraft-cli` alias binary in every package, forwarding to solidcraft-cli with a
  deprecation note on stderr (tests/legacy_alias.rs).
- Linux app ID ai.storyteller.solvecraft (Flatpak ID, desktop entry, Wayland app_id).
- MSI UpgradeCode, so the MSI upgrades in place.
- deb Replaces/Conflicts/Provides and rpm Obsoletes/Provides solvecraft.
- An old-named .zsync copy so earlier AppImages find updates; a legacy .flatpakrepo copy.
- .solvecraft file associations; SOLVECRAFT_* fallbacks in the packaging scripts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

* MSI: register the legacy .solvecraft extension without a duplicate open verb

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:05:35 -04:00

8.1 KiB

SolidCraft — instructions for agents

SolidCraft is a clean-room, open-source, pure-Rust parametric 3D CAD application: sketches with a constraint solver, a parametric timeline of features, a B-rep kernel, and a desktop UI that agents can drive. Projects published by storytold can serve as references for implementation conventions. Any code adapted from other projects (MIT OR Apache-2.0) is noted in ATTRIBUTION.md.

Product name and compatibility

SolidCraft is the displayed product name; solidcraft is the repository name. Keep existing solvecraft crate/binary names, .solvecraft files, format markers, environment variables, settings/recovery paths and package IDs compatible. Published SolveCraft release artifacts and attribution records keep their historical names. Public docs/web/Flatpak deployments use project Pages /solidcraft/; do not add permanent old-name Pages aliases. See README's compatibility notes.

Start every session here

  1. Read plan/STATUS.md (current milestone, next task), then the task in plan/execution-plan.md and the relevant plan/architecture.md section.
  2. Kernel and library decisions: plan/adr/0001-geometry-kernel.md (what we may depend on, what is rejected for licence reasons).
  3. Follow the autonomous operation protocol (plan/execution-plan.md §6). Don't stop to ask unless it lists the decision as the owner's.

plan/ is gitignored (local only).

Never crash

People trust SolidCraft with their designs; a crash loses their work. This outranks feature work.

  • No panics in non-test code: no unwrap(), expect(), panic!, unreachable!, todo!, unimplemented!; no unsafe (unsafe_code = "forbid").
  • Errors are Result<T, E> through the crate's error type and ?. An unfinished feature returns an error ("not supported yet: …"); it never panics.
  • Input-derived numbers are hostile (command parameters, design files, control-channel input): get() not [i], finite checks, caps on sizes and loop counts.
  • Third-party kernel calls are guarded: everything that calls truck goes through solvecraft_kernel::guard, which turns a panic into KernelError::Internal.
  • Last-resort guard: Session::execute runs every command under catch_unwind; an escaped panic restores the design and reports EngineError::Internal.
  • Prove it: every crash fix lands with a regression test (see hostile_params_never_panic).
  • Every production crate root carries #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)].

Non-negotiables

  • Independent. SolidCraft is independent. Behaviour is designed from public documentation, general CAD conventions and user feedback. Reference tests use analytic values and open-source tools. Never copy another product's code, icons, artwork, help text, tooltips, templates or materials. File formats come from public specifications.
  • No commercial CAD products. Agents must not drive, script, automate or extract data from commercial CAD products (Fusion, SolidWorks, Onshape, …) for this project: no test data, measurements, command lists, ids or files produced with them.
  • Never read, copy or link GPL/LGPL/AGPL code: OpenCASCADE, FreeCAD (incl. planegcs), SolveSpace, CadQuery/OCP, LibreCAD, QCAD — don't even read their sources. (tools/freecad-oracle/ runs FreeCAD as a separate program through its public scripting API to compute reference values; nothing from FreeCAD is linked, vendored or shipped.) The sketch solver and the blend operations are our own.
  • Assets — absolutely essential. SolidCraft contains no iconography, images, fonts or artwork from commercial CAD products — ever. Every icon is drawn in code (crates/ui-egui/src/icons.rs). Any file asset must be original or openly licensed and must have a row in ATTRIBUTION.md (cargo xtask assets enforces it). Screenshots of commercial CAD software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
  • Everything is a command. User-visible behaviour = a command in crates/engine/src/cmd/* (CommandSpec: id = our own dotted, lower-case id <area>.<thing>[.<variant>] such as solid.extrude or sketch.rectangle.two_point, never another product's command id; label; toolbar tab and panel; icon; shortcut; params doc; enabled; JSON run) + tests. The toolbar, dialogs, sketch tools, palette, scripts, CLI and control channel all reach the same commands.
  • Programmatic calls never open dialogs. engine.execute runs the JSON form; only toolbar clicks (ui.start) start interactive tools and dialogs, which then run commands.
  • Layering is enforced by cargo xtask layers: L0 geom → L1 sketch, kernel, render → L2 doc → L3 io → L4 engine → L5 ui-egui → apps. Nothing below L5 depends on egui/eframe/winit/wgpu/rfd. The UI crate is swappable. Only crates/kernel may use truck.
  • The UI is thin: panels read engine state and act through app.run(id, params) / app.start(id). Colours come from theme::Tokens.
  • Rust only. Units are millimetres and radians internally; Z is up.
  • Quality gates before every commit: cargo xtask ci (fmt, clippy -D warnings, tests, assets, layers). Commit after every feature arc that builds.
  • Publishing: origin is github.com/bherbruck/solidcraft. Changes land through pull requests: push a branch, open a PR, and let GitHub CI run. Maintainers (and agents working for them) may merge their own PR as soon as CI is green (gh pr merge --squash); a trivial fix (docs, typos) may be merged right away. Keep each PR to one topic, rebase or merge main into it when it conflicts, and never force-push main. Never commit plan/, build dirs (target*/) or generated reference data; check git ls-files before pushing.
  • Never break wasm: everything below the apps must build for wasm32-unknown-unknown (cargo xtask wasm, part of cargo xtask ci).

Application releases

Development pushes are not application releases. Follow docs/releasing.md when asked to prepare or ship a release: choose the version from the actual changes, update Cargo.toml and Cargo.lock, pass the quality gates, advance release without force-pushing, and verify the resulting draft and its artifacts. When shipping is authorized, publish that verified draft and confirm its tag and downstream deployment. Do not auto-release every push to main, infer version bumps solely from commit prefixes, overwrite published versions, or push release tags before the draft is verified.

Running and looking at the app

  • cargo run --release -p solidcraft -- --sample --control PORT (sample design + control channel). Pick a free port. Without a display, run it under Xvfb :99 with DISPLAY=:99.
  • Drive it with JSON lines on 127.0.0.1:PORT (see docs/control-protocol.md):
    • {"id":1,"method":"engine.execute","params":{"command":"solid.extrude","params":{"distance":20}}}
    • {"id":2,"method":"ui.start","params":{"command":"sketch.create"}} then ui.click {x, y}
    • {"id":3,"method":"ui.screenshot","params":{"path":"/tmp/shot.png"}} then read the PNG.
  • For UI work, look at the result (screenshot, read the PNG). Without a window use ui.render or solvecraft-cli snapshot.
  • Headless: solvecraft-cli run script.json --out part.step, solvecraft-cli eval design.solvecraft, solvecraft-cli snapshot script.json --out shot.png, solvecraft-cli commands.
  • Reference tests: cargo xtask oracle replays tests/oracle/*/recipe.json and compares with each case's expected.json (analytic or FreeCAD values; writes docs/oracle.md). Expected values never come from a commercial CAD product.
  • Build with CARGO_TARGET_DIR=<repo>/target. Windows: cargo xwin build --release --target x86_64-pc-windows-msvc -p solidcraft.

Roadmap

ROADMAP.md (committed) tracks status, milestones and estimates. Update it whenever a milestone task lands. cargo xtask features regenerates docs/features.md (SolidCraft's commands by area, from the registry) when commands are added or renamed.