* claim: #3654
* Control channel: control.running lists what the app is running, across connections (#3654)
control.pending answers only for the connection that asks, so a second client,
the MCP bridge after a reconnect or a script saw {"pending": null} while the app
was busy. control.running answers for the whole app, the same on every
connection and at once (the connection's own thread answers it, also while it
is busy with a timed-out request): every request the app has been sent and not
answered yet, oldest first, with its connection, id, method, command id (or a
batch's step count), seconds since it arrived and whether it still waits its
turn. A timed-out request stays listed until the app answers it, also after its
connection closed. Parameters are never shown.
The window marks a request started when it takes it (ControlRequest.started),
which tells queued from running. The MCP server gets a read-only `running` tool.
---------
Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
* claim: #3242
* MCP batch: rollback restores the design the batch began in (#3242)
A failed batch with rollback: true reported rolled_back: true even when the
design never went back. Two defects, both fixed:
- file.new (and any document-replacing command) replaced the session with it,
taking its checkpoints down too, so a batch that failed after file.new had
nothing to restore. Session::replace_design now carries the checkpoints over
to the fresh session: the checkpoint belongs to the batch, not to the
session that happened to be holding the document.
- rolled_back echoed the requested flag. It now reports whether the design is
actually back: the app answers engine.batch with a new restored field, and
the MCP tool reports restored && rollback. An app that predates the field
falls back to undone/completed.
* Batch: answer with main's rolled_back field after the merge (#3242)
Upstream #2900 put the real restore check on engine.batch as
`rolled_back` while this branch named it `restored`; the merge kept
main's control test and this branch's field, and CI caught it.
Standardize on main's wire name: the app answers `rolled_back`, the
MCP tool reads it (fallback for older apps unchanged), docs and tests
follow. The checkpoint carry-over across file.new is unchanged.
---------
Co-authored-by: DahakBuilds <dahakbuilds@users.noreply.github.com>
* ui: spacing, radius and type tokens, per-tab accents, agent and on-accent tokens
* ui: per-tab accent behaviour and a larger application bar with a Start page button
* icons: silhouette master and flat assistant and agent link icons (open for review)
* icons: apply review notes (sparkle assistant, refined plug, silhouette halo)
* icons: wire the silhouette master to inspect.silhouette; record the accepted icons
* ui: application bar to the design: separators, Save, house, assistant icon, readable hovers
* ui: ribbon structure: Model to View tabs, contextual Sketch and Sheet Metal, migrated pins
* ui: ribbon painting to the compact design
* ui: smaller icon button highlight and assistant mark on the bubble corner
* ui: short ribbon labels that wrap at spaces
* ui: ribbon buttons fit their labels and Finish Sketch shows its full name
* ui: constraint gallery, workspace menu, section list headings and richer tooltips
* ui: lighter selected tab label, ribbon surface and dimmer bar separators match the dark design
* ui: document tabs as rounded chips with a dimmer inactive label
* ui: document tabs fit their names and show close only when active or hovered
* icons: close and plus masters for the document tabs (open for review)
* ui: centre the new-tab plus and overflow button on the bar
* ui: a quiet rule under the ribbon tabs on non-contextual tabs
* ui: the application bar mark separates its faces with the bar colour, not white
* ui: open ribbon section label uses the selected tint and a chevron
* ui: dim the tab close and plus icons until hovered
* ui: every ribbon dropdown uses the chevron, the workspace card included
* ui: the active document tab uses the design's surface colour
* ui: the bug button's right padding mirrors its icon side
* ui: square constraint cells and a rule before the grid
* ui: constraint cells back to their earlier size, keeping the rule
* ui: smaller constraint cells and icons, centred in the section
* ui: constraint cells fit the height of the large buttons' icon and label
* ui: sketch Create titles share the other labels' line
* ui: format the application bar and ribbon changes
* ui: active tab surface token and the colour and hover tests that follow the redesign
* tests: the merged parameter and narrow toolbar tests follow the compact ribbon
* i18n: the Malay Gap label has an English source and its Japanese and Chinese translations
* apply_off_thread tests: the evaluation lingers in tests, so still computing never depends on machine speed
---------
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
* joint.inspect: what each joint is attached to, for agents
A read-only `joint.inspect {joint?}` gives each joint's definition: for each
side the occurrence, its component and path, the snap as saved, and what
each persistent face/edge name refers to (the feature that made it, and the
sketch and curve a swept side came from), whether the origin resolves and
why not; plus kind, offset, angle, flip, values with limits, expressions,
the motion links it is in, and its solve errors and conflicts. Its id ends
in `.inspect`, so agent gates treat it as reading only.
MCP `inspect_design` includes the definitions when the design has joints
(`joints: false` leaves them out). joint.list and joint.inspect share the
motion-link JSON.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: catalog entries for Inspect Joint (en, ja, zh)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
- motion.plot: joint values and a point's path sampled as the study plays (closed loops
following), with velocities and accelerations by finite differences, per step or per
second with a duration.
- motion.interference: the pairs of parts that pass through each other along a study, with
the first step, the step ranges, the depth and the shared volume; occurrences, against
or contact sets choose the pairs; bounded samples and work.
- Motion Study dialog: a Study box opens a saved study; a chart of a joint value or a
picked point with a cursor at the step shown (click to move there); Check collisions
with the steps shaded on the chart. ui.start motion.study takes study.
Adds an Interface font setting that leads the proportional family, with the default face and CJK/Hangul fallbacks kept behind it (#1290).
Co-authored-by: DuBearte <DuBearte@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Agent chat prototype: drive an ACP agent the user already has from a side panel
A desktop-only chat panel (off by default) that starts a coding agent over the
Agent Client Protocol and gives it SolidCraft's MCP server, bridged to the open
window through the token-protected control channel with the default folder
limits. It finds installed agents (Claude Code and Codex adapters, Gemini CLI,
Copilot, Qwen, OpenCode, goose) with version and login state, streams text,
tool calls and plans, shows the agent's permission requests, and when an agent
isn't signed in shows its own login methods without handling any credential.
Design notes and findings: docs/design/in-app-agent-chat.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: say only what the end-to-end run showed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: gate, one undo per message, docking, process groups, discovery polish
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: Settings → AI, several agents with a switcher, OpenAI-compatible endpoints, permission modes, toolbar button
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: translations, tool cards, Add agent dialog fixes, test agent saves on its own
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: third-party licences for the keychain crates; clippy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: badge text from the theme tokens
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Agent chat: Auto-allow model edits is the default permission mode
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Preferences ▸ Navigation ▸ Orbit around now offers View centre (the default, as before), Origin and Point under the cursor. A saved orbit_cursor preference migrates to the cursor option, and the control channel still accepts the old key.
Thanks to @kuraneko1 for this.
Co-authored-by: kuraneko1 <98832587+kuraneko1@users.noreply.github.com>
solidcraft-cli snapshot takes --camera JSON and --view with a saved view name (through view.apply, as the MCP screenshot does), plus --no-grid and --no-axes; the MCP screenshot and ui.render take grid/axes, the headless render skips a hidden origin axis, and the app's ui.render follows the Grid and Origin switches. Closes#1245.
Drive Joints opens on the joint picked in the browser, else the first joint that moves, and won't start on a rigid joint. ui.start takes params: joint.drive opens on a joint (id or name) at given values, driving nothing until OK; a command or param it doesn't take is refused.
A control-channel method that reads the orbit camera, sets any of target/yaw/pitch/roll/distance, and fits listed occurrences (or everything) keeping the direction. Its reply passed back sets the same view again; a refused field changes nothing.
An opt-in Touchpad navigation preset: Shift + pointer motion pans, Alt/Option + motion orbits, vertical scroll zooms, all without a mouse button. Existing presets are unchanged; view.navigate gains continuous motion for the control channel and scenarios.
Lands the Render workspace (R3), bounded preview-image jobs with cancellation and atomic PNG export (R4a), and opaque PBR looks as one change.
- Render workspace: an overlay-free product preview on the installed GPU device. Returning to Design restores its camera. render.scene and render.settings.apply are added.
- Image jobs: render.preflight/start/status/cancel/export run bounded CPU preview jobs. Export captures the job, overwrite choice and document, and checks the caller's file scope before writing.
- Opaque PBR: looks can carry metal fraction, roughness and dielectric IOR. The product viewport and preview PNG use them; geometry and mass are unchanged. The v1 catalog export refuses PBR rather than dropping it.
- Render setups and PBR looks are saved under design format 21. Labels are in en/de/ja/ko/zh/ru.
Supersedes #706 and #800. Refs #620, #673, #756, #1004.
Contributed by @0xlillith.
Co-authored-by: lillith <35337584+0xlillith@users.noreply.github.com>
Adds a French catalog as a partial locale (missing strings fall back to English, like Russian), registered in the language list, with tests and attribution.
Colour vision modes (Protan, Deutan, Tritan) in Preferences > Graphics, with palettes, shader and icon colours adapted per mode, translations and tests.
The screenshot controls, the submission steps and the Open GitHub draft button stay outside the scrolling review; the clipboard fallback is explained before a long draft opens; text fields leave a pixel of room so the window no longer widens while idle at 140% scale. Instructions in en/de/ja/ko/zh.
Open and Save use parented AsyncFileDialog sheets; their answers run on the UI thread in a later frame, so resizing the window while a picker is open no longer re-enters winit and aborts. Editors, tab changes, Close/Quit and model-changing control requests wait for the answer; the local library Open and Export in the Appearance dialog use the same flow. Fixes#1088.
The engine's headless scene takes a palette; ui.render and the CPU viewport build it from the window's theme tokens, so a dark window renders a dark picture. CLI snapshots, MCP screenshots and Home thumbnails keep the default colours.
At start, and at most once a day, a background thread asks GitHub for the latest stable
release (one HTTPS GET to releases/latest, nothing else sent; 15 s timeout; silent when
offline; GitHub's rate limit respected). When it is newer than this build, an Update button
appears next to Report a bug. It opens a window with the version, the release notes and
Download (the asset that fits this installation), Skip this version and Remind me later.
- Versions compare as semver; a nightly counts as the release it was built after, so it is
offered only a newer stable release.
- The installation is detected (AppImage, Flatpak, Snap from the store or a file, deb, rpm,
tar.gz, Windows MSI/portable/exe, macOS app); Download picks the fixed-name asset.
Development builds and the Flatpak (no network permission) never check.
- Preferences > General > Updates: Check for updates automatically (on) and Check now.
- HTTP via ureq + rustls with the operating system's certificates (desktop app only).
- docs: Updates and privacy page.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adds a complete Simplified Chinese (zh) catalog covering every English message, a font fallback for Chinese text, and `cargo xtask i18n --check`, which checks that the complete catalogs (ja, zh) carry every English message and that every command label is translatable.
Co-authored-by: Noly1990 <20500931+Noly1990@users.noreply.github.com>
The app's control protocol gets engine.batch: the steps run in one request (so one frame), each as engine.execute runs it, stopping at the first failure and rolling back to the checkpoint by default. The MCP batch tool sends it to a running app (with the control token), is never resent after a lost reply, and falls back to step-by-step when the app refuses (agent cursor shown, or a step loads a file). A batch may take up to an hour to answer.
solidcraft --control PORT writes a random per-launch token to a user-only file (<data>/control/PORT.token; 0700/0600 on Unix, icacls on Windows; SOLIDCRAFT_CONTROL_TOKEN overrides) and refuses any connection whose first request lacks it. mcp --connect, the demo and packaging smoke clients send it. MCP execute/batch/open/save/export/screenshot are annotated destructive and open-world, new_design destructive. Docs: control-protocol.md, mcp.md, AGENTS.md, pending release note in releasing.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent tool calls (MCP, and bridged control requests carrying allow_paths) reach files only in the open design's folder (strictly inside home or the temporary folder, not in a hidden folder, and never its hidden files), the app's recovery folder, the server's private scratch folder and each --allow-path; --allow-any-path lifts the limit. Paths are resolved first, so .. and symlinks that lead out (including a save through a link, #845) are refused. On Windows, UNC, device, NT, verbatim non-drive, drive-relative, alternate-stream, reserved-device and 8.3 short-name paths are refused before any file system call, and the resolved path must be on a local drive. doc.recovery_discard and doc.recover {discard} delete only real recovery entries. Docs: mcp.md, control-protocol.md, README.
`SolveApp::start` now honours a command's enabled flag, so shortcuts, the command palette and the control channel can't start a disabled command, and Move is disabled while a sketch is open.