243 Commits
Author SHA1 Message Date
PaddleStrokeandClaude Opus 5.5 6f5894683c Sketch: a preference to stop a quick double Esc from finishing the sketch (#12069) (#12694)
* claim: #12069

* wip: Sketch preference: a quick double Esc can be kept from finishing the sketch (#12069)

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

* wip: profile key count includes the new sketch preference (#12069)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 17:08:58 +00:00
Nathan Dane ea4513728b Panels: keep text readable on translucent surfaces (#11307) (#12985)
* claim: #11307

* Panels: preserve readable text on translucent surfaces

* Panels: keep surface snapshots small and color math in theme
2026-11-07 14:35:56 +00:00
Nathan Dane 8c32875160 Preferences: save and restore panel layouts by workspace (#11306) (#12587)
* claim: #11306

* Preferences: save and restore panel layouts by workspace (#11306)

* Preferences: keep layout keys out of the viewport and fix validation checks

* Preferences: save other settings when panel layout conversion is refused

* Preferences: keep layout key handling scoped and deduplicate web warnings

* fix: retain imported panel column widths

* fix: use shared panel preference controls and tokens

* test: cover custom-height rows in the UI gallery
2026-11-07 07:13:40 +00:00
8e55033d9a Orbit drags keep turning at the edge of the view (#3459)
* Orbit drags keep turning at the edge of the view

An orbit drag that reached the edge of the screen stopped turning: the cursor
stops there, so the pointer reports no more motion. Now, when an orbit drag
reaches the edge of the view, the cursor moves to the opposite edge and the
frame that reports the jump turns the view only by the hand's motion, so the
drag can go round the model as far as the user likes. Synthetic drags
(control channel, scripts) never move the real cursor. Where the cursor can't
be moved (Wayland, the browser) nothing changes.

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

* Orbit cursor wrap: a Navigation preference keeps the old behaviour

Wrapping the cursor during an orbit changes what an orbit drag does out of the
box, so Preferences › Navigation gets "Wrap the cursor while orbiting" (on by
default, `orbit_cursor_wrap` in ui.prefs). Off, wrap_cursor never moves the
cursor and the drag stops at the edge of the screen as before. The new strings
are a pending locale file, with Arabic, Hebrew, Japanese, Vietnamese and Chinese
for the complete catalogs.

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

* Use the current egui id calls

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

---------

Co-authored-by: rootarchitect <7781866+rootarchitect@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-11-06 08:49:18 +00:00
Mario GeigerandClaude Opus 5.5 1589e18f2a Point clouds: remember the source file and reload it (#8818) (#8821)
* Point clouds: remember the source file and reload it (#8818)

A cloud keeps the absolute path it was inserted from. pointcloud.reload
reads it again, keeping the cloud's name, placement, units and colouring,
and the filters on properties the file still has; the Edit Point Cloud card
has a Reload from file button.

The file is read beside the window through the file loader, with progress
and Cancel, as an insert is. A thinned cloud stays thinned to as many points,
which reads an unchanged file as the same points; any other is read as a new
insert would be, so a file that grew comes in whole.

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

* Point clouds: a reload asks before it reaches a network location (#8818)

A design names the cloud's file, and a design may come from anyone. On
Windows, only asking about `\\host\share\x` connects to that computer and
may send it the user's sign-in. So `pointcloud.reload` now reads through
`vfs::read_design_path`, as linked designs do, and Reload from file asks
with the same prompt as Update Links.

The button's label uses its stable message id. The strings gain Korean,
which a new label needs. `pointcloud.reload` gets its line in
tests/kernel-cases/EXEMPT, which the "Every command has a case" job needs.

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

* Point clouds: a reload reads under the limit the cloud was read under (#8818)

The limit was inferred from the counts, as if a cloud with fewer points than its
file had been thinned. A point that cannot be read makes the same difference:
such a PLY read as half its points on an unchanged file, since a limit one below
the file's count is a stride of two, and a file that grew was cut to the old count.
Keep the limit itself: a read is a function of the file and the limit.

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

* Point clouds: a reload drops a value filter when the file stops naming the values (#8818)

A set of values filters a label, and `pointcloud.edit` refuses one on a property with no names.
A reload kept such a filter while the property stayed, so a file that dropped its names comment
left a cloud every later edit refused. One predicate now says what is refused and what a reload
drops.

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

* Point clouds: a reload keeps its undo step and ends a play it moved (#8818)

A reload accepted with the Edit Point Cloud card open left the card's undo
boundary before it, so the card's next edit folded the reload into itself and
one Undo took back both. The boundary now moves past the reload.

A play told its filter by place alone. When a filter before it went, by a
reload, an agent's edit or an undo, the next filter took that place and the
play's range, on screen and written when the play ended. A play now names its
filter's property and ends, unwritten, when that place holds another.

`engine.batch` and the control hook compared command ids exactly, while the
engine takes any case: `POINTCLOUD.RELOAD` passed the refusal and read the file
on the window thread. Both now resolve the id as the engine does, for every
command that loads a file. The batch row of the protocol said the refusal held
only with the agent cursor shown; it always holds.

No test was run locally, at the owner's request: compile, clippy and fmt only.

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

* Point clouds: a file load keeps the request's own param_check (#8818)

`file_load::control` takes a command the file loader runs before
`control::handle` does, so that command skipped the request's `param_check`:
`pointcloud.reload` accepted a word that is no level, a `strict` call with an
unknown parameter read the file anyway, and the reply did not say the level.
`doc.open`, the imports and the DXF export went the same way.

The hook now takes the level itself and checks the call before the file is
touched, as a command that switches designs does: the worker's session goes on
to be the design's, which keeps its own level. Both share the same check, and
the reply says the level and any warnings.

No test was run locally, at the owner's request: compile, clippy and fmt only.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 06:56:52 +00:00
48bab1a65a Design tabs: double-click a tab to rename the design (#10364)
* Design tabs: double-click a tab to rename the design

A double-click on the selected design's tab opens a name field in the tab
with the name selected, so typing replaces it. Enter or a click anywhere
else keeps the new name; Escape keeps the old one. The tab grows with the
name while it is typed (up to the tab's usual 200 pt). The rename goes
through component.rename with component 0, so it is undoable, marks the
design unsaved and is what Save As offers next. A name left as it was or
left blank changes nothing, and names are cut to the 128 characters the
command takes.

On desktop the bar is the window's title bar, and a double-click on a tab
used to maximize the window. Double-clicking the bar's empty space still
does; the tabs now rename. The preference tab_double_click_renames
(Preferences > Interface, "Double-click a design tab to rename it") brings
the old behaviour back.

Changes a default: yes - a double-click on a design tab renames the
design, old behaviour (maximize the window) kept behind preference
tab_double_click_renames.

Strings in assets/locales/pending/design-tab-rename.json (en, ar, de, he,
ja, ko, vi, zh). Docs: the UI tour and the preference list in
control-protocol.md (handle tab:rename).

Tests in documents.rs: Enter renames and undo restores; a click elsewhere
keeps the name and the tab grows while typing; Escape, a blank name and
the same name change nothing; an over-long name is cut to fit; with the
preference off a double-click does not rename.

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

* Fix the tab rename for the current egui and ignore the rename result

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-11-06 04:53:05 +00:00
selune 068c46cf8b Render: restore saved shots, progressive CPU/GPU images and exports (#6201) (#11087)
* Render: restore saved shots, progressive images and exports

* Render: register existing live and coat command tests

* Render: isolate lens saves and retain bounded previews

Save only lens parameters on existing CPU/GPU jobs while keeping unrelated
draft settings dirty. Retain pinned checkpoints through preview and status,
and release host-only snapshots outside the status lock.

Use the admitted PNG bound for registered-executor checkpoint slots. Preserve
executor work credits, final publication and regrade ownership. Add regression
coverage and align help, translations and capability documentation.

* Render: preserve live feedback and address review regressions

* Preserve saved cameras when applying Render library edits

Keep the saved camera when lighting or maps are applied to an existing shot. Fit and centre the measured Render host using the painted picture. Carry forward the upstream CPU and GPU preset and ZoomTool contracts.
2026-11-06 02:47:52 +00:00
Nathan Dane 90d9c6488a Panels: add columns, stacks and tabs with exact drag previews (#11305) (#11608)
* claim: #11305

* Panels: add columns, stacks and tabs with exact drag previews (#11305)
2026-11-05 18:38:54 +00:00
db3558d820 Extrude: the distance arrow snaps to a parallel face and outlines it (#2398) (#9688)
* claim: #2398

* Extrude: the distance arrow stops at a parallel face and outlines it (#2398)

While Extrude's distance arrow is dragged, a flat face parallel to the
profile and lying over it takes the distance exactly once the tip comes
within 8 screen points of its plane, and the face is outlined as a hovered
face is. A cut dragged through a block so stops at its far side. Faces
beside the profile don't catch the arrow; Alt/Ctrl (free drag) turns it off.
The distance stays a number in the existing parameter.

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

* Extrude face stop: clippy (test-only current, +=)

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

* Extrude face stops: a preference, on by default, keeps the old round steps (#2398)

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

* Extrude face stops: follow world_state returning a Result (#2398)

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

* Extrude face stops: import Vec/Plane from solidcore_record after the layer split

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-11-05 18:31:55 +00:00
Leo d5e953871b Sketch Mirror: use the preselected construction line (#10486) 2026-11-05 15:09:19 +00:00
Colin Faulkingham 18b698ffa8 Keep raised models’ ground shadows on the ground (#9838) (#10257)
* claim: #9838

* fix: anchor raised ground shadows to the origin plane (#9838)

* docs: attribute ground shadow preference messages
2026-11-05 05:14:38 +00:00
SS-ENandClaude Opus 5.5 733f0b2254 MCP: opt-in compact inspect_design and tool output (split from #2901) (#3144)
* MCP: compact inspect_design and tool JSON, off by default (--compact / SOLIDCRAFT_MCP_COMPACT)

Split out of #2901 per review: the smaller inspect_design changed the default
for everyone, so it is now an MCP server option that is off unless asked for.

- solidcraft-cli mcp --compact, or SOLIDCRAFT_MCP_COMPACT=1 (true/yes/on;
  0/false/no/off/empty leave it off; anything else is an error at start-up).
  solidcraft_mcp::Options::resolve is the one place that decides, so an app
  Preferences setting can feed it later.
- With it on, inspect_design summarises sketches (id, name, plane, counts of
  points, curves, constraints and profiles, dof, status), returns full contents
  only for the sketches named in `sketches` (names/ids, true, false or
  "summary"), takes a `bodies` filter and measures only those; unknown names
  list the existing ones. Tool JSON is compact rather than pretty-printed.
- Off, tools/list, argument checks, inspect_design and tool JSON are exactly
  as before.
- document.inspect gains an opt-in `sketch_counts` (plane, points,
  constraints); without it its reply is unchanged.

Tests: both modes in the MCP suite, Options parsing, and the CLI flag and
variable end to end.

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

* MCP compact output: a Preferences setting too (AI › Agents through MCP)

The desktop app's Preferences › AI gets "Compact output" under a new "Agents
through MCP" section, off by default and shown with the chat off too. The app
reports it on the control channel as `mcp.options` ({"compact": bool}); the
agent chat lets its own MCP server read it.

A bridged MCP server (`solidcraft-cli mcp --connect`) asks the app when an
agent first lists or calls a tool and keeps the answer for the session, so the
tools it listed keep their shape. An app not running yet, or busy past 2 s, is
asked again on the next call; an app from before the setting counts as off.
`--compact` and SOLIDCRAFT_MCP_COMPACT=1 still turn it on whatever the app says.

Tests: the server follows the app's answer (waits for it, keeps it, the flag
still wins); the checkbox reaches `mcp.options` and Restore Defaults clears it;
the chat gate allows `mcp.options`. docs/mcp.md and docs/control-protocol.md.

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

* MCP compact output: review fixes (mcp.options never blocks, headless test, locales, prefs doc)

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

* MCP compact output: the setting is a section of the AI page; the bridged test answers mcp.options

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

* MCP compact output: the preference test sets it through ui.prefs; rustfmt

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

* MCP compact output: look for a newly started app before asking its options; counts from sketch.inspect for an older app

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 03:33:33 +00:00
froglemonade2andClaude Opus 5.5 71598c0354 Agent control: ui.menu refuses items the design doesn't have, reports the History bar's right-click menu, and gives Edit Joint Limits its own id (#10745) (#10746)
* claim: #10745

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

* Control channel: ui.menu refuses missing targets, reports the History item menu, and tells the joint menu items apart (#10745)

- ui.menu looks a target up and refuses one the design doesn't have ("no body `NoSuchBody`").
- The History bar's feature menu is the shared context menu (Target::Timeline), so ui.menu
  reports it, ui.menuPick runs its items and {"type":"timeline","feature":id} opens it.
  Its Show All toggle moves to TreeState so the menu can list Delete after the marker.
- Edit Joint Limits is ui.editJointLimits and opens Edit Joint with Limits expanded.

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

* Icon audit: open the section and canvas menus on a real section and canvas; a hidden section has a menu too

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

* ui.menu: check a group's or folder's scope and folder name; Delete after the marker gets its own id

A group or folder target is refused unless its scope is a row of its component (`c<id>` or a
placement of it) and the folder is bodies, sketches or construction. The History item menu's
delete of everything after the marker is ui.deleteAfterMarker, so ui.menuPick can tell it from
Delete (review on #10746).

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

* ui.menu: a component's own c<id> scope is the design root's only; test that Delete after the marker deletes

The browser draws a part's folders and groups under its placements (o:<path>), so a c<id> scope
for any component but the root names a row that isn't there (review on #10746). The History test
now picks ui.deleteAfterMarker and checks the features are gone.

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

* ui.menu: a placement scope must be spelt as the browser keys it

o:012 parses to placement 12 but isn't the row's key (o:12), so Show/Hide would store a key no
row reads (review on #10746).

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

* History item menu: no Delete after the marker when nothing shown is after it

A timeline target for a feature the bar's component filter leaves out listed no features, so the
item did nothing (review on #10746).

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

* ui.menu: a plane target must be construction geometry

The plane menu's Show/Hide keys the feature's name as an origin item, so any other feature got a
menu whose actions don't fit it (review on #10746).

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

* ui.menu: accept the view navigator's and selection filter's menus, which main added

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 02:35:55 +00:00
Colin Faulkingham 4d2691e636 Assistant: opt-in HTTP authentication for private endpoints (#5341) (#10674)
* claim: #5341

* Allow per-endpoint HTTP authentication with explicit consent

* fix: discard model listings after HTTP consent revocation
2026-11-05 02:12:56 +00:00
Christian HammacherandClaude Opus 5.5 4a906699ee Browser: the component menu keeps its everyday actions and groups the rest in flyouts (#8769) (#8770)
* Browser: the component menu keeps its everyday actions and groups the rest in flyouts

A component's or placement's right-click menu had grown to about thirty entries in seven
blocks. Activate, Edit in Place, Open Linked Design, Move/Copy, Show/Hide, Isolate, the
clipboard, Delete, Rename, Appearance, Physical Material and Properties stay on the menu;
Ground, Capture and Revert Position, Unlock Contents and Turn Up Axis move to a Position
flyout, Relink Source or Extract to File and the exports to File, New Component, New Group
and Paste New to New, and Show All Bodies, Cycle Component Color, Expand All and Collapse
All to Display. context_menu::entries lists a menu with its flyouts, as ui.menuPick reads it.

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

* Browser: the component menu nests its flyouts by topic, and flyouts no longer scroll

Position (Ground, Capture and Revert Position, Unlock Contents, Turn Up Axis), Component
(New Component, Rename, Appearance, Physical Material, Cycle Component Color, Relink Source
or Extract to File, Properties; Design on the design's row), Export (Export, Save As Mesh,
Send to Slicer) and Browser (New Group, Expand All, Collapse All) each open a flyout; Paste
New stays with the clipboard and Show All Bodies with Show/Hide. Flyouts open inside flyouts,
so Appearance keeps its quick choices inside Component; the keys walk in and out of them.

A flyout no longer scrolls or sits away from its row: every flyout has its own area, measured
whole, where a short one used to squeeze every later one into its height. A component's only
body is no longer offered as a component of its own on a folded Bodies folder's entries.

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

* Browser: the component menu starts with what a double-click does, and keeps the old order of its sections

A linked component's menu starts with Edit in Place and Open Linked Design when a double-click
edits it in place (double_click_components), and with Activate otherwise. Position, Component
and Export follow Move/Copy, then the clipboard, then Show/Hide and Isolate, with Browser last,
as the sections came before the flyouts.

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

* Browser: Show All Bodies is on a component's menu only while a body is hidden

It is listed while a body is hidden itself, in a hidden placement, or in a hidden Bodies folder or
group of bodies, anywhere in the design, since that is what it shows.

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

* Browser: Relink Source and Extract to File sit right below Rename in the Component flyout

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

* Browser: Placement and Organize flyouts, Turn Up Axis back as a flyout, and flyout fixes

Placement (Ground, Turn Up Axis, Capture and Revert Position, Unlock Contents) follows
Move/Copy above the first separator, Turn Up Axis opens its two turns in a flyout again, and
the Browser flyout is called Organize. The Component flyout has three blocks: New Component
with Relink Source or Extract to File, then Appearance, Physical Material and Cycle Component
Color, then Rename and Properties.

A flyout of a flyout that opened to the left opens to the left too instead of covering the
menu, Left back to the menu chooses the row that opened the flyout, ui.menuPick refuses a row
that only opens a flyout, and the icon audit checks every level. The guides and the control
protocol describe the new menu paths.

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

* Browser: ui.menu gives a flyout's rows their placeholder flag too

ui.menu set placeholder only on the top-level rows, so a client reading
a flyout row's placeholder got nothing. The icon audit now reads the flag
of the flyout rows instead of resolving their icons itself.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:05:26 +00:00
PaddleStroke af5644aee6 Ribbon: switch panel menus on hover after the first click (#11447) (#11713)
* claim: #11447

* Add an option to switch ribbon panel menus on hover

* Update profile membership count for ribbon hover setting
2026-11-04 22:22:38 +00:00
Mateusz SychandMateuszSychXpl 46edd8d749 Agent chat: Custom instructions in Preferences, added to the system note (#8220) (#11105)
* claim: #8220

* Agent chat: Custom instructions in Preferences, added to the system note (#8220)

Preferences > AI gets a multi-line Custom instructions field, saved with
the other AI preferences (agent_instructions, kept by page resets like
other user-written text). The chat adds the text after its own system
note when a session starts, by the routes #9811 set up: ACP session/new
(the Claude adapter's _meta key, the standard systemPrompt field, the
Antigravity key) and the system message or field of every API protocol.
Connect and New chat set it, so an edit applies from the next chat and
never changes the one running. Blank text adds nothing; at most 4000
characters are kept, in the field, over ui.agent_chat and from a hand-
edited settings file. ui.agent_chat takes and reports `instructions`.

* Custom instructions: typing in the field stays in the field

The text area did not report itself to Preferences search as a key sink, so with
the field focused, search took the typed characters and moved focus away. The
field now notes the sink while it has focus, like the other preference fields,
and the #8220 test types into it.

---------

Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
2026-11-04 22:07:30 +00:00
dudedagger42andClaude Opus 5.5 2fdcc5ae49 Appearance: a picture of your own behind the model (#11353)
* Appearance: a picture of your own behind the model

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

* Background picture: a label that fits its row

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:53:10 +00:00
raykholo 3aee35fe01 Web app: keep unsaved work in the browser instead of the leave-page box (#10220) (#10221)
* claim: #10220

* Web app: keep unsaved work in the browser instead of the leave-page box (#10220)

A new preference, off by default, on Preferences > General > Saving (web
app only): "Keep unsaved work in this browser instead of asking when the
tab closes". With it on, each open design with unsaved changes keeps a
copy in the browser's private storage (keep-<page>-<design>.sc/.json),
written once the design has been still for 0.8 s (at most 4 s after the
first change it lacks) and again on pagehide or when the page is hidden.
While every copy is current, beforeunload doesn't ask. A copy goes when
its design is saved, closed, or the preference is turned off.

The next visit offers the copies newer than their design's last save in
SolidCraft's own window, "Restore unsaved design: <name>, changed
<time>?", one window for several, with Restore, Open saved version, and
Discard. A page holds a Web Lock while it runs, so another open tab's
copies are never offered or removed.

With the preference off, the single autosave and the browser's prompt
work exactly as before.

* Web app: the restore window comes from the UI kit's recovery module (#10220)

The kit's text and divider helpers are private to the UI crate, so the
"Restore unsaved design?" window moves to recovery_ui
(browser_copies_window), beside the desktop recovery window, and the web
shell only maps its answer. Also keeps the window handle for the page
listeners instead of using the one moved into the app.

* Web app: restore window buttons sit in one row (#10220)

* Web app: keep unsaved work and still ask, unless told not to (#10220)

Keeping a copy in the browser no longer replaces the browser's leave-page
box by itself. A second option, shown once work is kept and on by default,
leaves the box in place; off, the box appears only while a copy isn't current.

* Web app: kept-copy review fixes (#10220)

A failed write of a kept copy waits 30 s before the next try, a recovery
copy is dropped only after the remembered saved file has opened, the
preference is documented under its current label, and the ui.prefs list
is sorted again.
2026-11-04 21:26:23 +00:00
0690ee5875 Web app: run as a modelling editor inside another page that keeps the design files (#8517) (#11273)
* claim: #8517

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

* web: editing embed for host pages (?embed=editor, #8517)

A host page that keeps the files itself and frames SolidCraft for modelling needs
the modelling UI without the application chrome. `?embed=editor` runs the web app
as such an embed:

- no application bar (logo, File menu, document tabs, update, help, report a bug)
  and no start page; the layout is docked;
- the ribbon, browser, timeline and properties stay; Ctrl+Z and Ctrl+Y still undo
  and redo;
- Ctrl+N, Ctrl+O, Ctrl+S, Ctrl+W and Ctrl+, are left to the host;
- nothing is kept in the browser (no stored designs, autosave, recovery prompt,
  preferences or leave-page prompt), as with the existing viewer embed.

The existing `?embed&open=` viewer embed is unchanged. SolveApp gets one flag,
`embed_editor`, for desktop and test hosts too.

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

* control: document.export / document.import / document.saved for a host (#8517)

An editing embed's host keeps the design itself. Three control methods
(window.solidcraft.request in the browser; the desktop control channel too; not
the agent chat's, whose method list is unchanged):

- `document.export` -> {name, revision, dirty, format: "json", text}: the active
  design as a `.json` design file holds it. `revision` is the one
  `document.revision` answers, so a host that follows the design compares one number.
- `document.import {text, name?}`: replaces the active design with that text,
  timeline and parameters as saved, opened saved with a new `document_id`. It runs
  as a design opened in a tab of its own, with the old tab closed without asking,
  so whatever was open in the old design leaves with it. A text that does not read
  leaves the design as it was. Waits behind a file loading or a design change, as
  commands do, and evaluates on the window thread.
- `document.saved {revision}`: the host saved that revision; refused when the
  design has changed since.

They are control methods, not commands: they act on the app's open design. The
browser API test gets a round trip through all three.

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

---------

Co-authored-by: aduijs <7501203+aduijs@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:23:25 +00:00
froglemonade2andClaude Opus 5.5 1432131e95 English: command labels in title case, other labels in sentence case (#9085) (#10734)
* English: command labels in title case, other labels in sentence case (#9085)

The rest of #9085 after #9194 (the plural and the spelling) and #9907
(the Preferences page names). Command labels are in title case (422 of
430 were already); the seven in sentence case follow, and Fix/UnFix
reads Fix/Unfix. The UI text skill states the rule. The user docs name
the Preferences footer's button by its current label, Restore page
defaults (#10295).

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

* Navigation bar menu test: the echo names the command by its own label

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

* UI text skill: state the case rule in one short sentence, under the 3600 limit

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

* Localization doc: the case rule in full, with examples

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

* Localization doc: the example button is Restore page defaults now

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:39:52 +00:00
cronos de9a2bc846 Shaded with hidden edges: optionally select edges through faces (#11841)
* Allow optional hidden-edge picking in Shaded with hidden edges

Keep visible-only picking as the default. Cover the preference, hover cache,
section and body visibility, and Fillet inputs in the existing UI tests.
Use platform-absolute fixture paths in the Windows CI argument-parser test.

* Respect section caps and visible-edge ties in hidden-edge picking

* Keep section caps as occluders behind nearer kept faces
2026-11-04 18:13:40 +00:00
froglemonade2andClaude Opus 5.5 3e70ad9876 View navigator: right-click to choose Axes, Cube or a Custom body (#10266)
* View navigator: a custom body as the navigator, and a right-click menu to switch types

A right-click anywhere on the view navigator opens a menu with its three types: Axes, Cube and
Custom. Custom opens the Custom View Navigator panel (a feature panel with OK and Cancel): pick a
body in the view, its texture (Themed: the cube's colours; Modeled: the body's own appearance and
the view's edge colour), and whether the cube's rotation arrows and Home button go around it. The
navigator previews the panel's choices while it is open; Cancel leaves it as it was.

The custom navigator draws the body at the cube's size through a small depth-buffered raster, so
hidden faces stay hidden; hovering a face highlights it, a click looks straight at it (and frames
the model with navigator_fit on), a drag orbits. Until a body is chosen it draws the cube.

The body is kept as a packed snapshot (16-bit, base64) with the preferences and in settings
profiles, so it stays across runs and designs and travels with an exported profile. Bodies over
10,000 triangles, and long or flat ones (thinnest width under a fifth of the widest), are refused.

New command view.navigator (style, body, texture, arrows, home) does the same without opening
anything; new preferences navigator_texture, navigator_arrows and navigator_home, and a Custom
choice for navigator_style. Defaults are unchanged.

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

* Custom view navigator: a hovered face in Modeled takes the view's selection colours

In the Modeled texture the face under the pointer is filled and outlined the way the view selects
a face of the model (sel_face, sel_edge), not in the cube's hover blue and accent, which Themed
keeps.

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

* Custom view navigator: a hovered face in Modeled lights up as the view's mouse-over does

The face under the pointer keeps its own colour, a little lighter (hover_face_lift) and still
shaded, with its edges in the view's mouse-over edge colour (hover_edge), as the 3D view shows a
face under the pointer; not the selection colours. Themed keeps the cube's hover blue and accent.

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

* Custom view navigator: rotation arrows and Home on by default

navigator_arrows and navigator_home start on, so a new custom navigator has the cube's arrows and
Home button around it; the Custom View Navigator panel turns either off.

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

* Custom view navigator: the strings in every complete language, and test fixes

- The new messages in Arabic, Hebrew and Vietnamese (complete catalogs, like Japanese and Chinese).
- The navigator's raster goes through one colour helper, listed with its reason among the files
  allowed colour literals (the design's appearance shaded into pixels).
- nav_settings joins the requested-icon manifest (the view.navigator command's icon).
- A visible edge piece is kept only when the stretch seen with it, across the edge's segments, is
  at least two samples long: a hidden edge no longer shows a sliver at a silhouette corner.
- The navigator layout test treats Custom without a body as the cube it draws; the panel and
  size tests no longer assume an empty undo list, the style before opening, or a coarse sphere.

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

* Custom view navigator: profiles carry its texture, arrows and Home

Settings profiles keep a fixed set of preference keys (#9907), which the custom navigator's newer
settings are not part of. They travel in the profile's own `view_navigator` entry, next to its
body (`view_gizmo`): captured, checked (a value this version can't read is left out) and applied,
leaving the fixed key set unchanged. The cube's arrow inversion (#10286) applies to the custom
navigator's arrows too, through the shared arrows().

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

* Custom view navigator: follow main's Vec3 move and fallible world_state

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

* Custom view navigator: list view.navigator in the rig's EXEMPT, refuse a stored body that can't save again, right-click without a widget over the navigator

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

* Custom view navigator: keep the body unless picked again, save only a profile that reads back, no navigator menu through a popup

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

* Custom view navigator: refuse a stored body with a triangle past its points

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

* Custom view navigator: a stored body meets the triangle and aspect limits a picked one does

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

* Custom view navigator: a body at the 5:1 limit stays inside it once packed

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 17:12:27 +00:00
7bd66b7c06 Sketch dimensions: enter the value in a small window with step arrows (#7246) (#7251)
* claim: #7246

* feat(sketch): enter a dimension's value in a small window with step arrows (#7246)

* Dimension window: fit the layer split, and keep the wheel off the camera over the window

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-11-04 05:12:31 +00:00
Nathan Dane c5bc849913 Blur: keep themed backing and notice actions accessible (#9810) 2026-11-04 00:52:09 +00:00
bherbruckandClaude Opus 5.5 381ff99f70 Desktop: one design's long kernel call no longer stops other designs (#11684)
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>
2026-11-03 19:00:01 +00:00
Nathan Dane fbd30b0bd0 Panels: inspect and change layouts through commands (#11304) (#11454)
* claim: #11218

* Panels: add shared layout rules and retained content runtime

* claim: #11304

* Panels: inspect and change layouts through shared commands (#11304)

* Panels: account for layout commands in geometry coverage
2026-11-03 13:55:50 +00:00
89f1234f28 Browser: placements start closed (#9274) (#9658)
* claim: #9274

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

* Browser: placements start closed (#9274)

A large assembly opened with every placement unfolded, so the browser was a
long list to scroll through. Placements now start closed; opening one shows
its own placements still closed, and closing and reopening it leaves them as
they were. Find in Browser, a pick in the view, Expand All and Collapse All
open and close them as before.

Preferences > Interface > Components start open (browser_components_open)
keeps every placement open from the start, as before.

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

* Browser: scenarios and the icon audit open placements, which now start closed

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

* Browser: tests that read rows inside placements set the open-placements preference

Three tests added on main since this branch started (joint folders, Features
folder marks, group rename) look at rows inside placements, which now start
closed.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <tenbee91@gmail.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-11-02 16:39:25 +00:00
bherbruckandClaude Opus 5.5 c7547eb3a8 Extrude: a face picked off the profile's plane is the target by default (#11201)
With a profile or face picked, clicking a face, vertex or parallel plane that is
not in the profile's plane now sets Extrude to To Object, not one more profile.
Clicking into the Profiles box first makes the next picks profiles again.
Preference extrude_auto_to_object (Tools) turns it off.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:00:40 +00:00
bherbruckandClaude Opus 5.5 21fc384e40 Control channel: a new connection has five seconds to show its token (#10961)
A client could connect and send nothing, or only blank lines, and hold one of the 16 connection
seats for as long as it liked. All reads before the token now share one five-second deadline; the
connection is then closed without a reply. An authenticated connection may idle as before.

`solidcraft-cli mcp --connect` used to open a connection at start and hold it until the first tool
call. It now only checks that the app is there, and the first call connects.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 04:23:23 +00:00
bherbruckandClaude Opus 5.5 5d6a80ff35 Control token file: no file in a custom folder when icacls times out (#10958)
On Windows the token file is restricted with `icacls`, which may not finish in time (#6145). That
counted as success everywhere, and is safe in the default folder, the user's own local app data.
A folder picked with SOLIDCRAFT_CONTROL_DIR may be readable by others, so there a timeout now
removes the still empty file and returns an error. The default folder behaves as before. The
decision is a small function of its own, tested without running icacls.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 04:08:13 +00:00
froglemonade2andClaude Opus 5.5 e9b08f4af4 Control channel: report the dialog as data, the open tool windows, and what ui.start opened (#9087) (#10740)
* claim: #9087

* Control channel: report the dialog as data, the open windows, and what ui.start opened (#9087)

`ui.inspect.dialog` (and `ui.editFeature`'s reply) was the dialog's Rust Debug text, which
changed with every refactor and couldn't be parsed. It is now an object: the dialog's command,
title, the feature an edit rebuilds, its selection inputs, its error, and the commands OK runs
(or what it waits for). `hover` in `ui.inspect` and `ui.selection` is a selection-like item
instead of Debug text.

`ui.inspect` gains `windows`: the tool windows open beside the model (Parameters, Bill of
Materials, Design Properties, Sketch Report, material card review) by the command that opens
each, and the Help menu's (About, Updates, Shortcuts, Crash Reports, Report, Messages) by their
`ui.help` item. Before, an agent couldn't tell these windows were open.

`ui.start` and `ui.editFeature` reply with what they opened (tool, dialog, windows), the status
line, and `pending` when the start waits for the history and opens on a later frame.

Scenario `dialog` checks match words of the dialog's state from the app directly, so the
scenario files are unchanged.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 00:08:48 +00:00
Rec0iLandClaude Fable 5.1 52f0b52b45 Agent chat: a searchable model picker with a custom entry, listed from every provider, and OpenClaw and OpenRouter presets (#2582) (#10255)
* ui_kit: search_picker, a filtered dropdown with a custom entry

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

* Agent chat: endpoints list their models with names, say when listing fails, and OpenClaw and OpenRouter presets (#2582)

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

* Agent chat: a typed model goes to endpoints and to agents that offer a model option

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

* Agent chat: the header's model pickers search and take a custom model

The popup can't grow once it is open, so search_picker now fixes the height of what changes below
its box when it opens: the custom row or a late list could otherwise end up out of reach.

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

* AI preferences: pick an endpoint's model when adding it and on its card (#2582)

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

* Agent chat: model picker rows read from the left, and a refused typed model says which

From running it: list_picker centres its text, which reads badly for a long list of ids, and an
agent's own refusal can say no more than "Internal error". The search box also asks for a repaint
while it waits for the focus, so an idle window does not stop short of it.

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

* Agent chat: docs for the model picker

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

* Agent chat: an endpoint's answer that is no model list says so, an empty list too, and editing lists with the kept key

A 200 without a `data` array (a web page where the endpoint should be, as OpenClaw's gateway
serves until its chat endpoint is enabled) was cached as a successful, empty listing, so the
picker stayed blank with nothing to say and never asked again. Now it is an error with its own
note, an empty list says so, and both are asked for again the next time.

The Edit dialog lists its endpoint's models when it opens, with the kept key read from the
keychain on the listing's thread, as the card does; the key stays out of the field.

The method-not-found test expects the refusal notice that names the model, as every refused
model gets since this branch.

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

* Agent chat: models from several providers fold under their providers inside the picker

As Chemiseblanc does in #10187: with two or more groups, `search_picker` draws each group as a
header with a chevron, the name and how many of its choices are listed, and a click folds or opens
it. Before anything is typed only the current value's group (and the one the caller asks for) is
open; a group with a match opens once something is typed; a fold made by hand stays until the popup
closes. Enter takes the first row shown, so never one folded away. A lone group keeps its plain
heading.

The header's model picker feeds its providers in as groups, so the separate provider drop-down
goes; the control channel's `provider` now says which group opens first. A header click gives the
focus back to the search box, so typing goes on filtering.

The dialog's listing test checks what kind of listing it got rather than translated words, which
the listing thread may render in another language than the test's.

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

* Agent chat: rustfmt the provider groups

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

* Agent chat: an endpoint's models named `Vendor: Model` fold under their vendors

OpenRouter lists `openai/gpt-6.1-terra` as "OpenAI: GPT-6.1 Terra". A listing whose ids read
`vendor/model` and whose names read `Vendor: Model` now names its providers, so the picker folds
it under its vendors like a multi-provider agent; the rows read the model's name, and the id stays
in the tooltip and in the search. An agent's own `Provider: …` word still comes first. One vendor
is one flat list, as before.

The Add dialog's picker has no current model to prefer, so with nothing to prefer every group
starts open; folding is a click away.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 20:01:26 +00:00
a5a561caae Add Creo Parametric navigation preset (#3507) (#9322)
* claim: #3507

Co-authored-by: Codex <codex@openai.com>

* Add Creo Parametric navigation preset (#3507)

Add middle-button orbit, Shift+middle pan and Ctrl+middle vertical drag
zoom, with downward dragging zooming in. Keep the default navigation
preset and existing presets unchanged.

Refs #3507

Co-authored-by: Codex <codex@openai.com>

* Navigation: Creo preset needs the NX preset's reverse_drag_zoom field

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

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:57:15 +00:00
Nathan Dane 7366fe0ecc Blur behind panels: render path, zero cost when off (#8876) (#9809)
* claim: #8876

* Add optional viewport-only Kawase blur and native UI composition

* Fix vendored panel hook imports and deprecated float constant import

* Drain texture updates in the full GPU blur fixture

* Hold the blur evidence fixture camera fixed across radii

* Address blur compositor lint checks

* Share animated Render preview background with blur source

* Use resolved Design background for blur source

* Exercise blur rendering independently of software adapter policy in CI

* Use stock egui hosts instead of vendoring the full crate

* Preserve feature-window open handling with stock egui hosts

* Target the native Window in close-handling regression fixture
2026-11-01 01:37:44 +00:00
Nathan Dane 07160d9366 Preferences redesign 3/11: page structure, aliases and profile card (#9875) (#9907)
* claim: #9875

* Preferences: split pages and preserve aliases and profiles

* Preferences: preserve moved-page regressions and complete translations

* Preferences: retain newly added settings in profiles

* Preferences: target Tools in tool-cursor persistence tests
2026-10-31 22:05:20 +00:00
Nathan Dane 4594d81f7a Gruvbox: light and dark themes with three contrast choices (#10292)
* claim: consolidate Gruvbox contrast variants

* Consolidate Gruvbox variants into light and dark contrast choices

* Check both original Gruvbox viewport gradient endpoints

* Reset Gruvbox scenario state before independent theme checks
2026-10-31 21:58:30 +00:00
froglemonade2andClaude Fable 5.1 441d67f9ff View cube and axis gizmo: a standard view centres and fits the model (#10091) (#10092)
* claim: #10091

* View cube and axis gizmo: a standard view centres and fits the model (#10091)

A new Navigation preference, "Fit the model after a navigator view change"
(`navigator_fit`, off by default): with it on, a face, corner or arrow of
the view cube and an axis tip of the gizmo look at the middle of the model
from the one distance that fits its bounding sphere, so Home, an opened
design and every view chosen on a navigator share one zoom and one centre
and only the direction changes. Off, both navigators turn in place as
before.

"Home and Fit size" (`home_fit_size`, 10–100 %, default 100 %) is how much
of the view between the panels and the controls the model fills when Home,
Fit, an opened design or a navigator view change frames it; 100 % is the
framing as before.

`view.navigate` takes an optional `fit: true` with a direction or a turn,
so programmatic callers get the same framing.

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-31 18:34:13 +00:00
85197c1224 Selection: a freehand lasso that takes what is fully inside it (#4376) (#10185)
* claim: #4376

* Selection: a freehand lasso that takes what is wholly inside it (#4376)

The SELECT panel gets a Lasso checkbox (UiState::lasso_select, ui.set
lassoSelect). With it on, a primary drag from empty space draws a
freehand loop; the release selects through the same path as the window
box: items whose points are all inside the loop and no segment crosses
it, so a concave loop leaves out a curve that bulges out of it. Shift
and Ctrl add as with the box. ui.drag takes via waypoints (and scenario
drag steps take more than two points) so agents and tests can draw it.

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

---------

Co-authored-by: thocsmith <193096300+thocsmith@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 18:31:21 +00:00
PaddleStrokeandClaude Opus 5.5 ef0914ff94 Design tabs: optionally keep each design's dialog, tool and toolbar tab (#9360) (#9656)
A switch between design tabs cancels the open dialog and tool of the design
left and shows MODEL. With the new Interface preference "Keep dialogs and
tools open when switching designs" (keep_work_on_tab_switch, off by default)
each tab keeps its dialog (with its picks and values), its editing state, its
tool and its toolbar tab, and has them back when it is shown again. A feature
still computing after OK is cancelled as before. A feature edit's saved source
revision follows the view refresh of the switch, so its Cancel still restores
the history.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:04:22 +00:00
HiroKenEzandClaude Opus 5.5 8f259d5b83 Sketch: the Line tool can switch to a tangent arc and back without changing tool (#9489) (#9553)
* claim: #9489

* Sketch: the Line tool can switch to a tangent arc and back without changing tool (#9489)

With Preferences > Sketch > "Rest on a line's last point to switch to a
tangent arc" on (off by default), leaving the chain's last point and resting
back on it for 0.35 s makes the next click a tangent arc, by the existing
sketch.arc.tangent command, and the same gesture goes back to lines. A label
at the cursor says which. sketch.arc.tangent's end can now name an existing
point, so an outline drawn this way closes.

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

* Sketch: the cursor label names the command in words (#9489)

The label asked the catalog for a message id that doesn't exist, so it showed
the id. It now takes the command's translated label, and the test checks the
words it paints. Moved clear of the pointer's own badge.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 11:21:59 +00:00
momysnowandClaude da23eb1377 Sketch dialog follows "Dialog buttons at top" (#9860) (#9884)
* claim: #9860

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

* Sketch panel follows Dialog buttons at top (#9860)

The Sketch panel drew Finish Sketch, Look at and Slice in a footer under
its options even with Preferences > Interface > Dialog buttons set to
Top. Panel::palette now reads the same published preference as the
feature cards and draws its footer row under the header, above the
options, when it is Top. With the preference off nothing changes.

Changes a default: no

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

* Docs: Dialog buttons at top also moves the Sketch panel's Finish row (#9860)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-31 06:23:41 +00:00
PaddleStrokeandClaude Opus 5.5 0067dcab28 Settings: edit an added AI agent (#9619) (#9653)
* claim: #9619

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

* Settings: edit an added AI agent (#9619)

Agents you added in Preferences > AI get an Edit button between Test and
Remove. It reopens the Add agent dialog filled with the agent's name and
command, or its protocol, preset, endpoint, model and request timeout, and
Save changes the entry in place: same id, permission override and
always-allowed tools. The stored key is never read back into the dialog;
an empty key field keeps it (still only sent to HTTPS or this computer),
a new key replaces it. The control channel gets `edit_dialog`.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 04:33:18 +00:00
Nathan Dane d7cba9e96d Preferences: theme options list and the opacity option (#8876) (#9807)
* claim: #8876

* claim: #8876

* Theme options: persist per-theme values and expose preferences contracts

* Restore selected theme mode after stopping a followed theme

* claim: #8876

* Preferences: render theme options and apply readable panel opacity

* Use floating-point scale expectation in theme preferences scenario

* Keep panel opacity colour construction inside theme tokens

* Complete theme options translations in Arabic Hebrew and Vietnamese

* Let standalone theme sliders fill their option cells
2026-10-31 04:01:29 +00:00
Colin Faulkingham 213e05da5f Shortcuts: normalize and validate text bindings (#9733) (#9800)
* claim: #9733

* Fix text shortcut normalization and current bindings (#9733)
2026-10-31 02:25:15 +00:00
PaddleStrokeandClaude Opus 5.5 3877ef08b9 Measure: drag the labels away from the part (#8510) (#9395)
* claim: #8510

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

* Measure: drag the labels away from the part (#8510)

The distance and X/Y/Z labels in the view follow a drag of the pointer and keep
a leader to what they measure; a double-click or a new measurement puts them
back. A press on a label picks nothing, starts no box selection and opens no
Select Other.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:00:23 +00:00
PaddleStrokeandClaude Opus 5.5 cce337f83f Sketch: alignment guides from any hovered point while drawing (#9105) (#9673)
* claim: #9105

* Sketch: alignment guides from any hovered point while drawing (#9105)

While a drawing tool waits for a point, hovering a line or arc end, a
rectangle corner or a free point wakes the same temporary horizontal/
vertical tracking guide as a circle centre or line midpoint. Idle
hovering keeps centres and midpoints only. Preference
sketch_tracking_points (on) turns it off.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:00:07 +00:00
Nathan Dane 5bd5be9543 Viewport status item: standard details card (#8613) (#8614)
* Keep viewport summary menus below modal owners

* Build viewport status details from shared blocks

* Keep details focus checks outside context data locks

* Preserve native editor Escape ownership in details cards

* Initialize strict contract test sessions directly

* Translate viewport status detail cards

* Use inferred slider options and test legacy Section editing
2026-10-31 01:27:12 +00:00
PaddleStrokeandClaude Opus 5.5 0096e694dd Parameters: an option to apply edits together, when you choose (#9279) (#9400)
* claim: #9279

* Parameters: an option to hold edits until Apply or OK (#9279)

"Apply each change as you leave its field" (on by default, remembered in
the preferences as parameters_apply_live). Off: an expression edit is
checked when its field is left but waits, without a preview; Apply or OK
sets every held edit in one parameters.change {changes}, so the design
rebuilds once and one undo takes them back. Cancel, the close button and
Escape drop them. Turning the option back on applies what waits.

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

* Docs: the parameters_apply_live preference in ui.prefs (#9279)

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

* Parameters: the hint says edits wait for Apply or OK when they do (#9279)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:57:45 +00:00
Alex Lytvynenko ffbf9836cc Agent chat: support ACP configuration options and OpenCode V2 (#3305) (#3867)
* claim: #3305

* fix(agent-chat): support ACP configuration options (#3305)

Handle current select options for model, thinking effort and mode, with confirmed snapshots and legacy compatibility. Full quality gate attempted; draft delivery authorized with unrelated geometry/property/timing failures documented in PR #3867.

* fix(agent-chat): keep configuration selectors inline (#3305)

Use compact value pickers and bounded wrapping to preserve conversation space; verified at normal and narrow widths with the installed OpenCode V2 server.

* style(agent-chat): format tool events
2026-10-30 20:00:26 +00:00