- The glyph-text icons (refresh, swap, remove, submenu and step arrows)
are SVG icons from ui::icons (new REFRESH and SWAP) or plain labels.
- The custom RowMenu widget is removed: Sheet Views / Model Views rows use
iced_aw::ContextMenu like the Sheet List rows, with a submenu expanding
in place while hovered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The wizard's folder scan, Import Layout as Sheet, the template layout
lists and the drawing cache behind Model Views, Place on Sheet, callout /
label blocks and block previews parsed whole DWGs on the UI thread. They
now go through the shared `background_task` worker: a cache miss reads the
drawing and handles the message that needed it again. Block previews lend
the cached drawing to the preview scene instead of cloning it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Place on Sheet gives its viewport a unique id (shared
`Scene::next_viewport_id`, also used by the normal viewport commit).
- Renaming a sheet's layout in an open tab records undo and marks the tab
modified; in a closed drawing the previous file is kept as `.bak`
(ISAVEBAK) before it is written back.
- New Sheet saves the drawing before the `.dst`: a failed save leaves no
sheet behind.
- Rename & Renumber Previous/Next no longer panics on an empty list.
- Leftovers: unused binding, a hard-coded localized Documents path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A VIEW record's centre is an offset from its target in view coordinates.
Views saved by earlier versions stored the target itself as the centre;
treating that as an offset put them (and VIEW plots) at about twice the
coordinates. One shared `named_view_center` now resolves the centre in
f64 (DVec3/DQuat), taking a centre equal to a non-zero target as the old
convention; VIEW RESTORE, the view plot window and Place on Sheet use it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `.dst` read/write go through native-only helpers (a browser answers
"Not available"); the folder pickers are web no-ops; time stamps use
iced::time (web-safe).
- Lock files are written only for drawings that are sheets of an open set,
released when the last set closes, and a lock a crashed session left
(recorded with its process id, same user and machine) is taken back.
The `.dwl2` header is well-formed and the date line comes from the OS
long date on every platform. The 1 Hz poll runs only while a set is open.
- Refreshing sheet set fields never stores `####`: fields no open set
resolves keep their value, and only the hosts that changed are redrawn
(and their tab marked modified).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closes the view-to-dispatch resort race: the nine Layer* variants plus ColorPickTarget::Layer now carry the layer name and resolve to the current panel row at dispatch time via layer_panel_index; unknown names no-op. View sites (layer panel, ribbon dropdown) and the CLI/plugin path send names, so the CLI position lookup and the ribbon enumerate are deleted. Panel-internal selection state stays index-based. Tests: layer_toggle_visible_targets_layer_by_name_after_resort pins name targeting across a re-sort; layer_toggle_visible_unknown_name_is_noop pins the graceful no-op. Full suite: 1974 passed / 0 failed / 25 ignored.
Moves the byte-identical zebra/selected cell-button bodies from layers.rs and xref_manager.rs plus the layers header-button body into one shared module. All six call sites now use the shared helpers; toolbar_btn helpers untouched (different semantics). No new tests per owner request (pure move, verified by build plus full suite before test removal).
- #1602 changed the COMMANDLINEFADETIME help text and added "Never"
without catalog entries, so both showed in English everywhere. Add
them to the catalog and all 21 locales; drop the "0 skips them" key.
- #1606 named another CAD vendor in a doc comment and two test names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A drawing's sheet set fields are refreshed when it opens with sets loaded.
- VIEW WINDOW <name> <x1,y1> <x2,y2> saves the plan view of a window.
- opencadcodec: block-attribute fields use their block reference's layout.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row menu is a small overlay widget: a click on a submenu entry opens
its fly-out instead of closing the menu, and the fly-out is placed beside
the menu where it actually landed (right when it fits, otherwise left), so
the menu never moves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Row menus open Set category / Place Callout Block as fly-out submenus
(hover or right press; leftwards when the palette is docked right).
- List of Blocks and Select Block show the Blocks palette's preview.
- VIEW SAVE keeps the window's width/height ratio.
- Placing view content in model space is refused with the reference message.
- Drawings read for views, placement and blocks are cached by modification time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`v2026.40.1` matched neither the weekly pattern nor plain semver (2026 is
past the MSI major limit), so a fix release could not be built. Weekly
tags now take an optional patch: Cargo 2026.40.1, MSI 26.40.1, display
2026.40.1 (week zero-padded, as build.rs and the update check expect).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The v2026.40 rebuild was dispatched with a separate `commit` input copied
from a stale local tag, so Windows/macOS assets were built from 20803948
instead of 8e122a4e. Dispatch now takes only `tag` and checks the tag out.
Reverts 4700e263: the skipped Python plugin was a symptom of that commit.
Fixes#1612
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Turning a 141k-entity layer off/on took 1.5-5 s; it now takes ~0.6-0.9 s.
- Off/freeze toggles go through invalidate_layer_visibility: entities on
the layer keep their tessellation memo (visibility gates them before
tessellation); only block users re-expand. No mesh recolor.
- The resident patch reuses a surviving memo entry instead of
re-tessellating, guarded by the same display-context hash as the full
build.
- The patch looked up `layout.order` linearly per re-shown entity, which
made turning a big layer back on quadratic.
- recolor_meshes_for_handles resolved materials for handles with no mesh.
- Wire arena: a hidden slab keeps its instances and sets a `hidden` flag
in its consts (collapsed in the vertex shader); an unchanged re-show only
clears the flag. Const writes are batched into merged spans.
- The `layer_visible` automation action indexed the document's layer
table instead of the sortable panel rows the Layer* messages use.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model Views lists named model views and places them on the current sheet
(xref, viewport, paper-space named view, view label with navigation
fields, sheet view record); sheet view rows get Display, Rename & Renumber
View, Set category, Place Callout Block and Place View Label Block; the
View Category dialog's Add Blocks opens List of Blocks / Select Block; a
sheet whose relative path is gone shows missing; sheet set fields store
their values when a set changes; named views keep their centre relative to
the target. Codec pin moves to the revision with these field helpers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving filled every 3D solid without stored wires with tessellated display
edges, so solids read from a file without a wireframe cache (for example a
DXF) were saved with edges OCS never created. Only solids without ACIS data
now get an edge cache on save; solids OCS creates or edits already get their
wires when they are built.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Import Layouts as Sheets shows the reference's statuses (already part of
a sheet set / may belong to another sheet set / available) and Browse
replaces the list; the Field dialog SheetView tree lists sheet views with
their properties, scale formats and hyperlinks; drawings open in tabs get
.dwl/.dwl2 lock files that other instances read as open; the codec pin
moves to the revision with sheet views and the default output folder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove Sheets confirmation, Open in drawing editor, Select Layout as Sheet
Template for subsets that prompt, Import Layouts as Sheets with status and
prefix, Rename & Renumber options with Previous/Next and real layout/file
renames, New Subset folder hierarchy and publish setting, subset properties
rows as the reference shows them, sheet status badges (SSMSHEETSTATUS /
SSMPOLLTIME), Sheet Views by category with the View Category dialog, Model
Views locations, Field dialog SheetSet/SheetView navigation, and .dwt/.dws
read as DWG.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tree menus follow the reference per row kind (New Sheet / Import on a
sheet work on its subset, Remove Subset only while empty, Rename Subset),
a new sheet is not opened, an open set reloads when its .dst changes on
disk, ViewportScale placeholders take the version of their format and
the codec pin moves to the revision with navigation fields.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The before-manifest was taken pre-bake while save mints *D geometry on its clone, so every new dimension failed verification 1-vs-7. Compute before on a bake-simulated clone: baked-vs-baked proves roundtrip stability (bake correctness itself is pinned by the explode geometry tests). Pinned by save_verified_accepts_new_dimension_with_baked_block.
The DXF reader keeps marker identities on the block record but never materializes the entities, so block_entity_handle/block_end_handle dangle after every DXF load (reopened baked *D dimension blocks hit this every time). Re-create missing sentinels at load finalize, reusing the file handle when free and minting otherwise. Idempotent and DWG-safe: loads whose markers already resolve are untouched. Pinned by dimlinear_survives_save_reload_with_baked_geometry.
resources/* vary as sessions open and snapshots land, so an hour of advertised freshness was optimistic. protocol_result now takes the TTL value: tools/list and discovery keep 3600000, resources/list/read/templates get 60000, on every protocol version. No tool surface change; digest untouched.
The GUI requires request_id and document_id on every non-query op, but the bridge sent neither on capture: every ocs_capture failed with request_id_required, then document_required. request() now always mints the GUI request id for capture (a client-supplied id wins and is echoed in metadata), and capture carries the active document. The op=capture read path answers guidance pointing at ocs_capture instead of a missing-path failure. Live-proven against the open window: plain and annotated captures return image content.
The cached PID snapshot predates a GUI spawn, so the newborn pid missed from it read dead and the bridge deleted its just-written descriptor inside the launching call itself: every fast launch reported still-starting forever while a healthy window sat undiscoverable. Two guards: the snapshot cache is invalidated right after spawning, and deletion now waits out a 120s file-age grace (unknown age counts as newborn). Slow starters that write late were the only ones surviving before, which is why this was intermittent. Covered by stale_snapshot_may_delete predicate tests.
Runs the official MCP Inspector against a fresh release build on every push and PR: initialize purity, four titled tools, headless resources/list, both resource templates. Headless-safe methods only; drawing-dependent coverage stays in unit tests and the pinned digest. Server addressed via config file (positional CLI targets break on Windows shells); TTL assertions stay at unit level (the CLI normalizes result envelopes on output).
A dispatched rebuild checks out the tag's commit but runs main's
workflow; v2026.40 has no stage-bundled.sh, so the macOS bundle step
failed. Skip the plugin with a warning in that case only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The wasm check broke on the MCP `tools` op, the block library's folder
picker and DWG thumbnails, and the PDF export-window culling helpers.
Gate each one like the code around it; `read_handle` needs no gate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Everything was written and only clipped at view time, so a window over a
corner of a large drawing produced a near-empty page of several MB.
Wires and hatches whose sheet bounds miss the window are now skipped.
Fixes#1568
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A dimension draws from its *D block by name, but loading an xref skipped
anonymous blocks and kept the name verbatim, so its dimensions fell back
to a regeneration (giant text at the origin) or a host block of the same
name. The load path now imports them prefixed like other blocks and
renames the dimension's block; BIND is unchanged.
Fixes#1578
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Splitting a boundary object erased it and added the pieces, so the hatch
lost that source and rebuilt from what was left, often the whole circle.
The pieces now take over the old object's association before it is
erased.
Fixes#1572
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A point carried a key vertex, so Endpoint (which outranks Node) claimed
it, and an absolute-size glyph's strokes were indexed for Nearest and
Intersection. Points now offer only their Node, in the indexed and the
unindexed snap paths alike.
Fixes#1570
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each band segment was a rectangle ending square at its vertex, so the
outer corner of every joint showed a notch. Every segment end now carries
the tangent of half its turn, and the shader slides that end's corners
onto the joint's bisector so neighbours meet in a miter. Turns sharper
than the limit keep butt ends. Constant-width runs inside a polyline split
around its arcs no longer count as tapered, which had kept them unmitred.
Fixes#1565
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The codec writes R2018 AuxHeader maintenance fields as RL, so AutoCAD no
longer reads a 2018 save as student-made. The kernel drops zero-area
spikes before triangulating, so a hatch whose boundary folds back on
itself fills on screen instead of vanishing.
Fixes#1564Fixes#1569
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rustc 1.99 overflows its default 8 MB stack compiling the crate in
release on Windows and macOS. Raise RUST_MIN_STACK to 64 MB in the cargo
config and the release workflow (the latter also covers rebuilding older
commits). The Windows Build step now runs in bash so a failed cargo build
stops the job instead of surfacing later as a missing exe at signing.
workflow_dispatch gains tag/commit inputs to rebuild a published release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Short interactive waits returned a bogus 10-minute timeout on first expiry, killing the re-poll pattern and blocking task creation. The dismiss branch now fires only when the requested wait actually reaches the ceiling; shorter waits return running as before. Predicate covered by interactive_timeout asserts.
tasks/cancel marks the task so polls report terminal cancelled with neither result nor error; late completions are discarded. Task envelope errors move from grandfathered -32000 to -32603. Agent schema sync on bridge start is now skippable via OCS_SKIP_SCHEMA_SYNC and logs one line when it writes.
resources/templates/list serves the two genuine parameterized URIs (pyramid tiles, snapshots) with TTL hints instead of -32601. Tool titles move top-level per the 2026-07-28 Tool shape (dropped from annotations); annotation keys are allowlist-tested. resources/list ids are sorted so client and prompt caches hit. Tool schema digest rolls to fbba987a; pin updated deliberately after reviewing the titles-only surface diff.
How to iterate the bridge: fast builds, digest pin, session model, discovery, launch serialization, cancellation, error routing, safety model, rebuild swaps, conformance gates. No diary entries, no harness names, no build-specific data.