npm puts a Unix shell script with the bare name (codex-acp,
claude-code-acp, gemini) beside the .cmd shim. The lookup tried the bare
name first, so every npm-installed agent failed with "not a valid Win32
application (os error 193)". Windows now only considers .exe/.cmd/.bat,
and a command saved with the bare path runs the shim beside it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit 60ea8c69d2)
On 32-bit Windows SetWindowLongPtrW is SetWindowLongW, which takes and
returns i32, so the window-procedure hook didn't compile for i686.
The macOS app bundle now signs the bundled solidcraft-cli before the
bundle itself; codesign refuses a bundle with an unsigned helper.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit 94e76cd97e)
* Copy, cut and paste sketch geometry (Ctrl+C/X/V, context menu)
Sketch geometry had no copy or paste: Ctrl+C / Ctrl+X / Ctrl+V arrive as
clipboard events that nothing handled, and the sketch context menu had no
Copy, Cut or Paste.
- sketch.copy / sketch.cut / sketch.paste: lines, arcs, circles, ellipses,
splines, conics, points and text. Constraints and dimensions wholly among
the copied entities come along (each dimension gets its own parameter
with the same expression); ones that reach outside, fixes and pattern or
offset relations are dropped. Paste goes centred at `at`, by
`translate`, or offset from the original (same sketch) / at the same
coordinates (another sketch, on its plane). One undo step; the pasted
geometry is selected.
- Ctrl+C / Ctrl+X / Ctrl+V in a sketch (paste at the cursor), and Cut,
Copy and Paste in the sketch context menu. Outside a sketch Ctrl+C /
Ctrl+V copy and paste the selected timeline features. A copy also puts a
line of text on the system clipboard so the next Ctrl+V is delivered.
Fixes#1480
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep a pasted text's height and angle expressions, drop its place's
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Checked locally on main merged with this: cargo check --workspace and the ui-egui tests (the only failures are the local-only TexturesDelta ones that main has too).
The product preview asked the viewport executor for the full physical
viewport, so a maximised 4K window (~8 MP) was refused against the 4 MP
limit on every frame. The preview now draws at the largest size of the
same aspect the executor admits (RenderLimits::fit, scratch included)
and filters it up into the viewport through the existing offscreen
blit. Viewports within the limits still draw at full size.
PNG setups past the image limits now say what the limits are and the
largest size at that aspect, and the image panel offers to use it.
Co-authored-by: Claude Opus 5.5 <[email protected]>
A sketch text's height, place (x and y) and angle can each be an expression over the design's parameters, and the text follows parameter changes, undo and reopening. Closes#1362.
Co-authored-by: NOWN-DEV <[email protected]>
The flat pattern now keeps a 2D view of its own, driven by navigation::handle with orbit off,
so pan, zoom to the cursor and reverse zoom follow the navigation preset. Input over it no
longer reaches the Design camera, and Fit and Home frame the pattern. Closes#1483.
* Chamfer: refuse a result that grew a convex edge's part (or shrank a concave one's)
A chamfer of a curved edge that runs off a face it skims (robustness seed 57's
ball rim) built a part bigger than before. Checked from the two faces' normals
at the edge; rounds and unclear angles are left to the wedge bound.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Action matrix: the sheet metal tray's relief corners refuse a 0.25 mm chamfer
Each is a 2.5 mm concave edge (the corner of a corner relief, between two
planes at right angles): a chamfer there fills at most 0.25²/2 × 2.5 = 0.08
mm³. What was built took 0.95 mm³ away; the chamfer guard now refuses it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Robustness goldens: seed 57's wrong-way chamfer is now refused (#1390)
On main with #391, seed 57's chamfer grew the part; this refuses it, so the run goes on
to its later steps and ends ok.
---------
Co-authored-by: Phanoob <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: bherbruck <[email protected]>
* Agent chat prototype: drive an ACP agent the user already has from a side panel
A desktop-only chat panel (off by default) that starts a coding agent over the
Agent Client Protocol and gives it SolidCraft's MCP server, bridged to the open
window through the token-protected control channel with the default folder
limits. It finds installed agents (Claude Code and Codex adapters, Gemini CLI,
Copilot, Qwen, OpenCode, goose) with version and login state, streams text,
tool calls and plans, shows the agent's permission requests, and when an agent
isn't signed in shows its own login methods without handling any credential.
Design notes and findings: docs/design/in-app-agent-chat.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* docs: say only what the end-to-end run showed
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: gate, one undo per message, docking, process groups, discovery polish
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: Settings → AI, several agents with a switcher, OpenAI-compatible endpoints, permission modes, toolbar button
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: translations, tool cards, Add agent dialog fixes, test agent saves on its own
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: third-party licences for the keychain crates; clippy
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: badge text from the theme tokens
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Agent chat: Auto-allow model edits is the default permission mode
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
A motion link's ratio is read in b's units per a's (mm per degree, degrees per mm) when an angle and a distance are linked; stored values stay per radian, so saved designs are unchanged. Follow-up to #1415.
Co-authored-by: SychPL <[email protected]>
Adds a bounded normalization path for PNG16 and ICC-bearing JPEG texture inputs, producing float RGBA with recorded color and orientation decisions.
Co-authored-by: 0xlillith <[email protected]>
Adds a read-only review window to Validate Physical Material Data: paste a schema-1 card, see its known properties in SI units, unknown ones marked, with stated conditions and source claims. Nothing is assigned or saved.
Co-authored-by: 0xlillith <[email protected]>
* Render preview uses the shared camera navigation
The Render workspace's product preview had its own hard-coded camera
controls. Camera input now lives in one component, navigation::handle,
which the modelling viewport and the Render preview both call (NavCaps:
orbit, pick). Render gets the navigation preset, Orbit around, zoom to the
cursor, the middle double-click and the axis view or navigation cube.
Flat pages can call it with orbit off. A test rejects pages that read the
wheel or move the camera themselves.
Fixes#1454
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Render panel hint says the camera moves as in Design
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
The continuity core (kernel bridge: Hermite control rows reproducing a support surface's position, tangent, curvature and change of curvature, G0 to G3), surface.blend between two edge chains (#764), and a crown for fitted patches. Existing patches and fillets are unchanged by default (crown 0 is the plain patch bit for bit). SurfaceBlend and Patch.crown are noted under format 22.
A point within the point tolerance of a boundary curve's end is that end in the boolean, whatever its parameter, so text cuts no longer leave unmatched sliver vertices (#391). Robustness goldens re-recorded for seeds 0, 34, 39, 41 and 57 with reasons.
Every other package (AppImage, deb, rpm, tar, Flatpak, Snap, MSI, portable zip, FreeBSD) already
puts solidcraft-cli next to the app; the macOS bundle only had it in a separate zip. The agent
chat starts it as its agent's MCP server and looks for it beside the running program.
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Sketch: the first dimension scales a sketch drawn by eye (#1365)
Lines drawn by eye have no size of their own until a dimension gives them one, but the first
dimension kept every other drawn length and distorted the sketch to fit (a free construction
line through the origin turned instead of the shape moving). The dimension tool now scales
the whole sketch about its origin to the first length dimension, as long as nothing in the
sketch fixes a size yet: no other driving length dimension, nothing fixed, projected or
patterned. Every geometric constraint and angle holds on the scaled sketch. Later
dimensions size what they measure as before; sketch.dimension does this only with
scale_sketch: true, so scripts are unchanged.
Fixes#1365
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Scenario s01: dimension the box's height too, now that the first dimension scales the sketch
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Material-card validation now names the exact condition fields missing for each property (missing_condition_fields), alongside the existing unspecified_conditions.
Co-authored-by: 0xlillith <[email protected]>
New frame::add_outlined adds a button that draws its own outline with the theme's outline width set to the same width in every state, so its padding no longer drops a pixel on hover. Used by the dialogs' Select chip, Sketch Text's Path chip and the bug report's Open GitHub draft button. New dialog_chip_hover test. Fixes the second point of #1335.
startup_steps_survive_a_rebase_and_running_ends_startup reads the open journal through a clone of its own handle (read_journal_file), as read_live_journal does, instead of opening a second handle that Windows' mandatory lock refuses. Test-only. Fixes#1448.
New Body extrusions and Offset Face previews show successful intermediate distances from the same setup while a distance drag runs, then compute the latest one (tool previews keep streaming as before; errors still need exact inputs). The drag arrow and value box are painted from this frame's pointer, removing a frame of lag. Drag regression tests and a perf note added.
List menus open below-right of the cursor and flip to end at the cursor where they don't fit (shared context_menu::place / show for viewport, browser, toolbar and Select Other). Right-clicking a plane in the viewport, a construction plane row or an origin plane row (new menu with Create Sketch and Show/Hide) offers Create Sketch on that plane. Fixes#1354.
AppRun installs nothing when an appimagekit_*.desktop entry for the same AppImage exists, and removes the entry it wrote earlier. An empty ~/.local/share/solidcraft/no-desktop-integration turns the integration off for good; SOLIDCRAFT_NO_DESKTOP_INTEGRATION=1 still works. Getting-started guide documents it. Fixes#1399.
scenario::scratch_dir builds the harness folder under solidcraft_engine::io::vfs::temp_dir() (long names), so a short 8.3 TEMP on Windows no longer trips the short-name refusal before the scope checks the scenarios test. Fixes#1385.
joint.motion_link offset is read in the linked value's units (degrees or mm, or an expression); links are still stored in radians, so saved designs open unchanged. A new joint whose values fall outside its limits starts at the nearer limit, stores it, and says so in warnings. Loop dof also counts at a nearby pose, so a part at a dead point of its loop keeps its mobility. The mechanisms skill is updated to match.
New command inspect.compare {a, b, tolerance?}: measures of both and their differences, two-way surface deviation from a bounding-volume tree, regions beyond the tolerance clustered by side (only_in_a / only_in_b) with integrated volumes and faces, a verdict, optional face colouring as one undo step, and warnings for open meshes. Geometry in solidcraft-geom (compare.rs), command in the engine. Closes#1363.
"2,5 mm" is 2.5 mm; inside a function's parentheses the comma still separates the arguments. Noted under design format 22: an expression typed with a decimal comma is saved as typed, so 0.12.0 asks for an update instead of failing to evaluate it.
A curved chamfer chain with straight planar ends can end across two earlier planar bevel faces, shortening their shared seam to where the new chamfer plane crosses it; picks on one tangent chain are applied once. Fixes#1303.
The mesher samples edges through a fallible evaluation, so an intersection curve whose projection fails to converge no longer panics; a boolean result with an edge that does not evaluate is refused with an error. Fixes#1252.
* Imports become components: a STEP assembly's tree as nested components (#1386)
Every imported file (STEP, IGES, 3MF, STL, OBJ: inserted, dropped, opened as a
design, or file.insert_step / file.insert_mesh / doc.open from scripts, the CLI
and MCP) now comes in as a new component named after the file, with its Import
feature inside it. A STEP assembly's products become nested components; a part
placed more than once is one component with an occurrence per placement, and
the Import feature skips the file's later copies (`skip`, format 21 note). The
contents are held as one rigid group (rigid joints, glyphs hidden); moving an
inner part is refused until component.unlock ("Unlock Contents") releases it.
Y up turns the import's component. Replies report component, component_name
and occurrence. Undo is one step; designs with loose imports are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep an import's rigid group hidden when the window loads the file in the background
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Import instances' skip list is format 22: format 21 ships in 0.12.0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Catalog entries for Unlock Contents
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
* View-dependent display refinement: bodies seen up close are drawn from finer display plans (#1320)
Each frame the viewport works out every shown body's screen-space error (the display
quality's chord tolerance in pixels where the body is nearest the eye) and picks a
refinement step past the chosen display quality, each halving the chord, with hysteresis.
Steps are planned off the UI thread and swapped in when ready, within a triangle budget
and a cache size. Faces (GPU plan or CPU mesh), edges, silhouettes and highlights of a
refined body all come from the refined plan, so a highlight stays on the drawn triangles.
Planned bodies are chunked by content on the GPU, so a refinement re-evaluates only its
own chunk. Display only: the reference mesh, the B-rep and exports never change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Display refinement: only collect finished plans while the view stands still, time the choice, keep the web planning one step a frame
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Format
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Keep the Display quality note as it was (the longer one pushed the Colour vision list off the Graphics page)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
* Web app: read a STEP file a piece per frame, with progress and Cancel (#1376)
The kernel's STEP reader walks the file first and converts its solids afterwards,
and StepReading exposes those stages: parse and walk, then convert a solid (or a
batch) per step, then finish into the shared import cache. The web app's file
load drives it from the frame loop for about 30 ms a frame, shows the same
progress card and Cancel as the desktop, and then runs the insert or open, which
finds the file already read. The desktop path is unchanged in behaviour.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Web app: make the imported bodies' meshes a few per frame too (#1376)
After the read, the insert or open runs, and then the bodies' display meshes are
made a frame's worth at a time ("Preparing the view"), as the desktop worker
warms them, instead of all in the first frame that draws the design.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
component.insert_design (a saved part as a linked component) had no button, so an
assembly of separately saved parts looked impossible. It is now on the ASSEMBLE panel
of every tab and in the File menu; it asks for the file, and a STEP or mesh file picked
there is inserted as Insert STEP or Insert Mesh would.
Co-authored-by: Claude Opus 5.5 <[email protected]>