5.7 KiB
Buildable module and host-service boundaries
Work package 3 implements a buildable service foundation. It does not register an IntelliJ editor, launch a standalone designer, initialize JavaFX inside IntelliJ, or implement target discovery/rendering. The earlier prototypes remain separate evidence.
Artifacts
| Artifact | Java release | Dependencies/responsibility |
|---|---|---|
| designer-contracts | 21 | Immutable draft and edit DTOs; no framework dependencies |
| designer-preview-api | 21 | Provisional example descriptor; no framework dependencies |
| designer-core | 21 | Contracts; schema validation, context selection, host interfaces, runtime mappings, process builds, lifecycle scope |
| designer-kit-ui | 25 | Core and Scene Builder Kit 26.0.0 (JavaFX 26); FX-thread construction seam |
| designer-standalone | 25 | Shared Kit UI; file-backed drafts and undo adapter |
| designer-target-tools | 21 | Contracts, preview API, recorded NeitzelLib snapshot; linkage smoke entry point |
| designer-maven-plugin | 21 | Maven 3.9.11 provided APIs; effective plan/dependency/runtime capture inside the build JVM |
| designer-intellij | 25 | Shared Kit UI; actual IDE Documents, commands, navigation, project disposal |
flowchart LR
IDEA[IntelliJ adapter] --> UI[Shared Kit UI]
Standalone[Standalone adapter] --> UI
UI --> Core[Core / HostServices]
Core --> Contracts[Contracts]
Target[Target tools: separate process] --> Contracts
Target --> Preview[Preview API]
Target --> Library[NeitzelLib]
The Maven reactor enforces transitive dependency exclusions: contracts/core/preview cannot acquire JavaFX, Kit, IntelliJ or NeitzelLib; target tools cannot acquire Kit or IntelliJ; other shared modules cannot acquire IntelliJ. The orchestration script verifies compiled class versions. There are no JPMS descriptors yet. Module-path qualification and public preview lifecycle signatures remain work package 6.
Service contract
HostServices supplies document access, builds, explicit runtime resolution, navigation, diagnostics and an owned SessionScope. Core imports neither host implementation. Each host owns its services; closing one handle does not close sibling handles or implicitly save a document.
Document operations return completion stages. Callers must not block UI threads waiting for them. Standalone IO/history runs on a serialized executor; IntelliJ operations marshal to its EDT with write-intent read access and use native write commands. Revisions are monotonically increasing identities, not undo indices. Every edit batch addresses one revision with UTF-16 offsets; all ranges are validated before any mutation. One batch is one undo command. Closing the IDE adapter releases its listeners/editors, while the native Document remains IDE-owned.
Save checks the expected revision and compares disk content with the captured baseline. Conflicts preserve both draft and external content. This is initial conflict detection, not atomic coordination with arbitrary external writers: another writer can race the check. IntelliJ autosave/external reload reconciliation and complete encoding/line-ending fidelity need the later document integration gate. Standalone currently reads/writes UTF-8 and retains history for the lifetime of its host.
Build execution accepts an already resolved command/environment/working directory, drains both output streams and supports cancellation of the process and observed descendants, with forced termination after a bounded grace period. The lifecycle scope closes owned resources once in reverse order and continues cleanup after individual failures. Runtime lookup requires an explicit name/role mapping and has no fallback JVM. Navigation and diagnostics remain host callbacks. The shared Build and Refresh coordinator now owns planning and snapshots above this process runner. Worker transport and owner-death IPC remain later work.
Validation and packaging
Run the single command documented in README. Shared modules use Maven 3.9.11; IntelliJ packaging uses Gradle 9.1.0 and IntelliJ Platform Gradle Plugin 2.20.1 against local SDK build 263.7307.200. The plugin range is restricted to the 263 branch. This is build/test evidence for that exact SDK, not binary compatibility evidence for every future build in the range.
Tests exercise atomic multi-range edits, stale and invalid requests, independent handles, standalone/native IDE undo and redo, disk conflicts, separate runtime roles, process output/cancellation and scope cleanup. The Java 21 target smoke checks linkage to the recorded library, contracts and preview descriptor; it does not initialize a Model or JavaFX rendering. Plugin ZIP creation and project configuration verification do not replace Plugin Verifier, manual IDE interaction, accessibility, or JavaFX exclusivity qualification.
Configuration/context resolution and compatibility are now implemented. The first full two-host workflow remains work package 7.
Validation on 2026-11-12: eight Maven tests and two native IntelliJ tests passed, Java 21 linkage passed, and the clean plugin build passed. A deliberately injected JavaFX dependency in contracts was rejected by Maven Enforcer and then removed. The plugin archive is checked for host JavaFX implementation JARs and exclusion of target artifacts. Gradle needs explicit macOS classifier dependencies because it does not select Maven's OpenJFX platform profiles. Other OS packaging is not qualified yet.
The plugin configuration check warns against an until-build restriction; this foundation intentionally retains 263.* rather than implying untested forward compatibility. No Plugin Verifier compatibility run is claimed.