mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-06 20:02:16 +00:00
develop
87 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f74c6605c4 |
Fillet: Mitre or Swept corners where two rounds meet (#11498)
* SMLib wrapper: a swept or mitred turn for constant rounds (Turn) Brep::blend_dropping takes a Turn: Mitre (the default, as before) or Swept, which sets solidcore's FilletSession::set_swept_turns before the corners are made. A swept turn solidcore refuses at CreateFilletCorners comes back as Error::TurnRefused with its reason and place (NoRoom at a concave side edge, else CornerUnsupported). Swept is for Blend::Round only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Kernel: fillet rounds turn in a mitre or swept (FilletTurn) fillet_removing, fillet_max, fillet_max_each and fillet_each take a FilletTurn and hand it to SMLib, through the reblend of earlier rounds at a later corner too. A swept corner solidcore does not build is refused as invalid input with its reason and place: no smaller radius builds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Design: a fillet saves its turn, mitre (default) or swept FeatureKind::Fillet gets `turn` (FilletTurn: mitre, the default and not saved, or swept), one pending format file. Evaluation hands it to the kernel, pattern copies included, and refuses a swept turn with a style, fit, corner or setbacks the kernel's swept corner does not take (SWEPT_TAKES). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * solid.fillet: the turn parameter, and the command's input and output schemas `turn: mitre|swept` on solid.fillet, refused when unknown or with options a swept corner does not take. solid.fillet now has its contract (FilletParams) and reply type (FilletResult), registered with checked!, and leaves schema/unconverted.txt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet dialog: a Turns choice, Mitre or Swept A Constant radius fillet's Turns row sends `turn: swept`; choosing a narrowed radius or a curvature corner puts it back to Mitre, and Swept puts those back. Its tooltip says what each does where two rounds turn round a corner edge. New strings in a pending locale file (en, de, ja, ko, zh); glossary entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet turn: the schema tests' fixes and the complete catalogs' strings The no-contract example in the schema tests is solid.chamfer now that solid.fillet has one; the reply test checks the mid-radii form against the contract (solidcore refuses that law's corner yet, #430) instead of building it; Arabic, Hebrew and Vietnamese, complete catalogs, get the new strings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet schema test: variable and spline forms checked against the contract solidcore fails a variable round on a box edge at this pin (status 1001, as variable_radius_on_a_box_edge), so the reply test checks those forms against the contract instead of building them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet turn: the swept rig cases pass; the MCP no-contract example is solid.chamfer cov-fillet-turn-swept-boss-base-r1 and cov-fillet-turn-swept-pocket-sharp-corner-refused-r1 pass now that solid.fillet takes `turn`: off the rig's known-failing list. The MCP bridge test's example of a command without a contract was solid.fillet, which has one now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ --------- Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
ea772a0438 |
Merge develop into main: SolidCraft on the SMLib kernel (v1.1.0-alpha) (#11351)
* UI: rim and wall picking tests for a circle of arcs that is one wall A circle drawn as two half arcs now extrudes to one full-turn wall with its seam edge, and each rim is one closed edge (tangency-labs/smlib#67). The tests keep their intent on that body: a rim clicked once is one item, measured and highlighted whole and picked from either side; a wall picked either side of its seam is the same surface, lit whole, and toggles off from the other side; every face is its own patch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fillets: a later round at a corner where earlier rounds meet blends them again with it The owner's ruling of 2026-10-30: a later fillet on an edge at a vertex where earlier rounds already meet in a mitre makes the corner rounding all of them at once makes, one smooth patch, the mitre gone. A body made by constant-radius rounds keeps what they were made on and which edges they rounded at which radius; a later round reaching such a corner blends the earlier rounds' edges (from the earliest of those meeting there on) with the new edges in one SMLib blend of the body before them. The result's history is put over the body the later round was given: an earlier round's face is that face trimmed anew (its name kept), the corner patch and the new rounds are the later fillet's. A picked mitre seam has no round of its own: it is refused unless a new edge of its radius meets it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: a later r3 round at an r2 mitre, through the Fillet feature, makes the all-at-once corner Two box edges rounded r2 in one fillet, then the upright edge at their mitre r3 in a second fillet (tangent chain on, so the seam comes with it): 10 faces, 7928.743041 mm³ as fillet_radii of the box gives, the r2 rounds' names kept, the r3 round and the corner patch the second fillet's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Kernel: a body's record of rounds goes with its history, and can be read back The rounds that made a body are over the body its history is over: a new history (an operation carrying a step's result back to its own operands) leaves the record out, so a later round never reads one history against another body. Body::rounds gives the record and Body::with_rounds_of takes one back, checked (edges of the body before them, a fillet's radii, the body's history over that body), for a saved model to keep it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Model cache: a body made by rounds keeps them, so a later round blends them the same after opening A design gave another body when opened from its model cache: the rounds a body was made of lived only in memory, so a later round at their mitre was built sequentially (or refused, as too large) after opening and blended with them when evaluated anew. The saved model now records, per kernel body made by rounds, the body they were made on (a place in the bodies, stored once though no state holds it) and the edges with their radii; reading it attaches them back down each chain, and a thinned model keeps those bodies with the bodies made from them. Model cache format 7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: a corner patch of rounds 2/3/4 takes no more than the strips leave in its block three_rounds_at_a_corner bounded the patch's extra cut at 3 mm³ beyond the strips, a figure with no derivation; SMLib's all-at-once body at radii 2, 3, 4 takes 3.099 (V 7878.579574 against strips 7881.678). That body is the strips' outside the block its patch lies in: its rounds are the strips' cylinders ending at a's section y = rc, b's x = 20 − rc and c's rails where they meet a's and b's (the patch's four corners, now asserted), so the patch takes at most what the strips leave in that block (11.86 at 2/2/3, 32.69 at 2/3/4). The lower bound is that block; the upper one, at most the strips' volume, stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: the io crate's hand-built saved models list their rounds, as format 7 records do Model cache format 7 ( |
||
|
|
c4808e4715 |
MCP: clean up empty scratch folders on shutdown (#7836) (#7929)
* claim: #7836 * fix(mcp): remove empty scratch directories on command exit |
||
|
|
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> |
||
|
|
251573a5a4 |
MCP: compare the model with a reference picture (#1486) (#6416)
* claim: #1486 * Compare picture: overlap and edge offsets of the model against a reference picture (#1486) inspect.compare_picture lays the model's silhouette over the part found in a PNG or JPEG and slides it to the best overlap: overlap (0..1), the model's edges against the picture's in mm at nine stations, and an overlay PNG. The MCP tool compare_picture runs it and hands the overlay back as an image block. inspect.silhouette grows a reusable silhouette::outline for the model side. * chore: re-trigger checks (defaults line already present in PR body) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n: carry the Compare Picture label in Arabic, Hebrew and Vietnamese too The complete-catalog guard (every_complete_catalog_carries_every_english_message) failed because the pending file covered only en/ja/zh; ar, he and vi are complete catalogs and need the key as well. * Compare picture: one uniform scale, capped fit, sturdier part finding Review on #6416: fit no longer stretches the axes apart (width is the default, both scales uniformly by width and reports aspect_mismatch); the fitted model takes the same MAX_GRID cap as the picture; the border flood seeds only from border pixels near the border's main colour, reads alpha, retries at a stricter step, and says which case failed; the slide searches the whole placement range instead of a tenth around the centre; the model's holes get the picture's fill rule; crop becomes crop_px / crop_fraction with explicit units. Pins #1486's bracket (overlap 0.865, bottom -10 mm at the upright) and adds a regression test per problem. * Compare picture: alpha only for a see-through border, part_fills_crop, outline-only wording Review re-test on #6416: one translucent backdrop pixel no longer switches the read to alpha — alpha decides only when most of the border is see-through, and any ink is then part, so a part drawn at alpha 100 survives; part_fills_crop: true takes the crop box as the part itself, for one view cropped tight off a board where the part takes most of the border and the flood would keep the backdrop strip instead; a third backdrop pass compares each pixel to the border's main colour, so a white part on (245, 245, 245) JPEG at quality 75 separates; the command, tool and docs descriptions now say the compare is outline only: holes are not compared. A banded light backdrop stays a follow-up. A test per case. * MCP compare: format the picture tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
176c22acaa |
MCP: explain when an unknown command id is actually an MCP tool name (#10678) (#10680)
* claim: #10678 * MCP: explain when an unknown command id is actually an MCP tool name --------- Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com> |
||
|
|
a69a7c6ffe |
Inspect: measure names_only lists every world body without measuring (#10402)
A caller that only needs the bodies' names (assembly occurrences included,
e.g. "Body2 (Part:2)") had to measure every body, or read document.inspect,
which lists definition bodies only. `inspect.measure {names_only: true}`
returns each world body's name and its definition's name, honouring the
`bodies` filter; an unknown name is refused before anything is measured.
The MCP `measure` tool passes it through, directly and as a batch step;
`summary` leaves such a list as it is, since there is nothing to narrow.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
||
|
|
0fb2e9b06b |
MCP batch: refuse a command entry with an unknown key (#7854) (#7865)
* claim: #7854 * MCP batch: refuse a step with an unknown key (#7854) A step's parameters under another key (`args`) were dropped and the command ran without them. The batch is now refused before its first step, naming the key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * MCP batch: a step carrying `expect` is refused, saying it is the batch's argument #9904 gave batch an `expect` argument and tested that a step carrying one runs with nothing checked. That is the silent drop this branch refuses: the step is now refused before it runs, and the error says `expect` belongs to the batch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e2a7a45c44 |
MCP: batch and execute take expect {volume, bodies, bbox} and flag a mismatch (refs #3380) (#9904)
* MCP: batch and execute take expect {volume, bodies, bbox} and flag a mismatch (refs #3380)
An optional `expect` argument on the `batch` and `execute` tools: the volume
(with a relative `tol`, default 0.002), body count and bounding box (0.05 mm)
the agent computed before building. Once the call has gone through the server
measures the design as the `measure` tool does and the reply gains
`expectation: {ok, measured, expected, mismatch}`. A mismatch flags the tool
result `isError` with the mismatch text first; the design is kept as built.
A malformed `expect` is refused before anything runs. Without `expect`
nothing changes, and a batch step carrying one is a step with a stray key.
In 29 logged agent sessions every agent computed these numbers beforehand
and then spent a `measure` call plus a comparison by hand after every stage;
one missed a 0.25 mm skin until it compared. Volume and body count are
kernel-independent checks.
Refs #3380
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* MCP expect: filter then map for the bbox coordinates that are off (clippy)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* MCP: expect's coordinate text helper no longer shares a name with the JSON reader
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: bherbruck <tenbee91@gmail.com>
|
||
|
|
9b31d29443 |
MCP: server instructions that say how to plan, build and verify (refs #3380) (#9903)
The `initialize` instructions were one paragraph of command shapes. Replace them with version-neutral guidance: read `skill_reference solidcraft-modeling` first, plan the numbers, build in a few `batch` calls, the primitive routes and the fillet-shell-inside-holes order, what follows a parameter, `measure` after each stage with a coalesced parameter check, and `timeline.edit` / `parameters.change` / `edit.checkpoint` to fix instead of rebuilding. The Assistant's system note gets the same pointer; docs/mcp.md says so. `instructions_name_only_real_tools` now checks the command ids as well as the tools, and `instructions_recipe_builds_a_parametric_shelled_box` builds a part the way the instructions describe and checks its volume, axes and parameters. Refs #3380 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
e16647a63f |
MCP: measure summary and body_topology faces: cylinders for small verification replies (refs #3380) (#9853)
* MCP: measure summary and body_topology faces: cylinders for small verification replies (refs #3380) `measure {"summary": true}` replies one short object per body (name, volume_mm3, bbox, faces, closed) with body_count and total.volume_mm3, as a tool and as a batch step. `body_topology {"faces": "cylinders"}` replies only the cylindrical faces, the kernel's split halves merged by radius and axis line into {radius, origin, axis, extent, names}, and no edges. Both defaults are unchanged. The merge uses only what model.faces and model.edges already reply. Measured on a 13-feature enclosure, body_topology is 74 KB and measure 1.1 KB per body; agents filter them with scripts, and seven of 29 benchmark runs asked for exactly a cylinders-only listing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * MCP: keep body_topology's cylinder merge next to check_parameters' without a name clash Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: bherbruck <tenbee91@gmail.com> |
||
|
|
c528964363 |
MCP: check_parameters tries parameter values and puts the design back (refs #3380) (#9910)
A new tool that checkpoints the design, sets every value in one parameters.change, reports measure, errors and cylinder axes, and restores the checkpoint, so the loop set_parameter / measure / body_topology / set back costs one call and one rebuild. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
66bd64cc5e |
Engine: one contract check for a call, used by the preflight, the bridge and the app (#9339)
`schema::issues(id, params)` looks up the command's typed contract and lists what is wrong with the parameters (none without a contract or for an unknown id). The batch preflight, the MCP bridge's pre-send check and the app's check of a design-switching command each did that lookup themselves; they now call it. No behaviour change. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
92af4a21c8 |
Control channel: a per-request param_check level, applied and confirmed by the app (#9184) (#9185)
* claim: #9184 * Control channel: a request's own param_check level, applied and confirmed by the app (#9184) `engine.execute`, `engine.batch` and `engine.script` take an optional `param_check: "off"|"warn"|"strict"` in their params. The app runs the request at that level through the same `run_checked` path and batch preflight a headless session uses, puts its own level back, and every reply says the level it ran at as `param_check` beside `ok`. A command that switches designs keeps the app's level; any other word is refused. Readings and exports answered on a copy off the window thread keep the level too. `control.capabilities`, answered at once on the control-server thread, lists what the channel does beyond the methods every version has: `{"param_check": ["off", "warn", "strict"]}`. An older app answers "unknown method". The MCP bridge asks it once per connection. When the app lists the level, every call and batch goes with it and the app checks against its own commands; otherwise the bridge checks before sending, as #9073 does. At strict, a reply that doesn't say the app checked the call is an error, and the next calls are checked by the bridge. Also: `add_param_warnings` takes the reply by `&mut`, and `with_param_check` sits beside `Remote::new`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Control channel: a design-switching command is checked at the request's level Review fixes for #9184. `component.edit_in_place`, `component.finish_edit`, `view.next_tab` and `view.previous_tab` ran at the app's own level and echoed `off`, so a misspelt call went through at strict. They now have their parameters checked at the request's level before they run (and still run at the app's own level, as each design keeps its own), and the reply echoes the requested level. The MCP bridge at strict now requires the echo to match its level, not just to be there. `param_check` is read only by `engine.execute`, `engine.batch` and `engine.script`; other methods ignore it. The off-thread test now shows the design change computing off the window thread before it is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4a781b8cd8 |
MCP: --param-check checks calls to the running app (#9072) (#9073)
* claim: #9072 * MCP: --param-check checks calls to the running app (#9072) `mcp --connect` (and `mcp` once it bridges to an app) took `--param-check` and forwarded every call unchecked, while the app's own session is always off. `Remote` now checks each `engine.execute` and `engine.batch` against this server's command contracts before sending: `strict` refuses a call, or a batch with such a step, without sending anything, and `warn` adds `param_warnings` to the app's reply (each step's result in a batch). A command with no contract here goes to the app unchecked. `Auto` carries the headless session's level over when it bridges to a late app. `batch_preflight::contracts` is the contract half of the existing preflight, for a runner in another process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
aae2c5e417 |
Assemblies: edit a linked component in place, with the assembly around it (#7672) (#7819)
* Links: update linked designs that changed while the assembly's tab was away A design coming back to its tab compares the modification time and size of its linked design files with what they were when it went to the background, and runs Update Links on the worker thread for those that changed: saved in another tab, another window or by a checkout. Preference update_changed_links (Design, Linked designs) turns it off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Docs: the assembly guide says linked designs update when their tab returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Links: Vietnamese strings, now that vi is a complete catalog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Links: remember what each design last read, so an update that fails is tried again A design's linked files are now recorded as the design last read them: when Update Links reads a link without an error, or when the link is first seen. Coming back to the tab reads again what differs, one link per run, so a file that cannot be read holds up no other and is tried again the next time, and a part changed while the assembly was shown is taken up on its next return. Closing several tabs together reads nothing on the way, and the web build, which keeps no file times, looks at nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Links: no read during a save-changes prompt, records for adopted designs and missing files A tab shown to answer "save changes?" reads no link before its save, and Cancel there or on a batch lets the tab left in front read what it skipped. A design opened in place of the blank one records its links at once, a link whose file is missing is recorded as missing so it is read when the file comes back, and a read queued for a design that is no longer shown by the time it starts is dropped. More changed links than can wait at once are read on the next return. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Assemblies: edit a linked component in place, with the assembly around it Activating a linked component opens the design it comes from in a tab of its own, with the rest of the assembly drawn faded around it where the component sits, so the part's own history, browser and commands are at hand. Finish Editing in the browser saves the part, goes back to the assembly and closes the part's tab when the edit opened it; coming back to the assembly updates the changed link (or Finish Editing runs Update Links when that is turned off). Update Links in the part also reads the assembly's links again, off the window thread, and redraws the assembly around the part; a result for an assembly changed meanwhile is dropped with a message. The part is an ordinary tab, so saving, autosave, recovery, closing and quitting treat it as any other design. The model scene's ghost triangles are now drawn (only the preview's were). Preference edit_linked_in_place turns it off. Builds on the update of changed links when an assembly's tab returns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: a double-click opens it, Activate only activates A double-click on a linked component edits it in place, in the browser as on a face in the view (around the placement clicked), and the component's menu gets Edit in Place. Activate and the browser's radio button make it the active component as they always did, so a linked component can still be activated without opening its design. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Double-click on a component's face: edit a linked one in place, activate any other A double-click on a face in the view activates the component the body belongs to, at that placement, as a double-click on its row does; a linked one is edited in place. Bodies of the design itself or of the active component are left alone, and so is a double-click with a modifier. One preference, double_click_components, covers both gestures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from review An edit whose part never opens is forgotten instead of starting on a later open of the same file, and the web build starts the edit after its synchronous open. Finish Editing goes on only for a save into the linked file and in the part's own tab, waits for a "changed on disk" answer, and says so when the part was saved elsewhere. Showing the assembly no longer drops a refresh, which now records the links it read so coming back reads nothing twice. The faded assembly is worked out once per picture, a bad mesh index skips its whole triangle, and the last two status texts come from the catalogs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: Finish Editing on the MODEL tab and the mouse's back button Finish Editing is a command now, component.finish_edit, with its schemas: the app window answers it, anywhere else nothing changes, as with view.fit. While a linked design is edited in place the MODEL tab ends with a FINISH EDITING panel, pinned at the right as FINISH SKETCH is, with a new left-arrow icon; the browser keeps only the line naming the assembly. The mouse's back button, or a keyboard's Back key, finishes too unless a dialog, tool or sketch is open. The assembly guide describes editing in place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from the second review Saving the assembly waits while it reads its links for the part Finish Editing waits for dialogs, tools, sketches and prompts open in the part, also when run as a command The assembly reads the edited part explicitly when it does not check its links on its own The FINISH EDITING panel cannot be customized A tab opened by an edit stays that edit's to close when the part is entered again The mouse's back button finishes editing; the keyboard's only while no text field has focus Refreshing the assembly keeps its selection and active component Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from the third review component.finish_edit run as a command opens nothing and answers with an error when it cannot finish; engine.batch and engine.script refuse it A double-click or Edit in Place while a dialog, tool or sketch is open in the assembly keeps it open What changes in the assembly while it reads its links without changing its document stays: picks, activation, components dragged but not captured Showing the assembly while it reads its links starts no second read A new or opened design in the part's tab ends the edit Finish Editing keeps the part's tab open while its agent chat runs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: Update Links run as a command in the part refreshes the assembly too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: the ribbon button reads Finish Edit, as Finish Sketch does A bare "Finish" took the catalogs' surface-finish translation (German "Oberfläche"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from the fourth review Finish Edit waits while the part's agent is in the middle of its turn, instead of keeping the tab of any chat open A part saved while its assembly refreshes is read again when the edit finishes: the refresh records the files as it found them A double-click on a linked component while something is open in the assembly says so instead of activating it Commands are recognised in any spelling the engine takes, so engine.batch and engine.script cannot slip Finish Edit through Update Links run as a command refreshes the assembly from the control channel only, not for the app's own reads Moves of components the refresh removed are not carried over, and a refusal is one message The command description and the guide say that the command does not save the part Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: the command is Finish Edit, as Finish Sketch is Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: a command to start it, and fixes from the full review Added component.edit_in_place {component, path?}: the double-click and Edit in Place in the menu run it, and as a command it asks nothing, so a network location not allowed yet or a design open elsewhere makes it fail instead Finish Edit asked by the part's own agent finishes once that agent's turn ends; the button still waits for the turn The parameters and design properties panels, with text typed and not applied yet, hold up entering and finishing an edit A refresh is not taken up under an undo, a queued command or a feature still being computed in the assembly Refusals say what holds them up (a refresh, a file being read or written) instead of nothing The browser strip names the assembly that is refreshing, not any assembly The schema description says the command does not save the part Korean strings for every new message Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from the second full review The MCP batch tool refuses component.edit_in_place and component.finish_edit as steps instead of sending them one by one Edit in Place asked while the assembly's agent is in its turn opens the part once the turn ends; a double-click then is refused rather than stopping the agent Both commands answer queued: true when they wait for the agent's turn, and stopping the agent forgets what it queued An undo, a queued command or a delete check running in the design holds up entering and finishing an edit A refresh redraws every edit of the assembly, the parts in other tabs too In an assembly never saved, a double-click activates the linked component as before The control and MCP docs list the new batch and script refusals, and the commands list every way they fail Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: fixes from the third full review The MCP batch tool refuses the two commands however a step names them, an execute step too A queued Edit in Place is checked fully when asked for, a second one is refused, and both queued requests wait for what runs in the design instead of being dropped Disconnecting the agent forgets what it queued, as stopping it does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Edit in place: help text for the Finish Edit button main now requires help for every toolbar command (#7134), and Finish Edit is one. Written in every language the branch's catalog carries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e181015fd1 |
MCP save: a folder the agent opened or saved a design in stays in scope (#7181) (#7216)
* claim: #7181 * MCP save: a folder the agent opened or saved a design in stays in scope (#7181) The agent's default folders held the open design's folder only while that design stayed open there, so after a new design, an opened STEP file or a save-as elsewhere a save beside the earlier design was refused, while the same save through the control port worked. The MCP server now keeps, for the rest of its run, the folder of every design file a call opened or saved (open, save, and doc.open, file.save, file.save_as through execute or batch, path given in full) and, headless, of every design open in its session. Such a call only succeeded because the folder was already in scope, so naming a path adds nothing. The folders get the open design folder's terms (inside home or temp, not hidden, hidden entries unreachable), at most 16. Bridged, they go to the app as design_folders, which it judges the same way. The save tool description and docs/mcp.md say how to add a folder with --allow-path. * MCP scope: a design's folder is the folder its file resolves to (#7181) A link in another folder to a design inside the agent's folders passes the scope check, which follows it, but its own folder was what got remembered (and, for the open design, what counted while it was open). Take the folder of the file as the check resolves it. * Control test: a hidden file the export format accepts (#7181) --------- Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com> |
||
|
|
03b8f4138b |
New designs save as .sc; .solidcraft files still open (#7325)
* claim: new designs save as .sc Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * New designs save as .sc; .solidcraft files still open and keep their name on Save DESIGN_EXT is now "sc"; DESIGN_EXTS lists sc, solidcraft and solvecraft and every open path (dialogs, drag-drop, recent files, CLI, MCP, links, the web picker) accepts all three. Save of an opened .solidcraft file writes that file; Save As, autosave, recovery and crash reports use .sc. Windows, macOS and Linux register .sc alongside the older extensions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update UI tests for the .sc default extension Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
309eda87a2 |
Agent skill for reproducible bug reports (#3983) (#3984)
* claim: #3983 * Agent skill for reproducible bug reports (#3983) skills/solidcraft-reporting has an agent gather the version, steps and exact error, reproduce the problem in a fresh design (a command script or one batch with rollback off), shrink it while it still fails, check the numbers with measure and a screenshot, keep private designs out, search for duplicates, and write the report in one shape: Reproduced on, Steps with a minimal script, Expected, Actual, Attachments. Listed in skills/README.md and docs/mcp.md; the bug template's steps field points agents to it. The skill-name check now covers its files. * Reporting skill: GitHub takes a design only as a .zip |
||
|
|
dfde1e032d |
mcp setup: add SolidCraft to the AI clients on this computer; plain mcp finds a late app (#6379)
solidcraft-cli mcp setup (alias install) and Help > Connect AI assistants edit each installed client's own configuration in place, with this program's absolute path: OpenCode, Claude Desktop, Claude Code, Cursor, Codex, Gemini CLI, Copilot CLI, Windsurf, Zed and VS Code. Only the solidcraft entries change; a stale path is refreshed and an entry the user changed is left alone. Plain mcp keeps looking for the app while its headless session has no work, and says on every tool result that it is headless when the app was not found. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
a5f7f5a921 |
Batch: consecutive parameter edits can rebuild the design once (#5822) (#5839)
* claim: #5822 * Batch: consecutive parameter edits can rebuild the design once (#5822) An agent's batch of parameter edits, one parameter per step, evaluated the design once per edit: an edit early in the timeline rebuilds nearly all of it, and 21 such edits ran for minutes. engine.batch and the MCP batch tool take coalesce_parameters (default false). With it, each run of consecutive plain parameter edits (parameters.change with only a name and an expression, or with changes) is set as one parameters.change {changes}: one rebuild for the run. Any other step ends a run, so later steps see the design up to date. Every step still gets its own result (coalesced: the run's length); the run is one undo step. A run whose combined edit is refused (a new parameter, which changes can't make; a bad expression) runs step by step, so a refused edit is still named by its own step. The app's off-thread evaluation computes the run the same way. The grouping is solidcraft_engine::batch_params, shared by both runners. 21 parameter edits on a plate with 21 extruded bosses (in-process MCP, ci profile): 40.1 s step by step, 3.5 s coalesced, the same volume. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Batch coalescing: say a run skips the states between its edits; test it against step by step (#5822) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
adbd2adf89 |
view.pick: map screenshot pixels to exact geometry (#6304) (#6329)
* claim: #6304 * view.pick: map screenshot pixels to exact geometry (#6304) A read-only command that answers, for screenshot pixels (window or model frame) or world-space rays: body, face index, exact world point and outward normal, depth, occurrence/component for placed parts, and the nearest edge/vertex within edge_px. Faces are raycast through the same per-body pick index the mouse uses; flat faces are solved exactly against their plane, curved faces take the mesh hit with the normal interpolated from the mesh's surface normals. Section-aware: faces on the removed side do not stop a pick and the cut cap answers with section_cap. Never touches the selection, camera, document or undo. Exposed as control ui.pick and as view.pick through engine.execute and engine.batch (and through them MCP execute and batch). --------- Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com> |
||
|
|
0520910bfd |
Control: name the token file and spot a stale one when a call is unauthorized (#4664) (#4670)
* claim: #4664 * Control: name the token file and spot a stale one when a call is unauthorized (#4664) When the app refuses a token that the MCP client read from a token file, the error now names that file, when it was written and how long ago, without printing the token. The app also writes `<port>.pid` beside the token file (its process id and, on Linux, its start time) and removes both at exit; when that process has exited, the error says the token file is stale. The process check runs only after a refusal, and the token file itself stays one line, so existing clients keep working. Document force-quit leftovers and the MSIX AppData redirection. * Bench assistant: read the token out of the new ClientToken Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: bherbruck <brennen.herbruck@gmail.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
6c6ffe4802 |
MCP: wait out long requests, honest batch outcomes, batch tool aliases (#2901)
Rebased onto main as one commit (was |
||
|
|
3bca787213 |
MCP tools: unknown command ids suggest the closest ids (#4846) (#4915)
* claim: #4846 * MCP tools: unknown command ids suggest the closest ids (#4846) An unknown command id in `execute` or `batch` now lists up to three closest ids, and an id with parameters packed into it says to pass them in `params`. |
||
|
|
36a354e3a7 |
Agent chat: serve the bundled skills' reference through an MCP tool (#4966) (#4970)
* claim: #4966 * Agent chat: serve the bundled skills' reference through an MCP tool (#4966) The bundled skills start with "read reference.md", but SolidCraft's own chat turns the agent's file tools off, so its agent could not follow them. The MCP server gains a read-only `skill_reference` tool that returns a skill's documents from copies built into the binary. It takes a skill name and a file name from a fixed list, never a path, and refuses an unknown skill or file with the available ones. The skills point to it, and docs/mcp.md and skills/README.md describe it. |
||
|
|
a05a0f1053 |
Fix/mcp stdio bounded request lines (#4972)
* test(mcp): reproduce whitespace bypass of request-size limit Add a source-level regression that rejects a JSON-RPC request larger than MAX_LINE even when most of it is whitespace, plus bounded-stdio framing coverage and invalid UTF-8 recovery. * fix(mcp): bound stdio line buffering and validate raw request size Consume oversize JSON-RPC lines in bounded memory while keeping the following request available. Reject whitespace-padded lines before trimming, preventing a request-size cap bypass. * docs(mcp): keep server framing comment idiomatic |
||
|
|
fdec948abc |
Control channel: control.running lists what the app is running, across connections (#3654) (#3689)
* 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> |
||
|
|
26c0c19ef7 |
Preserve imported part names and IGES assembly structure (#1609)
Build on #1426's import components and nested STEP assembly instances. Replace placeholder solid labels with meaningful part or instance names. Translate IGES groups and subfigure instances through the existing STEP component path, preserving nesting and placements and sewing surfaces within each group. Bound assembly walks and reuse work buffers. Related to: - tangency-labs/solidcraft#1386 - tangency-labs/solidcraft#1426 Co-authored-by: Codex <noreply@openai.com> |
||
|
|
2b1cb2c4e1 |
MCP batch: rollback restores the original document (#3242) (#3288)
* 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> |
||
|
|
c7bd467be7 |
joint.inspect: show agents what each joint is attached to (#3453)
* 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>
|
||
|
|
953fd7d5f8 |
Typed parameter contracts and JSON Schemas for solid.box and solid.extrude (#2829) (#2611)
* Spike: typed parameter contracts and JSON Schemas for solid.box and solid.extrude The schema RFC's spike (plan/schema-spike.md). solid.box and solid.extrude get typed contracts with generated JSON Schemas (2020-12), checked in front of the unchanged handlers by a per-session level: off (the default, which changes nothing), warn (the call runs and gains param_warnings) or strict (the call is refused and the design left alone). Also engine.describe and the MCP tool describe_command, `solidcraft-cli mcp --param-check off|warn|strict`, a FeatureResult type for feature replies, and an env-var audit recorder (SOLIDCRAFT_PARAM_AUDIT) used to check the contracts against every test. Local spike branch; not for upstream as is (see the results report). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Parameter contracts: put the audit recorder behind a feature; drop two ignored test keys The audit recorder is now on only in a build with the engine's `param-audit` feature and `SOLIDCRAFT_PARAM_AUDIT` set. Its code is still compiled, linted and tested without the feature. `scripts/param_audit.py` summarises a test run's audit logs, and the schema module's docs give the steps for converting a further command. Two tests passed keys their command ignores, which the audit found: `position` on `solid.box` (`hole_face_tests.rs`) and `symmetric` on `solid.extrude` (`face_tests.rs`). Both are removed, so the tests build what they always did. Comments no longer call the contracts a spike. 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> |
||
|
|
26f42ae09b |
Snapshot: draw a see-through appearance see-through, and show a tool body inside its target (#2329) (#2330)
* Snapshot: draw a see-through appearance see-through, and give the CLI --body, --tool and --section A headless picture dropped a body's opacity: the scene carried only a colour, so a design with a translucent appearance was drawn opaque by `solidcraft-cli snapshot`, by MCP screenshots and in a design's thumbnail, although the window has always drawn it as glass. There was then no way to look at the body a cut would remove inside the material it meets: only a volume to measure and reason about, which hides exactly the errors a picture makes obvious (a tool that stops short, or lands in the wrong place). - `SceneMesh` carries the body's opacity; `view::build_scene` takes it from the design (`model_body_opacity`), and a selected body stays solid so the selection colour reads. - The GPU capture routes a see-through body into the scene's glass at its own alpha, as the viewport does; the CPU rasterizer draws the solid bodies first (they own the depth buffer), then the see-through ones blended over them, far sides before near sides and without writing depth, so what lies inside shows and a line between the two is not hidden. - `snapshot --body NAME:opacity=0.3,color=#rrggbb`, `--tool NAME` (that body solid in the tool colour, the rest see-through) and `--section z=27` run the commands the app itself runs (`appearance.assign`, `inspect.section`): the options are shortcuts, not a second renderer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Tests: measure the tool colour as it is drawn through a see-through target The tool-colour filter was derived on paper and demanded a red more than twice either other channel, which the target in front of it tints away (measured: (200, 108, 85) through opacity 0.3); and the colour check painted the tool, which a solid target hides. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fmt * Snapshot options: strip the colour's # rather than slicing it; README Slicing `value[1..]` on an input-derived string is what the house rules ask us not to write, even where a length check has already made it safe. The error a failed assignment reports now names the body rather than claiming it came from --body, since --tool reaches it too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * --tool: assign the bodies around the tool in groups, not one command at a time Each appearance.assign is an undo step with a document snapshot behind it, so one per body made --tool cost grow with the size of the design for no reason: the bodies around the tool all get the same opacity, and the ones that share a colour can be named in one call. A design whose bodies all wear the default grey now costs two commands whatever its size. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Rasterizer: say where its glass and the GPU's differ Splitting each see-through body by facing orders its own two layers; it does not sort across bodies, which the GPU does. Worth stating rather than leaving a reader to find it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
fb82ccb273 |
Timeline/MCP API: suppress lists, dotted edit keys, set_parameter expression (#2899)
Timeline and MCP edits take suppress lists, dotted edit keys and parameter expressions. |
||
|
|
9eb1540a34 |
Docs: describe SolidCraft as independent CAD (#2768)
Reword comments, docs and package descriptions so they describe SolidCraft's own behaviour instead of comparing it to another product. The trademark notice, the commercial-CAD rule and the navigation preset name stay as they were. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
b04e0801d6 |
Per-command timings for script runs and batches (#1868)
Thanks @DuBearte. |
||
|
|
9194f4be09 |
Screenshot of a hidden window: at once, and say so (#1677) (#1707)
Thanks @DuBearte. |
||
|
|
1a0b33fcf3 |
Headless pictures draw on the GPU, with the viewport's pipelines (CPU rasterizer as last tier) (#1555)
Thanks @jyviko. |
||
|
|
a13124acdd |
Import glTF 2.0 files (.glb, .gltf) as mesh bodies (#1512)
glTF files open, insert and drop like 3MF/STL/OBJ: a component named after the file, the node tree as nested rigid components, repeated meshes as occurrences, metres to mm, Y up turned to Z up by default (up: z keeps axes), materials as PBR appearances. Bounded, hostile-input tested reader; no new persisted data. Closes #1505. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
27529d9742 |
Imports become components; STEP assemblies as nested components (#1386) (#1426)
* Imports become components: a STEP assembly's tree as nested components (#1386) Every imported file (STEP, IGES, 3MF, STL, OBJ: inserted, dropped, opened as a design, or file.insert_step / file.insert_mesh / doc.open from scripts, the CLI and MCP) now comes in as a new component named after the file, with its Import feature inside it. A STEP assembly's products become nested components; a part placed more than once is one component with an occurrence per placement, and the Import feature skips the file's later copies (`skip`, format 21 note). The contents are held as one rigid group (rigid joints, glyphs hidden); moving an inner part is refused until component.unlock ("Unlock Contents") releases it. Y up turns the import's component. Replies report component, component_name and occurrence. Undo is one step; designs with loose imports are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep an import's rigid group hidden when the window loads the file in the background Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Import instances' skip list is format 22: format 21 ships in 0.12.0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Catalog entries for Unlock Contents Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
1744fbb262 |
Measure: centre-to-centre for holes, diameters for circles and arcs, slot sizes (#1392) (#1419)
Measure now reads the picked item's exact shape (cylindrical faces, circular and arc edges, sketch circles, arcs and lines, profiles, planes, points): - A circle, hole or arc shows Ø, R and its length (circumference, or arc length and angle). - A slot (a sketch profile, or a half-cylinder end of a slot in a solid) shows its width, centre-to-centre length and overall length. - Two items where one is round measure from the centre or axis by default (axis to axis, axis to plane, edge or point), with the closest and farthest distances listed too; the panel switches between centre, min and max, and the canvas line follows. - inspect.measure and MCP `measure` (new `items` argument) add diameter, radius, center_distance, min and max; existing fields are unchanged. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b3df2c382b |
snapshot --camera and saved views; grid: false / axes: false for headless renders (#1313)
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. |
||
|
|
0ee5e97db5 |
STEP import takes up for Y-up files and names for the bodies' names (#1312)
file.insert_step and doc.open on a STEP file take `up` (turn a Y-up file so its up is +Z) and `names` (names for the imported bodies). The MCP tool and the app's control requests pass them through; an import without them works as before. Tests in the kernel's STEP reader, the engine, MCP and the file-load UI; docs/step-import.md and docs/mcp.md describe both. |
||
|
|
81d9b7e04a |
Agent skill for mechanisms: joints by coordinates, loops, links, motion (#1315)
A solidcraft-mechanisms agent skill with a worked example that a test replays through the MCP server (the actuator follows the hinge with the stated stroke and the drive stops at the rod's limit); the skills index and docs/mcp.md list it. |
||
|
|
1473893b08 |
MCP: a bridged server starts without the app and connects once it runs (#1298)
The bridged MCP server starts when no app is listening, says so in its instructions and in each tool error, and connects on the first call after the app starts. A batch that could not be sent says the app is not running. docs/mcp.md describes it. |
||
|
|
5c6f70cc00 | Faces by name in the face commands; model.faces gives a point on each face (#1243) | ||
|
|
a261aaa841 |
Render: integrated workspace, preview image jobs and opaque PBR (#1046)
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> |