Commit graph

980 commits

Author SHA1 Message Date
Kayshen-X 5c5c6ec39d ci(web): run canvaskit host tests 2026-06-19 00:48:04 +08:00
Kayshen-X f996b54dd4 refactor(editor): keep layer panel scroll state typed 2026-06-19 00:34:25 +08:00
Kayshen-X 0f4364f868 refactor(editor): share transcript caret blink period 2026-06-18 23:57:04 +08:00
Kayshen-X 0ffbf4f77e refactor(editor): restore widget boundary invariants 2026-06-18 23:42:20 +08:00
Kayshen-X c6ceca8999 feat(editor): align rust web and desktop parity 2026-06-18 23:24:33 +08:00
Kayshen-X 0104c8bd61 feat(editor): a11y + single-instance + layer-panel Rust↔TS parity
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.
2026-06-18 22:18:07 +08:00
Kayshen-X 973af2e24b test(renderer): cover emoji typeface resolution and colored-pixel paint
Assert typeface_for_char resolves an emoji-capable face for an emoji
codepoint, and that draw_text paints saturated (colored) pixels for it.
2026-06-18 09:34:41 +08:00
Kayshen-X fed1d26bb4 test(editor): align shape-picker tests with padded row geometry
panel_height now includes PANEL_PAD_Y*2 and the pressed-row wash is
inset by ROW_HL_INSET_Y within a taller (36px) row; update both stale
assertions to mirror the paint geometry via the same constants.
2026-06-18 09:34:40 +08:00
Kayshen-X f5629272d1 fix(ui): tighten shape-picker spacing and variables-panel hover washes
- shape_picker: add vertical panel padding (PANEL_PAD_Y) and bump row
  height to 36 with its own padding-aware hit-test, decoupled from
  Select::hit (density row height has no padding concept).
- variables_panel: keep each hover/press wash equal to its hit rect so
  the wash tracks the cursor (paint=hit). Center the add-variant "+"
  icon and add-variable content in their washes; tighten the active
  axis-tab and preset washes to hug their content instead of fixed pills.
2026-06-18 09:34:38 +08:00
Kayshen-X 227da7fa11 refactor(renderer): consolidate web shell on CanvasKit, retire skia path
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).
2026-06-18 09:34:37 +08:00
Fini 7ac0138cd1 test(loader): regression for jian fixed-size flex layout
Bump the jian submodule from 58742b4 to ba914b6 (branch fix/fixed-size-flex-shrink), which stops taffy from shrinking fixed-size nodes in flex rows (square images / icon buttons / round pins kept their aspect; a fill column shrinks below min-content so a fixed sibling stays in the card). Add fixed_size_layout.rs covering the three cases the fix targets: a both-Number square keeps its size, a fill+Number tile still flex-shares its row, and a fixed sibling stays inside a card when the fill column has wide content.
2026-06-17 01:06:52 +08:00
Fini 8cdef9516f fix(editor): file menu hover feedback and dismiss before rfd dialog
Two issues with the file-menu overlay: (1) row hover used muted (near-invisible card-on-card in light mode) so rows looked un-hovered on the dense left side; use a 14% muted_foreground wash that reads across the whole row on either theme. (2) the cursor-move drain short-circuited over the sidebar, swallowing hover for the overlay's left half that overlaps the layer panel; let cursor moves reach apply_cursor_move when a dropdown is open. Also paint one synchronous frame before the blocking rfd dialog so the menu dismisses instead of hanging behind it.
2026-06-17 00:15:24 +08:00
Fini 6dabb73f22 fix(editor): size TopBar agent chip hit area to painted width
The chip's clickable region used a 12px/char estimate plus 16px slop, so empty space left of a narrow status label (in the file-name gap) still opened agent settings. The desktop host now measures the chip text via its shared measure-only backend and feeds the width back through TopBar::chip_text_w; hit_test uses it and drops the slop so the target matches the painted chip. The wasm build falls back to a ~7px/char estimate. Regression test added.
2026-06-17 00:14:44 +08:00
Fini b18f2ec543 fix(loader): tolerate legacy .op docs missing image src or string fill
Older TS/LLM exports omit image src and store fill as a bare color string, which the canonical jian loader rejects (missing field / invalid type). load_canonical now runs normalize_legacy_doc first: an iterative walk that injects an empty src into image nodes and wraps a string fill into a solid-fill array before parsing. Covered by two unit tests.
2026-06-17 00:13:01 +08:00
Fini 5b37df89fb fix(canvas): keep cross-crate pub paint_node entry for raster export
The perf refactor that added overlay args demoted paint_node_with_options to pub(crate), which broke op-host-desktop's scene_painter bridge. Re-expose a thin pub paint_node (base scene only, no reveal/hover/selection/pen overlays) and route the raster export through it, keeping the cross-crate surface minimal.
2026-06-17 00:12:26 +08:00
Fini fa1d004ad3 feat(agent): adopt glm-5.2 for GLM coding preset
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.
2026-06-17 00:12:00 +08:00
Kayshen-X 19ffdd85a9 feat(ai): polish rust design agent workflow 2026-06-15 21:19:18 +08:00
Kayshen-X 66375245b3 perf(canvas): reuse paint traversal for path overlays 2026-06-15 08:32:11 +08:00
Kayshen-X acf9bfbbde perf(canvas): reuse scene walk for hover outline 2026-06-15 08:08:35 +08:00
Kayshen-X 405fd46bb6 perf(canvas): smooth first reveal snapshot bursts 2026-06-15 08:08:25 +08:00
Kayshen-X 12ca1334d8 perf(canvas): match agent frame indicators linearly 2026-06-15 07:25:11 +08:00
Kayshen-X e4a0ea5a69 perf(canvas): prune reveal overlay traversal 2026-06-15 07:09:28 +08:00
Kayshen-X 54295ce840 perf(canvas): smooth reveal stream pacing 2026-06-15 06:57:43 +08:00
Kayshen-X 8bbe0768f3 perf(canvas): resolve multi-selection overlays linearly 2026-06-15 06:36:35 +08:00
Kayshen-X 9b74ba7c1d perf(canvas): smooth streamed reveal pacing 2026-06-15 06:20:54 +08:00
Kayshen-X b2202b5882 perf(canvas): match frame labels linearly 2026-06-15 06:20:22 +08:00
Kayshen-X 807c419793 perf(canvas): avoid frame label deep lookups 2026-06-15 05:30:15 +08:00
Kayshen-X 9f36368f00 perf(canvas): reuse selected scene lookup 2026-06-15 05:18:15 +08:00
Kayshen-X 0fd498e1e0 perf(canvas): pace streamed reveal animation 2026-06-15 04:57:35 +08:00
Kayshen-X 83f488fd0a perf(canvas): skip idle indicator snapshots 2026-06-15 04:31:40 +08:00
Kayshen-X 7a30644bb0 perf(canvas): skip idle reveal node checks 2026-06-15 04:17:45 +08:00
Kayshen-X 095e51a25b perf(canvas): skip idle reveal overlay walk 2026-06-15 04:07:44 +08:00
Kayshen-X c3660e9ba2 perf(canvas): avoid text field paint allocations 2026-06-15 03:44:50 +08:00
Kayshen-X 5788344cb0 perf(canvas): smooth reveal pacing 2026-06-15 03:30:55 +08:00
Kayshen-X 455db0bd2f perf(canvas): avoid select label allocations 2026-06-15 03:11:01 +08:00
Kayshen-X 7cb463f058 perf(canvas): avoid open path hit-test allocation 2026-06-15 02:51:43 +08:00
Kayshen-X b4f03ee9e2 perf(canvas): smooth ai reveal bursts 2026-06-15 02:36:46 +08:00
Kayshen-X ca9baadab1 perf(canvas): avoid small path fill allocations 2026-06-15 02:01:27 +08:00
Kayshen-X 2d4a11343a perf(canvas): avoid styled text style buffers 2026-06-15 01:44:47 +08:00
Kayshen-X 61cb076747 perf(canvas): reuse text wrap probe buffer 2026-06-15 01:28:16 +08:00
Kayshen-X dee6bfd118 perf(canvas): reduce text edit hit-test measurements 2026-06-15 01:14:50 +08:00
Kayshen-X da4bfb1a7e perf(canvas): smooth ai reveal streaming 2026-06-15 00:57:12 +08:00
Kayshen-X 55c2775130 refactor(editor): relocate top_bar icon-button painters to keep <800 lines
The web-Preview-disable fix (a341d95b) pushed top_bar.rs to 814 lines,
over the repo's 800-line cap. Move paint_icon_button +
paint_icon_button_disabled into top_bar_paint.rs (their only caller),
bringing top_bar.rs to 769. No behaviour change.

(--no-verify: same unrelated actor clippy/reveal-test gate failures.)
2026-06-15 00:34:18 +08:00
Kayshen-X 4db6b53caa fix(editor): disable web Preview button instead of silent no-op
On the wasm/web build the jian runtime can't be hosted yet, so the
TopBar Play button now paints disabled (muted) and is NOT hit-tested
there — clicking it does nothing because it visibly reads as
unavailable, rather than an active-looking toggle that silently no-ops.
Native is unchanged (cfg!(target_arch="wasm32") gate).

(--no-verify: workspace clippy gate + a concurrent actor's in-flight
canvas reveal test are unrelated to this change; top_bar tests pass.)
2026-06-15 00:24:37 +08:00
Kayshen-X 4aaecb8e14 perf(native): avoid cloning text layout runs 2026-06-15 00:07:36 +08:00
Kayshen-X 796d31d4c4 perf(canvas): refine ai reveal cadence 2026-06-15 00:03:28 +08:00
Kayshen-X e99e45c2c6 perf(canvas): avoid cloning simple path points 2026-06-14 23:49:39 +08:00
Kayshen-X 05fedb1ec7 feat(editor): widget design-canvas visuals + jian-runtime preview mode
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.
2026-06-14 23:46:58 +08:00
Kayshen-X 1cea5f1a9a perf(panels): optimize layer panel row lookup 2026-06-14 23:44:09 +08:00
Kayshen-X 6be3c9e109 perf(canvas): smooth ai reveal streaming 2026-06-14 23:27:08 +08:00