- Move CODEGEN_PROMPT to codegen.md, loaded via raw-md bundler plugin
- Add JSX_REFERENCE as jsx-reference.md with full prop/tag/example docs
- Copy JSX Reference button (book icon) in Code panel header
- Multi-root JSX: try parsing as-is, wrap in fragment on failure
- Component and Instance tag aliases in JSX renderer
- renderJSX returns RenderResult[] to support fragments
- raw-md plugin for both tsdown and Vite
Co-authored-by: sld0Ant <sld0Ant@users.noreply.github.com>
The Tip (Tooltip) wrapper around PopoverTrigger caused floating-ui
to miscalculate the popover position as translate(0px, -200%),
rendering it off-screen. Replaced with a plain title attribute
for the hover hint.
Fixes#218
The canvas had no tabindex, so clicking on it didn't move focus away
from previously focused input elements. When document.activeElement
was still an input/textarea (e.g. from a panel interaction), the
keyboard shortcut guard treated Backspace as blocked by an active
input — making it impossible to delete selected nodes via the canvas.
- Add tabindex="-1" + outline-none to the canvas element
- Explicitly focus canvas on mousedown (except during text editing)
Fixes#220
Previously only Shift+click toggled additive selection in the layers
panel. Cmd+click (macOS) and Ctrl+click (Windows/Linux) had no effect
beyond replacing the selection with a single layer.
Treat Shift, Cmd, and Ctrl modifiers equally as additive toggle, matching
common design tool conventions (Figma, Sketch).
Co-authored-by: TKman <102001532+greekr4@users.noreply.github.com>
* fix(a11y): tab order in inspector panel follows visual layout
- ScrubInput gets tabindex=0 so Tab reaches it; on focus it enters
edit mode and transfers focus to the inner <input>
- All inspector buttons get explicit tabindex=0 to follow DOM order
- Tab flow: align buttons → X → Y → W → H → rotation → flip/rotate →
opacity → corner radius → ...
Closes#180
* fix(inspector): apply ScrubInput value live while typing
* fix(keyboard): block shortcuts while ScrubInput is focused
- Detect scrub input focus via closest() in isEditing() guard
- Add isScrubInputFocused() check in plain() so tool shortcuts,
Backspace, Enter etc. don't fire while typing in inspector fields
* fix(inspector): use reactive state for ScrubInput focus, remove redundant tabindex on buttons
- Surface editing state from ScrubInputRoot via editing-change emit
- Track scrubInputFocused in editor store instead of querying DOM
- Remove no-op tabindex="0" from all <button> elements
- Keep tabindex on ScrubInput wrapper <div> (actual tab order fix)
---------
Co-authored-by: Danila Poyarkov <dev@dannote.net>
Add disabled prop to Tip — forces tooltip closed when the parent popover
is open. Fixes the settings gear and variable-bind popovers not opening
on Windows WebView2 due to TooltipTrigger intercepting pointer events.
Closes#171
Co-authored-by: Anton Soldatov <sld0Ant@users.noreply.github.com>
Allow insecure localhost connections via NSAllowsLocalNetworking so the
WebSocket bridge works in release builds on macOS.
Also add debug logging for WebSocket and MCP health check failures.
Closes#190
Co-authored-by: Anton Soldatov <sld0Ant@users.noreply.github.com>
- Move use-external-link.ts → utils/external-link.ts (plain function, not a composable)
- Remove non-null assertions on providerDef.keyURL (v-if already guards)
- Remove test scaffolding from production global.d.ts
External links (<a target="_blank">) in the AI panel triggered
"Command plugin:shell|open not allowed by ACL" on Tauri desktop.
Root cause: Tauri v2 intercepts <a target="_blank"> via the shell plugin,
but only the opener plugin had ACL permissions. Replace all external links
with programmatic openUrl() from @tauri-apps/plugin-opener, which is already
whitelisted via "opener:default" in capabilities.
- Extract openExternalLink() composable for Tauri/browser switch
- Replace <a target="_blank"> with <button @click> in ProviderSetup/Settings
- Add E2E test verifying window.open is called in browser context
Fixes#193
Co-authored-by: Danila Poyarkov <dev@dannote.net>
Error toasts had `duration: 0` which in reka-ui means "never auto-
dismiss." Combined with the global `window.error` /
`unhandledrejection` handler in `setupGlobalErrorHandler`, any error-
emitting source — even a transient one called repeatedly per frame
(wheel events, render-loop callbacks) — could pile up over the
canvas with no way to recover except a hard-restart.
Three small changes that compose:
- Errors now use ERROR_TOAST_DURATION (10s) instead of 0. Long
enough to read; short enough to self-clean.
- Dedupe by (message, variant): repeating the same error increments
a count badge ("×3") on the existing toast instead of stacking
duplicates. Prevents the cascade-on-every-frame failure mode.
- Hard cap at 5 stacked toasts; oldest drop off when a 6th would
arrive. Belt-and-suspenders against any source we missed.
The Toast interface gains a non-optional `count: number` (defaults
to 1). External callers (info/warning/error) are unaffected — they
go through the new internal `push()` which sets it.
Add nodeToXPath() to core — builds a unique XPath selector for any node
by walking up the tree and using name predicates (or positional index
when names collide among same-type siblings). Properly escapes names
containing quotes using XPath concat() or double-quote delimiters.
UI: "Copy node ID" and "Copy XPath" items in the canvas right-click
"Copy/Paste as" submenu. Also i18n the entire submenu — all labels now
use menuMessages with translations for de, es, fr, it, pl, ru, zh-CN.
CLI: `open-pencil selection` command (app-mode only) returns selected
nodes with id, name, type, size, and xpath. Connects to the running
app via the automation WebSocket.
Automation: new `selection` RPC handler that returns selected nodes
with computed XPath selectors.
- Convert button, input, icon-button, toast, surface from flat-string
functions to slot-based { base: string } return pattern
- Convert section from bare TV exports to useSectionUI() with
{ wrapper, label } slots
- Remove standalone select helpers (selectTrigger, selectContent,
selectItem) in favor of useSelectUI()
- Delete use-component-ui.ts — no longer needed
- Update all 20+ call sites across property panels and chat components
Long localized labels like 'По содержимому' overflow the input.
Add sizingHugShort/sizingFillShort i18n keys with abbreviated
translations for all locales. Dropdown items keep full labels.
Replace the separate ScrubInput + AppSelect pair with a single
combined control: the sizing mode (Hug/Fill) shows as an inline
label inside the scrub input, swapping to a chevron on hover.
- ScrubInput: add group class and #suffix slot (stays generic)
- LayoutSection: embed reka-ui Select in the suffix slot with
group-hover toggle between label and chevron
The layout section was gated on node.type === 'FRAME', hiding it for
COMPONENT, COMPONENT_SET, and INSTANCE nodes that also support
auto-layout. Also use copyStyleRuns instead of structuredClone per
project lint rules.
* fix(acp): show install errors for missing agent CLIs (#172)
* Use npm for install commands, toasts for errors, tighten error matching
- Replace bun add -g with npm i -g (universal baseline)
- Replace initError inline banner with toast.show() (consistent with rest of app)
- Remove overly broad 'not found' / 'no such file' from isMissingCommandError
* Refactor toast API to toast.info/warning/error
Adds a new scenario to the pen tool specifications defining the behavior for relocating the active vertex with spacebar during a curve drag, including asserting that the cursor remains a crosshair instead of switching to the hand tool.
Made-with: Cursor
Align selected anchor points relative to each other in vector edit mode. The standard alignment buttons in the position panel now operate on selected vertices when 2 or more are selected, enabling precise vector path editing workflows.
Localize remaining menu state labels like Hide/Show and Lock/Unlock,
wire toolbar tool/action labels through the i18n stores, and localize
the app menu UI toggle tooltip.
Replace template-string JSON imports with an explicit locale loader map
so published package builds have stable locale asset references.