Commit graph

1435 commits

Author SHA1 Message Date
Kayshen-X 54fb746881 feat(mcp): expand rust editor mcp surface 2026-06-05 22:19:08 +08:00
Fini 3f1beb7afb fix(ai): pick the parse candidate with the most total nodes (robust bare-object handling)
The bracket scan could return a nested children array or a stray field array instead of the real node tree. Earlier heuristics each had a hole: combined-depth missed valid JSON after an unmatched prose bracket, and colon-skip dropped legitimately-labelled outputs (a wrapper object whose node array sits under a key).

balanced_spans now just collects candidate spans robustly: each bracket tried independently (an unmatched prose bracket cannot hide a later array), skip-past so nested sub-spans are not separate candidates, string-aware. parse_nodes tries both the array-form candidates and the bare-object/JSONL collection, then keeps the result with the MOST total nodes including descendants — a full tree (root + children) always beats a stray inner array, with no colon/label heuristic.

Adds regression tests for nested-children, JSONL, unmatched-prose, and labelled-wrapper inputs. 40 parse tests pass. Hardened across Codex stop-time reviews.
2026-06-04 03:53:02 +08:00
Fini 79895c5f0f fix(ai): exit non-zero on failed benchmark output/render steps
The headless benchmark paths reported success even when their output/render step failed: op-smoke still returned SUCCESS when the OPENPENCIL_SMOKE_OUT write failed, and --render-shots returned the GUI-skip 'handled' signal (exit 0) on an unreadable/unparsable .op, an empty page, or a node that failed to render.

op-smoke now exits 4 when a requested save fails; --render-shots exits 1/2 on any read/parse/empty/partial-render failure and only exits 0 when every top-level node rendered. Verified: good .op -> 0, missing file -> 1. Found by Codex stop-time review.
2026-06-04 03:22:15 +08:00
Fini 2e0d4700e0 refactor(editor): split handle_menu_action out of desktop main.rs
main.rs reached 927 lines (over the project 800-line cap, mostly pre-existing) after wiring --render-shots. Move the 177-line handle_menu_action into a sibling menu_action.rs (same pattern as the widget_host split), dropping main.rs to 748. Behaviour unchanged; the method becomes pub(crate). Also drops the now-unused ActiveEventLoop/Fullscreen imports from main.rs. Addresses Codex stop-time review (touched file over 800-cap).
2026-06-04 03:08:58 +08:00
Fini 89ce5bd679 fix(ai): parse JSONL bare-object node output so DeepSeek generates
DeepSeek emits node JSON as JSONL: bare top-level objects, one per line inside a json code fence, with no enclosing array brackets. The bracket scan only saw the inner fill sub-arrays (not node arrays), so the parser returned 'no JSON array found' and DeepSeek produced nothing.

parse_nodes now falls back to collecting top-level brace objects and deserializing each as a PenNode when the array path yields no nodes. balanced_arrays/balanced_end were generalized to a shared balanced_spans(open, close) used by both the bracket and brace scans. Adds a JSONL test; 37 parse tests pass.
2026-06-04 02:52:38 +08:00
Fini da21f59d20 fix(ai): keep outer node array, not nested children, in parser candidate selection
Multi-candidate selection picked the candidate with the most nodes, but balanced_arrays also collected nested children arrays. For nested-format output (a single root frame whose children array holds 3 nodes), the inner array could outrank the outer (1 node), returning the children and dropping the real root. Flat _parent-style output (what M2.7 emitted in testing) hid it. balanced_arrays now collects only top-level arrays, skipping past each captured span. Adds a regression test. Found by Codex stop-time review.
2026-06-04 02:45:34 +08:00
Fini b349b06f2a feat(ai): headless model-design benchmark harness
Adds a fully-headless pipeline to benchmark built-in-Agent design generation across models, with no GUI or live canvas.

op-smoke: OPENPENCIL_SMOKE_OUT saves the generated PenDocument to a .op; OPENPENCIL_SMOKE_DUMP dumps the raw LLM response for diagnosing weak-model JSON malformations. openpencil-desktop --render-shots FILE OUTDIR SCALE loads a .op, runs the jian layout pass, and exports one cropped PNG per top-level node via export_node_raster (skia CPU raster) for node-only benchmark screenshots.
2026-06-04 02:33:08 +08:00
Fini 4bae93b3e8 fix(ai): tolerate weak-model JSON malformations in node parser
M2.7 and other weak models emit malformed PenNode JSON the strict parser rejected, losing whole subtasks (Food Delivery restaurants; Dashboard charts-row dropped to 0 nodes and aborted downstream subtasks).

Multi-candidate extraction scans every balanced bracket span and keeps the result with the most nodes instead of grabbing the first open bracket, so reasoning-prose brackets (e.g. step markers) no longer trigger 'expected ident'. Per-element tolerant deserialize keeps valid PenNodes and skips+logs bad elements instead of failing the whole array on one stray node (e.g. a fill of type 'solid' written where a node was expected). Both are strict generalizations; fully-valid JSON is unchanged. Adds tests for both classes; 35 parse tests pass.
2026-06-04 02:33:07 +08:00
Kayshen-X 54ca298352 feat(editor): wire the TopBar fullscreen button
The Maximize icon (rightmost of the TopBar right cluster) was painted
but had no hit-test mapping, so clicking it did nothing.

- Add TopBarHit::ToggleFullscreen + a hit-test rect matching its paint
  position; add a regression test.
- Native: the host raises a pending_fullscreen_toggle intent (it can't
  reach the winit window); app_handler consumes it after the press and
  routes through the existing handle_menu_action(ToggleFullscreen) ->
  window.set_fullscreen(), the same path the macOS menu item used.
- Web: the WASM host toggles the browser Fullscreen API directly
  (document request_fullscreen / exit_fullscreen) — no runner round-trip
  and no unconsumed intent.
2026-06-02 23:25:11 +08:00
Kayshen-X e35d26fa71 fix(canvas): correct boolean-op geometry — smooth curves, holes, chaining
flatten_path (ContourMeasureIter) + compound even-odd SVG d so curves stay smooth and Subtract/Exclude holes render; build_node_path parses svg_path so chained ops round-trip. Native + web.
2026-06-02 22:14:02 +08:00
Kayshen-X fecdd395d0 fix(panels): layer context-menu Delete/Duplicate act on the whole selection
Right-press menu-open + Delete/Duplicate dispatch kept the multi-selection instead of collapsing to the right-clicked row (web + native). Adds a multi-delete core test.
2026-06-02 22:14:01 +08:00
Kayshen-X 3d3ba232c8 fix(editor): pass page_id on chat-design InsertSubtree (native + web)
Restore page_id: None on the two chat_design_apply InsertSubtree initializers (dropped by a branch reset).
2026-06-02 22:14:00 +08:00
Kayshen-X 96753a7b5d feat(canvas): boolean-ops buttons on the align toolbar
Add Union/Subtract/Intersect/Exclude boolean-operation controls to the align toolbar.
2026-06-02 09:42:08 +08:00
Kayshen-X 5b33f8f5d4 feat(agent): orchestrator scaffold, subagent, and validation fixes
Extend the op-orchestrator phased design runner (single-screen scaffold, sequential sub-agent execution, dashboard columns, validation-fix apply) and adapt the headless smoke runner to the new InsertSubtree page_id field.
2026-06-02 09:42:07 +08:00
Kayshen-X 9edc9f71c3 feat(cli): expand CLI command and flag surface
Add CLI path-args, file-flag, selection and design command coverage matching the expanded MCP tool surface, with tests and usage text.
2026-06-02 09:42:06 +08:00
Kayshen-X cc3e664f65 feat(mcp): layered-design workflow and element-alias tool surface
Expand the Rust MCP server toward pen-mcp parity: layered batch_design helpers with TS-shaped structured args, semantic element-alias builders for high-frequency elements, insert/update node-data parsers, and desktop mcp_serve/runtime wiring (incl. a file-path tool) with tests.
2026-06-02 09:42:05 +08:00
Kayshen-X 0282283cb6 feat(editor): command-layer ops for MCP layered design
Add EditorCommand support powering the MCP layered-design workflow: authored-id subtree insertion for design skeletons, deterministic RefineDesign cleanup, plus batch-page and replace-node apply paths and an InsertSubtree page_id target. Includes command_apply/command_node wiring and tests.
2026-06-02 09:42:04 +08:00
Kayshen-X 82d481547c feat(panels): git-panel commit-detail diff, overflow menu, signature form
Bring the Rust git panel to TS parity across four surfaces:

- Commit rows expand inline into a semantic diff card (ported
  diffDocuments / indexNodesById / engineDiff over serde_json::Value)
  instead of navigating to a separate diff page; the card shows the
  "~modify N nodes" summary plus a per-node patch list. blob_at_commit
  reads the {rev} and {rev}^ blobs to compute base-vs-next.
- Overflow menu (...) with the 5 TS actions — switch tracked file, clear
  commit author, remote settings, SSH keys, close repository — backed by
  GitOverflowView subviews (tracked-file picker + SSH-keys list) and
  remote-settings rows (origin URL + ahead/behind + fetch; no HTTPS token
  field, matching TS).
- Commit signature form: empty commits are refused, and committing with no
  configured author opens an inline name/email form (Enter saves, Escape
  cancels) that writes the repo-local identity before retrying the commit.
- Polish: taller commit-detail card, removed panel shadow, lengthened the
  ready panel, and unified the commit-textarea caret blink to the app's
  500 ms cadence.

New overflow/SSH/author/remote labels resolve via Document::t with an
English fallback for keys not yet in the locale tables.
2026-06-02 09:42:03 +08:00
Kayshen-X ae492e7aa2 fix(editor): add backdrop box behind active agent-chip provider icon
The TS top-bar shows the active provider glyph inside a rounded bg-muted
box; the Rust chip painted the bare icon, so a spinning/active provider
read as a floating glyph with no chip affordance. Paint a theme.muted
rounded backdrop (pad 4, radius 5) behind the brand icon(s) to match.
2026-06-02 09:42:02 +08:00
Kayshen-X a26e1b0f48 fix(mcp): support ts move copy targets 2026-06-02 09:42:01 +08:00
Kayshen-X dd34ca8526 fix(mcp): accept ts delete page targets 2026-06-02 09:42:00 +08:00
Kayshen-X 4f251c138c fix(mcp): accept ts update payloads 2026-06-02 09:41:59 +08:00
Kayshen-X 85a5401574 fix(mcp): accept ts insert data payloads 2026-06-02 09:41:58 +08:00
Kayshen-X 79a2d0830c fix(mcp): support insert parent and page targets 2026-06-02 09:41:57 +08:00
Kayshen-X bbb26b86e8 fix(mcp): support svg import page targets 2026-06-02 09:41:56 +08:00
Kayshen-X aefdf1800f fix(mcp): support svg import parent 2026-06-02 09:41:55 +08:00
Kayshen-X 2a3cb6123e fix(mcp): support refine batch operations in rust 2026-06-02 09:41:54 +08:00
Kayshen-X 776a06bcbc fix(mcp): sync live server bound port 2026-06-02 09:41:53 +08:00
Kayshen-X 61f50999e2 fix(mcp): accept batch design operations in rust 2026-06-02 09:41:52 +08:00
Kayshen-X c966e06233 fix(editor): add exclude boolean toolbar button 2026-06-02 09:41:51 +08:00
Kayshen-X 0362ba3993 fix(cli): add skill install command parity 2026-06-02 09:41:50 +08:00
Kayshen-X 40d3371448 fix(cli): add rust mcp start stop commands 2026-06-02 09:41:49 +08:00
Kayshen-X 7ea28b32c4 fix(cli): add save command parity 2026-06-02 09:41:48 +08:00
Kayshen-X 68394826fe fix(cli): add figma import parity 2026-06-02 09:41:47 +08:00
Kayshen-X 09277fa77c fix(cli): report mcp status without server 2026-06-02 09:41:46 +08:00
Kayshen-X 9d5edd5812 fix(cli): add codegen command parity 2026-06-02 09:41:45 +08:00
Kayshen-X b5fac1e32b fix(mcp): add debug tool parity 2026-06-02 09:41:44 +08:00
Kayshen-X 9cd1aa4558 fix(mcp): add codegen tool parity 2026-06-02 09:41:43 +08:00
Kayshen-X eb083784c9 fix(mcp): add style operation parity 2026-06-02 09:41:42 +08:00
Kayshen-X f1b7e0989c fix(mcp): bootstrap desktop live server 2026-06-02 09:41:41 +08:00
Kayshen-X ce813bcb3e fix(mcp): add open document parity 2026-06-02 09:41:40 +08:00
Kayshen-X cb1cf55ae9 fix(mcp): add batch get parity 2026-06-02 09:41:39 +08:00
Kayshen-X 69037b9ea2 feat(editor): add boolean exclude operation 2026-06-02 09:41:38 +08:00
Kayshen-X 0dbd414837 fix(mcp): add style guide parity 2026-06-02 09:41:37 +08:00
Kayshen-X 2469f424f0 fix(mcp): add design prompt parity 2026-06-02 09:41:36 +08:00
Kayshen-X 8f9b220a27 fix(mcp): add design-md parity 2026-06-02 09:41:35 +08:00
Kayshen-X 1055c8c1b3 fix(mcp): add theme preset parity 2026-06-02 09:41:34 +08:00
Kayshen-X b393daeafa fix(mcp): add read-nodes parity 2026-06-02 09:41:33 +08:00
Kayshen-X 67ea8c3e25 fix(mcp): add bulk variable parity 2026-06-02 09:41:32 +08:00
Kayshen-X 2b89331984 fix(mcp): start web mcp server from settings 2026-06-02 09:41:31 +08:00