Commit Graph
86 Commits
Author SHA1 Message Date
Felix RiestraandClaude Sonnet 5 e583da83db Map Ole2Frame as update-only with the embedded object preserved
Frame corners and the aspect lock are scriptable; the opaque storage and
envelope are excluded and refused on edit. The audit embeds a real PNG
through OCS's own builder and proves it survives DWG and DXF byte-for-byte.
Python creation stays a follow-up.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 16:43:25 +02:00
Felix RiestraandClaude Sonnet 5 eb22de636b Decide Insert and Polyline: Insert creatable by block name, Polyline update-only
Insert can be created by naming an existing ordinary block; the host refuses
unknown blocks, model/paper space and containment cycles, and keeps legacy
inserts of missing blocks editable. The legacy Polyline is update-only with a
hint toward Polyline2D and Polyline3D because both writers convert it on
save. The generator gains update_only_message.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 16:14:02 +02:00
Felix RiestraandClaude Sonnet 5 bd43ed7e91 Audit the 17 pre-existing mapped kinds; add shared basic-geometry validation
Runs every first-generation kind through the real-runner lifecycle driver.
The audit found Ellipse unvalidated, zero-height Text/MText and non-finite
Arc angles and Point/Line thickness accepted, and no creation-time checks
for most kinds. validate_basic_entity now covers them and refuses only
problems an edit introduces. Twelve kinds pass every gate; Polyline,
Polyline2D, Polyline3D and Spline carry pinned persistence findings, and
Insert is update-only.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:44:26 +02:00
Felix RiestraandClaude Sonnet 5 12b0823e76 Map Light; record SectionSymbol as blocked
Light placement, intensity, colour, attenuation and shadow fields are
writable with host validation. staged_python_light_lifecycle_over_real_ipc
passes every gate except DXF cast_shadows, pinned by a canary.
SectionSymbol is recorded as blocked: it needs host-created style and view
representation objects and its raw point counts have no documented
derivation.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:18:13 +02:00
Felix RiestraandClaude Sonnet 5 21ce4b0e2b Map ViewBorder in the Python host model; record DXF kind blocker
Bounds, scale and rotation are writable with viewport and scale reference
rules. staged_python_view_border_lifecycle_over_real_ipc passes every gate
in DWG; a DXF DRAWINGVIEW reopens as an opaque entity, pinned by a canary.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:13:23 +02:00
Felix RiestraandClaude Sonnet 5 9075e53511 Map Viewport in the Python host model
Curated view fields are writable; the owner must be a paper-space block and
frozen layers must exist. staged_python_viewport_lifecycle_over_real_ipc
passes every gate except a paper-space canvas oracle, so the kind is
recorded as integration-tested.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:09:23 +02:00
Felix RiestraandClaude Sonnet 5 2e4d77dc09 Map Underlay in the Python host model; record DXF rotation blocker
Scripts place an underlay against an existing UnderlayDefinition; the host
checks that the definition exists and matches the underlay type.
staged_python_underlay_lifecycle_over_real_ipc passes every gate except DXF
persistence: acadrust's reader returns the degree-valued rotation
unconverted and repeated saves compound it. Pinned by canary expectations.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:05:11 +02:00
Felix RiestraandClaude Sonnet 5 96e3b54f08 Complete Wipeout host model coverage
Maps the placement, display and clip-boundary fields with rectangular and
polygonal clip validation. staged_python_wipeout_lifecycle_over_real_ipc
passes the full gate including DWG and DXF reopen with re-edit.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 15:00:04 +02:00
Felix RiestraandClaude Sonnet 5 7f65d6d373 Map RasterImage with host-created image definitions
Scripts name an image file; the host reads its pixel size, creates and links
the ImageDefinition and derives size and the default clip boundary.
staged_python_raster_image_lifecycle_over_real_ipc passes every gate in OCS
with a real PNG. ACAD_IMAGE_DICT and reactor linkage are not created, so the
kind is recorded as integration-tested.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:55:29 +02:00
Felix RiestraandClaude Sonnet 5 d4c2520907 Map Helix in the Python host model; record DXF handedness blocker
The host rebuilds the derived spline from the generating parameters on
scripted create/edit. staged_python_helix_lifecycle_over_real_ipc passes
every gate except DXF handedness, which acadrust's reader never applies;
the gap is pinned by a canary via per-format expectations in the shared
mesh lifecycle driver.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:48:44 +02:00
Felix RiestraandClaude Sonnet 5 b97d74efa4 Complete PolygonMesh, PolyfaceMesh and Mesh host model coverage
Maps all three mesh kinds with host validation of grid counts, face indices
and edge topology, and skips sub-record common data in the generator.
A shared run_mesh_lifecycle driver passes the full gate for each kind,
including DWG and DXF reopen with re-edit.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:42:42 +02:00
Felix RiestraandClaude Sonnet 5 0206c7c30b Complete Table host model coverage
Maps rows, columns, merged ranges, style and placement through the generic
generator (now with tuple and usize support), adds grid/merge/reference
validation, and keeps DXF cell merge dimensions in step with merged_ranges.
staged_python_table_lifecycle_over_real_ipc passes the full gate including
DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:36:12 +02:00
Felix RiestraandClaude Sonnet 5 b3f5388208 Complete MultiLeader host model coverage
Extends the adapter generator (Color, LineWeight, mixed unit/payload enums,
fixed float arrays, bitflags-2 newtypes, keep_types override) and maps
MultiLeader with a merge-style context patch, host validation and
reference checks. staged_python_multileader_lifecycle_over_real_ipc passes
the full gate including DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:27:43 +02:00
Felix RiestraandClaude Sonnet 5 22f9c20fe8 Support Color in the Python adapter generator; map Leader.override_color
Color converts as {'kind': ByLayer|None|ByBlock|Index|Rgb, 'value': ...}.
Leader.override_color is now writable; neither DWG nor DXF stores it, which
is recorded as a fourth persistence blocker with a canary assertion.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:18:12 +02:00
Felix RiestraandClaude Sonnet 5 6b4c86fd7a Complete Dimension host model coverage for all nine subtypes
Adds a hand-written flat Dimension model to the adapter (manifest
manual_kinds hook) and a synthetic-property section to the host coverage
policy. The host derives actual_measurement and the base definition point on
scripted create/edit. staged_python_dimension_lifecycle_over_real_ipc passes
the full gate for every subtype including DWG and DXF reopen. Python ints are
now accepted for coordinates and angles.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:15:03 +02:00
Felix RiestraandClaude Sonnet 5 a86d5bc727 Complete MLine host model coverage
Maps vertices, flags, justification, normal, scale and style with host
validation and MLineStyle binding. The host recomputes vertex direction,
miter and element parameters on scripted create/edit, so scripts only supply
positions. staged_python_mline_lifecycle_over_real_ipc passes the full gate
including DWG and DXF reopen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 14:02:40 +02:00
Felix RiestraandClaude Sonnet 5 ec10bdbc48 Map Leader in the Python host model; record acadrust W blockers
Adds Leader validation and annotation/dimension-style reference checks to
ocs_plugin_api, maps 15 writable and 5 read-only fields in the adapter, and
adds staged_python_leader_lifecycle_over_real_ipc covering C/R/E/D/U/I/V/P.
The W gate stays open: acadrust's DXF writer omits the annotation handle and
DXF reads drop annotation_offset; DWG R2010+ does not store text size or the
hookline flag. Each gap is pinned by a canary assertion.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-20 11:12:27 +02:00
Felix Riestra 8648225ac5 Merge remote-tracking branch 'origin/main' into plugin/host-model-api
# Conflicts:
#	crates/ocs_plugin_api/src/process/v4.rs
#	src/app/update/mod.rs
2026-09-19 23:58:01 +02:00
Felix Riestra 98b56ef673 Complete Hatch host model coverage 2026-09-19 18:44:31 +02:00
Felix Riestra cf2a923568 Add nested attribute entity host support 2026-09-19 13:16:40 +02:00
Felix Riestra 5b854bd121 Add AttributeDefinition host model support 2026-09-19 12:47:48 +02:00
Felix Riestra 54322e00e3 Complete Shape host model coverage 2026-09-19 07:43:30 +02:00
Felix Riestra 3387031038 Complete Tolerance host model coverage 2026-09-19 07:33:19 +02:00
Felix Riestra 4dda2dace9 Add host model integration compatibility tests 2026-09-19 01:56:25 +02:00
Felix Riestra db61379bfe Add validated Insert transform scripting coverage 2026-09-19 01:20:20 +02:00
Felix Riestra 11d5614991 Add versioned scripting host model and entity coverage 2026-09-19 01:13:24 +02:00
Karim Jerbi 7ea51d81d3 refactor(plugin): share legacy round-trip helper across interactive calls
Collapse the triplicated send/timeout/deadline/nested-request loop in interactive_event, get_prompt and needs_entity_pick into PluginProcess::call_simple. Timeout floors, error strings and UnexpectedResponse behavior preserved exactly. Net: +64 / -72 in one file, no behavior change. Verified: cargo check clean, cargo test -p ocs_plugin_api --lib --features host (92 passed), clippy shows only pre-existing warnings.
2026-09-18 15:40:32 +01:00
Karim Jerbi 1bc20b9ecc refactor(plugin): share timeout helpers between process and process::v4
Delete the 5 copy-pasted timeout helpers in process/v4.rs (CALL_TIMEOUT_DEFAULT, call_timeout, request_timeout, execute_code_timeout, base_max_floor, request_kind) and reuse the canonical process.rs versions, now pub(crate). Prevents floor drift between v1 and v4 paths. Net: +3 / -59, no behavior change. Verified: cargo check -p ocs_plugin_api clean, cargo test -p ocs_plugin_api --lib --features host (92 passed).
2026-09-18 14:18:23 +01:00
Felix Riestra ec2271fc9c Add versioned host settings API for plugins 2026-09-18 15:13:06 +02:00
Hakan Seven 7b4cef41f7 Complete parametric ribbon and constraint tools 2026-09-14 01:05:39 +03:00
Sebastian fe8397b3cb remove ocs_doc_api crate and DocApi v2 host integration
- Drop crates/ocs_doc_api from workspace and host dependency.
- Remove src/app/doc_api.rs and its module declaration.
- Strip DocApi v2 undo/dispatch plumbing from HostSession.
- Remove HostApi::doc_api_dispatch default method.
- Remove PluginRequest::DocApiRequest / PluginResponse::DocApiResponse.
- Revert plugin API version from 6 back to 5.
2026-09-11 08:07:30 +02:00
Hakan Seven 4ddd19f6e8 feat(mcp): describe complete CAD record schemas 2026-09-09 01:01:44 +03:00
Karim Jerbi 6e01d464e5 fix(workspace): resolve clippy warnings in ocs_plugin_api and ocs_doc_api 2026-09-07 14:52:58 +01:00
Hakan Seven 3385160493 Merge PR #1028: add document API with atomic edits
Add the typed document facade and plugin IPC adapter. Prepare bulk edits
before mutation, preserve undo and dirty state, keep profile elevations,
validate numeric inputs and session bindings, and generate Python constructors
with typed results.

Reuse existing entity transforms and profile conversion. Compute mass
properties and closed-surface bounds in cadkernel; pin its main revision
6a5e6fc2822f6af6b2611cd605b44437b35158f0. Keep plugin API metadata at version 6.

Validation: 646 native application tests, 597 kernel tests, 12 document API
tests, 91 plugin API tests, 3 Python tests, default/IPC feature builds and
wasm32 check passed.
2026-09-06 21:43:02 +03:00
Sebastian 919128e087 ocs_doc_api: fix branch-review findings (tab auth, bulge center, budget, caps, dead code)
CRITICAL:
- execute_doc_api: reject tab_id != bound tab (confused deputy); test
  doc_api_tab_mismatch_is_rejected.
- bulge_arc_segment: fix negative/CW bulge center (apothem magnitude + sign picks
  side; was double-sign-mirrored); test CW-vs-CCW center offset.
- cold-tess budget: move mass_cache/cold_tess_used to per-tab Scene so the budget
  persists across DocApi dispatches (was reset per request); budget-exhausted ->
  approximate meshes.metrics fallback instead of error.

WARNING:
- Loft: add BULK_ITEM_CAP (was uncapped -> unbounded kernel call from one request).
- CreateMany: pre-validate EntitySpec::Curve (ellipse ratio) in prepare phase ->
  all-or-nothing restored; regression test.
- Partial Ellipse: offset start/end_parameter by rot_z on rotation; regression test.
- resolve_body: add with_body borrow accessor (host overrides to borrow cache in
  place, O(1)); bounds() uses it instead of deep-cloning the B-rep per query.
- add_raster_image: validate file path (non-empty, image extension, reject
  UNC/traversal); regression test.

SUGGESTION:
- deploy: bump API_VERSION 5 -> 6 so DocApi plugins are gated at handshake on old
  hosts (append-only wire + defaulted method keep old V2-V5 plugins loading).
- dead code: wire query_name into apply_queries error labels; host uses crate's
  ObjectId::from_handle/to_handle (drop local duplicates); delete is_null/backend_mut.
- mock drift: test mock now stores curve specs + computes curve bounds (aligns with
  example mock); Spline/Dimension bounds delegate to points_aabb.

623 host lib + 8 crate + 3 consistency + 34 plugin_api green.
2026-09-06 16:03:34 +02:00
Sebastian e41086b058 Add ocs_doc_api: object-oriented CAD entity API (v2)
New crate crates/ocs_doc_api: object-centric facade (DocApi -> Document ->
collections -> typed handles), transport-agnostic wire layer (DocApiEnvelope =
single op | read-only query batch), per-op autocommit (no write transactions),
bulk ops with upfront-validation all-or-nothing, structured ApiError, and
build-time codegen (spec/entities.toml -> ops/query enums, api_reference.md,
binding_schema.json).

ocs_plugin_api: append-only PluginRequest::DocApiRequest / PluginResponse::
DocApiResponse (serde_bytes payload) + defaulted HostApi::doc_api_dispatch.

Host: DocApiBackend impl for HostSession (src/app/doc_api.rs) mapping to scene
primitives (solid_models lift-on-miss, register_prepared_solid_model, meshes
metrics), entity conversions (doc_api_convert.rs), HostSession accessors +
doc_api_dispatch override.

Tests: 592 host lib (incl. 7 DocApi integration tests: create/boolean/query,
unknown-id, transform-many all-or-nothing, query-batch cap, 2D/geometric/DWG
roundtrips), 8 crate unit tests. Examples + README/ARCHITECTURE/IMPLEMENTATION docs.
2026-09-06 00:15:27 +02:00
Sebastian c60326ad4a Expose XRecord types and bump ocs_plugin_api to 0.2.1 2026-08-30 02:16:49 +02:00
Sebastian 8825ce5274 Expose XDataValue re-export from acadrust xdata module 2026-08-29 22:18:39 +02:00
Hakan Seven 0d766be3df fix(plugins): preserve document path encoding
Keep OS-native path data intact across IPC instead of replacing non-UTF-8 bytes.

Refs #901
2026-08-29 16:00:18 +03:00
Hakan Seven 1c52a2afcf Merge remote-tracking branch 'origin/main' into HEAD 2026-08-29 15:58:18 +03:00
Hakan Seven 2842f6dc58 fix(plugins): gate on_load behind API v5
BREAKING CHANGE: plugins using on_load must target API v5 and declare api_version = 5.

Refs #901
2026-08-29 15:57:26 +03:00
Hakan Seven c527466791 Merge remote-tracking branch 'origin/main' into HEAD 2026-08-29 15:55:50 +03:00
Sebastian 4668042df5 fix(plugins): compare rustc version tokens instead of concatenating
Tightens the rustc compatibility gate so that whitespace-normalised

version strings are compared token-by-token. This prevents a corner case

where 'rustc 1.98.0' and 'rustc1.98.0' would be considered equal.
2026-08-29 11:29:41 +02:00
Sebastian 996f6f7299 feat(plugins): add BuiltinPlugin::on_load lifecycle callback
OpenCADStudio/plugins#901 (comment)

- Add BuiltinPlugin::on_load(&mut self, host: &mut dyn HostApi) with a default
  no-op implementation so existing plugins remain source-compatible.
- Invoke on_load once for V4 plugins immediately after the runner connects
  and before entering the request loop, giving plugins a HostApi surface to
  cache plugin_request_sender() or set up worker threads before any dispatch.
- V2/V3 plugins are unchanged: HostApi is only available during dispatch.
2026-08-29 11:12:33 +02:00
Sebastian 09ba67bfd1 feat(plugins): expose document path to plugins via HostApi
OpenCADStudio/plugins#901 (comment)

- Add HostApi::document_path(tab_id) returning Option<PathBuf>.
- Add PluginRequest::DocumentPath and PluginResponse::DocumentPath for
  out-of-process plugins.
- Implement the request in the IPC server and in both V3/V4 plugin-side
  HostApi proxies.
- Implement HostSession::document_path by looking up the tab by id and
  returning its current_path.
2026-08-29 11:09:31 +02:00
Sebastian ed3e064a47 feat(plugins): include rustc version in plugin compatibility gate
OpenCADStudio/plugins#901

- Record the host's rustc --version output in the embedded version_info.json.
- Add rustc_version/rustc_declared/rustc_compatible to plugin manifests and
  release metadata, mirroring the existing acadrust gate.
- Reject API v4+ plugins whose declared rustc differs from the host, with a
  clear one-line error message.
- Propagate the rustc gate through the marketplace, install flow, and UI.
- Update plugin architecture docs to describe the new ABI metadata.
2026-08-29 10:34:47 +02:00
Hakan Seven 81e7add1dd fix(tolerance): complete workflow integration
Sync current main and companion codec changes before preserving unsupported frame rows, rendering in the entity plane, and sharing final layout metrics with placement preview.
2026-08-27 00:14:08 +03:00
Hakan Seven 1e1eeea527 feat(plugin): gate dependency mismatches 2026-08-25 08:12:13 +03:00
Sebastian 3d35919656 feat(plugin): gate marketplace and load on acadrust source
- Add host_acadrust_source and source-hash comparison helpers to ocs_plugin_api.

- Track acadrust_source and acadrust_declared in ExternalPlugin/ReleaseInfo.

- Apply repo-level policy: if any release in a repo declares acadrust_source, undeclared v4+ releases from that repo are incompatible.

- Preserve API v2/v3 backwards compatibility: legacy undeclared releases stay installable.

- Update Plugin Manager UI to only offer compatible releases and show 'acadrust mismatch' status.

- Drop acadrust_version from gate logic; only acadrust_source is required.
2026-08-24 19:01:06 +02:00
Hakan Seven 94f5971fdb docs(ipc): clarify polled response reads 2026-08-23 13:23:26 +03:00