Commit graph cad-editor/Cargo.lock
Author SHA1 Message Date
Hakan Seven
8a69ef9de3 chore(release): bump to 0.7.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 01:02:40 +03:00
Hakan Seven
78670a2a27 fix(dwg): bump acadrust for R2013 save conformance (#182, #225)
Pull in acadrust 4ae2ceb, which fixes two R2013+ (AC1027) DWG writer
bugs that made OCS-saved files unreadable in AutoCAD/TrueView/BricsCAD:

- #182: R2013 header string stream was unlocatable because the file
  wrote maintenance_version 0 (omitting the R2010+ extra RL).
- #225: 3DSOLID/REGION/BODY omitted the R2013+ revision block, corrupting
  the entity stream and dropping 3D solids on load.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:55:31 +03:00
Hakan Seven
ad5b71440f fix(dwg): bump acadrust to fix solid hatch missing (#46)
Pull in acadrust ad0471e, which corrects the entity ENC color decode
for book colors. R2007 files whose hatches carry a book color (e.g.
the santeen.dwg from issue 46) desynced on read, dropping all 270
SOLID hatch boundaries; they now load and render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:02:07 +03:00
Hakan Seven
53a4882c7f chore(release): bump to 0.7.1
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 19:17:42 +03:00
Hakan Seven
c71950fa7c fix(deps): bump acadrust for MOVE attribute/MultiLeader fix (#224)
Pulls the acadrust translate fix: MOVE now carries a block's attributes
and the whole MultiLeader (text/base/block-content anchors + break
points), not just the insert point / leader line. No OCS code change —
the transform path already calls translate and re-tessellates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:39:00 +03:00
Hakan Seven
0eb347bf47 feat(attedit): show attribute prompts in the editor
Each row in the attribute editor now shows the attribute's prompt — the
text defined on the block's ATTDEF — falling back to the tag when the
block defines no prompt. The prompt is read from the block definition,
since attribute instances carry only tag + value.

Bumps the acadrust pin to pull the matching reader fix: its DWG object
reader was discarding the ATTDEF prompt, so every prompt came back empty.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 08:23:54 +03:00
Hakan Seven
27896e3401 chore(deps): bump acadrust for AcDs SAB scan perf fix (#203)
Pulls the quadratic→linear AcDs blob-extraction fix in acadrust. 3D-heavy
DWGs (and master files that xref them) that took 28s+ to parse — minutes
for a multi-discipline set — now open in well under a second each.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:51:50 +03:00
Hakan Seven
da76918320 chore(release): bump to 0.7.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 16:48:15 +03:00
Hakan Seven
2ec3348740 chore(deps): bump acadrust 7e20fd1 — DXF dangling-ref cleanup
DWG→DXF conversion now drops references to objects that have no DXF form
(unsupported AEC/application objects dropped on conversion), so the output
opens clean instead of auditing 619 dangling handle references.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 11:01:20 +03:00
Hakan Seven
76ef544cda chore(release): bump to 0.6.9
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 01:48:04 +03:00
Karim Jerbi
3d23c45016 chore: disable printpdf default features (unused html deps)
printpdf's default = ["html"] pulled in azul-layout, rust-fontconfig,
kuchiki, xmlparser and their transitive trees (~40+ crates including
two with cdylib targets) — none of which are used by the project's
PDF export (only basic primitives like Mm, Line, Polygon, Rgb).

Also fixes a MinGW linker error (export ordinal too large: 100035)
triggered when ld.bfd tries to build a DLL for printpdf with >65535
exported symbols.
2026-06-29 01:06:28 +03:00
Hakan Seven
7c0d9d003a chore(deps): bump acadrust ffdd494 — R2018 MLEADER tail fix
R2018 cross-version saves now open in AutoCAD with NO recovery: the
MLEADER entity tail (block labels + dir/bottom/top attach order) is
correct, so all 3 MLEADERs are accepted — the Civil3D test file opens
clean (only the unconvertible AEC objects are dropped, as expected).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:07:35 +03:00
Hakan Seven
c23b956861 feat(io): default DWG save to 2018; bump acadrust handle-counter fix
- Save As now defaults the version dropdown to DWG/DXF 2018 (latest)
  instead of the loaded file's version; the selected version is written
  as-is (removed the source-version fallback for version-locked data).
- Pin acadrust 55a2caa: allocate_handle respects header.handle_seed as a
  floor, fixing the corruption where opening a file and saving it
  silently overwrote existing XRECORD/DICTIONARY objects (handle reuse)
  and AutoCAD refused the result.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:31:30 +03:00
Hakan Seven
e04b580a70 chore(deps): bump acadrust to R2018 cross-version conformance fixes
Pins acadrust 0831995 (HakanSeven12/acadrust main): cross-version DWG
writer/reader conformance so R2004->R2018 saves open in AutoCAD for
LAYER, VPORT and ATTRIB objects (22/25 previously-discarded objects in
the Civil3D test file now open clean). MLEADER cross-version still WIP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:26:06 +03:00
Hakan Seven
d1efa4ea7c feat(io): preserve source DWG version for files with version-locked data
Civil3D/AEC objects (and raw MLEADER/Surface records, EED) can only be
written losslessly in their source DWG version. On save, fall back to the
source version when the chosen version is an incompatible encoding family
(acadrust CadDocument::has_version_locked_data), with a command-line
notice, across every save path (Save, Save As, save-before-close/quit)
via a shared dwg_save_version helper. Default the Save-As format dropdown
to the loaded file's version so a round-trip preserves it.

Picks up acadrust DWG-writer conformance fixes (3dbae05) so a Civil3D
R2004 drawing round-trips through OCS and opens in AutoCAD with no errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 02:46:13 +03:00
Hakan Seven
959dd66e93 fix(dimension): land DXF round-trip fixes (re-pin acadrust)
Re-pins acadrust to the dimension DXF round-trip fixes (rotation/text/oblique
degree<->radian units, radial/angular/ordinate group codes, ordinate X/Y bit)
and drops the OCS-side fix_dxf_dimension_rotations dimension arm, which now
lives in the acadrust DXF reader (keeping it here would double-convert).

Completes the dimension audit (Batch 5). Refs #181.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:15:14 +03:00
Hakan Seven
4116b85af0 chore(release): bump to 0.6.8
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 12:23:51 +03:00
Hakan Seven
f40144deac deps: bump acadrust to latest main (7c0c12fe)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:06:14 +03:00
Hakan Seven
da9562466d deps: bump acadrust to LWPOLYLINE BD/3BD parse fix
Picks up acadrust 2a59d3e, which reads/writes LWPOLYLINE thickness and
extrusion as BD / 3BD instead of BT / BE. Without it, polylines carrying
a thickness or extrusion flag parsed with a garbage normal and point
count and were dropped by the corrupt-entity guard on open — e.g. ~1600
valid polylines in the PLN_Sev block of a route drawing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 16:47:31 +03:00
Hakan Seven
eaf72254e7 chore(release): v0.6.7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:33:41 +03:00
Hakan Seven
0efa559bd6 chore(deps): bump acadrust 0.3.4 → 0.4
Tracks acadrust main at 0.4.x: plotstyle/material common-entity
ordering fix plus in-flight DWG reader work. Patch comment updated
to match; drop the git patch once these land in a published 0.4 crate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:00:36 +03:00
Karim Jerbi
627761b629 fix(text): render TTF glyphs as solid fills, fix font fallback, correct Z-order
Text elements previously rendered as hollow wireframe outlines and sometimes
fell back to the wrong system font due to case-sensitive exact matching. Also,
the viewport background grid drew on top of solid entities.

Case-insensitive and partial-name fallback matching (e.g., mapping "arialn"
to "Arial Narrow") is now added to `sysfont::canonical_family_name`, ensuring
text resolves to the correct installed system font.

TrueType font contours are now triangulated into solid fills (`fill_tris`)
using `lyon_tessellation` in `ttf_glyph.rs`. To prevent the GPU from misclassifying
this 2D text as a 3D mesh (which broke flat shading), text tessellation splits
the output into separate outline and fill `WireModel`s.

The background grid is extracted from `SelectionCanvas` into `GridCanvas` and
moved beneath the 3D viewport to ensure proper layering. Finally, `DepthBiasState`
is enabled on all face/fill pipelines to apply a polygon offset, perfectly
resolving Z-fighting between coplanar wireframe lines and solid faces.
2026-06-25 18:17:01 +01:00
Hakan Seven
57153254bc build(deps): bump acadrust for the SORTENTSTABLE draw-order fix (#146)
Pull in acadrust 16332e5, which reads/writes the DWG SORTENTSTABLE in the
correct stream layout (sort handles inline in the data section; owner block
+ entity handles in the handle stream). Draw order set in other CAD apps —
e.g. a line sent behind a hatch — is now honoured instead of falling back to
handle order.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 15:04:53 +03:00
Hakan Seven
44fa9df278 build(web): restore the wasm build — gate native-only deps off wasm
The web build had bit-rotted: native-only features added since it last
compiled pulled crates that don't build for wasm32-unknown-unknown.

- printpdf (PDF export / printing) → native-only target; the web build gets
  stub export_pdf / print_wires. It pulls a wasm-incompatible memchr 1.0.2
  via lopdf → nom_locate, and the web has no filesystem.
- getrandom 0.3 (via ahash via acadrust) → enable its wasm_js feature and add
  the matching --cfg getrandom_backend rustflag in .cargo/config.toml.
- ocs_plugin_api "host" feature (out-of-process plugin runtime: interprocess,
  libloading, memmap2, rkyv) → native-only target; the web gets the
  dependency-free manifest/ribbon contract. The host code was already
  wasm-gated; only the Cargo wiring pulled it in unconditionally.

`trunk build --release` succeeds again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:11:18 +03:00
Hakan Seven
dfdf8f6702 build(deps): bump acadrust to twist-aware VPort view fix
Pull in acadrust 88ea9f0, which fixes the DWG VPort zoom-extents safety
net to be twist-aware. A twisted saved view on a survey-coordinate
drawing no longer has its camera flung to empty space on save/reopen
(the view_center was double-rotated about the origin).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 08:57:38 +03:00
Hakan Seven
b4093724f2 fix(plugin): f64 pick coords + harden out-of-process lifecycle
Follow-ups after merging the out-of-process plugin isolation work:

- Convert the out-of-process interactive adapter's `on_point` /
  `on_entity_pick` to `glam::DVec3`, matching the `CadCommand` trait,
  which moved to f64 pick coordinates. The branch predated that change
  and no longer compiled against the trait.
- Contain plugin constructor panics in `export_plugin!`: the constructor
  runs across the C ABI boundary in `ocs_plugin_register`, where an
  unwinding panic is undefined behavior. Catch it and return null, which
  the loader already treats as a failed registration.
- Reap killed runner processes. The spawn-timeout and disconnect paths
  called `child.kill()` without `wait()`, leaving a zombie on Unix until
  the host exited. Route both — and `shutdown()` — through a shared
  `reap()` that kills and waits on a detached thread.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 00:16:08 +03:00
Hakan Seven
8020286553 chore(release): v0.6.6
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 23:22:43 +03:00
Hakan Seven
e507e6615b chore(release): v0.6.5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 20:16:02 +03:00
Hakan Seven
2de5c7668f chore(deps): update lock so the wasm build compiles again
A toolchain/libc shift broke the previously-locked transitive set on wasm32
(memchr 1.0.2's libc::memchr binding stopped resolving), failing the web/Pages
deploy. Re-resolve within the existing version requirements — no Cargo.toml
change needed. Native and wasm32 both build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:40:26 +03:00
Hakan Seven
7fa12b757b chore(release): bump to 0.6.4
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:12:03 +03:00
Hakan Seven
e7352cfc24 chore(deps): bump acadrust for block header owned-handle fix
Picks up the fix that keeps a block's owned-handle list in sync with the
entities actually written, so AutoCAD no longer drops model-space geometry from
OCS-saved files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:05:30 +03:00
Hakan Seven
ba834fb166 fix(layout): faithful paper-space round-trip and page setup (#156)
Builds on the acadrust viewport/PlotSettings round-trip fixes:

- Write the sheet viewport's view position into view_center (DCS) with
  view_target at the origin, matching AutoCAD; the old view_target form shifted
  the layout.
- PAGESETUP now writes paper size, rotation, origin and units onto the Layout's
  embedded PlotSettings (not just a side object), and bumps geometry, so an edit
  shows on the sheet immediately and survives a save.
- Draw the printable-area guide (paper inset by plot margins, rotation-aware) as
  a dashed rectangle, matching AutoCAD's layout view.
- Plot/PDF export falls back to the Layout's embedded PlotSettings via
  effective_plot_settings(), so a loaded file's rotation/origin/scale apply.

Bumps acadrust to pick up the viewport-status and PlotSettings round-trip fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:47:36 +03:00
Hakan Seven
5052d2338c fix(block): bump acadrust so REFEDIT'd arcs aren't distorted
Picks up the acadrust transform_arc fix that rotates/reflects an arc's
start/end angles, so editing a rotated or mirrored block in place (and
rotating/scaling a standalone arc) keeps arcs intact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 07:52:25 +03:00
Hakan Seven
de1f1c0e24 fix(3d): move and paste ACIS solids to the right place
Solids were missing from the entity transform dispatch, so move / rotate /
scale / mirror were silently no-ops on a 3D solid (only its wires shifted)
and a pasted solid stayed at its original location. Add a Transformable impl
for Solid3D/Region/Body/Surface (delegating to acadrust, which now composes
the move into the ACIS body placement) and register them in the dispatcher.

Also make cross-drawing paste land at the cursor: the clipboard centroid is
measured in the source drawing's offset-relative frame, so correct the paste
translation by the source/target world_offset difference (zero within one
drawing). Bumps acadrust for the solid-geometry transform fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 02:46:56 +03:00
Hakan Seven
31ed911714 fix(3d): place and move ACIS solids and tilted-normal blocks correctly
Bump acadrust to pick up real ACIS body transforms (so moving/copying/
rotating a 3D solid relocates its geometry) and OCS-aware INSERT placement.

- body_transform: read the SAT transform record from its first 13 float
  tokens instead of by raw index, which skipped the matrix because the
  record leads with a book-keeping pointer — so the body placement was
  silently ignored and solids never honored their stored transform.
- Insert grips: the grip lives in world space but insert_point is stored in
  the block's OCS, so grip display and grip-drag now round-trip through the
  OCS. A block whose extrusion normal isn't +Z no longer shows its grip in
  the wrong place or drags along the wrong axes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 01:52:53 +03:00
Hakan Seven
54ff2c97e2 chore(release): bump to 0.6.3
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:46:53 +03:00
Hakan Seven
54106ca9b0 feat(web): lazy per-script font loading for international CAD text
The web build has no system-font access, so CAD text in non-Latin scripts
(Cyrillic, Greek, CJK, …) rendered as nothing — build_fallback was a hard
None on wasm (#141). Instead, ship per-script Noto subsets under web/fonts
(one alphabet per file, SIL OFL 1.1) and fetch them lazily over HTTP the
first time a drawing uses that script, then outline glyphs with ttf-parser.

- web_font: Script enum + script_of (char → script font), a per-script
  store with lazy fetch, and a pending queue drained by the app loop.
- CJK is split by language (chinese/japanese/korean). Han ideographs share
  code points but differ by language, so the shared block is routed by the
  document's $DWGCODEPAGE (932→JP, 949→KR, GB/936→CN); kana is always
  Japanese, Hangul always Korean. Re-tessellates when the language changes.
- build_fallback (wasm) outlines from the fetched subset; clear_fallback_cache
  lets glyphs that missed while a font was in flight reappear on load.
- PollWebFonts subscription (web only) + WebFontLoaded message drive fetches.
- Trunk copy-dir serves web/fonts; nothing is bundled into the native binary
  (desktop keeps using system fonts).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 16:13:26 +03:00
Hakan Seven
79bb1d67b1 feat(cli): full command-line interface via clap
Replace the ad-hoc `--serve` arg sniff with a clap-parsed CLI:

- positional <file> to open at startup (also the OS file-association path)
- --new, --read-only, --backend, --safe-mode/--no-gpu
- --serve/--port (headless JSON automation, unchanged behaviour)
- --export IN OUT (headless format convert via the automation load/save infra)
- --script FILE (run command lines at startup)
- --log/RUST_LOG, plus --version/--help for free

GUI-only options pass to app::boot through a OnceLock config; read-only
gates the save paths. The web build skips parsing (no args).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 13:59:20 +03:00
Hakan Seven
0dc537b669 chore(release): bump to 0.6.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:42:27 +03:00
Hakan Seven
93e2d20412 fix(3d): render pierced solid faces with their holes
Build pierced planar faces (a wall with a window opening) as truck faces
with inner hole boundaries: collect every face loop (outer + holes), wind
each hole opposite the outer so try_attach_plane cuts it, and let truck
triangulate. Drop the back-face cull on the solid-mesh pipelines so faces
show regardless of the import's winding (the shader already lights
two-sided). Relies on the acadrust SatLoop next_loop fix that makes hole
loops reachable. (#123)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:21:21 +03:00
Hakan Seven
aa81d7fe7e fix: bump acadrust to drop the forced VPORT grid in saved DWG/DXF
acadrust's DWG VPORT writer hardcoded grid_on=true, so every file OCS saved
showed a phantom grid in other CAD apps (BricsCAD, DWG TrueView) that was
invisible and unselectable in OCS. The writer now emits the VPort struct's
real grid_on (default false for OCS, which never forced it on), so the
stray grid no longer appears. (#121)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 21:57:50 +03:00
Hakan Seven
4d8ea95974 chore(release): bump to 0.6.1
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 16:37:27 +03:00
Hakan Seven
4954551808 chore(release): bump to 0.6.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 02:01:34 +03:00
Hakan Seven
9cb11e77d2 chore(release): bump to 0.5.9
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 16:06:35 +03:00
Hakan Seven
eb53e445ab refactor(plugin): drop built-in plugins, external-only
OpenCADStudio no longer bundles plugins — every add-on is an external
cdylib loaded from the plugins folder or installed via the marketplace.

- Remove the demo plugin and the in-tree ocs_example_plugin crate.
- Remove the inventory-based built-in registration path (PluginRegistration,
  all_plugins, installed_manifests); registry now serves core ribbon tabs
  plus loaded external plugins, and try_dispatch routes only to externals.
- Plugin Manager drops the 'compiled into this build' section; the
  enable/disable toggle moves onto loaded external cards.
- Prune the now-dead HostSession/DocumentTab helpers and re-exports.

Part of the #100 extensibility epic (phase 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:50:52 +03:00
Hakan Seven
020a3a4c84 feat(plugin): marketplace — install plugins from a curated registry
Add a Plugin Manager marketplace that installs external add-ons from a
GitHub repo's Releases. A curated registry (plugins/registry.json in this
repo, extended by PR) lists discoverable plugins; the host fetches it,
shows each entry with a release dropdown, and on install downloads the
asset matching the user's platform plus plugin.toml into the plugins
folder (API-version checked first). Users can also link arbitrary
owner/repo manually. Linked repos persist in settings.

Desktop only (ureq + serde_json); the install path reuses the phase-2
loader. Part of the #100 extensibility epic (phase 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:24:56 +03:00
Hakan Seven
29c71be101 feat(plugin): load external cdylib plugins at runtime (phase 2)
Move BuiltinPlugin into ocs_plugin_api (host feature) so out-of-tree
crates can implement it, and add export_plugin! to emit the two C
symbols a cdylib exposes: ocs_plugin_api_version (checked first, so an
ABI-incompatible build never runs) and ocs_plugin_register -> boxed
BuiltinPlugin. The host loads every compatible package from the plugins
folder at startup via libloading (desktop only), keeps the library
resident for the session, and merges its ribbon tab + command dispatch
into the same paths as built-ins (honouring enable/disable). The Plugin
Manager shows external packages with a Loaded / incompatible status.

Approach B: the plugin hands back a boxed trait object, assuming a
matching toolchain + ocs_plugin_api version (the version symbol enforces
the latter). crates/ocs_example_plugin is the reference cdylib.

Part of the #100 extensibility epic (phase 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 14:48:56 +03:00
Hakan Seven
5ccf5cfe36 feat(plugin): lift host surface behind a HostApi trait (phase 1b)
Plugins targeted the host's concrete HostSession type. Add a HostApi
trait in ocs_plugin_api behind an optional `host` feature (the only thing
that pulls acadrust, so the core crate stays dependency-free). HostSession
implements it and BuiltinPlugin::dispatch now takes `&mut dyn HostApi`, so
an out-of-tree add-on compiles against the contract crate alone. Per-tab
plugin state is reached through object-safe plugin_state* helpers.

Completes the phase-1 host-surface extraction in the #100 epic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:31:05 +03:00
Hakan Seven
e3c9e538e2 release: v0.5.8
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 01:37:20 +03:00
Hakan Seven
fefae274d4 feat(wasm): web Save/Save As go through the dialog with a direct download
On the web, Save and Save As now open the in-app Save dialog (filename +
format) like the desktop, and the unsaved-changes prompt's Save routes
through it too — instead of an immediate rfd download. Confirm serializes
to bytes and downloads directly via a Blob + hidden `<a download>` click
(a user gesture), so there is no intermediate "click to download" link.

Replaces the rfd-based download_web / WebSaveResult round-trip with a
synchronous sys::download_bytes. Native save is unchanged.

Native + web build; 75 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 00:52:20 +03:00