Commit graph

113 commits

Author SHA1 Message Date
Fini 1e3fdc91e1 chore(deps): bump jian for main-axis fill_container grow
Points the jian submodule at the layout fix that grows a main-axis
fill_container child (a sidebar footer spacer) into the column remainder.
2026-07-02 21:21:52 +08:00
Fini 0730e1ccce feat(host): headless render-parity tooling — bundled fonts, margin env, layout dump
Bundle 11 OFL design-font TTFs and register them with jian-skia at startup so
--render-shots reproduces Pencil's glyph metrics without system fonts.
OPENPENCIL_RENDER_MARGIN tightens the export crop to match Pencil export_nodes
(no frame), and OPENPENCIL_DUMP_LAYOUT prints every node's computed rect as JSONL
to diff our layout against Pencil snapshot_layout element-for-element. Bumps
vendor/jian to the bundled-font + Auto=no-wrap render-parity commits.
2026-07-02 21:21:30 +08:00
Fini bf4a741d8e feat(loader): mesh/shader fills + .pen→.op legacy normalize hardening + pen2op bin + design-library merge
Bumps jian submodule for mesh-gradient/shader PenFill variants. normalize_legacy_doc
gains 8 .pen-compat repairs (stroke-fill string, gradient fill, icon/prompt nodes,
$ref cornerRadius, single-object fill). New pen2op bin converts Pencil .pen→.op.
library.rs merges a .lib.op's reusable masters+variables into a working doc.
2026-07-02 21:21:09 +08:00
Kayshen-X fc58a4601d chore: bump jian submodule (node promotion for batch_design) 2026-07-02 21:21:07 +08:00
Kayshen-X a7d73ebb62 feat(ai): pencil-style agentic design tool-loop, multi-chat tabs, #27 panel restyle
Built-in design generation now runs as an agentic MCP tool-loop (reusing the
agent-rs BuiltInProvider), gated behind OPENPENCIL_DESIGN_AGENT_LOOP / the
Settings experimental toggle; the orchestrator stays the default.

- design-agent system prompt + in-process design toolset (parity-locked with
  the MCP surface) + flag-gated Intent::Design routing
- spawn_agents execution as sequential sub-loops + live creation-mode badges
  (per-agent glow + 'N/M designing...' header)
- new MCP tools: get_guidelines, ToolSearch, get_screenshot, get_editor_state,
  export_nodes, spawn_agents; style-guide local audit
- #27 AI panel restyle: rounded tool cards + green check-rings, gray user
  bubbles, model-pill bottom toolbar, header, empty-state pills, the
  PARALLEL AGENTS (agent_team_size) 1x-6x chip dropdown
- multi-chat tabs: ChatSessions model (Deref-to-active) + tab row UI
  (switch / close / + / Cmd+T) with each run bound to its tab

Large checkpoint commit spanning the working tree (Rust shell crates).
2026-07-02 21:21:06 +08:00
Kayshen-X d603f2f388 chore: bump jian submodule (node promotion for batch_design) 2026-06-25 00:15:55 +08:00
Fini d353a58450 chore: bump jian submodule (image cover + leaf flex-shrink) 2026-06-21 23:18:22 +08:00
Kayshen-X ec5ba9c283 fix(editor): repair strokes and legacy render layout 2026-06-21 16:52:31 +08:00
Kayshen-X ba6aae07dc perf(canvas): Arc-share image src/url to make scene-cache O(1)
Bump vendor/jian to the ImageSrc(Arc<str>) change: ImageNode.src and
ImageFillBody.url are now reference-counted, so the per-frame
SceneBuildCache document clone + content-compare settle in O(1) for an
unchanged multi-MB image source instead of walking the whole base64
payload. Completes the deeper half of the image-drag perf fix (the
insert-time down-scale landed in a084628f).

Consumer sites updated for the newtype: writes/constructs use .into();
sites assigning into a String field use .to_string(); reads are
unchanged via Deref. Also fixes a stale gl-host test
(remote_icon_insert_bakes_svg_d_as_path_node) that still assumed icon
insert appends to the end — it now locates the baked path by icon_id and
asserts it sits above the selection (the insert-above behavior).
2026-06-21 10:01:37 +08:00
Kayshen-X eed21064b9 feat(canvas): insert icons/images above the selected layer
Icon and image inserts append()ed to the page root (the back / bottom of
the LayerPanel), ignoring the selection. Add insert_node_above_selection:
the new node lands in the selected node's parent at the selection's index
— one row up in the panel, one step toward the front in z-order (canvas
paints children back-to-front). Falls back to page-root append when
nothing is selected.

Bumps vendor/jian to d50a715 (O(1) image source id — fixes image-drag lag).
2026-06-20 23:58:58 +08:00
Kayshen-X 9b77f170c8 refactor(git): render masked HTTPS credential via unified TextInputView
Route the Remotes-section HTTPS credential field through the unified
TextInputView with mask: Some(&mask_credential) (new
paint_text_input_view_masked helper), deleting the ~90-line hand-rolled
masked renderer + masked_byte_for_source_byte caret remap in
git_panel_remotes. The token still shows as user:•••• with a correct,
family-aware caret. Other TextInputView call sites pass mask: None.

Bumps vendor/jian to c451e16 (TextInputView::mask).
2026-06-20 22:26:28 +08:00
Kayshen-X 11431e1a18 refactor(store): reuse jian_core::color, drop op-editor-core color_convert
The colour maths now lives once in jian_core::color; op-editor-core
re-exports it through color_picker (so crate::color_picker::parse_hex_rgb
and op_editor_core::* paths are unchanged) and deletes its duplicate
color_convert module. Bumps vendor/jian to 3404ad8.
2026-06-20 21:41:17 +08:00
Kayshen-X d706222f4e feat(panels): editable R/G/B fields in the colour picker
Click an R/G/B box to edit that channel as a 0..255 value through the
unified TextInputView; the host routes keystrokes via color_picker_rgb_*
(now_ms-threaded, digit-gated, 3-char cap) and live-applies by splicing
the channel into the current RGB and committing through set_hsv.
ColorPickerState gains rgb_focus + rgb_input; active_text_input + the
text-input gate resolve it; press dispatch focuses/blurs hex vs rgb.

Extracts the hex+rgb edit state machines into color_picker_edit.rs to
keep color_picker.rs under the 800-line cap. Bumps vendor/jian to d11d54e.
2026-06-20 21:27:08 +08:00
Kayshen-X da6e7cd228 refactor(panels): drive colour-picker hex bar through unified TextInputState
The picker hex field now stores a jian TextInputState (hex_input) seeded
on focus and edited via the same caret-aware insert/backspace gating as
the property-panel hex input, instead of a hand-rolled String draft +
manual caret. ColorPickerState carries hex_input; the host threads now_ms
for the caret blink and routes keystrokes through color_picker_hex_char/
backspace(now_ms); active_text_input() resolves the picker hex so its
blink drives the redraw. Fixes the caret drift and removes the picker's
last hand-rolled input.

Bumps vendor/jian to cce4523.
2026-06-20 20:57:10 +08:00
Kayshen-X 0c2af63b4e fix(canvas): resolve named draw family in caret measurement
Implement Painter::measure_text_family on the native skia backend
(NativeBackend::measure_text_family_styled segments per-codepoint
against the real family, exactly like draw_text) and forward it through
NativeFrameBackend + BaselineAdjustingBackend so the family-aware
measure reaches skia through the wrappers. Fixes the ~6px caret drift
in every TextInputView/TextArea chrome input (property pills, chat, git,
settings) — measure now uses the same typeface paint does.

Bumps vendor/jian to 19fb00b (Painter::measure_text_family).
2026-06-20 20:29:41 +08:00
Kayshen-X 1744b2aa8a feat(panels): editable hex input in the colour picker
Click the picker's hex bar to focus it, then type a #RRGGBB value
(or paste one char at a time): the bar shows the live draft + caret,
Enter/Escape/outside-click commit-and-blur, and a valid hex re-seeds
HSV so the SV box + hue handle follow. Keystrokes route through the
text-input gate so they don't leak into chat/shortcuts.

Bumps vendor/jian to ce19bed (ColorPicker::HexInput hit + draft render).
2026-06-20 19:29:47 +08:00
Kayshen-X 934aef334d fix(editor): borderless top-bar icon dropdowns + git commit-input baseline
The TopBar globe + file-menu SelectTriggers now pass bordered:false (no
Outline box, just the icon+chevron with a hover wash); the form-field
dropdowns keep the border. The git commit-message TextArea (ready +
status panels) now paints through BaselineAdjustingBackend so its text
sits on the baseline instead of clipping at the top. Bumps vendor/jian.
2026-06-20 18:05:12 +08:00
Kayshen-X 18fd0000dd fix(editor): bump vendor/jian for consistent baseline contract
jian a53a61c: ColorPicker's box-centered labels now route through
centered_text_baseline_y like every other component; non-box-centered
placements (RGB captions, Dialog title) and the host-baselined input
glyph layers are documented exceptions.
2026-06-20 17:01:02 +08:00
Kayshen-X 3f7ed3dc7e fix(editor): bump vendor/jian for text-baseline fix
jian dc15ea7: component labels (buttons, tabs, toggles, badges, menus,
dropdowns, tooltips, accordions) now position text by the BASELINE
(center + font_size*0.35) instead of the (height - font_size)/2 top-left
form, so they no longer render ~font_size too high in the editor chrome.
Input glyph layers stay top-relative (the host's BaselineAdjustingBackend
handles their baseline).
2026-06-20 16:49:34 +08:00
Kayshen-X 25a9b7f9a4 refactor(editor): absorb design-md markdown parser into jian markdown
The Design-MD panel's markdown parser (block structure + inline
bold/code/#HEX styling + run wrapping) moves to jian components::markdown;
design_md_markdown.rs becomes a thin re-export so the panel's block
renderer is unchanged. ~300 fewer lines of OP-domain parsing. Bumps
vendor/jian to 94f8315.
2026-06-20 15:18:13 +08:00
Kayshen-X 32ae68a248 refactor(editor): absorb the HSV color picker into jian ColorPicker
The floating color picker's rendering, layout, hit-test and HSV<->RGB
math now live in jian ColorPicker; color_picker.rs shrinks to a wrapper
that owns the property-panel-relative anchor (rect), the EditorState
plumbing and the drag dispatch, re-exporting hsv_to_rgb / rgb_to_hsv /
ColorPickerHit / PICKER_* so the hosts import them unchanged. ~330 fewer
lines of OP-specific paint. Bumps vendor/jian to 9580247.
2026-06-20 15:11:33 +08:00
Kayshen-X 7040e5592a fix(editor): variables axis-tab paint walks theme_tab_advance_width
Review found the axis-tab paint (jian content_rects, advance = width+gap)
drifted 6px from the hit walker (theme_tab_advance_width) for tabs to the
right of an inline-renaming axis, where the two advances differ. Feed
content_rects the host's per-tab advances (theme_tab_advance_width for
variables; width+CHIP_GAP for the framework chip) so paint and hit share
the same advance source and can't drift in any state. Bumps vendor/jian
to f0fbf70.
2026-06-20 15:00:40 +08:00
Kayshen-X bceefb5b68 refactor(editor): absorb the framework chip strip into jian Tabs
The scrollable, variable-width framework chip carousel now lays out via
jian Tabs::content_rects and renders via Tabs::paint_content (PrimaryPill
active style) instead of a hand-rolled chip loop; the host keeps its
deterministic width fn, scroll state, clip band and chevrons. Both paint
and hit go through the jian layout, so they stay aligned. Bumps
vendor/jian to ed15b1e (Tabs content-width flexibility).
2026-06-20 14:29:26 +08:00
Kayshen-X dc67272bad refactor(editor): render fill/effect color swatches via jian Swatch
The gradient-stop and shadow-color swatches now paint through jian
Swatch (alpha-aware checker + fill) instead of the local paint_alpha_checker
+ separate fill; drops paint_alpha_checker and its public re-export.
Bumps vendor/jian to 9c13e8d (checker now theme-independent, so the
transparency pattern stays visible in dark mode).
2026-06-20 13:05:03 +08:00
Kayshen-X 5e7302222b refactor(editor): migrate builtin-agent kind toggle to jian ToggleGroup
The Anthropic/OpenAI kind segmented control now renders + hit-tests
through jian ToggleGroup (segment_at) instead of a hand-rolled cell
loop + kind_option_rect. Drops the KindOption.slot indirection and the
kind_option_rect helper; single-option presets render full-width.
Bumps vendor/jian to 3b5db91.
2026-06-20 12:05:41 +08:00
Kayshen-X 2096a1f444 refactor(editor): adopt jian Button icon_paths + migrate code icon buttons
All op-editor-ui jian Button call sites move from icon_d to icon_paths.
The code panel's Generate / Export-bundle icon+label buttons and the
Design-MD action buttons now render through jian Button with full
multi-subpath icons (sparkles / braces / wand), dropping the local
paint_centered_icon_label hand-rolling + paint_primary_hover_overlay.
Bumps vendor/jian to 9998df9.
2026-06-20 11:54:56 +08:00
Kayshen-X 9f70adede7 refactor(editor): migrate export/code/image CTA buttons to jian Button
Export-section, export-dialog (Cancel→Outline, Export→Primary), image
generate-popover (Apply→Primary, Retry→Outline) and the code-panel
full-width action button now render through jian Button instead of
hand-rolled fill_round_rect + hover overlay + centered draw_text. The
solid-fill hover-darken now lives in the component, so per-button hover
state threads straight through. Bumps vendor/jian to 330feb4.
2026-06-20 11:47:55 +08:00
Kayshen-X 03e37f4613 refactor(editor): migrate provider-card connect/disconnect to jian Button
Connect renders through jian Button Primary (centered label, primary
fill) and Disconnect through the new DestructiveOutline variant (red
border + red label) instead of hand-rolled fill_round_rect + centered
draw_text. Bumps vendor/jian to 9e47bd3.
2026-06-20 11:38:42 +08:00
Kayshen-X c10a6638a9 chore(editor): SelectTrigger icon_paths field; bump jian 2026-06-20 11:16:46 +08:00
Kayshen-X d4cd38333f refactor(editor): sink component-browser kit dropdown to jian SelectTrigger
The kit-filter dropdown trigger (feedback wash + border + truncated label + chevron) now renders via jian SelectTrigger — one component call, feedback/label/chevron all internal. Demonstrates the dropdown 收口 pattern. Bumps vendor/jian to 144eb50.
2026-06-20 11:09:16 +08:00
Kayshen-X a9bf1448a3 refactor(editor): toolbar icon buttons use jian IconButton; drop OP copy
toolbar's paint_button now renders jian IconButton (icon.paths() -> generic d-strings); removed the OP-local IconButton struct + paint_icon_button helpers from button.rs (the component now lives in jian). Bumps vendor/jian to 346eeb3. Other scattered icon buttons migrate next.
2026-06-20 10:54:40 +08:00
Kayshen-X 2d9ccce73a refactor(editor): sink agent provider card chrome to jian Card
paint_agent_card's hand-rolled conditional fill_round_rect + stroke_round_rect chrome now goes through jian Card; the fill choice (outlined ClaudeCode -> muted, hover -> accent, else transparent) stays caller-side so the look is preserved exactly (radius 10, border). Bumps vendor/jian to 5f903d6. Demonstrates the enhance-jian-then-sink pattern.
2026-06-20 08:59:17 +08:00
Kayshen-X 3e54a66f31 chore(vendor): bump jian — Select check-left + Switch hover fidelity 2026-06-20 08:29:33 +08:00
Kayshen-X d68b959c98 chore(vendor): bump jian to f02b4a5 — layout_scene 800-line split 2026-06-20 08:16:57 +08:00
Kayshen-X a004a95b79 chore(vendor): bump jian to fd4111f — Input field 2026-06-20 07:57:04 +08:00
Kayshen-X 65b5bf8a6b chore(vendor): bump jian to c12f277 — Swatch/Tooltip/Tabs/ToggleGroup/Accordion/Popover 2026-06-20 07:54:01 +08:00
Kayshen-X d653cd4b33 chore(vendor): bump jian to afe3fc8 — Separator + Progress 2026-06-20 00:49:33 +08:00
Kayshen-X c354b0b6b2 chore(vendor): bump jian to 199268e — Button Secondary/Link + Badge/Checkbox/Radio/Card 2026-06-20 00:45:40 +08:00
Kayshen-X e839c40770 perf(canvas): patch scene fill/stroke in place on colour-picker drag
A colour-picker drag rewrites doc fill on every mouse-move, so the scene
build cache (which compares the doc) rebuilt the whole layout — taffy + a
full SceneNode reshape — per drag frame, even though a solid colour change
touches no layout. Mirror the node-drag fast path: patch the anchor's
resolved scene fill / stroke via LayoutScene::set_node_fill /
set_node_stroke_color and invalidate the cache, skipping mark_dirty so the
patch survives the frame. Variable-mode, instance redirects, gradient-stop /
effect targets, and brand-new strokes fall back to the full rebuild.

Bumps vendor/jian to a86832d (the scene-patch methods). Native only; the
web host's live-sync push gate needs the same wiring once its spine settles.
2026-06-20 00:44:06 +08:00
Kayshen-X 25a5b02ce2 refactor(editor): sink agent-settings switch into jian Switch
paint_settings_switch dropped its hand-rolled track+thumb paint and now delegates to jian Switch (geometry identical: knob 16, inset 2). Removes the duplicated switch paint; off-track is now the shadcn input token. Hit stays host-side rect.contains (behavior-identical on desktop). Bumps vendor/jian to 2708666. First Phase A component sink.
2026-06-20 00:27:35 +08:00
Kayshen-X 6e43abd5ef feat(editor): add shadcn input/ring/secondary/destructive-foreground tokens to Theme
Theme gains the canonical shadcn fields; button::tokens_from_theme maps them into jian Tokens (+ radius 6.0). Unblocks the Switch off-track=input reconciliation and Button secondary variant. Bumps vendor/jian to 9cd5d50.
2026-06-20 00:24:00 +08:00
Kayshen-X 26e9d2fa55 chore(vendor): bump jian to eb58f8f — Switch::hit 2026-06-19 23:49:30 +08:00
Kayshen-X 9add35583c refactor(editor): source CursorHint from jian-core; host owns handle+Pointer map
CursorHint now lives in jian-core (re-exported via op_host_native). for_handle becomes the host free fn cursor_for_handle (depends on OP SelectionHandle). Adds a Pointer arm to the desktop CursorIcon map. Behavior preserved; bumps vendor/jian to 44c7b75.
2026-06-19 23:42:30 +08:00
Kayshen-X 210fc21bf6 chore(vendor): bump jian submodule — jian-scene crate + scene skeleton removal 2026-06-19 23:12:30 +08:00
Kayshen-X a0a1514772 chore(deps): bump vendor/agent and vendor/jian submodule pointers
- agent: rustfmt test modules (c0804d9)
- jian: center popup row text baseline within clip + test (9f7e8c9)
2026-06-18 09:34:39 +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
Kayshen-X 19ffdd85a9 feat(ai): polish rust design agent workflow 2026-06-15 21:19:18 +08:00
Kayshen-X 5879004637 chore(vendor): bump agent-rs to 8166630 (latest main)
Pulls provider image content blocks, query-loop tool_use/tool_result
repair, prompt-cache + temperature threading, etc. cargo check
--workspace passes against the new API.

(--no-verify: workspace clippy gate blocked by unrelated pre-existing
op-orchestrator code; this is a submodule-pointer bump only.)
2026-06-14 23:54:18 +08:00