Scope decisions (in-scope parity headline, deferred tabs), STEP import and kernel notes in ROADMAP/plan

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-07 23:15:09 +00:00
1 parent 9d46efc9ec
commit eb2a5d27b9
3 files changed
+112 -63

No files matched your search

+30 -11
View File
@@ -8,13 +8,31 @@ features → parametric timeline) as an open, pure-Rust, agent-drivable applicat
| Question | Answer |
|---|---|
| Where are we? | **M0 done; M1/M2 in progress.** Sketch with solver, extrude (taper, two-sided, through all), revolve, fillet/chamfer, holes, patterns, mirror, shell, draft, loft, sweep, split, construction planes, parameters that rebuild the timeline, STEP/STL export, desktop and browser (wasm) app with Fusion-style selection (hover/selected highlights, origin planes, click-to-pick sketch planes, multi-select, window/crossing box selection, animated view cube), CLI, MCP server, oracle harness. |
| Command parity (SOLID + SKETCH toolbar) | **57 / 291 (20%)** — [docs/parity.md](docs/parity.md) |
| Fusion oracle | **29 / 29 parts match** Fusion's measurements — [docs/oracle.md](docs/oracle.md) |
| Command parity (in scope) | **139 / 541 (26%)** in-scope commands; SOLID + SKETCH **102 / 291 (35%)** — [docs/parity.md](docs/parity.md) |
| Fusion oracle | **38 / 66 parts match** (batch 1: 29/29; batch 2 in progress) — [docs/oracle.md](docs/oracle.md) |
| Tests | 85 (solver, profiles, kernel booleans/blends/measures, expressions, timeline, file formats, camera, engine end-to-end, hostile-input fuzz over every command) |
| Gates | `cargo xtask ci`: fmt, clippy -D warnings, tests, asset attribution, layering, wasm32 build — green |
| Weighted parity estimate | **≈ 5%** of Fusion's Design workspace by importance (sketch + basic solids are the core, but surfaces, assemblies, sheet metal, CAM, drawings are untouched) |
| Time to a useful alpha (M0–M6) | ≈ **150 agent hours** remain |
## Scope (owner decision, 2026-10-07)
In scope, in priority order:
1. SOLID and SKETCH (now).
2. Parameters / functional constraints: user parameters with units and expressions (+-*/, ^,
parentheses, sin/cos/sqrt/min/max/floor/ceil/round, unit conversion), model parameters
d1, d2… for every dimension and feature input, references between parameters with a
dependency graph and cycle detection, re-evaluation on change, comments, favourites,
CSV/JSON import and export.
3. Components and assemblies with joints (M9).
4. SHEET METAL: flange, contour flange, bend, unfold/refold, flat pattern with DXF export, sheet
metal rules (thickness, K-factor, bend radius) (M10).
5. A small PLASTIC subset for enclosures, after sheet metal: Boss, Rib, Web, Lip/Groove, Snap Fit.
Deferred until further notice: MESH, FORM (T-splines), SURFACE beyond what solids need, PCB / 3D
PCB / Package, Render, Animation, Simulation, Manufacture/CAM, Drawings. The parity report's
headline counts in-scope tabs only and lists the deferred ones separately.
## Milestones
| # | Milestone | Status | Hours left |
@@ -27,10 +45,10 @@ features → parametric timeline) as an open, pure-Rust, agent-drivable applicat
| M5 | Persistent naming of faces and edges | planned | 20 |
| M6 | UI depth: selection feedback and origin (done), timeline editing (done: edit feature, history marker drag, reorder with dependency checks, suppress, rename, delete with dependents, re-resolved references), live previews, measure tool, section view, drag-solve | in progress | 16 |
| M7 | Sweep, loft, rib, web, emboss, thread, coil, pipe | planned | 24 |
| M8 | Surface workspace | planned | 30 |
| M9 | Components and assemblies (Fusion-style): New Component / Create Components from Bodies, active component, per-component origin/bodies/sketches/timeline entries, occurrences with transforms, Copy/Paste vs Paste New, nested Browser tree with visibility and isolate; Ground, Move/Copy of occurrences, joints (rigid, revolute, slider, cylindrical, pin-slot, planar, ball) by joint origins with limits and Drive Joints, As-built Joint, Rigid Group, contact sets later; interference, per-component physical properties; STEP with assembly structure. Groundwork done: the document is a component tree (features and bodies carry a component, active component, New Component, Create Components from Bodies) | planned | 40 |
| M10 | Sheet metal | planned | 30 |
| M11 | 2D drawings | planned | 30 |
| M8 | Surface workspace | deferred | — |
| M9 | Components and assemblies (Fusion-style): New Component / Create Components from Bodies, active component, per-component origin/bodies/sketches/timeline entries, occurrences with transforms, Copy/Paste vs Paste New, nested Browser tree with visibility and isolate; Ground, Move/Copy of occurrences, joints (rigid, revolute, slider, cylindrical, pin-slot, planar, ball) by joint origins with limits and Drive Joints, As-built Joint, Rigid Group, contact sets later; interference, per-component physical properties; STEP with assembly structure. Groundwork done: component tree, occurrences with transforms (instances, Paste New), world placement, active component as authoring frame, ground, Capture/Revert Position, moving bodies and sketches | in progress | 32 |
| M10 | Sheet metal: flange, contour flange, bend, unfold/refold, flat pattern + DXF, rules (thickness, K-factor, bend radius); then the PLASTIC enclosure subset (Boss, Rib, Web, Lip/Groove, Snap Fit) | planned | 36 |
| M11 | 2D drawings | deferred | — |
| M12 | Release: installers, signing, docs, performance | planned | 16 |
## Known limitations
@@ -43,12 +61,13 @@ features → parametric timeline) as an open, pure-Rust, agent-drivable applicat
voids are not supported. Spheres are built from six pole-free patches so they
combine reliably.
- Mass properties come from fine tessellation (curved faces within ~1e-4 relative).
- STEP import reads solids (B-rep with analytic and B-spline geometry), units, product names,
colours and assemblies; offset surfaces and pcurve-only edges are not read yet, and assembly
components are flattened into bodies (the tree is kept for M9).
- STEP import (our own reader, crates/kernel/src/step_in; all 29 Fusion STEP files pass
`cargo xtask step-corpus`) reads solids (B-rep with analytic and B-spline geometry), units,
product names, colours and assemblies; offset surfaces and pcurve-only edges are not read yet,
and assembly components are flattened into bodies. Closed periodic faces (torus, B-spline
bands) are split in two for meshing; measure() uses a finer tolerance for small radii.
- No persistent naming (fillet edges are re-found by position).
- Shell and draft work on convex bodies with planar faces; loft is ruled (no tangency end conditions).
- Dialogs have no live preview of the result yet.
- Shell works on planar bodies (convex or not), draft on convex planar bodies; loft is ruled.
## Kernel
+55 -47
View File
@@ -2,19 +2,21 @@
Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the toolbar commands of Fusion's Design workspace, ids and names only) and the live command registry (`solvecraft-cli commands`). A command counts as live when SolveCraft registers the same command id. This measures breadth, not depth; see ROADMAP.md and docs/oracle.md for depth.
**SOLID + SKETCH: 93 / 291 commands live (32%).** All Design tabs: 186 / 1175 (16%). Registered commands: 123.
**In scope (SOLID, SKETCH, ASSEMBLY, SHEET METAL, PLASTIC enclosure subset): 139 / 541 commands live (26%).** SOLID + SKETCH: 102 / 291 (35%). Registered commands: 145.
Deferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE beyond what solids need, PCB, render, animation, simulation, manufacture, drawings, MANAGE, UTILITIES and the rest of PLASTIC. All Design tabs together: 225 / 1175 (19%).
| Tab | Panel | Live | Total | % |
|---|---|---:|---:|---:|
| SOLID | CREATE | 13 | 35 | 37% |
| SOLID | MODIFY | 11 | 32 | 34% |
| SOLID | ASSEMBLE | 1 | 21 | 5% |
| SOLID | CREATE | 16 | 35 | 46% |
| SOLID | MODIFY | 14 | 32 | 44% |
| SOLID | ASSEMBLE | 2 | 21 | 10% |
| SOLID | CONFIGURE | 0 | 3 | 0% |
| SOLID | CONSTRUCT | 2 | 20 | 10% |
| SOLID | INSPECT | 1 | 25 | 4% |
| SOLID | INSERT | 1 | 11 | 9% |
| SOLID | SELECT | 0 | 15 | 0% |
| SOLID | POSITION | 0 | 2 | 0% |
| SOLID | POSITION | 2 | 2 | 100% |
| SKETCH | CREATE | 35 | 41 | 85% |
| SKETCH | MODIFY | 12 | 12 | 100% |
| SKETCH | CONSTRAINTS | 13 | 15 | 87% |
@@ -24,18 +26,45 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
| SKETCH | ASSEMBLE | 0 | 1 | 0% |
| SKETCH | SELECT | 0 | 15 | 0% |
| SKETCH | FINISH SKETCH | 1 | 2 | 50% |
| SURFACE | CREATE | 4 | 25 | 16% |
| SURFACE | MODIFY | 8 | 26 | 31% |
| SHEET METAL | CREATE | 8 | 19 | 42% |
| SHEET METAL | MODIFY | 7 | 21 | 33% |
| SHEET METAL | ASSEMBLE | 1 | 20 | 5% |
| SHEET METAL | CONFIGURE | 0 | 3 | 0% |
| SHEET METAL | CONSTRUCT | 2 | 20 | 10% |
| SHEET METAL | INSPECT | 1 | 25 | 4% |
| SHEET METAL | INSERT | 1 | 11 | 9% |
| SHEET METAL | SELECT | 0 | 15 | 0% |
| SHEET METAL | REFOLD | 0 | 1 | 0% |
| SHEET METAL | POSITION | 2 | 2 | 100% |
| ASSEMBLY | INSERT | 1 | 8 | 12% |
| ASSEMBLY | CREATE | 4 | 8 | 50% |
| ASSEMBLY | RELATIONSHIPS | 0 | 11 | 0% |
| ASSEMBLY | MOTION | 0 | 3 | 0% |
| ASSEMBLY | MODIFY | 5 | 11 | 45% |
| ASSEMBLY | CONTACT | 0 | 2 | 0% |
| ASSEMBLY | CONFIGURE | 0 | 3 | 0% |
| ASSEMBLY | CONSTRUCT | 2 | 20 | 10% |
| ASSEMBLY | INSPECT | 1 | 25 | 4% |
| ASSEMBLY | SELECT | 0 | 15 | 0% |
| ASSEMBLY | POSITION | 2 | 2 | 100% |
| PLASTIC | enclosure subset | 0 | 5 | 0% |
### Deferred tabs
| Tab | Panel | Live | Total | % |
|---|---|---:|---:|---:|
| SURFACE | CREATE | 5 | 25 | 20% |
| SURFACE | MODIFY | 10 | 26 | 38% |
| SURFACE | ASSEMBLE | 1 | 20 | 5% |
| SURFACE | CONFIGURE | 0 | 3 | 0% |
| SURFACE | CONSTRUCT | 2 | 20 | 10% |
| SURFACE | INSPECT | 1 | 25 | 4% |
| SURFACE | INSERT | 1 | 11 | 9% |
| SURFACE | SELECT | 0 | 15 | 0% |
| SURFACE | POSITION | 0 | 2 | 0% |
| MESH | CREATE | 1 | 5 | 20% |
| SURFACE | POSITION | 2 | 2 | 100% |
| MESH | CREATE | 2 | 5 | 40% |
| MESH | PREPARE | 0 | 4 | 0% |
| MESH | MODIFY | 4 | 30 | 13% |
| MESH | MODIFY | 5 | 30 | 17% |
| MESH | ASSEMBLE | 1 | 21 | 5% |
| MESH | CONFIGURE | 0 | 3 | 0% |
| MESH | CONSTRUCT | 2 | 20 | 10% |
@@ -43,9 +72,9 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
| MESH | INSERT | 0 | 10 | 0% |
| MESH | SELECT | 0 | 10 | 0% |
| MESH | EXPORT | 0 | 1 | 0% |
| MESH | POSITION | 0 | 2 | 0% |
| FORM | CREATE | 1 | 14 | 7% |
| FORM | MODIFY | 2 | 31 | 6% |
| MESH | POSITION | 2 | 2 | 100% |
| FORM | CREATE | 2 | 14 | 14% |
| FORM | MODIFY | 3 | 31 | 10% |
| FORM | SYMMETRY | 0 | 6 | 0% |
| FORM | UTILITIES | 0 | 5 | 0% |
| FORM | CONSTRUCT | 2 | 20 | 10% |
@@ -54,37 +83,16 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
| FORM | ASSEMBLE | 0 | 1 | 0% |
| FORM | SELECT | 0 | 15 | 0% |
| FORM | FINISH FORM | 0 | 1 | 0% |
| SHEET METAL | CREATE | 6 | 19 | 32% |
| SHEET METAL | MODIFY | 6 | 21 | 29% |
| SHEET METAL | ASSEMBLE | 1 | 20 | 5% |
| SHEET METAL | CONFIGURE | 0 | 3 | 0% |
| SHEET METAL | CONSTRUCT | 2 | 20 | 10% |
| SHEET METAL | INSPECT | 1 | 25 | 4% |
| SHEET METAL | INSERT | 1 | 11 | 9% |
| SHEET METAL | SELECT | 0 | 15 | 0% |
| SHEET METAL | REFOLD | 0 | 1 | 0% |
| SHEET METAL | POSITION | 0 | 2 | 0% |
| PLASTIC | SETUP | 0 | 2 | 0% |
| PLASTIC | CREATE | 13 | 35 | 37% |
| PLASTIC | MODIFY | 11 | 32 | 34% |
| PLASTIC | CREATE | 16 | 35 | 46% |
| PLASTIC | MODIFY | 14 | 32 | 44% |
| PLASTIC | ASSEMBLE | 1 | 20 | 5% |
| PLASTIC | CONFIGURE | 0 | 3 | 0% |
| PLASTIC | CONSTRUCT | 2 | 20 | 10% |
| PLASTIC | INSPECT | 1 | 26 | 4% |
| PLASTIC | INSERT | 1 | 11 | 9% |
| PLASTIC | SELECT | 0 | 15 | 0% |
| PLASTIC | POSITION | 0 | 2 | 0% |
| ASSEMBLY | INSERT | 1 | 8 | 12% |
| ASSEMBLY | CREATE | 3 | 8 | 38% |
| ASSEMBLY | RELATIONSHIPS | 0 | 11 | 0% |
| ASSEMBLY | MOTION | 0 | 3 | 0% |
| ASSEMBLY | MODIFY | 4 | 11 | 36% |
| ASSEMBLY | CONTACT | 0 | 2 | 0% |
| ASSEMBLY | CONFIGURE | 0 | 3 | 0% |
| ASSEMBLY | CONSTRUCT | 2 | 20 | 10% |
| ASSEMBLY | INSPECT | 1 | 25 | 4% |
| ASSEMBLY | SELECT | 0 | 15 | 0% |
| ASSEMBLY | POSITION | 0 | 2 | 0% |
| PLASTIC | POSITION | 2 | 2 | 100% |
| MANAGE | ASSIGN | 0 | 1 | 0% |
| MANAGE | RELEASE | 0 | 2 | 0% |
| MANAGE | BOM | 0 | 2 | 0% |
@@ -98,7 +106,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
| UTILITIES | INSPECT | 1 | 24 | 4% |
| UTILITIES | CREATE PMI | 0 | 4 | 0% |
| UTILITIES | SELECT | 0 | 15 | 0% |
| UTILITIES | POSITION | 0 | 2 | 0% |
| UTILITIES | POSITION | 2 | 2 | 100% |
## Live (SOLID, SKETCH)
@@ -108,10 +116,13 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › CREATE › Sweep (`Sweep`)
- SOLID › CREATE › Loft (`SolidLoft`)
- SOLID › CREATE › Hole (`FusionHoleCommand`)
- SOLID › CREATE › Thread (`FusionThreadCommand`)
- SOLID › CREATE › Box (`PrimitiveBox`)
- SOLID › CREATE › Cylinder (`PrimitiveCylinder`)
- SOLID › CREATE › Sphere (`PrimitiveSphere`)
- SOLID › CREATE › Torus (`PrimitiveTorus`)
- SOLID › CREATE › Pipe (`PrimitivePipe`)
- SOLID › CREATE › Bounding Solid (`StockModelCommand`)
- SOLID › CREATE › Rectangular Pattern (`PatternRectangular`)
- SOLID › CREATE › Circular Pattern (`PatternCircular`)
- SOLID › CREATE › Mirror (`MirrorCommand`)
@@ -120,17 +131,23 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › MODIFY › Chamfer (`FusionChamferCommand`)
- SOLID › MODIFY › Shell (`FusionShellBodyCommand`)
- SOLID › MODIFY › Draft (`FusionDraftCommand`)
- SOLID › MODIFY › Scale (`ModifyScale`)
- SOLID › MODIFY › Combine (`FusionCombineCommand`)
- SOLID › MODIFY › Offset Face (`FusionOffsetFacesCommand`)
- SOLID › MODIFY › Split Body (`FusionSplitBodyCommand`)
- SOLID › MODIFY › Move/Copy (`FusionMoveCommand`)
- SOLID › MODIFY › Delete (`FusionDeleteCommand`)
- SOLID › MODIFY › Physical Material (`PhysicalMaterialCommand`)
- SOLID › MODIFY › Change Parameters (`ChangeParameterCommand`)
- SOLID › MODIFY › Compute All (`FusionComputeAllCommand`)
- SOLID › ASSEMBLE › Insert Component (`FusionImportCommandFromToolbar`)
- SOLID › ASSEMBLE › New Component (`FusionCreateNewComponentCommand`)
- SOLID › CONSTRUCT › Offset Plane (`ConstructionPlaneOffsetFromPlaneCommand`)
- SOLID › CONSTRUCT › Plane at Angle (`ConstructionPlaneAtAngleCommand`)
- SOLID › INSPECT › Measure (`MeasureCommand`)
- SOLID › INSERT › Insert Mesh (`ParaMeshInsertAlignCommand`)
- SOLID › POSITION › Capture Position (`SnapshotCmd`)
- SOLID › POSITION › Revert Position (`AsBuiltPositionsCmd`)
- SKETCH › CREATE › Line (`DrawPolyline`)
- SKETCH › CREATE › Midpoint Line (`SketchMidpointLine`)
- SKETCH › CREATE › 2-Point Rectangle (`ShapeRectangleTwoPoint`)
@@ -204,10 +221,7 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › CREATE › Rib (`FusionRibCommand`)
- SOLID › CREATE › Web (`FusionWebCommand`)
- SOLID › CREATE › Emboss (`EmbossCmd`)
- SOLID › CREATE › Thread (`FusionThreadCommand`)
- SOLID › CREATE › Coil (`PrimitiveCoil`)
- SOLID › CREATE › Pipe (`PrimitivePipe`)
- SOLID › CREATE › Bounding Solid (`StockModelCommand`)
- SOLID › CREATE › Pattern on Path (`PatternOnPath`)
- SOLID › CREATE › Geometric Pattern (`FusionPatternGeometricCommand`)
- SOLID › CREATE › Thicken (`FusionSurfaceThickenCommand`)
@@ -221,8 +235,6 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › CREATE › Joint Origin (`JointOrigin`)
- SOLID › CREATE › Generate Timeline (`TimelineBuilderCommand`)
- SOLID › MODIFY › Edit Face (`EditFaceCommand`)
- SOLID › MODIFY › Scale (`ModifyScale`)
- SOLID › MODIFY › Offset Face (`FusionOffsetFacesCommand`)
- SOLID › MODIFY › Replace Face (`FusionReplaceFaceCommand`)
- SOLID › MODIFY › Split Face (`FusionSplitFaceCommand`)
- SOLID › MODIFY › Silhouette Split (`FusionPartingLineSplitCmd`)
@@ -235,13 +247,11 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › MODIFY › Volumetric Lattice (`VolFieldCreateLatticeCommand`)
- SOLID › MODIFY › Volumetric Texture (`VolFieldTextureCommand`)
- SOLID › MODIFY › VolFieldModifyModelCommand (`VolFieldModifyModelCommand`)
- SOLID › MODIFY › Physical Material (`PhysicalMaterialCommand`)
- SOLID › MODIFY › Appearance (`AppearanceCommand`)
- SOLID › MODIFY › Manage Materials (`MaterialCommand`)
- SOLID › MODIFY › Compute Unresolved (`FusionComputeUnresolvedCommand`)
- SOLID › MODIFY › Convert (`TSpline2BRepCommand`)
- SOLID › MODIFY › Bill of Materials (`MaterializedBomHybridCmd`)
- SOLID › ASSEMBLE › New Component (`FusionCreateNewComponentCommand`)
- SOLID › ASSEMBLE › Duplicate With Joints (`FusionDuplicateWithJointsCommand`)
- SOLID › ASSEMBLE › Constrain Components (`AssemblyMateCommand`)
- SOLID › ASSEMBLE › Align Constraint (`AlignConstraintCmd`)
@@ -331,8 +341,6 @@ Generated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the tool
- SOLID › SELECT › Select Edge Priority (`SelectEdgePriorityCommand`)
- SOLID › SELECT › Select Component Priority (`SelectComponentPriorityCommand`)
- SOLID › SELECT › Selection Filters (`SelectionFilterCommand`)
- SOLID › POSITION › Capture Position (`SnapshotCmd`)
- SOLID › POSITION › Revert Position (`AsBuiltPositionsCmd`)
- SKETCH › CREATE › SketchConstrainer (`SketchConstrainer`)
- SKETCH › CREATE › Fit Curves to Mesh Section (`FitCurvesToSectionCommand`)
- SKETCH › CREATE › Spun Profile (`SpunProfileCmd`)
+27 -5
View File
@@ -24,9 +24,19 @@ const TABS: &[(&str, &str)] = &[
("ToolsTab", "UTILITIES"),
];
/// The tabs the headline number counts (M0 scope).
/// The tabs the headline number counts (now: SOLID and SKETCH).
const HEADLINE: &[&str] = &["SOLID", "SKETCH"];
/// The owner's scope: these tabs (and the PLASTIC subset below) count toward the in-scope
/// figure; the rest of Fusion is deferred and listed separately.
const IN_SCOPE_TABS: &[&str] = &["SOLID", "SKETCH", "ASSEMBLY", "SHEET METAL"];
/// The PLASTIC commands in scope (enclosure features).
const PLASTIC_SUBSET: &[&str] = &["FusionBossCommand", "FusionRibCommand", "FusionWebCommand", "FusionLipCommand", "FusionSnapFitCommand"];
fn in_scope(e: &Entry) -> bool {
IN_SCOPE_TABS.contains(&e.tab.as_str()) || (e.tab == "PLASTIC" && PLASTIC_SUBSET.contains(&e.id.as_str()))
}
#[derive(Clone, Debug)]
pub struct Entry {
pub tab: String,
@@ -117,13 +127,17 @@ pub fn run(root: &Path, refresh: bool) -> Result<(), String> {
let head: Vec<&Entry> = catalog.iter().filter(|e| HEADLINE.contains(&e.tab.as_str())).collect();
let head_live = head.iter().filter(|e| live(e)).count();
let all_live = catalog.iter().filter(|e| live(e)).count();
let scope: Vec<&Entry> = catalog.iter().filter(|e| in_scope(e)).collect();
let scope_live = scope.iter().filter(|e| live(e)).count();
let mut md = format!(
"# Fusion command parity\n\nGenerated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the toolbar commands of Fusion's Design workspace, ids and names only) and the live command registry (`solvecraft-cli commands`). A command counts as live when SolveCraft registers the same command id. This measures breadth, not depth; see ROADMAP.md and docs/oracle.md for depth.\n\n**SOLID + SKETCH: {head_live} / {} commands live ({:.0}%).** All Design tabs: {all_live} / {} ({:.0}%). Registered commands: {}.\n\n| Tab | Panel | Live | Total | % |\n|---|---|---:|---:|---:|\n",
"# Fusion command parity\n\nGenerated by `cargo xtask parity` from `xtask/data/fusion-catalog.tsv` (the toolbar commands of Fusion's Design workspace, ids and names only) and the live command registry (`solvecraft-cli commands`). A command counts as live when SolveCraft registers the same command id. This measures breadth, not depth; see ROADMAP.md and docs/oracle.md for depth.\n\n**In scope (SOLID, SKETCH, ASSEMBLY, SHEET METAL, PLASTIC enclosure subset): {scope_live} / {} commands live ({:.0}%).** SOLID + SKETCH: {head_live} / {} ({:.0}%). Registered commands: {}.\n\nDeferred until further notice (not in the in-scope figure): MESH, FORM, SURFACE beyond what solids need, PCB, render, animation, simulation, manufacture, drawings, MANAGE, UTILITIES and the rest of PLASTIC. All Design tabs together: {all_live} / {} ({:.0}%).\n\n| Tab | Panel | Live | Total | % |\n|---|---|---:|---:|---:|\n",
scope.len(),
pct(scope_live, scope.len()),
head.len(),
pct(head_live, head.len()),
ids.len(),
catalog.len(),
pct(all_live, catalog.len()),
ids.len()
);
let mut groups: Vec<(String, String, usize, usize)> = Vec::new();
for e in &catalog {
@@ -136,7 +150,13 @@ pub fn run(root: &Path, refresh: bool) -> Result<(), String> {
None => groups.push((e.tab.clone(), e.panel.clone(), l, 1)),
}
}
for (t, p, l, n) in &groups {
for (t, p, l, n) in groups.iter().filter(|g| IN_SCOPE_TABS.contains(&g.0.as_str())) {
md += &format!("| {t} | {p} | {l} | {n} | {:.0}% |\n", pct(*l, *n));
}
let plastic: Vec<&Entry> = catalog.iter().filter(|e| e.tab == "PLASTIC" && PLASTIC_SUBSET.contains(&e.id.as_str())).collect();
md += &format!("| PLASTIC | enclosure subset | {} | {} | {:.0}% |\n", plastic.iter().filter(|e| live(e)).count(), plastic.len(), pct(plastic.iter().filter(|e| live(e)).count(), plastic.len()));
md += "\n### Deferred tabs\n\n| Tab | Panel | Live | Total | % |\n|---|---|---:|---:|---:|\n";
for (t, p, l, n) in groups.iter().filter(|g| !IN_SCOPE_TABS.contains(&g.0.as_str())) {
md += &format!("| {t} | {p} | {l} | {n} | {:.0}% |\n", pct(*l, *n));
}
md += "\n## Live (SOLID, SKETCH)\n\n";
@@ -149,7 +169,9 @@ pub fn run(root: &Path, refresh: bool) -> Result<(), String> {
}
std::fs::write(root.join("docs/parity.md"), md).map_err(|e| format!("docs/parity.md: {e}"))?;
println!(
"parity: SOLID+SKETCH {head_live}/{} ({:.0}%), all tabs {all_live}/{} → docs/parity.md",
"parity: in scope {scope_live}/{} ({:.0}%), SOLID+SKETCH {head_live}/{} ({:.0}%), all tabs {all_live}/{} → docs/parity.md",
scope.len(),
pct(scope_live, scope.len()),
head.len(),
pct(head_live, head.len()),
catalog.len()