Commit graph

42 commits

Author SHA1 Message Date
Danila Poyarkov 8bf71bd92f
feat(ai): add guided AI setup for providers, coding agents, and Pi (#916)
* feat(storybook): prototype guided AI setup and task assignments

* refactor(storybook): adopt shared control foundations

* refactor(storybook): build AI setup on current settings foundations

Move the prototype to settings/ai-setup and compose SettingsSection, SettingsGroup, SettingsRow, AppAlert, AppBadge, and AppCheckbox instead of local section, status, and badge markup. Replace the nonexistent danger color and raw amber with the error and warning tokens.

* feat(ui): add a shared radio group

AppRadioGroup wraps the Reka radio group with typed options, labels each radio by its option text with any description as its accessible description, and supports all arrow keys unless an orientation is set. The AI setup wizard uses it for the spending choice, named by the step heading, and shares the choice card style with its checkboxes.

* fix(ui): draw unchecked checkboxes on the field background

AppCheckbox filled its box with the surface (text) color, so unchecked boxes were nearly black in the light theme and nearly white in the dark theme. Use the panel field background and accent hover border shared with the radio group and switch.

* refactor(storybook): drop the simplified AI connections panel

AI setup has two modes: skippable guided onboarding for most people and the existing advanced settings for power users, both editing the same model settings. Remove the third, simplified connections and tasks panel. The wizard's Advanced settings action and the returning-user screen now stand in for ModelsPanel, which offers Run guided setup. Removing Gateway's own Back button also fixes the blank screen it led to.

* feat(ai): plan guided AI setup from the model catalog

planOnboarding proposes design and vision models from the access a person already has, using the real provider and agent catalog, and falls back to OpenRouter only when pay-as-you-go is allowed. applyOnboardingPlan merges a confirmed plan into the model settings, reusing matching connections and profiles, keeping roles it was not asked about, and dropping only the empty fresh-install profile.

* refactor(ai): share model provider display names

Move the provider, agent, and Pi display-name lookup out of the model settings workflow so guided setup can reuse it.

* feat(ai): offer guided AI setup over the real model settings

Guided setup asks what AI should help with, what access the person
already has, and whether pay-as-you-go models are allowed, then
proposes design and vision models from the provider and agent catalog.
Connections reuse the provider key field and connection test, keys are
saved through the credential manager, and the confirmed plan is merged
into the model settings, keeping anything configured by hand. Saving
reports saved, partial, or failed like the profile editor.

A fresh install whose model settings are still the empty placeholder is
offered setup once with a skippable welcome; existing setups never see
it. Settings → AI & agents can run it again, and Advanced settings hands
off to the model editor. The Storybook fixtures for agents, OpenRouter
sign-in, Vercel AI Gateway, and the local server are replaced by the
real flow, with all copy translated.

Browser tests start with the offer dismissed through the shared
Playwright storage state; the first-run spec clears it.

* fix(ai): keep configured models and credentials safe in guided setup

Running guided setup again planned from the catalog defaults, so it
replaced hand-configured design and vision models and dropped their
settings; it now keeps a configured model while its access is still
selected or onboarding cannot offer that provider, and keeps vision when
nothing new covers it. Reused profiles must have the capabilities the
plan relies on, and an explicit vision assignment without image input is
cleared.

A server's saved key and its status now apply only to the connection at
the address being entered, and its connection test uses that
connection's API type. Entered keys are copied before saving, so closing
setup mid-save no longer drops them, and the Models list refreshes key
status after setup saves a key. Servers that do not check keys get a
hint to enter any value, and a step that only keeps configured models
says so instead of showing nothing.

* test(ai): check key status right after guided setup

The Models list must show a key saved by guided setup as connected without reopening Settings.

* feat(ai): sign in to OpenRouter from guided setup

OpenRouter can now be connected with its OAuth PKCE flow instead of a
pasted key. In the browser, sign-in opens in a popup that returns to a
static callback page on the app's origin, which relays the redirect to
the editor over a BroadcastChannel, so the editor never navigates away.
The desktop app opens the system browser and receives the redirect on
a one-shot 127.0.0.1 listener, the localhost callback OpenRouter
documents. Either way the editor checks the state, exchanges the code
for a key directly with OpenRouter, fills it in, and runs the
connection test. Waiting, blocked pop-ups, cancellation, expiry, and
failures are reported in the step, which keeps the pasted-key path.

Setup no longer offers Clear for a saved key, since removing keys
belongs to the advanced settings, and the service worker leaves
/oauth/ pages to the network.

* fix(settings): report unreadable model keys as unavailable

A saved key the browser credential store could not read, for example one left from an older session on the same origin, rejected the model status refresh and the startup credential check, which surfaced as a global error toast. Each read failure now marks only that connection as unavailable.

* feat(ai): map every role in guided setup and verify OpenRouter sign-in

Guided setup now proposes a model for design, vision, review, and fast
work, and the review step is a map of those roles with every suitable
model from the connected providers and a "Use recommended setup"
shortcut. Fast work defaults to the provider's catalog model tagged as
fast; behind an agent, review and fast work use the API model chosen
for vision. Review and fast work are never asked about, so a configured
choice, including none, stays unless it follows a design model it can
no longer follow.

The pay-as-you-go question only appears when the access already
selected leaves a requested role without a model, so choosing
OpenRouter or another account no longer asks it.

After signing in with OpenRouter, setup checks the key with
OpenRouter's key endpoint, which costs no credits, instead of a text
generation test. The step then says it is signed in, names the key,
warns when the account has no credits yet, and offers another account
in place of the key field and test button.

* feat(ai): offer OpenRouter only for goals nothing selected covers

The separate pay-as-you-go step asked an abstract question even when
the selected access already covered every goal. The connect step now
names a goal nothing selected can cover, such as visual review behind
a coding agent or a local server, and offers to add OpenRouter for it;
once added, it says OpenRouter fills the gap and can be removed again.
Setup can finish without visual review, but not without a design model.

A local or company server can be marked as able to read images, which
lets it cover visual review and makes it the preferred vision model
over a paid account.

* feat(ai): show provider logos and more providers in guided setup

Guided setup shows monochrome logos for coding agents, API accounts,
and local servers, from LobeHub's MIT-licensed static SVG set loaded as
an `ai` icon collection, so they follow the theme like Lucide icons.
DeepSeek, Z.ai, and MiniMax are offered under "More providers", and a
local server can start from the Ollama or LM Studio address instead of
typing it.

* feat(ai): guide coding agent setup in guided setup

Choosing Claude Code, Codex, or Gemini CLI in the desktop app now checks
whether the agent's ACP program and OpenPencil's MCP server, which
agents use to reach the canvas, are installed. An allowlisted
agent_lookup command finds the program on the same widened PATH as the
MCP lookup. The card shows install commands only for what is missing,
checks again on request, links a new setup guide, and copies a prompt
that asks an agent the person already uses to install both, confirm
they are on PATH, and sign in. In the browser, the agent section links
to the desktop app.

* fix(ai): space the More providers toggle like a group heading

The toggle sat flush against the account cards above and below it; it now reads as a group heading with the same rhythm as the other sections.

* feat(ai): detect and install coding agents in guided setup

Adopt the local agent discovery from #847. A desktop agent_lookup
command reports each agent's own CLI, its ACP adapter, npm, and
OpenPencil's MCP server on the widened PATH without starting any of
them, and the app can install a missing adapter or the MCP server with
npm, limited by the shell capability to those exact packages and the
MCP version that matches the app. Guided setup now tells "installed but
the OpenPencil adapter is missing" apart from "not installed", offers
one-click installs, links each vendor's own setup guide, and keeps the
manual commands and setup prompt for the browser, missing npm, or a
failed install. Codex install instructions move to
@agentclientprotocol/codex-acp, which replaces @zed-industries/codex-acp.

Kiro CLI support from the same pull request is left for a separate
change, since it needs ACP transport work.

Co-authored-by: GitttHomie <134371845+GitttHomie@users.noreply.github.com>

* build(app): resolve LobeHub icons with import.meta.resolve

The architecture lint forbids createRequire in ESM build code.

* test(app): seed AI setup specs through storageState

Follows the storage seeding used by other browser specs and the import type rule.

* feat(ai): set up Pi with its own sign-ins in guided setup

Pi now runs with the providers signed in to in the Pi CLI and Pi's
default model. The Harness companion reuses ~/.pi/agent; the app reads
only Pi's settings.json for the default model and never auth.json. A
saved key is still used as an AI Gateway key.

Guided setup offers Pi next to the other coding agents. On the desktop
it checks the Harness companion, the MCP server, and Pi's default
model, and installs the companion with one click through npm.

Agent discovery now reads the installed versions of the MCP server and
the Harness companion from their package.json without starting them.
Setup flags a version that does not match the app and shows the update
command for the package manager that installed it, instead of
reporting the server as installed and failing at the first message.

* feat(ai): check agent companions before a chat starts

A Pi chat without the Harness companion, or any agent chat whose
companion or MCP server version does not match the app, failed when the
process started and showed only the generic request error. The chat now
checks the companions through agent discovery first and names the fix,
with an action that opens guided setup. Pi sign-in and model problems
use the same path.

The Pi model editor shows the same companion, MCP server, and default
model status as guided setup, and no longer requires a model ID, since
Pi falls back to the default model set in Pi.

Supersedes the companion detection in #566, which ran the companion to
read its version and required an exact version match.

* fix(harness): start Pi sessions with MCP tools and keep unsent messages

Pi chats in the desktop app always configure OpenPencil's MCP server,
and three companion problems stopped them:

- @ai-sdk/harness-pi imports pi-mcp-adapter, which publishes TypeScript
  sources. Node refuses to strip types under node_modules, so the
  companion now strips them through a module load hook limited to
  TypeScript dependencies. Bun runs them as is.
- pi-mcp-adapter imports @earendil-works/pi-tui, declared only as an
  optional peer, so npm left it out. The companion depends on it at the
  version pi-coding-agent uses.
- Pi reports live-process resume, yet the service handed it state saved
  by an earlier session, and the just-bash sandbox cannot resume, so
  every later session with that ID failed. Live-process backends now
  start fresh and drop saved state.

When a chat cannot start, the composer now keeps the typed message
instead of discarding it.

* fix(harness): keep companion stdout for protocol messages

Pi prepares the packages listed in a person's Pi settings with npm,
which inherits the companion's stdout, and libraries log through
console.log. Both landed in the JSONL protocol stream, where the app
discarded them with warnings. The companion now keeps the real stdout
for protocol messages, sends other stdout writes to stderr, and quiets
npm on success through its environment.

The type-stripping hook no longer prints Node's experimental warning,
and the app logs companion stderr as diagnostics rather than errors,
since failures arrive as protocol errors.

Document Pi in the coding agents guide, the AI chat page, and the
README: guided setup installs the companion, Pi uses the Pi CLI's
sign-ins and default model, an AI Gateway key is optional, and the
companion needs Node.js 22.15 or later.

* test(harness): keep the pi-tui pin in step with pi-coding-agent

The companion depends on pi-tui only because pi-mcp-adapter imports it while declaring it optional (nicobailon/pi-mcp-adapter#805). Upgrading @ai-sdk/harness-pi moves pi-coding-agent, and a pin left behind would make npm install a second, mismatched pi-tui. The test fails until the pin matches.

* test(ai): follow the model catalog in guided setup tests

The plan and apply tests repeated catalog default and fast model IDs, so master's model update broke them without any change in setup behavior. They now read those models from the catalog.

* test(ai): keep the model catalog helper with the shared test helpers

Unit test homes under tests/app accept only *.test.ts files, so the onboarding tests' catalog helper moves to tests/helpers/ai.

* docs: tighten the guided setup and Pi changelog entries

Name every provider and server preset guided setup offers, describe the role step as it now works, and shorten the Pi entry.

* test(ai): type the guided setup test stubs for the test typecheck

Master now typechecks the test suites: fetch fakes go through fetchStub, the chat ref is shallow like the real one, and mocks declare the arguments the tests inspect.

* test: type the tabs module in the closed-documents spec

The spec imported the tabs module by its served URL without a type, which fails the test type check on master.

* test(ai): assert outcomes instead of copy in guided setup tests

Drop the setup-prompt test, which checked prompt prose, the onboarding wrapper cases that restated discovery, and the coversGoals case. Story plays and the OpenRouter E2E flow now assert controls and saved models instead of sentences and catalog model names, and the fast-model helper checks the planned model's catalog entry instead of recomputing the choice. tests/AGENTS.md states the rule.

* feat(ai): return desktop OpenRouter sign-in through a deep link

The desktop app ran a hand-written HTTP server on a localhost port to receive OpenRouter's redirect, and OpenRouter labels apps with a localhost callback by host and port. OpenRouter now redirects to a page on the web app that opens openpencil://oauth/openrouter with the same query, and the desktop shell forwards that link to the webview as an oauth-callback event. The attempt that started sign-in checks the state and exchanges the code with its PKCE verifier, which never leaves the app.

* feat(ai): ask OpenPencil's companions for their version

The desktop app read a companion's version by following its executable's symlink up to a package.json. That only worked for the Unix npm and bun layouts: Windows .cmd and .exe shims and version-manager shims such as Volta and mise are not links into the package, so the version was always unknown and an outdated companion went unreported. The MCP server, stdio bridge, and Harness companion now print their version for --version, and the app runs each installed one with --version --help under a timeout. A release older than --version prints its help or exits without a version line, which reads as outdated. A bun global install on Windows now gets the bun update command too.

* fix(ai): ask for a Pi sign-in when Pi has none

readPiAccount returned an account whenever a home folder existed, so a chat with no Pi sign-in reached the Harness and failed with a provider error instead of the guided pi-sign-in fix. It now reports whether Pi's auth.json exists, without reading it, and the capability allows that one check.

* fix(ai): keep the attachments of a message that was not sent

A message that never reached the chat came back to the composer as text only: its image previews were revoked and its referenced layers dropped. The composer now takes back the whole submission, or releases the previews when newer text replaced it. A message counts as sent once the chat holds it, so a failure after that no longer hands it back to be sent twice.

* refactor(app): read the app version from one constant

Four modules each derived the app version from the build define with the same test fallback.

* refactor(ai): report chat submission errors from their own module

Reverting turns from master and keeping unsent drafts together took useChatSubmission past the composition-root limit. The test for reverted turns now passes the setup messages the submission reports.

* refactor(app): keep the app version with the runtime config

Tools typecheck src/constants.ts through app imports without the Vite defines, so the version constant moves to src/app/runtime/version.ts.

* test(desktop): check npm installs of the companions at the app's release version

The scope test named the companion packages and version literally, so it would keep passing if the app requested something else. It now builds them from the app's package names and the release version a build embeds.

* refactor(ai): parse OpenRouter, Pi, and sign-in callback data with Valibot

The OpenRouter key info and code exchange checked their JSON with typeof chains, Pi's settings parsed JSON in a try before validating it, and the desktop sign-in trusted the shell's callback payload as typed. Each now goes through one schema.

* fix(ai): take back a message whose images could not be prepared

A message with images appears in the chat before its images are prepared, so a preparation failure counted as sent: the draft did not come back and its previews were already revoked. A message now counts as sent once it is dispatched; a failure before that removes the shown message and hands the draft back, and the composer's previews are revoked only after dispatch.

* fix(ai): restore an unsent message only in its own conversation

Switching conversations while a message was being sent could restore it into the newly opened one. The draft now comes back only if the conversation is unchanged, and its previews are released otherwise.

* refactor(app): keep one app version constant

The update window added an APP_VERSION to src/constants.ts beside the one in src/app/runtime/version.ts. The tools typecheck reaches src/constants.ts without the Vite defines, so the update window now reads the runtime one.

---------

Co-authored-by: GitttHomie <134371845+GitttHomie@users.noreply.github.com>
2026-10-07 08:46:57 +00:00
Danila Poyarkov 6c6f24409e
feat: let a collection name the attribute its modes switch by (#913)
* feat: let a collection name the attribute its modes switch by

Manually switched modes were always selected by data-<collection name>, so a collection called New wrote data-new and a codebase already using data-color-scheme could not be matched. A collection can now name its attribute in the inspector, validated so a stylesheet can select it as is. The stylesheet and exported code use it, setting it is undoable, and .fig files keep it in the collection's plugin data.

* fix: show the switch attribute only where there are modes to switch

* fix: return to the list after committing the switch attribute

* fix: keep a collection's switch attribute when a new one is refused

setModeAttribute cleared the attribute when given a name a stylesheet cannot select on; it now leaves the current one, and only an empty name restores the default. In the inspector, Enter on a refused name keeps the focus so it can be corrected.

* docs: describe the switch attribute in the mode conditions

The Switched manually row still said the attribute is named after the collection. The changelog had collected four copies of the variables dialog entry through rebases; one remains, with the switch attribute in it.
2026-10-06 12:35:41 +00:00
Danila Poyarkov 29e0d3acf2
refactor(vue)!: remove the variables table composables (#908)
The variables dialog now uses the tokens panel, so useVariablesEditor, useVariablesTable, useVariablesDialogState, and the table-only formatModeValue, parseVariableValue, and shortName helpers have no users. Removing them drops the @tanstack/vue-table dependency; their SDK pages redirect to useVariables.
2026-10-06 12:35:41 +00:00
Danila Poyarkov 03b70328bf
feat: edit variables as tokens in the variables dialog (#907)
* feat: prototype the design tokens panel

Undoable editor actions for token fields and mode conditions, a token view model, and table, inspector, collection and stylesheet panels shown in a Storybook story with a real editor.

* feat: lay the tokens panel out for mobile

Below the mobile breakpoint the collection tabs become a select, the list shows one chosen mode with the CSS name under each token, and the token, the modes, and the stylesheet each open over the list behind Back. CodeViewer can fill its container for the full-screen stylesheet.

* feat: share drill-in navigation and put tokens on a listbox

PanelDrillIn gives detail views one back control that names where it returns, a slide preset from theme/motion, and focus that moves into the detail and back to what opened it. The Settings model editor and the tokens panel's mobile views use it. The token list is a Reka Listbox with arrow-key navigation and labelled groups, and the inspector and stylesheet swap with a short fade under the motion policy.

* feat: lay the tokens panel out by container width

The panel switches to the compact drill-in by its own measured width, and the list's columns follow the list's width through container queries, so the panel adapts inside dialogs and split views, not only on phones. src/AGENTS.md now says when to use container queries, measured size, and viewport breakpoints.

* test(core): group the variable undo tests in a domain folder

* feat: edit variables as tokens in the variables dialog

The variables dialog now hosts the tokens panel: a grouped token list with CSS names, an inspector for each token and for the collection and its modes, and the live stylesheet. It keeps adding variables by type, search, collection and mode management, and copying the document's stylesheet, and lays out by its own width down to phones.

useVariables().collections returns copies, so components given a collection see modes added or renamed in place, and addVariable returns the new ID so the panel can open it.

* fix: satisfy the type-aware lint in token updates and panel stories

* docs: describe the tokens panel in the translated variables guides

* feat: say when each mode applies in plain words

A mode's condition was a raw CSS field that designers could not read. Each non-default mode now picks when it applies (switched manually, system dark or light mode, high contrast, reduced motion, screen or container width, or custom CSS), with the CSS it writes shown underneath and a note on how the mode behaves on the canvas and in exported code. Presets only write the condition string modes already store, so files round-trip unchanged. Column headers name the condition in words, and deleting the collection moves into a menu beside its name.

* feat: bring the variables dialog up to Figma's

The dialog now covers what Figma's variables dialog offers: collections and groups in a sidebar with counts, a group, search and type filter, type icons, names and values edited in place, drag to reorder, multi-select with a context menu, the Delete key and a side panel to duplicate, group and delete, aliases chosen from a variable picker and detached back to the value they showed, hiding from publishing, and an expand toggle. It opens from View → Variables… and the command palette as well as the Design panel.

It also fixes review findings: a single-mode collection labels its value Value, column titles share one font, a CSS name is typed after a fixed -- and checked by the CSS parser before it is saved, and the stylesheet previews CSS with the format chosen when copying. AppInput applies an instance's input classes last so they can override adornment padding.

* feat: undo and redo inside the variables dialog

Canvas shortcuts stop while any dialog is open, so Cmd+Z did nothing in the variables dialog although every edit there is on the editor's history. Undo and redo now take a document scope: they also run when the topmost layer is a dialog that edits the document, which the variables dialog marks, while menus, pickers and Settings still hold them back and a field with uncommitted text keeps its own undo.

Enter commits a field and returns focus to the list. The panel drops selections, group filters and collections that undo removed. A color picker session undoes as one step through a coalesce key on updateVariableValue, and undoing a deletion puts the variable back in its place.

* feat: search variables like the command palette

The variables search matched a substring of the name only, so a CSS name, a hex color or a description found nothing, and the palette, AppPicker and AppCombobox each spelled out the same Fuse.js options. One helper in @open-pencil/vue now owns the matching: fuzzySearch ranks results for lists people pick from, and fuzzyFilter keeps a list's own order for lists people arrange. The panel searches names, CSS names, descriptions and every mode's value, alias names included; useVariables() searches names and descriptions.

* fix: say a token group once when its name repeats it

Kits that mirror Tailwind classes name tokens like Gap/gap-1, which derived --gap-gap-1. A group the next segment repeats is now said once, giving --gap-1.

* fix: keep the add variable menu under its button after a resize

The toolbar swaps the icon button for the labelled one when the dialog widens. Reka keeps the anchor it mounted with, so the menu opened at the window corner; keying the trigger remounts it with the new button.

* fix: leave bound layers alone when variables are added or reordered

Adding, copying, or reordering variables re-resolved every bound layer in the document. In the shadcn kit two Avatar instances are saved at 24 while their binding gives 40, so adding a number resized them and relaid out about 7,800 layers, freezing the browser for seconds. These changes alter no bound value and now only request a render, as renaming already did.

* refactor: let the variables dialog own its undo shortcuts

Undo and redo in the dialog went through a document scope in the global shortcut registry, which decided whether the dialog was on top by querying Reka's dismissable layers in DOM order. The dialog now listens on its own content with a tinykeys handler built from the command keybindings: menus and pickers it opens portal elsewhere, so their keys never reach it, and the registry is back to one scope.

* refactor: read mode conditions with css-tree

Presets were recognized by normalizing the condition with regular expressions and matching another. css-tree, which Core already ships through unifont, now parses the condition into its media or container feature, so spacing, case and comments are handled as CSS does, and a non-breaking space, which CSS does not treat as whitespace, no longer turns a custom condition into a preset.

* refactor: take the mode attribute hint from modeAttribute

The hint for a manually switched mode cut the brackets off its selector with a regular expression. It now reads the attribute name and value from modeAttribute, which the selector is built from.

* fix: keep a refused CSS name in focus and color picker sessions apart

Enter on a CSS name the parser refuses no longer hands the keyboard back to the list, so the name can be corrected. The typed name is read with parseCSSName instead of stripping a leading -- by hand, so a pasted var(--name) works too.

Each color picker session takes a random undo key; a counter restarted when the inspector remounted, so two sessions on the same token could merge into one undo step.

* fix: keep token expressions and cleared fields in step with their variable

Editing a number left its CSS expression recording the old number, so reopening the file dropped the expression as edited elsewhere. A number now updates its expression, and an alias drops it, in the same undo step.

Undoing a token field that had been unset kept the key with an undefined value; it is now removed.

* fix: preview and detach aliases in their own mode

An alias in the Dark column showed, and detached to, what its target gives in the mode the canvas is in. Both now resolve in the column's mode.

* fix: drop tokens a filter hides from the selection

A search, group, or type filter could hide selected tokens that stayed selected, so the inspector, the bulk actions, and the Delete key still acted on rows the list no longer showed.

* fix: keep a drill-in's list out of the tab order while its detail slides

The list stayed focusable until the detail finished sliding in, and became focusable again under a detail sliding out. It is now inert from the moment the detail opens and the departing detail is inert. A detail with no field focuses its back control, and hidden inputs are skipped.

* docs: drop a duplicated Stroke entry from the changelog

Two merges left the Stroke-extends-Fill breaking change twice; the copy that still said strokes render solid only is outdated, since gradient and image strokes now import and render.
2026-10-06 12:35:40 +00:00
Danila Poyarkov b9753aa016
docs: sync translations with documentation changes since v0.15.1 (#886)
Eleven translated pages changed in English since the last release without
matching updates: system requirements, the Lint tab, AI chat diff tools,
collaboration with agents, design JSX imports and export fidelity,
Storybook and live-app export, lint fixes, page navigation, and Checking
Designs. Bring de, es, fr, it, pl, and ru up to date, add the sections
the abridged translations lacked where a change landed, use each
language's UI labels, and point the export page at documents list.
2026-10-04 16:38:35 +00:00
mrhard9090 2c9bb8fcd7
feat(figma-api): add detachInstance() to instances (#778)
instance.detachInstance() turns an instance into a frame that keeps its content, as in Figma, from scripts run through eval. It reuses the graph's shared detach implementation, asserts editability like the proxy's other mutations, and joins the instance surface check against @figma/plugin-typings.
2026-09-30 05:19:11 +04:00
Danila Poyarkov 904f3ca390
fix: use official Homebrew cask installation guidance (#712)
* fix: use official Homebrew cask installation guidance

* docs: guide localized pages through the old Homebrew tap

The translated getting-started pages documented the official cask but not
the migration from the archived tap, so readers of those pages had no
uninstall step for the old formula.
2026-09-17 13:36:17 +03:00
Danila Poyarkov c3412a44fc
docs: polish localized documentation
* docs: polish localized documentation

- Rewrite Russian documentation for natural terminology and current source parity\n- Continue the Polish editorial pass across guides and SDK references\n- Refresh shared localized SDK API data imports

* docs(pl): complete editorial pass

- Rewrite the remaining advanced Vue SDK references\n- Refresh the Figma compatibility matrix against the canonical source\n- Align terminology and behavior across every Polish documentation page

* docs(de): complete editorial pass

- Rewrite German guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix

* docs(es): complete editorial pass

- Rewrite Spanish guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix

* docs(fr): complete editorial pass

- Rewrite French guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix

* docs: correct localized terminology

- Replace unnecessary English prose with natural localized terminology\n- Derive documentation aliases from named directory roots\n- Preserve English only for identifiers, APIs, and exact product terms

* docs(it): continue editorial pass

- Rewrite Italian user guides and automation documentation\n- Update Vue SDK composables and component references\n- Restore current AI, export, component, and variable behavior

* docs(it): complete editorial pass

- Finish Italian advanced SDK and reference documentation\n- Refresh the Penpot comparison and Figma compatibility matrix\n- Replace literal machine translations with natural technical prose

* docs(pl): refine property panel terminology

* docs: refine remaining localized prose

- Replace overfitted English prose in Polish feature documentation\n- Rewrite the Russian property-list reference in natural terminology

* docs(ru): rewrite Penpot comparison naturally

- Replace remaining English prose with natural Russian\n- Preserve code identifiers and library names only where required

* docs: rewrite localized feature overviews naturally

- Replace avoidable English prose in German, Spanish, and French\n- Keep identifiers and product names unchanged

* docs(de): refine property panel terminology

* docs: refine Spanish and French SDK terminology

* docs(ru): continue full prose audit

- Rewrite homepage, setup, navigation, and guide index naturally\n- Restore missing zoom shortcuts

* docs(ru): audit user and automation guides

- Rewrite selection, collaboration, and automation prose naturally\n- Preserve API identifiers while localizing ordinary terminology

* docs(ru): audit CLI inspection and analysis

* docs(ru): audit Vue SDK overview and guides

* docs(ru): audit Vue SDK API prose

- Localize ordinary component and composable terminology\n- Preserve API symbols and code identifiers

* docs(ru): audit advanced and gradient API references

* docs(ru): finish advanced API prose audit

* docs(ru): audit JSX renderer guide

* docs(ru): audit CLI export and scripting guides

* docs(pl): audit Penpot comparison prose

* docs(pl): audit selection and automation guides

* docs(pl): audit homepage and variable guides

* docs(pl): audit vector, layers, and Pen guides

* docs(pl): audit Auto layout and shape guides

* docs(pl): audit context menu and export guides

* docs(pl): audit JSX and analysis guides

* docs(pl): audit AI Chat guide

* docs(pl): audit components and CLI inspection

* docs(pl): audit scripting and SDK overview prose

* docs(pl): audit SDK API indexes

* docs(pl): audit SDK component references

* docs(pl): audit SDK composable references

* docs(ru): refine usePosition terminology

* docs(pl): audit advanced SDK references

* docs(pl): audit Figma compatibility matrix

* docs(pl): finish residual SDK terminology audit

* docs(pl): finish component terminology audit

* docs(pl): finish SDK guide terminology audit

* docs(de): begin full user guide prose audit

* docs(de): audit navigation, Pen, and layers guides

* docs(de): audit Auto Layout, shapes, menu, and export

* docs(de): audit components, text, and vector guides

* docs(de): audit variables and automation overview

* docs(de): audit AI Chat and collaboration guides

* docs(de): audit CLI inspection, analysis, and export

* docs(de): audit scripting and JSX guides

* docs(de): audit Vue SDK overview and guides

* docs(de): audit SDK API indexes

* docs(de): audit SDK component references

* docs(de): audit SDK composable references

* docs(de): audit advanced SDK references

* docs(de): audit Penpot comparison prose

* docs(de): audit Figma compatibility reference

* docs(es): begin full user guide prose audit

* docs(es): audit document organization guides

* docs(es): audit editing workflow guides

* docs(es): audit automation and collaboration prose

* docs(es): audit CLI inspection and export guides

* docs(es): audit CLI scripting guide

* docs(es): audit JSX and feature overview prose

* docs(es): audit Penpot comparison prose

* docs(es): audit SDK overview and guides

* docs(es): begin SDK component reference audit

* docs(es): audit SDK navigation component references

* docs(es): audit SDK color and layout components

* docs(es): begin SDK composable reference audit

* docs(es): audit SDK property composable references

* docs(es): audit SDK editor composable references

* docs(es): begin advanced SDK reference audit

* docs(es): audit advanced SDK state references

* docs(es): complete advanced SDK reference audit

* docs(es): audit Figma compatibility reference

* docs(es): complete residual terminology sweep

* docs(fr): begin full prose second audit

* docs(fr): audit AI and variables prose

* docs(fr): audit core user guide prose

* docs(fr): audit editing workflow guides

* docs(fr): audit CLI and JSX prose

* docs(fr): audit Penpot comparison prose

* docs(fr): audit SDK overview and guides

* docs(fr): begin SDK API reference audit

* docs(fr): audit SDK navigation component references

* docs(fr): audit SDK color and layout components

* docs(fr): begin SDK composable reference audit

* docs(fr): audit SDK property composable references

* docs(fr): audit editor composables and advanced APIs

* docs(fr): audit advanced SDK state references

* docs(fr): complete advanced SDK reference audit

* docs(fr): audit Figma compatibility reference

* docs(fr): complete residual terminology sweep

* docs(it): begin full prose second audit

* docs(it): audit document workflow guides

* docs(it): audit editing and automation prose

* docs(it): audit CLI and JSX prose

* docs(it): audit Penpot comparison and SDK guides

* docs(it): begin SDK API reference audit

* docs(it): audit SDK component and state references

* docs(it): audit residual SDK references

* docs(it): audit Figma compatibility reference

* docs(it): complete residual terminology sweep

* docs(i18n): verify residual locale terminology
2026-08-20 18:36:50 +03:00
Danila Poyarkov d67415c793
docs: explain component library workflows (#520)
Documents component libraries and localized workflows added by #512.
2026-08-14 20:39:47 +03:00
Danila Poyarkov 3572eeec5e docs: remove untranslated localized placeholders
- Route copied English MCP, CLI, technical reference, shortcut, and useNumberField pages to their canonical English sources
- Repair remaining mixed-language user-guide and SDK labels
- Detect cross-locale placeholder copies and substantial English content in localized Markdown during documentation integrity checks
2026-08-13 20:40:41 +03:00
Danila Poyarkov 3c385ebe15 docs: explain font substitution diagnostics
- Document the missing-font banner, active substitutions, retry flow, and font source behavior in every maintained user guide
- Add list_available_fonts and get_font_status to the MCP tool reference and replace stale exact tool counts with a durable 100+ description
2026-08-13 20:26:25 +03:00
Danila Poyarkov 3ef554ab2d docs: reorganize documentation and improve integrity
- Replace the ambiguous Guide section with explicit overview, reference, and development routes while preserving legacy URLs with redirects
- Route missing localized content to maintained canonical pages and emit SEO alternates only for real translations
- Add parser-backed documentation integrity checks and make the optimized local build the default while retaining a complete production build
2026-08-13 14:19:12 +03:00
Danila Poyarkov 0036d762e2 docs(ai): polish BYOK compatibility guidance
- Publish the compatibility reference in the VitePress site and link localized AI guides to the canonical English page
- Correct current Anthropic and credential-storage behavior
- Make CORS, streaming, pricing, context, and reasoning measurements reproducible and security-safe
2026-08-03 19:19:38 +03:00
Danila Poyarkov de8578c435
feat(app): expand Figma menu and selection parity (#459)
- Add Figma-style object, component, selection, view, settings, and browser Move to Page actions
- Add undoable z-order, transformed distribution, inverse selection, and single/bulk rename behavior
- Keep browser and native menus, shortcuts, generated schema, localization, and documentation aligned
2026-08-03 00:23:05 +03:00
Danila Poyarkov 8ceda4d12f docs: close Fig package boundary track
- Describe complete Fig archive, conversion, instance, and metadata ownership\n- Refresh contributor paths across localized development guides\n- Mark Track D complete in the local master plan
2026-07-18 03:41:17 +03:00
Danila Poyarkov a62cec00f8 refactor(vue): remove deprecated panel APIs
- Remove FillPickerRoot and useFillPicker from source, exports, and localized docs
- Replace the final PanelRow consumer with accessible auto-layout controls
- Document the canonical panel and fill composition contracts
2026-07-14 18:13:20 +03:00
Danila Poyarkov fcdf7f1d4c feat(app): migrate layout size controls
- Replace duplicated width and height binding branches with shared semantic fields

- Switch edited Hug and Fill dimensions to Fixed in one reversible transaction

- Add typed LayoutControls actions, documentation, and visual coverage
2026-07-13 15:34:25 +03:00
Danila Poyarkov 1b7934b98e feat(vue): add property panel primitives
- Add headless PropertySection and accessible SegmentedControl anatomy

- Make PropertyList controlled and exactly typed with an undo-aware editor adapter

- Consolidate SDK metadata loaders and link untranslated docs to canonical pages
2026-07-13 12:36:03 +03:00
Danila Poyarkov ffb12824eb feat(vue): add BindableValue primitives
- Add provider-driven binding state, picker composition, and edit policies

- Integrate NumberField interactions with binding transactions and cancellation

- Migrate numeric variable fields and document the public API
2026-07-13 11:02:54 +03:00
Danila Poyarkov 5d9730ae04 feat(vue): finalize NumberField API and docs
- Remove ScrubInput aliases, app wrappers, test hooks, and translated legacy references

- Share a Tailwind NumberField demo between Storybook and VitePress

- Generate component API tables from Vue metadata and type-check examples with Twoslash

- Upgrade the docs stack to VitePress 2
2026-07-13 10:19:24 +03:00
Danila Poyarkov 883782846f docs(cli): use released openpencil command 2026-05-29 15:56:52 +03:00
Danila Poyarkov 9431c1935e docs: remove stale roadmap pages 2026-05-22 19:46:57 +03:00
Danila Poyarkov 3850be9512 build: publish node-compatible packages 2026-05-21 17:03:19 +03:00
Danila Poyarkov e3d6056bf5 docs: update MCP setup and landing screenshot 2026-05-19 17:58:08 +03:00
Danila Poyarkov 6545f20c53
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules

Split the monolithic editor factory and large action modules into focused
domain helpers:

- create.ts assembles context through bridge modules (clipboard,
  components, structure, undo) and delegates to graph-reads, graph-events,
  layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
  reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
  and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
  fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison

New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space

Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit

* refactor(core): split tool definitions by domain

Split the monolithic tool registry into domain-specific modules:

- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens

Split registry into core/extended tiers; refine schema and AI adapter

* refactor(core): restructure kiwi codec and instance overrides

Reorganize the Kiwi .fig codec into domain subdirectories:

- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
  symbol-overrides, symbol-props, sync, types

Vendored kiwi-schema/ left isolated

* refactor(core): split profiler, icons, IO, and add subpath exports

Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup

Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants

* refactor(vue): decompose canvas input, surface lifecycle, and controls

Canvas surface: gl-surface, kit-loader, render-loop, resize-observer

Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler

Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root

Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers

Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases

Expose MenuActionNode/MenuSeparatorNode from public API

* refactor(app): split document IO, editor session, and automation bridge

Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets

Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model

Automation bridge: eval, tools, exports, files, selection, RPC fallback

AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files

Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator

Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs

* refactor(app): decompose UI components with provide/inject context

Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:

- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip

Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal

* refactor(mcp): split server into focused modules

- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter

* refactor(cli): split analyze subcommands and shared helpers

- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports

* refactor(docs): split VitePress config and shared table component

Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales

Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable

Update contributing and testing docs

* refactor(tauri): decompose desktop entrypoint

Split lib.rs into focused service modules:

- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle

* test: share domain test factories and migrate fixtures

New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers

Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction

* build: add structural lint rules, split vite config, update docs

Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
  naming conventions, and import discipline

Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins

Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig

* fix(vue): normalize canvas directory casing and remove duplicate export

- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
  (PascalCase was correct for component primitives but canvas/ is a
  non-component domain directory)
- Remove duplicate ./random subpath export in core package.json

* fix: add #vue and #core Vite resolve aliases for dev server

* refactor(core): reduce remaining large modules

Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.

- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint

Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes

* fix(app): forward color input attrs

* fix(app): cover section drawing errors

* fix(editor): undo option-drag duplicates

* docs: document domain subfolder convention

* fix(app): handle undo redo on keydown

* refactor(app): dispatch shortcuts from keydown

* refactor: group prefixed domain modules

* refactor(app): use tinykeys for shortcuts

* refactor(core): group symbol override modules

* refactor(core): group fig kiwi container helper

* refactor(canvas): split overlay rendering modules

* refactor(vue): remove unused internal barrels

* fix(app): lay out demo components before instancing

* fix(app): restore demo badge spacing

* perf(canvas): split scene and overlay rendering

* refactor(vue): wrap wheel gesture lifecycle

* fix(canvas): wait for fonts before hiding loader

* docs: update unreleased changelog
2026-04-30 15:14:19 +03:00
Danila Poyarkov 14325280d9 docs(i18n): translate all missing pages to 6 languages
- 78 SDK pages per language (components, composables, advanced API,
  guides, architecture, getting-started)
- vector-edit.md user guide page (5 languages)
- Update stale ru/programmable/cli/inspecting.md
- Fix YAML frontmatter quoting for colons in descriptions

474 files, 0 missing pages across de/es/fr/it/pl/ru.
VitePress build verified — all 546 SDK pages render.
2026-04-22 18:35:22 +03:00
Danila Poyarkov cd4e1a2271 feat(mcp): add stdio transport for Claude Code / Cursor
- Add packages/mcp/src/stdio.ts — proper stdio MCP server that
  connects to the running app via WebSocket
- openpencil-mcp bin now points to stdio entry (was HTTP)
- openpencil-mcp-http bin added for the HTTP server
- Extract registerTools() from server.ts to share between transports
- Move index.ts banner output to stderr (prevents stdout corruption)
- Update Tauri shell spawn to use openpencil-mcp-http
- Update all docs (EN + 6 translations): correct binary names, source
  paths, port number

Fixes #194
2026-04-13 11:51:01 +03:00
Danila Poyarkov 25788dae36 Remove OpenSpec workflow files 2026-03-27 22:01:38 +03:00
Ilya Nikitin 0ff5a87ccb update pen tool space drag spec
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
2026-03-27 21:27:45 +05:00
Danila Poyarkov fe755fbb85 Release v0.9.0 2026-03-09 17:43:11 +03:00
Danila Poyarkov c98ac0f230 Update README and docs for CSS Grid support
- Add 'Auto layout & CSS Grid' to README features
- Update architecture, tech-stack, features, figma-comparison, comparison
- Mark grid as ✅ in all 7 locales
- Replace 'blocked on upstream' with Yoga fork links
2026-03-08 18:29:44 +03:00
Danila Poyarkov bfa4b7de8b Translate AI & Automation + CLI reference to all 6 locales
48 translated pages (de, es, fr, it, pl, ru) for the Programmable
section: overview, AI Chat, Collaboration, JSX Renderer, CLI
(inspecting, exporting, analyzing, scripting).

CLI reference and MCP server pages copied as-is (mostly code/tables).
2026-03-08 18:25:35 +03:00
Danila Poyarkov e5b147148e Add AI & Automation docs section, CLI reference, formatting fixes
New 'AI & Automation' top-level nav section with 9 pages:
- AI Chat: setup, 87 tools, example prompts
- Collaboration: room sharing, cursors, follow mode
- JSX Renderer: elements, style props, visual diffing
- CLI (4 pages): inspecting, exporting, analyzing, scripting
- MCP Server: moved from Reference, setup + 90 tools

New CLI reference page in Reference with all 12 commands,
every option, alias, and default value.

Formatting fixes across all 7 locales:
- Wrap enum values in backticks (FRAME, SOLID, ROUND, etc.)
- Fix single-backtick code blocks → triple backticks
- Use <kbd> for all keyboard shortcuts
- Remove implementation details from user guide
- Delete stale eval-command.md and mcp-tools.md (14 files)
- Update dead links to new locations
2026-03-08 18:25:35 +03:00
Danila Poyarkov e67dd3fbd9 Rewrite docs: landing page, features, architecture — all 6 locales
- Landing page: reorder features (Figma-compatible first), add collaboration card, fix app size
- Features: cut implementation details, group into clear sections, add MCP/CLI/Homebrew
- Architecture: replace ASCII diagram with mermaid, add RPC bridge, update tool counts
- Remove ~500 lines of internal implementation prose from user-facing docs
2026-03-08 11:04:26 +03:00
Danila Poyarkov 0109d33846 Add AI agent skill to README and docs
- README: new 'AI Agent Skill' section with install command
- MCP tools reference: skill section, fix tool count 78→90,
  add 10 missing tools (export_image, export_svg, flatten_nodes,
  list_fonts, page_bounds, set_layout_child, set_text_properties,
  viewport_get, viewport_set, viewport_zoom_to_fit)
- Features page: mention skill with install command
- All 6 locales updated
2026-03-08 01:08:28 +03:00
Danila Poyarkov 5ac70a5976 Update docs: tool counts 75/78 → 87/90, schema.ts → tools/ directory, add RPC bridge 2026-03-08 00:28:11 +03:00
Anton A S 513e0b6f4a Add SEO: OG tags, Twitter Card, hreflang, JSON-LD, sitemap
- config.ts: og:site_name, og:image (+w/h/alt), twitter:card/site/image
- config.ts: transformPageData — per-page canonical, og:url, og:locale,
  og:locale:alternate, hreflang for all 6 locales + x-default,
  og:title/description and twitter:title/description from frontmatter
- config.ts: sitemap with xhtml:link alternates for all 174 pages × 6 locales
- SchemaOrg.vue: SoftwareApplication JSON-LD on EN homepage only
- HomeLayout.vue: render SchemaOrg in home-features-after slot
- index.md + de/fr/es/it/pl index.md: add translated title to frontmatter
2026-03-07 19:49:24 +03:00
Anton A S 940d0de5b6 Sync docs with v0.7.0 and unreleased features
- Update comparison tables: 78 tools (was 75), SVG export no longer a Penpot advantage,
  renderer LOC updated to ~3,200 after split into 10 files
- Update figma-comparison: Rename layers ✅, SVG export ✅, +Copy/Paste as, +Tailwind export,
  +Stroke align, +per-side stroke weights; coverage 88/152 → 94/158
- Add What's Next roadmap to architecture.md: AI providers, figma-use tool set,
  CI tooling, prototyping, CSS Grid, PDF export, .fig fidelity
- Update user-guide: SVG in export format table, Copy/Paste as submenu,
  stroke align + per-side weights, layer inline rename, mobile drawer, Code tab format toggle
- Fix keyboard shortcuts: ⌘N/⌘T/⌘W ✅, ⌘\ ✅, add ⇧⌘C ✅
- Expand MCP tools reference from ~25 to all 78 tools in full category tables
- Add Homebrew tap install to Getting Started
- Add new features.md sections: SVG export, Copy/Paste as, stroke align, mobile/PWA,
  Tailwind JSX export, Google Fonts fallback, auto-save toggle, Homebrew tap,
  layer rename, renderer profiler
- Full locale sync for DE, ES, FR, IT, PL: all 7 files updated in each locale
2026-03-07 19:25:41 +03:00
Anton A S 8a486d5307 Sync docs with v0.5.0–v0.6.0: full locale translations, 75 tools
- Update tool count from 29 to 75 across all docs and locales
- Expand all locale pages (de/es/fr/it/pl) to full translations
- Add missing German sections: Advanced Rendering, Z-Order, ScrubInput,
  CI/CD, JSX Renderer, Code Panel, full figma-comparison matrix
- Write complete figma-comparison (152-row matrix) for all locales
- Expand comparison, features, tech-stack, contributing for es/fr/it/pl
- Fix garbled text in locale mcp-tools reference pages
- Architecture diagrams use '75+ tools' to avoid staleness
2026-03-04 18:12:01 +03:00
Anton A S f4cb76b2e2 Translate reference & development pages prose for all locales 2026-03-03 12:57:17 +03:00
Anton A S 8ca1bc790f Add reference & development pages for all locales, fix nav missing menu items 2026-03-03 12:46:35 +03:00
Anton A S c39e1fd71a Add i18n docs: German, Italian, French, Spanish, Polish translations (95 pages) 2026-03-03 12:15:39 +03:00