more figma parity based on rules#2314
Conversation
Importing feature-flag definitions from @agent-native/core/feature-flags dragged the barrel's server store -> settings/store -> db/client -> request-telemetry chain into the client dev graph. Vite dev does not tree-shake, so the browser evaluated it and request-telemetry's top-level new AsyncLocalStorage() threw against the externalized node:async_hooks stub, breaking app load in dev (prod tree-shakes it away). - Add client-safe @agent-native/core/feature-flags/registry entry (package export + dev source alias + optimizeDeps). - Resolve AsyncLocalStorage / EventEmitter lazily via process.getBuiltinModule (shared/optional-node-builtins.ts); no top-level value import, no-op fallback off Node. - Repoint design + clips shared config and all 15 feature-flags SKILL.md docs at /registry. - Add browser-safe import-graph regression guard spec.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Here's a visual recap of what changed: Open the full interactive recap |
3438f22 to
4f9385d
Compare
# Conflicts: # templates/design/app/pages/DesignEditor.tsx
…as state badge, collab-recovery checkpoints, and the unused paste-placement module; keep drag/selection/snap/align enhancements and the chrome-placement rule
There was a problem hiding this comment.
Builder reviewed your changes and found 3 potential issues 🟡
Review Details
Code Review Summary
PR #2314 adds Figma-parity behavior to the Design editor: selection-only undo/redo with coalescing, z-stack cycling and selected-layer drag priority in the iframe bridge, selection-chrome suppression during nudges, hierarchy-aware alignment, and zoom-aware snapping. The bridge changes are mirrored in the generated artifact and have focused unit/snapshot coverage; the overall approach is sound, and no security concerns were identified. This is standard risk because it changes core editor state and interaction behavior.
Key findings
- 🟡 Selection history can cross edits: coalescing is based only on the last selection timestamp, not whether an edit was appended after that selection.
- 🟡 Alignment can mix coordinate spaces: collapsed pass-through wrappers can group nodes whose authored offsets are relative to different direct parents.
- 🟡 Selection history misses common local paths: ordinary overview frame selection and empty-canvas clearing do not invoke the new recorder.
The new pure helpers and tests are a good foundation, and the iframe bridge keeps the source and generated implementations aligned.
🧪 Browser testing: Could not verify — the planner reached the dev server and created 19 grounded cases, but all executor retries were blocked by unavailable Chrome automation tools.
| // its order token so Cmd+Z doesn't stop on a no-op. | ||
| selectionOnlyUndoStackRef.current = stack.slice(0, -1); | ||
| historyOrderRef.current = removeRecentUndoRedoOrderKinds( | ||
| historyOrderRef.current, |
There was a problem hiding this comment.
🟡 Do not coalesce selections across an intervening edit
shouldRecordSelectionHistory coalesces solely from the previous selection entry's timestamp and does not verify that the latest chronological history token is also "selection". If a user selects A, selects B, edits within 800ms, then selects C, this path merges C into the old A→B entry without adding a new order token, so Cmd+Z can undo the edit before restoring the selection state that existed at the edit. Only coalesce when the latest undo-order entry is "selection", and cover an interleaved content/geometry edit.
Additional Info
Reported by 1 of 3 parallel code-review agents; validated against the current history-order and coalescing implementation.
| // moves the cards, not their titles). Each group shares one coordinate | ||
| // space, avoiding the cross-parent left/top mismatch; results merge | ||
| // into one commit. | ||
| const groups = partitionSelectionForAlignment( |
There was a problem hiding this comment.
🟡 Keep alignment calculations in one coordinate space
partitionSelectionForAlignment collapses single-child, no-layout wrappers to a shared meaningful parent, but rectFromCodeLayerNode returns each node's authored left/top in its direct parent's coordinate system and commitNodePositions writes those values back to that direct parent. Nodes under separately offset wrappers can therefore be treated as aligned when they are not, or receive coordinates from the wrong parent. Keep groups limited to a shared direct parent, or transform rects into the collapsed ancestor's space and convert positions back before committing.
Additional Info
Reported by 1 of 3 parallel code-review agents; confirmed by tracing rect extraction and commit paths.
| recordSelectionOnlyHistory(before, captureCurrentSelection()); | ||
| }); | ||
| }, [recordSelectionOnlyHistory]); | ||
|
|
There was a problem hiding this comment.
🟡 Record overview screen selection and clear-selection changes
The new recorder is invoked from handleScreenElementSelect and the marquee handler, but ordinary overview frame clicks through handleOverviewScreenSelectionChange and empty-canvas clearing through handleScreenElementClear do not invoke it. As a result, Cmd+Z cannot restore a normal screen selection or a deselected layer even though captureCurrentSelection includes both overview screen ids and layer ids. Add recording before those local state updates while preserving the existing pending/echo guards, and cover select/clear flows.
Additional Info
Reported by 1 of 3 parallel code-review agents; validated by tracing the local selection handlers.

No description provided.