Bumps the version to 0.40.0-rc.2 and folds the pending format changes into format 50. A published pre-release no longer reaches the Flatpak feed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Web app: a page that hands designs saved at the old address to app.solidcraft.io
The stable web app moved from docs.solidcraft.io/app/ to app.solidcraft.io, and a browser keeps
storage per address, so designs saved at the old one don't appear at the new one. The docs site
gets app-transfer.html: framed by the move page at app.solidcraft.io it answers that page's
requests, and opened on its own it offers each design as a file. It only reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Web app: name the browsers the one-step move was checked in
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
solidcraft-smlib held one process-wide kernel lock for the whole of every
solidcore call, so a long call in one design (a modeled thread, a fillet)
held up every kernel call in every other design, even after its tab was
closed, and a call that never returned held them until restart.
Each call now takes a kernel from a pool and the lock is only held to take
or put one back. Calls one after another get the same kernel as before; one
that starts while another runs gets its own. Each kernel has its own range
of procedural blend serials, since a body keeps the serials of the kernel
that made it.
History commands and delete checks now belong to their design: they wait
with its tab, go when it closes, and can't land in another design. An
agent's command for a design that left the window is refused at once
instead of holding up the requests behind it.
Closes#11681
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* claim: Sketch dimension: typing replaces the proposed value (#11204)
* Sketch dimensions: typing replaces the proposed value until you move the caret (#11204)
The value box selected the proposed value only on its first frame. A frame
in which the field misses the keyboard collapses egui's selection to its
caret, so typing 400 over a proposed 40 mm could give 40040 mm (seen in a
WebView2 host). Now every frame starts with the whole value selected, before
the field reads its state, until the person takes the value over: typing, a
completion or reference, a key in the box, or a press into the box after it
stayed in place. The click that placed or pinned the value does not count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Preferences: one heavier, evenly detailed icon set for the page tabs
* Build: import traced body records from their new owner
* Build: read exported kernel records from their new crate
document.units gets input and output schemas: `units` (mm, cm, m, in or
ft, with the handler's messages for a missing or unknown unit) and its
reply, `units` and `kept`, which the handler now builds from the reply
type. Its line leaves unconverted.txt.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Threads: a 12 mm hole takes M12, and a modelled thread narrows a bore that is too wide (#11609)
Automatic sizing of a hole now takes the size whose nominal diameter the hole has (a 12 mm hole
is M12, not M14, the size whose tap drill is 12 mm); a hole near no nominal diameter is still
matched by tap drill. A modelled internal thread in a hole as wide as the thread or wider no
longer refuses with "too wide": the bore is filled in to the thread's minor diameter over the
threaded length and the groove cut there, and the feature's warning says so. A size that does
not fit the hole names the size that does.
A saved thread with no designation keeps the old rule through a pending format step, so an
existing design rebuilds with the size it had.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Threads: keep an old automatic size through edits; kernel-rig cases expect the narrowed bore (#11609)
Editing a saved automatic thread keeps `old_auto_size`, so it does not change size. The five
kernel-rig cases that expected a modelled thread in a hole as wide as the thread to be refused
now expect the narrowed bore, with the volume worked out analytically in each case. The thread
dialog's reopen pattern names the new field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Thread dialog test: a 5 mm hole is suggested M5, its nominal size (#11609)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Typed schemas for Appearance, Appearance Library and List Appearances (part of #2829)
appearance.assign, appearance.library and appearance.list get contracts
that read what their handlers read, with the handlers' messages, and
reply types the handlers build their replies from. Their lines leave
unconverted.txt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Appearance library: the opacity is already a number
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Every point on a spline surface returned its basis tables by value, up to
272 bytes several times over. Filling them in place takes about a quarter off
meshing a round extrude's wall, with the same numbers.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* claim: #6257
* Align: move bodies by frames that follow sketch and model geometry (#6257)
solid.align takes from_frame and to_frame: a joint origin on the model
(a face's or round end's centre, an edge's middle, a corner, found again
by name) or a sketch point or a sketch circle's, arc's or ellipse's
centre. Both are resolved on every evaluation, so the bodies follow
their target when it changes. An optional angle turns the bodies about
the target's direction after the move.
The Align dialog takes sketch points and curves as From and To, offers
the Joint Origin snap and an Angle row.
* Align frames: box the joint origin (clippy large_enum_variant)
* Align frames: every moved body on the frame's component, placed once
* Align frames: a sketch id's length in characters
* Align frames: the dialog test's sketch curve hit carries its point
* Align frames: the dialog test takes Vec2 from solidcore-record
---------
Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
* New kernel cases go to solidcore's corpus; tests/kernel-cases/ only shrinks
tests/kernel-cases/CASES lists every rig and ladder case there is today. `cargo xtask lists`
fails on a case directory it does not list, saying where a kernel case goes instead
(solidcore's crates/solidcore/tests/kernel_cases/, exported with `cargo xtask kernel-cases
--export` or written by hand), and on a listed case that is gone. AGENTS.md, CONTRIBUTING.md,
the tests skill, the rig README and EXEMPT say the same; a new command gets an EXEMPT line
naming where it is tested.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
* CONTRIBUTING: the kernel-cases paragraph ends before the naming corpus one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
---------
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Each path test opens its own device and compiles the path pipeline. On a
cold driver cache that takes minutes and gigabytes per compile, and libtest
ran one per CPU thread side by side: on NVIDIA the solidcraft-gpu tests ran
for hours and committed ~80 GB. Executor::new now holds a process-wide lock
while it compiles; the first compile fills the driver's cache and the
waiting ones get the pipeline from there.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The CLI's kernel_cases_export.rs still imported Brep from solidcraft_geom::brep after the layer split moved it to solidcore_record::brep. Changes this one import.
The second half of #11626: apps/solidcraft-cli/src/kernel_cases_export.rs (#11568) imported
solidcraft_engine::geom::brep::Brep, which #11496 moved to solidcore_record::brep::Brep.
cargo clippy --workspace --all-targets -D warnings is clean with it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
#11568's trace (crates/smlib/src/trace.rs) named the record as solidcraft_geom::brep::Brep,
and #11496 moved that type to solidcore_record::brep. Each merged green on its own; together
main does not compile (error[E0425]: cannot find type Brep in module b).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
* Kernel: the B-rep record and the native body file come from solidcore-record
SolidCraft's portable B-rep record (`solidcraft_geom::brep`: brep.rs, topology, history,
envelope, part, curve2) and the native body file (`solidcraft_kernel::native`: the tagged binary
codec and the container) move to solidcore's `solidcore-record` crate: geometry as data, with
structural validation and no maths (solidcore's docs/layers.md, stage 1). Every caller uses
`solidcore_record::brep` and `solidcore_record::native`; the old copies are deleted.
What computes from coordinates stays with the kernel, in geom's `brep`:
- `brep::check`: the record's geometric checks (orthonormal frames, non-degenerate planes,
unit revolution axes, non-singular placements). `check::validate` and
`check::validate_built` are the record's validation and these together, and every caller of
`Brep::validate` uses them, so what is accepted is unchanged;
- `brep::label`: a surface's natural ranges (a cone's apex), `curve_interval`,
`edge_curve_interval` and `form_turns`;
- `brep::pcurve::eval`: a pcurve's point;
- `geometry::check`, `placement::moved` and `split_edges` become functions on the record.
The kernel's native module keeps the conversion between a body and its saved record
(metadata.rs) and checks the decoded record's geometry. `native/analytic.rs`, which no module
declared, is deleted.
solidcore-record is pinned to its rev on solidcore's `layer-record` branch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
* Geometry: Vec2, Vec3, Plane and the profile types come from solidcore-record
The plain data of vectors and points, sketch planes and planar profiles (`Seg2`, `Loop2`,
`Region2`) moves to `solidcore-record`, with its constants and component-wise operators only
(owner decision, solidcore layer split). Their geometry stays in geom as traits:
`Vec2Geom`, `Vec3Geom`, `PlaneGeom`, `Seg2Geom`, `Loop2Geom`, `Region2Geom`, `Seg2ArcFit`,
`Loop2ArcFit` and `Region2ArcFit`, in scope with `use solidcraft_geom::prelude::*`. Every caller
names the types from `solidcore_record`; geom no longer defines or re-exports them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
* Kernel: pin solidcore-record to solidcore main f5e8e9a29
solidcore-record is merged on solidcore main (tangency-labs/solidcore#2519); its crate there is
identical to the rev pinned before but for its clippy configuration. The lock is regenerated
against the merged rev.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
---------
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
It fails with status 1001 since #11360 moved SolidCraft onto solidcore alone, as the
kernel test variable_radius_on_a_box_edge already listed in tests/KNOWN_FAILING_TESTS.
The oracle keeps its own list, so main's Reference tests have been red since.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
The web app is now offered at /app/ (latest release), /app-rc/ (newest release candidate) and /app-edge/ (current main), each with its own browser storage. /app/ is built from the latest release's web zip instead of main.
- Picks run on a copy of the operand: a pick builds query caches on the body it
reads, so the traced body stays as an untraced run leaves it.
- An untrim and an extension record their picks with the pickers they run
(`face_at`, `nearest_edge`).
- A final body matches the newest export of its record that an operation made.
- A stopped run is the kernel's when the last failed operation is followed by
copies only.
- A re-export removes each case's old entry first; fixes.json is written whole.
- The manifest names no commit for a copy without git, never an empty one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
An entry keeps what each operand body is and names <case>.bodies.json.gz, which
holds the records (gzip with no timestamp, so the same records give the same
bytes); the entry itself is pretty JSON. The corpus of 1202 cases is 33 MB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
An entry's operation is expressible when the kernel accounts for its result; the
values only SolidCraft grades (continuity, meshes, files, command answers, merged
counts, SolidCraft's wording of a refusal) are listed under `ungraded` instead of
making the whole case inexpressible.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
`cargo xtask kernel-cases [--ladder] --export DIR` runs the rig with the kernel's
operations traced (`smlib::trace`) and writes one entry per case: the operation, or
chain of operations, that made the bodies the case ends with; each operand that came
in as a record, as that record; the parameters, with every pick by points also given
as the topology index it picked; the fix set; the case's expected values and the
rig's result. A case no kernel operation alone accounts for is written too, marked
not expressible with its reasons. DIR/manifest.json counts them per area.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
The packaging action can't read a hyphenated version from the tarball's name, so the job gives it a name without the hyphen and renames the package back. A hyphenated version no longer fails the build if its Arch job fails; a plain version still does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bumps the version to 0.40.0-rc.1 and folds the pending format changes into format 49. The default-layout header test now expects the room the version really takes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>