11 KiB
First connected workflow in both minimal hosts
Bootstrap work package 7 connects the existing build/snapshot services to real target workers and the same Kit UI in standalone and IntelliJ. This is a runnable development milestone, with bounded scalar/layout projection, not the complete designer product.
Later implementation: source-preserving projection replaces the original serialization and extends anonymous/nested Component and fx:root editing. Historical qualification and initial limitations below describe work package 7.
Flow and ownership
sequenceDiagram
participant UI as Shared Kit UI
participant Host as Standalone / IntelliJ documents
participant Core as DesignerWorkflow
participant Build as BuildRefresh / SnapshotStore
participant Worker as Java 21 target JVM
UI->>Core: Build and Refresh
Core->>Host: Inventory build drafts / exact save approval
Core->>Build: Scoped Maven build and immutable publication
UI->>Core: Discover successful build
Core->>Build: Acquire verified snapshot lease
Core->>Worker: Authenticated loopback discovery
Worker-->>UI: Resource-only example descriptors
UI->>Host: Capture parent and known Component drafts
UI->>Core: Render selected example and Component sizes
Core->>Build: Lease same build identity
Core->>Core: Private FXML overlay and tooling copies
Core->>Worker: New process, one loaded parent / Model graph
Worker-->>Core: Correlated RGBA images
Core->>Host: Recheck document revisions
Core-->>UI: Images if request generation remains current
UI->>Host: Canvas edit as one native document command
Core->>Worker: Close owner channel / bounded termination
Core->>Build: Release lease after worker shutdown
A render batch shares one target View, Model graph and configured services across all Component images. A later draft/size/example refresh uses a fresh process. No application Controller, Component or provider is loaded in the host. Kit receives host-owned SnapshotRegion objects.
Source remains authoritative. The projection preserves original Controllers, bindings, processing instructions, comments and unrepresented attributes outside Kit. Supported scalar/layout edits on the root or identified nodes become one host document transaction; structural edits and unsupported attributes are rejected. Metadata is preserved semantically, although XML whitespace/serialization may change. Native document undo/redo reloads the projection.
Transport, overlays and lifetime
PreviewWorker launches the configured target JDK, using the captured runtime and private copies of the three target tooling JARs. The application runtime never points at original mutable Maven outputs. Both classpath and boot-module-layer launches are implemented. Module launches deduplicate repeated module artifacts, retain configured explicit reads/opens, require the selected entry module to exist, and do not invent broad access fixes.
Each launch gets a random token delivered through a reserved stdin pipe, not command-line arguments or logs. The worker replaces application stdin with an empty stream and watches the original owner pipe independently of FX responsiveness. HELLO validates token, session, launched PID, versions and required capabilities on a loopback socket. Stdout/stderr are bounded presentation logs, separate from binary framing. Each request/result includes context, build, revisions and size through the existing protocol validator.
The host applies handshake/read deadlines and an overall 45-second worker deadline. Closing/cancelling the owner closes the socket and lifetime pipe, then forces termination if needed. Worker-side owner loss attempts cleanup and halts after a bounded grace period, independently of blocked FX. Abrupt owner death is tested in a separate process. Cleanup callbacks remain cooperative; they cannot be guaranteed after forced death.
FXML overlays contain at most 128 drafts, each at most 1 MiB. Only affected class directories/JARs are privately copied; unchanged dependencies remain leased immutable snapshot files. An overlaid JAR with signature metadata is rejected. Resources must map unambiguously to captured source roots and exist in the runtime. The store verifies that overlays never alter the published snapshot.
Saved FXML can differ from captured inputs only when that exact file is supplied by the overlay. Java/POM/settings changes and uncovered resource changes still invalidate current-build selection. Dirty and clean known/open Component drafts are captured, so saving an open Component does not require Java recompilation. A failed build still requires explicit Preview last successful.
Images retain the existing 16 MiB per-frame limit; a batch additionally caps aggregate pixels at 64 MiB. Document-change notifications invalidate queued UI results immediately; revision checks and generation checks reject stale responses. The previous image stays visible during asynchronous updates. Snapshot viewports use parent coordinates, as required by JavaFX SnapshotParameters.
Minimal host UI
Both hosts show the shared source view, Kit hierarchy/canvas/inspector, build output, example selection and actions for build, cancellation, rendering, explicit retained-build preview, save, undo/redo and opening Component source.
- Standalone owns shared file drafts across its windows. Closing the last window offers save/discard/cancel for unsaved drafts. Invalid setup opens a source-only editor with save and undo/redo.
- IntelliJ registers a separate Neitzel Designer editor after the normal editor. It uses native Documents and commands, including asynchronous edits from FX. Setup failures leave the regular source editor available.
- The IntelliJ gate checks the qualified SDK, disabled
embed.scene.buildersetting, bundled-provider refusal and absence of preloaded Glass before initialization. It revokes the designer if the registry setting changes. JavaFX/FXML language support stays enabled. - The narrow Kit 26 I18nStringEditor selection patch is shared by both hosts. Its source/license provenance is in third-party notices.
The IDE adapter retains the actual VirtualFile/Document opened through a path alias while using canonical paths for snapshot identities. This avoids a second document for macOS /var versus /private/var aliases.
Run and verify
First run the full build command in README. The development launchers use that installed build and the verified NeitzelLib snapshot:
python3 scripts/run-fixture-host.py standalone --java-home "$JAVA_HOME" --target-java-home "$TARGET_JAVA_HOME"
python3 scripts/run-fixture-host.py intellij --java-home "$JAVA_HOME" --target-java-home "$TARGET_JAVA_HOME" --idea-home "$IDEA_HOME"
Add --mode modulepath for the named-module application. Each launch makes a fresh disposable fixture and prints its location/PID. The IntelliJ launcher uses a private config/system/plugins directory with bundled embedding disabled; it does not alter the user's normal IDE settings. Select Neitzel Designer, then Build and Refresh.
Machine-local .neitzel-fx-designer/host.properties explicitly selects configuration, context, runtime-settings file, fallback Maven executable and target tooling JAR paths. Relative paths resolve from that file. Multiple application contexts require an explicit context value; the minimal setup has no configuration wizard. These local files are not application configuration or published artifacts.
Automated gates:
python3 scripts/check-connected-workflow.py --target-java-home "$TARGET_JAVA_HOME" --idea-home "$IDEA_HOME"
python3 scripts/check-ide-host.py --java-home "$JAVA_HOME" --target-java-home "$TARGET_JAVA_HOME" --idea-home "$IDEA_HOME"
The first is included in check-bootstrap.py: real Maven builds, socket discovery/rendering, parent/Component overlays, shared render batches, source navigation, stale responses, saved-FXML reuse, native document undo/redo, invalid FXML and cancellation run through standalone and actual IntelliJ document adapters. Native standalone Kit windows verify both application layouts, inspector text selection, canvas commits, binding preservation, undo/redo, save and source-only fallback. A separate owner process verifies worker death after an abrupt shutdown.
The second launches real isolated IntelliJ instances with a test-only companion plugin, excluded from the delivered plugin ZIP. It verifies editor registration, the shared UI, build/discovery/render, native document edits and undo/redo, then captures screenshots and hashes loaded OpenJFX natives. Evidence is written under target/connected-workflow/ and target/ide-workflow/.
Qualification result — 2026-11-12
The clean bootstrap command passed 56 tests (50 Maven, six IntelliJ), zero failures/errors/skips; 346 assertions across 24 target JVMs; 14 Build and Refresh smoke checks; and 64 connected workflow assertions across both host document adapters and both application layouts. Native standalone Kit windows passed the five real inspector mouse-selection cases, build/render, canvas edit, undo/redo, save and source-only fallback for each layout. Abrupt owner death terminated its worker.
The separate real-IDE command passed for classpath and module-path applications on IU 263.7307.200. Both registered editors completed Build and Refresh, rendered both Components, committed Kit edits to the native Document, performed undo/redo and rendered drafts. Screenshots were inspected. Both processes reported JavaFX 26+27, exactly one Glass library, and loaded OpenJFX native hashes matching the JavaFX 26 artifacts. Glass SHA-256: 8fe9cc20e424b078ecaeb01ad6d72436439fb2b66d48dd094fa5d262a65d546a. Disposable IDEs were terminated after verification.
This work also fixes two issues exposed by the real registered editor: native edits now use IntelliJ's non-modal write-safe scheduling, and canonical snapshot paths retain the original alias-opened VirtualFile/Document. Artifact identity, dependency/bytecode gates, plugin ZIP checks and documentation validation passed. The intentional IntelliJ until-build restriction still produces its previously documented configuration warning.
Limits and next stage
The qualified platform is macOS arm64, IntelliJ IU 263.7307.200, JavaFX/Kit 26 in hosts and the recorded Java 21 / JavaFX 21.0.7 target. This is not a Plugin Verifier result or wider OS/SDK/runtime qualification.
Canvas support is intentionally bounded: explicit Component imports with fx:id, the tested Caption/alignment/layout attributes, and scalar/layout edits on identified standard nodes. fx:root/include/script, inline Component content, wildcard application imports, arbitrary structural edits and complete binding/generation editing retain source editing and later projection gates. Opening an fx:root Component currently gives source editing; its parent can preview those drafts. Separate interactive preview controls, general Component authoring, handoff, accessibility, remote IDEs, installers and product release packaging remain later roadmap work.
The first workflow is now connected; the next roadmap stage is Establish authoritative documents and generalize the Kit projection, followed by richer Component preview and binding authoring. This milestone does not establish a corrected public NeitzelLib release or freeze a public preview API.