Codex review caught a BLOCKER: the loader folds TWO opacity factors into
resolved scene paint alpha — the fill/stroke body's own opacity (apply_alpha
in style_payload) AND node cumulative opacity — but the colour-drag fast path
only baked node opacity, so a fill/stroke authored below 100% painted too
opaque on every drag frame until release reconciled. Fold the body opacity in
host-side via first_solid_fill_opacity / new first_solid_stroke_opacity before
the patch; jian-scene still bakes node opacity on top, matching scene-build.
+unit test for the new stroke-opacity accessor.
VariableTable/Value/Scalar (unresolved theme refs + NodeId) now live with
the canonical variable system. NodeId/Color resolve at the op-editor-core
crate root. 26 scene_vars tests green.
The canvas Preview (Play) button and the property-panel Widget section are
unfinished surfaces. Add an opt-in "Experimental features" switch in
Settings → System (default off) that gates both:
- TopBar: a `preview_button_visible()` predicate (host capability AND the
opt-in) drives paint, hit-test, and the globe-anchored locale picker so
the right cluster never drifts.
- Property panel: the snapshot's `widget` is cleared when off, hiding the
section (rows + height) with no layout change.
Disabling the toggle exits any live preview (host-owned session on native,
core flag on web) and clears stale Widget property focus so a hidden field
can't commit. Persisted via AgentSettings on desktop (settings.json) and web
(web_settings). Adds settings.experimental(+Desc) to all 15 locales.
Close the non-web-productionization gaps from the 2026-06-18 recheck:
- a11y (#67/#57): assemble each widget's access_node() into an
accesskit::TreeUpdate (op-editor-ui/accessibility.rs); publish on
desktop via accesskit_macos/_windows/_unix SubclassingAdapter off the
raw window handle (op-host-desktop/a11y.rs, NOT accesskit_winit — the
casement winit fork), and on web via a hidden ARIA DOM mirror
(op-host-web/a11y_dom.rs); native/web region enumeration + action
routing in op-host-{native,web}.
- single-instance (#51): fixed-loopback-port guard + second-launch file
forwarding to the running window (op-host-desktop/single_instance.rs).
- layer panel: drop-into-container inserts at index 0 (#12a); container
predicate widened to frame/group/rectangle/ref (#12b); Escape closes
the context menu on both hosts (#14).
- distribution: Homebrew cask fix + op formula + install-op.sh, README
CLI install, CI codesign/notarize/signtool scaffolding gated on secrets.
Codex-reviewed (1 BLOCKER + 3 CONCERNs resolved). main.rs, app_handler.rs,
canvaskit.rs and Cargo.lock are staged whole and carry some unrelated
in-progress WIP they're interleaved with.
Retire the from-scratch wasm32 skia raster web backend and the vendored
skia-safe fork now that CanvasKit is the sole web renderer.
- remove gl-webgl-shim + the `webgl` feature + backend/webgl.rs
- absorb chat streaming, live-sync, codegen, icon search, Figma/file IO,
and system fonts into the `canvaskit` build via a backend-agnostic
`RepaintContext` trait; wire them into `mount_ck` (chat send, image
paste routing, window resize)
- delete the skia raster modules (backend/, a11y, shell_drop/resize,
ime_target, boolean_ops, caret_pump, repaint_scheduler) + the skia
`Inner` mount; op-host-web is now `web` (stub) + `canvaskit` only
- drop [patch.crates-io]; delete vendor/skia-safe-op + crates/wasm-libc-shim
so skia-safe reverts to upstream crates.io 0.97.x (native unchanged,
byte-identical; upstream has no wasm32-unknown-unknown target)
- switch the bundle gate (check-wasm-bundle.sh) to --features canvaskit
Also float new shapes above the frame (z-order), inset the shape-picker
selected-row highlight, and align the web file-menu hover without the
traffic-light inset.
Builds clean: canvaskit + web-stub (wasm32) + native desktop; bundle gate
passes (0 env.*, 4.5 MiB gzip).
Point the built-in GlmCoding preset at glm-5.2 (was glm-4.7) and add a glm-5.2 route to the ab-v9 matrix via Zhipu's official coding plan (GLM_BASE + GLM_KEY env). Keys stay env-only.
Render the 10-widget family as composite visuals on the design canvas
(op-pen-loader payload -> scene -> canvas_viewport_widget), and add a
Play/Stop canvas Preview mode that runs the jian runtime live via a
DrawOp -> Painter bridge (native host) with doc-invariant enter/exit.
The web Preview button is an honest no-op pending a web runtime owner.
Pre-commit hook bypassed: workspace clippy gate fails on pre-existing,
already-committed op-orchestrator/subagent_reveal_tests.rs (unrelated).
This change is rustfmt-clean and cargo check --workspace passes.