Skip to content

v2.0.0-rc3

Pre-release
Pre-release

Choose a tag to compare

@gsdali gsdali released this 23 Aug 04:21
079019e

Third release candidate. Everything in v2.0.0-rc2, plus a feature that landed after it and a dependency fix that main could not build without.

rc2 still resolves and builds; it simply predates everything below. Consumers pinned to 2.0.0-rc2 should move to 2.0.0-rc3 to exercise the sidecar, which is what the remaining candidate phase is for.

Added: the agent-viewport selection bridge

startSelectionSidecar(directory:) / stopSelectionSidecar() on CADViewportService, plus PresentationStyle.agentHighlight (#16, #19). Three new public declarations; the wire types stay internal, because a host reads the JSON against the documented shape rather than linking this package for them.

An out-of-process agent can now read a human's live selection and ask the viewport to highlight geometry, over a file protocol in a shared directory. The design is written down in okf/decisions/agent-viewport-selection-bridge.md (#18), and the ADR rather than this source is the contract an MCP-side client codes against.

Four things it does that a file protocol usually gets wrong:

  • Writes are atomic, temp-name-then-rename, so a reader never sees half a file. A truncated selection.json that still parses would read as a shorter selection, which is worse than a parse error.
  • Requests are moved to handled/, never deleted, with their outcome recorded. Deleting throws away exactly what a retry needs, and makes "applied and cleaned up" indistinguishable from "never seen".
  • Liveness is an exclusive flock(2) on host.lock, released by the kernel when the process exits or crashes. Exact, needs no timeout, and detects a second host for free. A timestamp cannot tell an idle host from a dead one.
  • ifRevision gives compare-and-swap (#21), new in this candidate. Without it, an agent that read a selection, decided what to highlight, and lost a race to the human still applied its request and reported applied, with nothing recording that the premise had moved.

Fixed on main, and it never reached a release

The sidecar needs DirectoryWatcher, which was unreleased when it landed, so it pinned OCCTSwiftIO to a branch as a stopgap. That branch was deleted when the upstream PR merged, which is correct and also the moment the stopgap stopped working:

error: could not find a branch named 'issue-42-directory-watcher'

main could not resolve for a day; no tagged release ever carried the branch pin. rc2 predates it and pins OCCTSwiftIO from: "1.7.8" normally, so nothing a consumer could have pinned was affected.

DirectoryWatcher now ships in OCCTSwiftIO 1.8.0, so this is a version pin again (#20). Worth remembering as a pattern: a branch pin is a promise to come back, and deleting the branch on merge collects that debt immediately rather than eventually.

Changed

OCCTSwiftViewport floor raised to 1.2.0, which carries a real fix rather than bookkeeping: a Swift 6 concurrency crash where unannotated MTLCommandBufferHandler closures inherited @MainActor on Xcode 16.4, giving a SIGTRAP after every test had already reported green. Real-GPU and Xcode-16.4 only, masked locally by Xcode 26.x's NS_SWIFT_SENDABLE, so the declared floor is the only thing that carries the fix to a machine that would hit it.

Verified

384 tests in 36 suites. swift-format lint --strict and swiftlint --strict clean. CI green.

Why this is still a candidate

Nothing has exercised the sidecar end to end. It is a new protocol between two processes, and the tests drive both halves inside one. ACADStudio takes it next; that exercise is what 2.0.0 final is waiting on.

The other readiness items from #13 are done: the deprecated API is gone, CADViewportService is split into per-domain files, the pick-resolver deduplication is verified by execution rather than by reading, the identity-table docs are consolidated, and a real multibody fixture exists.

Going to final also means unwinding a prerelease chain. Six consumers pin this package's rc, two of them also pin OCCTSwiftScripts 1.7.0-rc1, and ACADStudio pins OCCTMCP 1.37.0-rc1. Those move to stable in dependency order once 2.0.0 ships (ecosystem#52).