Commit Graph

783 Commits

Author SHA1 Message Date
Jesper We 436ee95095 Preference: return to the previous view when a sketch ends (#7038) (#7043)
* claim: #7038

* Preference: where the view goes when a sketch ends (#7038)
2026-10-26 19:31:55 +00:00
github-actions[bot] 1ee2532678 Regenerate generated files and fold pending files [skip ci] 2026-10-26 20:00:04 +00:00
github-actions[bot] 3152e02fe5 Regenerate generated files and fold pending files [skip ci] 2026-10-26 19:51:41 +00:00
Nathan Dane fbcd4852c1 Navigation bar: the view commands (#6585) (#6586)
* claim: #6585

* Navigation bar: the view commands (#6585)
2026-10-26 17:46:15 +00:00
Daniel 2e566e2c58 Placement handles for Rest, Boss and Snap Fit (#4384) (#5362)
* claim: #4384

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: shared module, with Rest as the first tool

The Rest handles spike becomes a shared module, place_gizmo, so other features placed on a face can
use the same marker and knob. The mechanics (crosshair with its three states, the grab offset, the
footprint while dragging, the turn knob) live in place_gizmo.rs. The handles own the pointer through
canvas::owns_pointer, as the move triad does, so navigation and Select Other's press-and-hold leave
them alone. Each tool is one file under place_gizmo/ that gives a Spec: which dialogs it serves,
which commands' Position input also takes sketch points, where the place is, how the pointer
re-places it, its footprint and its turn, if any. The module lists the tools one per line, so tools
added on separate branches each add one `mod` line and one list line. Rest is the first.

The handles are always on; the preference the Rest spike had is gone. The POINTS accept flag on a
Position input is granted from the tools' Specs instead of a Rest-only arm in the plastic dialog's
start. Handles are published as `rest:position` and `rest:rotate` as before.

Seen straight down, the dialog's height arrow collapses onto the place and its value box sits just
right of it, where it took the press meant for a knob pointing that way. The knob now slides out
along its ray until it is clear of the box.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Placement handles: Boss

The marker moves a boss across the model, also from Edit Feature, and its Position input takes
sketch points while the handles are on, so a screw boss can be dragged onto the centre of a
circle drawn for it. A boss is round, so it gets no knob; the footprint while dragging is its
outer circle. Published as `boss:position`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Placement handles: Snap Fit

The marker moves a snap fit across the model and its Position input takes sketch points while
the handles are on, so the arm can be put where a sketch says (#3423). The knob points the
catch: it turns between the four directions the Catch Direction combo offers for the face, so
the knob and the combo always agree; the command keeps only those four, so there is no free
turn. The footprint while dragging is the arm's foot, its thickness behind the place and its
width across. Published as `snap_fit:position` and `snap_fit:rotate`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Placement handles: the look in one file

Everything that draws the handles (the crosshair and its three eased states, the knob's ball, the
cased lines, the angle label, the colours) moves from place_gizmo.rs into place_gizmo/look.rs, so a
restyle touches one file and the mechanics (hit radius, drags, knob geometry) stay where they are.
No change in behaviour.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: behind a Design preference, off by default

The handles sit behind Preferences > Design > Placement > Placement handles (`placement_handles`,
also through `ui.prefs`), off by default as the hole placement work in #2912 is: a Rest, Boss or
Snap Fit is then placed by its click alone, its Position input takes faces only, and no handle is
drawn or published. The tests switch the preference on; one checks the default.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the tests hide the origin through set_origin_shown, as main does since #1849

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the move marker as designed in the prototype, drawn with theme tokens

The marker is a dot with four arms to the screen cardinals: short and dotted at rest, longer with open arrowheads when pointed at, solid while dragging, each state growing out of the previous one (360 ms). Sizes are the prototype's. Its core is the icon highlight and its casing the marker halo, the tokens main's hole handle uses, so the literal allowance goes. The tip shows while pointing, not during a drag.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the dialog's drag arrow stands above the move marker

With the handles on, the Height arrow started at the marker's centre and ran through its upper arm, head on arm tip. The arrow now keeps the marker's full reach and a gap free at the base, its shortest length grows by as much, and the base dot is left to the marker. Other dialogs are unchanged (clearance zero).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: a turn ring on the face replaces the knob

The ring lies on the face about the move marker's centre, drawn in perspective, a fixed 65 px on screen like the move triad's arrows (it is a control of something on the screen, not a measure of the model). At rest it is a short dotted arc with an open chevron grip just outside; pointed at, the dotted circle opens from the grip both ways round and the grip slides in and fills; while turning, a solid arc around the grip. Dragging the grip turns the feature as the knob did, through the same handle name, so the harness tests stand.

The floating value box yields: with a handle's centre under it, it moves to the other side of the arrow's tip or above it, since seen straight down the box sat exactly where the grip is. A handle the arrow's stem crosses keeps the pointer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: a compass while turning, and the turn pulled onto the face's compass points

Four ticks just outside the ring at the face's in-face world directions (the ones the Snap Fit combo names, +X, −Y, …) appear while turning and stay put, so you can see how far you have gone. A Rest's turn is pulled onto one of them within 8°, otherwise it steps by 5° as before; Alt or Ctrl frees it. The readout beside the grip names the point it sits on ("90° · +X") and keeps clear of the ring.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the footprint in the preview's blue, the idle handle steps back

The footprint drawn while the marker drags is a filled shape in the preview's own blue with a thin darker edge, not a white outline, so white stays reserved for what can be grabbed. While one handle is dragged the other fades to a quarter and comes back when the drag ends.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the ring in the preference text, the docs and the tests' wording

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the look as tuned in the app

Marker: drawn to the redrawn design (dot r 3.9 pt, two dashes per arm, a filled head 8.7 × 7.1 pt whose base is where the outer dash began); pointed at, the outer dash becomes the head (its far end narrows to a point, its near end widens); dragging runs the inner dash on into the head as a shaft. Every casing is 0.4 pt outside the edge, for lines, heads and the dot alike.

Ring: the grip and the compass lie in the ring's plane like the circle, so the grip is never skewed against it; the grip is a thick chevron with a hole that flattens into the base as the grip slides onto the ring, and fills; the dotted circle stays while turning, with the solid arc laid over it; opening eases in and takes 0.3 s, leaving is a 0.15 s fade over the resting ring, not the sweep backwards; a drag keeps the angular gap of the press, so the grip does not jump onto the pointer; the compass ticks and the readout's point name are in their axis colours, and the grip takes the axis colour (eased) while aligned with one, with that point's tick left out; free turning keeps a hair of pull (0.5°) so an axis can still be hit; the readout wraps to a half turn.

Value box: with a ring it keeps out of the circle the ring, grip, compass and readout sweep, one place per view, nothing moves when a turn starts; also when the value does not evaluate and there is no arrow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the readout shows a half turn as 180°, not −180°

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the motions in one place

The animations the handles grew (a factor eased in and out each way on its own time and easing, a handle stepping back while the other works, a colour that comes and goes from the last one it was on, the gap a press keeps for its drag, an offset that slides instead of jumping) move out of place_gizmo into motion.rs, so the next manipulator reuses them. The look's timings become Transitions in look.rs. No change in behaviour: the contact sheet before and after is identical, the harness tests stand.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Placement handles: the axis colours as main names them since #4430

The compass and the aligned grip take the one set of X, Y and Z colours (axis_x, axis_y, axis_z); the Move gizmo's own array is gone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-26 15:35:10 +00:00
amolinari-autotex 47285ccb88 Thread: right- and left-handed direction (#4414) (#4415)
* claim: #4414

* feat: persist right and left thread handedness (#4414)

* fix(thread): verify handedness with referenced holes and complete locales

* test: verify handedness with merged tapped thread catalogues

* test: retain tapped thread depth when changing handedness (#4414)

* test: restrict Unix symlink coverage to Unix targets

* test: inspect hole thread depth inside edit command parameters (#4414)

* test(doc): initialize cylinder radius in handedness fixture
2026-10-26 13:57:08 +00:00
github-actions[bot] da16362626 Regenerate generated files and fold pending files [skip ci] 2026-10-26 18:45:42 +00:00
Nathan Dane c5e63b7871 macOS DMG: blueprint window with larger icons and a drag arrow (#5831) 2026-10-26 12:50:24 +00:00
froglemonade2 e063a7778e Axes and points from circular edges and round faces (#3128) (#4610)
* Axes and points from circular edges and round faces

In 3D, a round edge or face stands for its circle wherever a command
takes an axis or a point.

Revolve, Surface Revolve, both Circular Pattern dialogs, Plane at Angle
and Move -> Rotate take a circular edge (through its centre, along its
normal) or a cylinder, cone or torus face (its axis). The features keep
the pick as a model reference, so they follow the model when a parameter
moves it. Straight edges work as before; flat faces are refused.

Every 3D point input takes a circle's centre: construction points (which
follow the circle), To Object, patch points, hole placement, and Move's
pivot and points. Hovering shows the axis as a dashed construction line
or the centre as a star, and the dialog's chip names what the pick
stands for ("centre of edge 10", "axis of face 3").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Format the round-pick hover check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Selection chips: name a round pick as a circle centre or axis

The chip has room for little more than the body and a word or two:
"Shaft · circle centre", "Shaft · circle axis", "Shaft · face 2 axis",
and "Shaft · point" for a point of the model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Move: a circle's centre in a placed component is where the component shows it

Move's pivot and points read a picked circle from the model in its
component's own frame, while the pick is in the world. They now read it
from the world state (and, editing a Move, from the state before it,
placed the same way), as the viewport and the other round picks do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Plane at Angle on a planar face about a model edge: test that it follows both

Upstream #1956 made a planar face a base for Plane at Angle; this branch makes a model edge an
axis. The rebase keeps both in one PlaneRef::AtAngle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:27:32 +00:00
Karl Von Richter 44b0056d48 Frames: a Weldments ribbon tab (#4003) (#5262)
* Frames: a Weldments ribbon tab (#4003)

- WELDMENTS joins the ribbon after SHEET METAL and is built the same way:
  Sketch (New Sketch), Create (Frame Member) and Configure (Parameters,
  Configurations). Frame Member's home moves there from MODEL > Create.
- Always shown, as a frame starts from a sketch of its lines. It selects
  itself and takes the contextual style when the selected body (or the last
  body of the active component) is a frame member; sheet metal comes first.
- It uses the default accent until the palette has a colour for it.
- The tab label is in every catalog; docs/ribbon-layout.md, docs/frames.md
  and the tab list in docs/control-protocol.md follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Frames: Weldments keeps the ordinary tab look (#4003)

Weldments still selects itself when a frame member is the active body, but
no longer takes the solid contextual fill or the 2 px accent line under the
tab row: selected, it looks like a selected Model tab. Only Sketch and Sheet
Metal (on a sheet body) are contextual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:24:38 +00:00
ivisaf 3bcf77ee32 Expressions: a number and its unit are one value (10 mm / 2 mm is 5) (#6331)
* Expressions: a number and its unit are one value (10 mm / 2 mm is 5)

A unit written after a number was multiplied in at the precedence of `*` and
`/`, so `10 mm / 2 mm` was (10 mm / 2) mm = 5 mm² and `90 deg / 1 rad` a value
in angle², reported as a unit error. The number now takes the unit after it
before `*` and `/` apply; a fraction of numbers before a unit stays one value
(`1/2 in` is half an inch), and an exponent stays a plain number (`2^3 mm`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Expressions: after a division, a fraction before a unit only when closed up

`width / 10 / 2 mm` read the `10 / 2 mm` as the fraction 5 mm and gave
width / (5 mm) = 8 instead of (width / 10) / 2 mm = 2. After a `/` the
fraction rule now needs the fraction written without spaces (`1 in / 1/2 in`
is still 2); elsewhere `1/2 in` and `10 / 2 mm` are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:24:34 +00:00
Victor Santos Oliveira 91638cb1f3 Add practical command guides and a contribution template (#5237) (#6772)
* claim: #5237 command-level guide follow-up

* docs: add practical command guides and resource contributions (#5237)

* docs: index practical guides and reject incomplete command links
2026-10-26 12:24:23 +00:00
raykholo 66b872a749 Web app: open a design from a same-origin path (#6670)
?open= now also accepts an absolute path on the page's own origin, fetched
with the page's scheme, so a self-hosted setup that serves SolidCraft and
other tools under one origin can link a design on a LAN without a public
HTTPS address. Absolute URLs keep the HTTPS-only rule (a URL on the page's
own origin is also accepted), redirects must end on HTTPS or the same
origin, and protocol-relative, dot-segment, backslash and control-character
values are refused.
2026-10-26 12:23:52 +00:00
rlartot c7e53899af Updated AppImage takes the release file name (#3538) (#3658)
* claim: #3538

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Updated AppImage takes the release's file name (#3538)

A versioned AppImage name (solidcraft-<version>-linux-<arch>.AppImage) is
replaced by the new release's name, so zsync-based tools keep finding the
update data. Other names are kept.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 11:58:47 +00:00
Colin Faulkingham b55f30959d AI Preferences: reflect agent authentication results (#2578) (#4253)
* claim: #2578

* fix: reflect agent authentication in login badges (#2578)
2026-10-26 11:57:00 +00:00
Dahak Builds d3720041b6 CI tooling: opt-in bound for local test concurrency (#1188) (#6831)
* claim: #1188

* #1188: split per-binary test threads and matrix workers under SOLIDCRAFT_TEST_JOBS

---------

Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com>
2026-10-26 11:50:10 +00:00
github-actions[bot] c71234edfb Regenerate generated files and fold pending files [skip ci] 2026-10-26 17:24:19 +00:00
Homero Thompson 72a76edcf7 Shortcuts: Ctrl+Shift+S opens Save As in the workspace (#6558) (#6567)
* claim: #6558

* Shortcuts: Ctrl+Shift+S opens Save As in the workspace (#6558)

The Home page already opened Save As with Ctrl+Shift+S, but the design workspace matched Ctrl+S, so the chord saved over the current file instead of offering another one. The workspace now routes the chord to Save As, and the File menu shows that shortcut next to Save As, taken from the command registry.
2026-10-26 11:14:07 +00:00
HiroKenEz 0d32821e9e Top-level cut and join reach bodies in sub-components (#5679) (#6246)
* claim: #5679

* Top-level cut and join reach bodies in sub-components (#5679)

An extrude, revolve or press-pull from a sketch on a face of a body in a
component inside the active one now cuts or joins that body, moved or
turned, in its own component, so every placement shows the change. The
automatic operation probes that body where it is shown. A linked part, or
a face on a further placement of a part placed more than once, is refused
with the reason instead of a silent no-op (#5678).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:13:45 +00:00
sascha2101 e1ff3fa9c0 Batch: refuse a step that would fail at its turn before the first step runs (#5853) (#6781)
* claim: #5853

* Batch: refuse a step that would fail at its turn before the first step runs (#5853)

engine.batch and the MCP batch tool checked only a batch's shape up
front. A misspelled command id in a late step was found at its turn,
after every earlier step had run, and then all of it was rolled back: a
160-step batch with a typo as its last step ran for a minute and
changed nothing.

solidcraft_engine::batch_preflight::check finds, before anything runs,
the first step the batch would certainly refuse at its turn: a step
without a command, an unknown command id (the error names the closest
ids, as at the step's turn) or, with strict parameter checking, a call
that breaks its command's typed contract. Anything that depends on the
design is left to the step's turn.

- engine.batch (control channel) checks against the app's registry and
  its session's level; view.pick, which the app answers itself, passes.
- The MCP batch tool checks when the commands run in its own process
  (headless, with --param-check from the backend). A running app may be
  another version with other commands and checks the batch itself; its
  reply's not_run is passed on.
- The refusal is the failing step's reply with completed 0, undone 0,
  not_run listing every step and a note.

Tests that used an unknown command only to make a late step fail now
use a step that fails at its turn (a bad extrude distance), so they
still test rollback, timings and file.new as before.

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

---------

Co-authored-by: sascha2101 <221609842+sascha2101@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:11:10 +00:00
github-actions[bot] b20f522f5d Regenerate generated files and fold pending files [skip ci] 2026-10-26 16:34:07 +00:00
Mateusz Sych d895fef354 Control channel: a pushed design.changed event for clients that subscribe (#6985) (#6986)
* claim: #6646

* Control channel: document.revision, a design revision and a document id (#6646)

A program that follows the open design asks document.revision and exports
only when the answer moves: document_id names the open design (kept through
edits, saves and renames, another for each design started or opened, never
shared between two tabs or two runs) and revision moves whenever the design,
what is hidden or an uncaptured component position changes. It stays put on
reads, selections and view changes, unlike the session's view revision.

The revision is read lazily: the session remembers the design it last
reported (held weakly, so Arc::make_mut can never change it in place and its
address can't be reused) and takes a new number from one counter for the
whole run when the design is another one. The control method answers at once,
also while a slow command computes; engine.execute reaches the same command
for scripts and MCP.

* document.revision: hash the run's id prefix with the process's random keys

A clock set before 1970 gave every run the prefix 0, so a restarted app could
answer a new design with the id and revision of the old one. The docs no
longer promise an answer at once: a screenshot waiting for an opened design to
be meshed still holds the requests behind it.

* document.revision: its label in the complete catalogs (ja, zh)

* claim: #6985

* Control channel: control.subscribe and design.changed events (#6985)

A connection that sends control.subscribe gets the active design's id and
revision in the reply (as document.revision answers), then a
{"event":"design.changed","params":{document_id, revision}} line whenever
either changes, so a live link need not poll.

The window publishes the design at the end of each frame's logic and
drawing while a connection is subscribed (one atomic load otherwise). Each
subscribed connection waits on that from a thread of its own and writes
the latest after a 100 ms gap, so a burst of changes is one line. Replies
and events share one lock per connection, each written whole (#6390).

* control.subscribe: the reply before any event, a second one refused

The events thread started before the subscribe reply was written, so a
change right after the window's answer could reach the client before the
reply that named the older revision. The subscription now starts holding
the connection's line lock and writes the reply under it.

A second control.subscribe on a subscribed connection is refused on the
connection itself: its answer could arrive behind a newer event. When no
thread or socket is left for the events, the reply says it did not
subscribe instead of ok.

* control.subscribe: a second one does not lose a finished late reply

The already-subscribed answer came before the busy check, so a request that timed out and had finished since lost its reply: control.pending then said the app ended it without one. It now comes after the busy check and drops a finished late reply as every other request does.

* control_server: declare the subscribe guard at the top of the loop

Clear of the lines #6643 changes (its token check moves to where the declaration was).

* control_server: the subscription's items beside serve

Away from the lines next to send, where #6643 adds token_of.

* control test: New on a blank design reuses its tab, so redo the box first

---------

Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
2026-10-26 11:10:03 +00:00
Frank c13e516cd5 fix: allow SpaceMouse rotation after tilting sketch view (#6687)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-26 10:44:31 +00:00
raykholo c264c7a42a Startup falls back from a Direct3D 12 that can't build the UI pipeline (#6648) (#6682) 2026-10-26 10:44:13 +00:00
github-actions[bot] 1cd14e2412 Regenerate generated files and fold pending files [skip ci] 2026-10-26 14:29:06 +00:00
Homero Thompson 2ec11cfc3a Docs: how to open the macOS build when the Gatekeeper blocks it (#5393) (#6566)
* claim: #5393

* docs: how to open the macOS build when the Gatekeeper blocks it (#5393)
2026-10-26 10:41:32 +00:00
Lars Jansen 4a0d519727 View: OK and Cancel in the corner of the view while a dialog or sketch is open (#6709) (#6714)
* claim: #6709

* feat(view): OK and Cancel in the corner of the view while a dialog or sketch is open (#6709)
2026-10-26 10:40:36 +00:00
Thosch 06af6e1107 Pattern dialogs: Quantity is the count in every language, the motion plot keeps its own entry (#6538) (#6733)
The catalogue entry Quantity served both the pattern dialogs' number of
instances and the motion study's plotted quantity. Nine locales had
translated the second meaning, so the rectangular pattern dialog showed
e.g. "Größe" above "Anzahl 2" in German.

The motion study's row now reads motion.plot_quantity (a pending file
that keeps every locale's previous word there). Quantity takes each
catalogue's own ui.quantity text, which the "Quantity 2" row already
shows; nothing is newly translated. The glossary lists Quantity under
words with more than one meaning.

Fixes #6538

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:40:26 +00:00
sascha2101 8108646e2c Docs: a sketch family's shortcut starts the variant used last (Refs #6630) (#6817)
Since #4308, L, R and C start their family in the variant used last, as
the toolbar button does, so L can start a Midpoint Line. The shortcuts
table still read "L | Line". Say so under the table and in the
sketching guide's Geometry section, with the preference that steps
through the variants.


Claude-Session: https://claude.ai/code/session_01FN5eEMrqWWXqi65FcK8GXq

Co-authored-by: sascha2101 <221609842+sascha2101@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:39:51 +00:00
Victor Santos Oliveira b3cbbe7bd5 CLI: reject incomplete and unsupported run/eval options (#6918) (#6919)
* claim: #6918 validate run and eval options

* fix(cli): reject invalid run and eval options (#6918)
2026-10-26 10:38:56 +00:00
Badger B dc3061a039 Docs: on Windows, give claude mcp add the CLI's full path (#5895) (#5896)
* Docs: on Windows, give claude mcp add the CLI's full path (#5895)

The Windows installer puts solidcraft-cli.exe in C:\Program Files\SolidCraft but not on PATH,
so the README's and docs/mcp.md's `claude mcp add solidcraft -- solidcraft-cli mcp` registers a
server that can't start there. Say so next to the command and give the full-path form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: word the Windows full-path note so it holds once the installer sets PATH (#5895)

#5898 makes the MSI add its folder to PATH. Say "if a terminal doesn't find solidcraft-cli
(older Windows installers don't put it on PATH)" instead of stating that the installer never
does, so the note stays true whichever change lands first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: the Windows CLI path is the default, not the only place (#5895)

The MSI installs to ProgramFiles6432Folder and lets people choose the folder
(WixUI_InstallDir), so C:\Program Files\SolidCraft\ is only the x64 installer's default; the
x86 MSI on 64-bit Windows lands in C:\Program Files (x86)\SolidCraft\. Say "by default" in
the README and docs/mcp.md (review on #5896).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:24:34 +00:00
Thosch 102314dbb2 Docs: blurry interface on Linux with display scaling, and how to fix it (#5979) (#6195)
SolidCraft runs through XWayland whenever an X display is available. A
compositor that doesn't let X11 apps scale themselves draws the window at
100 % and stretches it. docs/nix.md said so only for fractional scaling,
but GNOME 47 (RHEL and Rocky Linux 10) does it at any scale: the report
shows 1.05 physical pixels per point at 200 %.

The troubleshooting page gets a section with the cause, the Window system
preference, SOLIDCRAFT_WAYLAND=1 for 0.21.0 and earlier, and the file drop
trade-off; docs/nix.md links to it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:24:30 +00:00
DuBearte a82f839255 Docs: don't offer winget install before the package is in winget-pkgs (#5734) (#5827)
* claim: #5734

* Docs: don't offer winget install before the package is in winget-pkgs (#5734)

The README and docs/downloads.md said Windows users could run
`winget install bherbruck.SolidCraft`, but winget-pkgs has no manifests for
bherbruck.SolidCraft (manifests/b/bherbruck doesn't exist), so winget finds
no package. winget.yml only updates a package that is already listed, and
does nothing until then. Drop the command from both pages, and say in
docs/releasing.md that the first version has to be submitted once by hand
and the command added back when it's listed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Releasing: a first WinGet submission is already open; take it up (#5734)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:39:29 +00:00
raykholo d29e70bad9 docs: Save As blocked by Windows Controlled folder access (#4490)
Saving into Documents fails with the Windows dialog's "File not found" when
Controlled folder access blocks the app, and the message gives no hint.
Refs #4479.
2026-10-26 06:49:53 +00:00
Logan Night 1d482aff74 Docs: AppImageLauncher 2.x can't start the AppImage; update to 3.0 (#4640) (#4674)
* claim: #4640

* Docs: AppImageLauncher 2.x can't start the AppImage; update to 3.0 (#4640)

AppImageLauncher 2.x intercepts every AppImage through binfmt_misc and
can't start static-runtime AppImages such as SolidCraft's: it fails with
"execv error: No such file or directory" after a FUSE message. 3.0 starts
it. One paragraph in the Linux AppImage section says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: AppImageLauncher 3.0 is so far only published as betas (#4640)

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
2026-10-26 06:49:52 +00:00
raykholo 2a01cca00e User guide: local models with the Assistant (#4851) (#4964)
* claim: #4851

* User guide: local models with the Assistant (#4851)

A page on choosing and setting up a local model (Ollama, LM Studio, or any
OpenAI-compatible server) for the Assistant: tool support, VRAM, permissions,
the measured results from the standard test in #4851, and troubleshooting
for the common failures.

* Guide: local models table with the full set of measured results
2026-10-26 06:49:46 +00:00
raykholo d7cc5621fa Troubleshooting: what to do when a design won't open (#5114)
Point to the `<file>.bak` copy every save keeps, the design.solidcraft in crash
reports, the recovery folder for unsaved designs, and how to attach the file
to an issue.
2026-10-26 06:49:44 +00:00
bherbruck 15269f85a1 docs: how to bump the Homebrew tap on a release (#6276)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 06:49:37 +00:00
bherbruck e53390ea1b Roadmap: a short user-facing ROADMAP.md, with the developer detail moved to docs/roadmap-detail.md (#6797)
* Roadmap: a short user-facing ROADMAP.md, developer detail moves to docs/roadmap-detail.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Roadmap: feature milestones with progress counts, daily releases through the in-app updater

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Roadmap: count issues as pieces, show work built on the drawings and render branches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 06:49:35 +00:00
raykholo ffbeb42b5c Assistant: say so when a turn ends without using SolidCraft's tools (#4846) (#5188)
* claim: #4846

* Assistant: say so when a turn ends without using SolidCraft's tools

When tools were offered and a completed turn made no tool call and no
change, the chat panel shows a short notice pointing to tool-capable
models: always for an empty reply, and for a text-only reply to an
explicit edit request. Plain answers to questions stay quiet. The
control channel exposes it as turnWarning.

* Fix the Anthropic loop test for the tools event; add ja and zh for the no-tool-call notice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 02:19:57 +00:00
Matthew Knutson 816bcf10de Every new command comes with input and output schemas (#2829) (#4035)
* Every new command comes with input and output schemas

A test fails for a command without a contract or an output type, unless it is a planned!
placeholder or listed in schema/unconverted.txt, which holds the 400 commands that predate
the rule and only shrinks: the test also fails when a listed command has its schemas, when
the list names a command that doesn't exist, or when it isn't sorted.

`checked!` now takes only the command's id and checks the contract that id publishes
(`run_checked_as`), so the contract enforced is always the one described. Another test runs
every command that has a contract in strict with an unknown key, so a contract is never
published without `checked!`, under the command's own id, enforcing it.

A new book page, Command schemas, explains how to write a contract and a reply type, the
tests to add, the shared field types and how to add one, with a checklist; the failure
messages point to it. "Adding a command", CONTRIBUTING.md and AGENTS.md now include the
schemas, and the MCP tool description and docs/mcp.md no longer list the converted commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* List the commands added on main since: view.layout, view.history_layout, view.normal_to

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Command schemas guide: what participants and targets do, checking the evaluation, warning-free replies

- `participants` changes the result for some features and nothing for others; where it and
  another key override each other, or where it has no effect, say so in that key's
  description or in the summary.
- The example primitive's `targets` default to every body in the feature's component, not the
  bodies it meets; they're ignored when `participants` lists bodies.
- Check what each value does where the feature is evaluated, not only how the handler reads it.
- A reply test runs every form in Warn and checks for no `param_warnings` (Strict for a reply
  that isn't an object).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* List the 43 commands added on main since: frame, component, render and others

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* List the 11 commands added on main since: browser folding, standard views, parameter sweep, path flange

browser.collapse_all, browser.expand_all, inspect.parameter_sweep, sheet.path_flange and the
seven view.* standard views (back, bottom, front, isometric, left, right, top) landed on main
without schemas; the gate flags them, as intended. 457 commands listed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Schema rule warns instead of failing for now

A command without input and output schemas prints a warning listing it
(test output and a CI annotation). SCHEMA_RULE_STRICT in coverage_tests.rs
(or SOLIDCRAFT_SCHEMA_RULE_STRICT=1) makes it fail again. Docs say "should,
and will become required".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-26 01:43:02 +00:00
github-actions[bot] cbac207852 Regenerate generated files and fold pending files [skip ci] 2026-10-25 23:29:18 +00:00
CamWight ab80a410a1 Viewport theme: a light 3D view in a dark window, and the reverse (#4146) (#4147)
* claim: #4146

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Viewport theme: a light 3D view in a dark window, and the reverse (#4146)

Preferences › Interface › Theme gets a Viewport row under the theme tiles:
Follow theme (the default, as before), Light or Dark. Light or Dark draws
the 3D view in the built-in Light or Dark theme's colours whatever the
window uses, so a dark window can show the model on a light view and the
other way round; it works with every theme, theme files included.

The view takes the background and grid, bodies, selection and hover, the
origin, previews, sketches with their dimensions and glyphs, the navigation
cube and triads, box selection and the analysis colours. Panels, dialogs,
menus and the chips over the view keep the window's. Text and warnings drawn
straight onto the view (the sketch status line, the loose-end and midpoint
markers, the section's cut outlines, the 3D sketch tool and the sketch tools'
previews) take the view's side, so they read on its background.

theme::ViewportTheme is the setting (saved as `viewport_theme`: theme, light
or dark; an unknown saved value reads as Follow theme, as ColorVision's
does). Tokens::get() takes the view's colours from the other side only when
the view's dark or light differs from the window's; Tokens::view() is the
view's side for colours drawn onto it. The ground shadow follows the view
(the scene and highlight caches already key on the colours themselves),
ui.render draws in the view's colours, and ui.prefs takes `viewport_theme`
and reports `viewport_dark`. An older release ignores the setting and draws
everything in the theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Viewport theme: follow the single set of axis colours

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-25 22:17:04 +00:00
leValdemar19 b94692497e Sketch Dimension: arc length from an arc and its end point (#754) (#4245)
* claim: #754

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

* Sketch Dimension: arc length from an arc and its end point (#754)

The arc-length dimension existed (sketch.dimension type arc_length) but
the Dimension tool could only give an arc its radius. An arc and one of
its own end points, in either order, now dimension the arc's length:
click the arc, then its end. The pair was refused before ("cannot
dimension that combination"), so no existing result changes. A point
where the arc's end is (a coincident line end) counts as that end.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:17:01 +00:00
raykholo 4355d117ef Assistant: warn when an Ollama model has no tool support (#4846) (#4916)
* claim: #4846

* Warn when Ollama models lack tool support (#4846)

Check Ollama model capabilities in the background and cache results per
endpoint and model. Show an advisory warning for models without tools,
expose it through ui.agent_chat, and document the behavior.

Cover capability parsing, warning selection, background probing, caching,
and selection changes with synthetic regression tests.

* Keep the Ollama capability probe out of the web build

The panel never calls it there, so it would only be dead code.

* Wrap the model warning instead of cutting it off

In a narrow panel the end of the sentence, the part that says what to do, was truncated.

* Fix AgentConfig default after rebase onto main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Move the Ollama no-tools warning into a pending locale file with ja and zh

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 21:37:30 +00:00
ChrisNo a3890b3bd5 Open a linked part from its assembly Browser row (#2348) (#2349)
* claim: #2348

* Open linked designs from assembly browser

* claim: #2348

* Test linked design action with multiple components selected

* Fix linked design lookup in browser storage and translate its menu action

* Add Turn Up Axis to complete UI catalogs

* Keep browser DXF download after linked-design checks
2026-10-25 21:15:48 +00:00
bherbruck 57d787f5ba Docs site: canonical links, robots.txt and sitemap.xml (#6888)
Search Console lists docs.solidcraft.io/, /introduction.html (the same page) and /guide/mcp.html as duplicates without a user-selected canonical. The Pages build now adds a canonical link to every book page (index.html and introduction.html both name /), skips the redirect stubs that already have one, marks 404 and the toc frame noindex, and writes a robots.txt pointing at a generated sitemap.xml.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 18:35:56 -04:00
HiroKenEz b1d4293cf0 One set of X, Y and Z colours for the origin axes, view triad and Move gizmo (#976) (#4430)
* claim: #976

* One set of X, Y and Z colours for every axis (#976)

The origin axes, the navigation cube's triad, 3D sketch triads and joint
origins drew `axis_x/y/z` (255,0,0 / 0,255,0 / 2,2,248), the view triad and
the headless picture drew `triad` (220,60,60 / 60,170,60 / 60,100,230) and
the Move gizmo drew `gizmo` (225,70,60 / 80,190,80 / 70,130,240). The
`triad` and `gizmo` tokens are gone: every axis reads `axis_x/y/z`, now the
view triad's values (the engine's `view::colors::AXIS_*`, so headless
pictures are unchanged, and the set the red-green table was measured for).
Older theme files' `triad` and `gizmo` lists still read and set the axes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 19:59:36 +00:00
raykholo 46f7d4d8dc Preferences: the web app's Updates section says how it updates (#5496) (#5500) 2026-10-25 19:29:04 +00:00
bherbruck 8071096a99 Docs: refresh every UI screenshot, GIF and video from the current UI (#6763)
* Docs: refresh every UI screenshot, GIF and video from the current UI

Re-record the README demo, the rover build, the sample plate and the class-A surface pictures
with 0.22.1 in the default dark theme. The demo script is fixed for the current sketch dimension
boxes and MCP file limits, and the rover replay and class-A pictures now have scripts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: cut the idle time out of the demo and rover recordings

The README demo plays at 6x and the rover replay at 15x with a constant-rate camera orbit, with the stretches where nothing on screen changes cut out by the new trim_idle.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 19:21:01 +00:00