vectorcraft · diff
git:20261023.8287b5e to git:20261026.76415fe
93 added, 87 removed. Audit A to A.
---
name: vectorcraft
description: >-
VectorCraft is a free, open-source, pure-Rust vector illustration app — a clean-room
reimplementation of Adobe Illustrator for macOS, Windows, Linux, FreeBSD and the web (WASM) —
- with an MCP server, a JSON control channel, a browser JS API and a headless CLI. Use this skill
- whenever the user mentions VectorCraft (or "the vector app", a `.vectorcraft`/`.vctemplate` file,
- or the ArtCraft vector tool), asks what it can do, which formats it opens/saves/exports, its CLI
- flags, control or MCP tools, or its keyboard shortcuts; wants to create, edit, automate, script,
- batch-convert or export vector art with it; needs assets prepared for it (SVG/PDF/EPS/images/DXF/
- fonts/`.wasm` plug-ins); wants its output verified or repaired; or troubleshoots it — even when
- the app is not named but the job is Illustrator-style vector work ("draw a logo", "make an SVG",
+ with an MCP server (32 tools), a JSON control channel (28 methods), a browser JS API (9 calls)
+ and a headless CLI (7 subcommands). Use this skill whenever the user mentions VectorCraft (or
+ "the vector app", a `.vectorcraft` / `.drawcraft` / `.vctemplate` file, or the ArtCraft vector
+ tool), asks what it can do, which formats it opens/saves/exports, its CLI flags, control or MCP
+ tools, or its keyboard shortcuts; wants to create, edit, automate, script, batch-convert or
+ export vector art with it; needs assets prepared for it (SVG/PDF/EPS/DXF/PSD/rasters/fonts/
+ `.wasm` plug-ins); wants its output verified or repaired; or troubleshoots it — even when the
+ app is not named but the job is Illustrator-style vector work ("draw a logo", "make an SVG",
"edit this .ai", "trace this bitmap", "convert this DXF"). Not for Adobe Illustrator itself.
---
# VectorCraft
- Audit basis: this checkout is tag `v0.15.0`, commit `705eda5dc8cb06fb665a7d6e3d32176c25f8742a`. The installed `/Applications/VectorCraft.app` reports version `0.15.0` and its binary prints `vectorcraft 0.15.0`, so the bundle matches this source exactly. **Verify against your installed version** if the ArtCraft Launcher has auto-updated since. No `references/` directory ships with this skill: everything below is cited inline to the repo (see `evidence.md` for the claim map).
+ Audit basis: this checkout is tag `v0.17.0`, commit `43313f9451de7ab5b909801006b8881458f2bf04`. The installed `/Applications/VectorCraft.app` reports version `0.17.0` (`CFBundleIdentifier ai.storyteller.vectorcraft`) and its desktop binary prints `vectorcraft 0.17.0`, so the bundle matches this source. **Verify against your installed version** if the ArtCraft Launcher has auto-updated since. No `references/` directory ships with this skill: everything below is cited inline to the repo, and `evidence.md` holds the claim → path map.
## Overview
- VectorCraft is a clean-room, open-source reimplementation of the Adobe Illustrator workflow, written from scratch in pure Rust (`README.md`). It runs natively on macOS, Windows, Linux and FreeBSD, and in the browser via WebAssembly (`README.md`; `apps/vectorcraft-web/`). Maturity: **alpha**. The authoritative parity table (`docs/target-app-parity.md`) self-assesses ~88% feature breadth — 353/375 Illustrator menu items wired (94.1%), 89/92 tools, 57/57 Photoshop-style effects, 4/4 initial 3D types — ~75% feature depth and ~62% (57–67%) ready for real work; `ROADMAP.md` prints slightly older counts (348/375, 46/50), so treat percentages as self-assessed and code as authoritative. Source: GitHub `storytold/vectorcraft`; installed on this Mac as VectorCraft.app (`CFBundleIdentifier ai.storyteller.vectorcraft`). Every user-visible action is a command reachable over MCP, the JSON control channel, the browser API and the CLI (`AGENTS.md`; `docs/mcp.md`; `docs/control-protocol.md`).
+ VectorCraft is a clean-room, open-source reimplementation of the Adobe Illustrator workflow, written from scratch in pure Rust (`README.md`). It runs natively on macOS, Windows, Linux and FreeBSD and in the browser via WebAssembly (`apps/vectorcraft-web/`). Maturity: **alpha** — the parity doc self-assesses ~88% feature breadth (353/375 menu items wired, 89/92 tools, 44/50 Illustrator effects, 57/57 Photoshop-style effects, 4/4 initial 3D types), ~75% depth and ~62% ready for real work; `ROADMAP.md` still prints older counts (348/375, 46/50), so treat percentages as self-assessed and the code as authoritative. Source: GitHub `storytold/vectorcraft`. Every user-visible action is a command reachable over MCP, the JSON control channel, the browser API and the CLI (`AGENTS.md`; `docs/mcp.md`; `docs/control-protocol.md`).
Project rules that bind anyone working in or around the repo: never run, script or copy from Adobe applications (clean-room, `AGENTS.md`); no panics in shipped code (clippy-denied, plus `crates/engine/src/guard.rs`); every bundled asset is attributed in `ASSETS.md`.
## Capabilities (verified)
### Automation surface at a glance
- | Surface | Count at v0.15.0 | Change vs the v0.14.0 skill |
+ | Surface | Count at v0.17.0 | Change vs the v0.15.0 skill |
|---|---|---|
- | Engine command specs | **780 `cmd!` entries** in `crates/engine/src/cmd/**`, plus table-built specs | not counted before; `docs/architecture.md` says ~710 — stale |
- | UI commands | **325** in `UI_COMMANDS` (`crates/ui-egui/src/menus.rs`) | not counted before |
- | CLI subcommands | **7**: `mcp`, `run`, `commands`, `convert`, `info`, `bench`, `perf` | unchanged; `run` gained `--commands FILE\|-` |
- | MCP tools | **32** names (aliases share handlers) | unchanged; `draw_path`/`draw_shape` styling is now one atomic batch |
+ | Engine command specs | **805** = 789 `cmd!` entries + 16 table-built character/paragraph-style specs | was 780 `cmd!`; **+9** `cmd!` |
+ | UI commands | **343** entries in `UI_COMMANDS`, all ids unique | was 325; **+18** |
+ | CLI subcommands | **7**: `mcp`, `run`, `commands`, `convert`, `info`, `bench`, `perf` | unchanged |
+ | MCP tools | **32** definitions (5 are documented aliases of another handler) | unchanged; all 32 named in `evidence.md` |
| MCP prompts / resources | **5** prompts; **3** fixed resources + **4** URI templates | unchanged |
- | Control-channel methods | **28** canonical names (29 with the `command` alias) | unchanged |
- | Open extensions | **31** in `OPEN_EXTS` (25 formats opened or placed) | unchanged |
+ | Control-channel methods | **28** canonical names (**29** accepted strings with the `command` alias) | unchanged |
+ | Browser JS API | **9** calls on `window.vectorcraft` | unchanged |
+ | Open extensions | **31** in `OPEN_EXTS`; Place additionally reads `.txt`/`.rtf`/`.docx` (**34**) | unchanged |
| Save formats | **6**: `vectorcraft`, `template`, `pdf`, `svg`, `svgz`, `ai` | unchanged |
- | Export formats | **20** formats / **19** extensions, plus plug-in formats | unchanged |
- | Photoshop-style filters | **57/57** | was 46/57; the Effect Gallery dialog now ships (docs still say missing) |
- | Tools | **92 ids**, 89 wired | unchanged |
- | Interface languages | **25** (24 catalogues + English) | was 24; Turkish added |
- | Panels | **42** panel modules in `crates/ui-egui/src/panels/` | was "40+" |
+ | Writable formats | **20** formats → **19** export extensions + `plugin.<id>`; catalogue holds **24** formats (22 readable) | 20/19 unchanged |
+ | Photoshop-style filters | **57** = 56 `PIXEL_EFFECTS` + `blur.gaussian` | unchanged |
+ | Effect catalogue | **116** entries: 86 literal + 15 warps + 12 Pathfinder + Trap + Crop Marks + Rasterize | Trap is new |
+ | Tools | **92** ids in the tool catalogue (89 wired per parity doc) | unchanged |
+ | Panels | **42** panel modules | unchanged |
+ | Interface languages | **25** = 24 `.tsv` catalogues + English | unchanged |
- Never quote a count from memory: `vectorcraft-cli commands`, MCP `command_list`/`list_commands`, or control `engine.commands` return the live catalogue with shortcuts and params. Unknown param keys are rejected with a did-you-mean before anything runs (`crates/ui-egui/src/menus.rs::check_params`).
+ Never quote a count from memory: `vectorcraft-cli commands`, MCP `command_list` / `list_commands`, or control `engine.commands` return the live catalogue with shortcuts and params. Unknown param keys are rejected with a did-you-mean before anything runs (`crates/ui-egui/src/menus.rs::check_params`).
### Documents and UI
- - Native format `.vectorcraft` (legacy `.drawcraft` still opens): versioned JSON, `VERSION = 4`, down-saves to v1/v2 as `drawcraft`, optional gzip, embedded PNG preview, compact JSON for path-heavy documents (~1/5 size), atomic saves, and unknown keys from newer versions preserved (`crates/format/src/lib.rs` L52-65; `docs/mcp.md` › Native files).
- - Multiple documents open as **tabs** in one window, each with **artboards**, layers and sublayers; dockable/floating panels; user workspaces that now keep layout changes across restarts; panels dock into any dock group or the icon column, dock groups collapse to tabs (double-click or `window.panel.collapse`); dragging a selection over another visible tab for 400 ms switches tabs and copies the artwork (`crates/ui-egui/src/state.rs`; `crates/ui-egui/src/workspaces.rs`; `docs/ui-parity.md` revisions 2026-10-21; `docs/development.md` › Drag artwork between document tabs).
- - 42 panel modules (Layers, Appearance, Properties, Swatches, Gradient, Transparency, Character/Paragraph/OpenType/Glyphs, Artboards, History, Links, Libraries, Asset Export, Image Trace, Pathfinder, Actions, Variables, CSS Properties, Separations, SVG Interactivity, Magic Wand, Navigator, Blend, Pattern Options, Flattener Preview…) (`crates/ui-egui/src/panels/`).
+ - Native format `.vectorcraft` (legacy `.drawcraft` still opens): versioned JSON, `VERSION = 4`, down-saves to v1/v2 as `drawcraft`, optional gzip, embedded PNG preview, atomic saves, unknown keys from newer versions preserved (`crates/format/src/lib.rs` L53-66; `docs/mcp.md` › Native files).
+ - Multiple documents open as **tabs** in one window, each with **artboards**, layers and sublayers; dockable/floating panels that collapse to tabs (double-click or `window.panel.collapse`); workspaces keep layout changes (`crates/ui-egui/src/state.rs`; `docs/ui-parity.md`).
+ - 42 panel modules (Layers, Appearance, Properties, Swatches, Gradient, Transparency, Character/Paragraph/OpenType, Artboards, History, Links, Libraries, Asset Export, Image Trace, Pathfinder, Actions, Variables, CSS Properties, Separations, SVG Interactivity, Magic Wand, Navigator, Blend, Symbols…) (`crates/ui-egui/src/panels/mod.rs`).
- Export bytes are reproducible: `SOURCE_DATE_EPOCH` replaces the wall clock in PNG, PDF, EPS, legacy `.ai`, packaged zips and `.vectorcraft` saves; a malformed value is ignored (`crates/doc/src/metadata.rs` L88-108).
+ - **New at this tag**: Artboard Options' Show Center Mark / Show Cross Hairs / Show Video Safe Areas / Video Ruler Pixel Aspect Ratio (`artboard.setProps`, `artboard.new`) draw canvas-only guides per artboard (`crates/engine/src/cmd/layer.rs` L128, L146); Distance Guides on Alt/Option hover with the `distanceGuides` preference (`crates/engine/src/cmd/prefscmds.rs` L237); a Constrain Angle preference that arrow keys, Shift drags and new objects follow (`docs/gaps.md` 2026-10-23).
### Drawing, paths and paint
- - Full tool set (92 ids in `crates/tools/src/catalog.rs`; 89 wired per `docs/target-app-parity.md`): Pen, Curvature, selection/anchor tools, shapes, pencil/brush/blob brush, eraser, lasso, magic wand, scissors, shape builder, live paint, width tool, symbol tools, Dimension tool, Perspective Selection, Touch Type… Tools never mutate the document directly — they emit commands, which makes gestures replayable by agents (`crates/tools/src/lib.rs`; `AGENTS.md`).
- - Exact curve-preserving Pathfinder booleans (linesweeper sweep-line on cubics), Shape Builder regions with Gap Detection, Live Paint, offset, outline stroke, simplify (slider + Auto-Simplify), join/average (`crates/pathops/src/lib.rs`; `crates/engine/src/cmd/buildcmds.rs`; `docs/gaps.md` G11).
- - Appearance stacks (multiple fills/strokes, per-item effects), transparency, blob/opacity masks, clipping masks, graphic styles, global/spot swatches, gradients (linear/radial/freeform, mesh) with **Method Classic/Perceptual** (OKLab; SVG/PDF export as an image) and **Dither** (fills only), patterns, recolor; ~97%-depth appearance area per `ROADMAP.md` (`crates/engine/src/cmd/{appearance,paint,gradient,patterncmds,recolor,opacitymask}.rs`).
- - Brushes (calligraphic, scatter, art, pattern, bristle) with a default library and expansion to real objects; `brush.move` reorders brushes within their type (`crates/brush/src/lib.rs`; `crates/engine/src/cmd/brushsym.rs`).
- - Symbols, blends (editable spines, Blend panel Type/Ramp/Shift; on-canvas handles partial), envelopes, radial/grid/mirror Repeat, perspective grid, Intertwine, **Objects on Path**, 9 graph types with graph designs, Variables/data sets (`crates/engine/src/cmd/{objects_on_path.rs,graph.rs,variablecmds.rs,perspgrid.rs,intertwine.rs}`; `docs/ui-parity.md`).
+ - Full tool set (92 ids in `crates/tools/src/catalog.rs`): Pen, Curvature, selection/anchor tools, shapes, pencil/brush/blob brush, eraser, lasso, magic wand, scissors, shape builder, live paint, width tool, symbol tools, Dimension tool, Perspective Selection, Touch Type… Tools never mutate the document directly — they emit commands, which makes gestures replayable by agents (`crates/tools/src/lib.rs`; `AGENTS.md`).
+ - Exact curve-preserving Pathfinder booleans (linesweeper sweep-line on cubics), Shape Builder regions with Gap Detection, Live Paint, offset, outline stroke, simplify, join/average (`crates/pathops/src/lib.rs`; `crates/engine/src/cmd/buildcmds.rs`).
+ - Appearance stacks (multiple fills/strokes, per-item effects), transparency, blob/opacity masks, clipping masks, graphic styles, global/spot swatches, gradients (linear/radial/freeform, mesh) with **Method Classic/Perceptual** (OKLab) and **Dither** (fills only), patterns, recolor (`crates/engine/src/cmd/appearance.rs`, `crates/engine/src/cmd/paint.rs`, `crates/engine/src/cmd/gradient.rs` L110, `crates/engine/src/cmd/patterncmds.rs`, `crates/engine/src/cmd/recolor.rs`, `crates/engine/src/cmd/opacitymask.rs`).
+ - Brushes (calligraphic, scatter, art, pattern, bristle) with a default library and expansion to real objects (`crates/brush/src/lib.rs`).
+ - Symbols, blends, envelopes, radial/grid/mirror Repeat, perspective grid, Intertwine, Objects on Path, 9 graph types with graph designs, Variables/data sets (4 kinds: text, visibility, image, graph) (`crates/engine/src/cmd/graph.rs`, `crates/engine/src/cmd/variablecmds.rs`, `crates/engine/src/cmd/perspgrid.rs`, `crates/engine/src/cmd/intertwine.rs`, `crates/engine/src/cmd/objects_on_path.rs`; `crates/doc/src/variables.rs` L14-23).
+ - **New at this tag**: **Pathfinder › Trap** (`pathfinder.trap` effect and the `object.pathfinder.trap` panel command) adds overprinting traps where solid colours meet (`crates/effects/src/trap.rs`) — the effect menu hole that remains is only the **SVG Filters** submenu; **Global Edit** (`select.globalEdit`, `select.globalEditOptions`); **Symbol libraries** (13 window/UI ids: `window.symbolLibrary`, `window.symbolLibrary.other`, `ui.saveSymbolLibrary`, `window.userSymbolLibrary1`…`10`) (`crates/engine/src/cmd/globaledit.rs`; `crates/ui-egui/src/menus.rs`); **part-path Simplify** on direct-selected anchors/segments (`crates/engine/src/cmd/pathops.rs` L837).
### Type
- - Point, area and type-on-a-path type, threading from the out port (area type and type on a path in one thread), character/paragraph styles, OpenType features (stylistic sets, alternates, figures, super/subscript), vertical type with initial CJK support plus manual tate-chu-yoko, Hebrew/Arabic bidirectional layout, Thai/Lao/Khmer/Myanmar word breaking, Touch Type, Hyphenation…/Justification…, Roman Hanging Punctuation, Optical Margin Alignment, No Break, System Layout, Fractional Widths, Snap to Glyph (`crates/text/`; `crates/ui-egui/src/panels/character.rs`; `docs/type-parity.md`).
- - **Ruby (ふりがな)** at this tag: `type.ruby` sets/removes a reading over a byte range — above/below, aligned, sized, overhanging or squeezed, right of the column in vertical type; saved natively, laid out with line growth, drawn and exported in SVG/PDF (as outlines where ruby is present). **No UI panel or type-on-a-path ruby yet** — call the command (`crates/engine/src/cmd/typecmd.rs` L119; `ROADMAP.md` 2026-10-22).
- - **Colour emoji with bitmap glyphs** (`sbix`: Apple Color Emoji; `CBDT`: Noto Color Emoji) draw and export (PDF Type 3 glyphs or images, SVG images when type is outlined, EPS/legacy `.ai` images); COLR/OpenType-SVG fonts and emoji in ruby, envelopes or warps are not supported (`crates/text/src/bitmap.rs`; `docs/type-parity.md`).
- - Text placed from `.txt`, `.rtf` and Word `.docx` as area type with formatting (`crates/engine/src/cmd/place/`; `docs/file-format-parity.md`).
+ - Point, area and type-on-a-path type, threading across frames (with visible in/out ports), character/paragraph styles, OpenType features, vertical type with initial CJK support, Hebrew/Arabic bidirectional layout, Thai/Lao/Khmer/Myanmar word breaking, Touch Type, Hyphenation…/Justification…, Roman Hanging Punctuation, Optical Margin Alignment, No Break, System Layout, Fractional Widths, Snap to Glyph (`crates/text/`; `docs/type-parity.md`).
+ - **Ruby (ふりがな)**: `type.ruby` sets/removes a reading over a byte range — above/below, aligned, sized, overhanging or squeezed; saved natively, laid out with line growth, drawn and exported in SVG/PDF, and (new at this tag) kept through Create Outlines, EPS, EMF/WMF and legacy `.ai` (`crates/engine/src/cmd/typecmd.rs`; `docs/type-parity.md` 2026-10-24). No UI panel or type-on-a-path ruby yet.
+ - **Colour fonts (much further than the previous skill)**: `sbix`/`CBDT` bitmap emoji, **COLR v0/v1** (`crates/text/src/colr.rs`) and **OpenType SVG glyphs** (`crates/text/src/svg_glyph.rs`) draw and export as vector art; bitmap glyphs also survive effects, Expand Appearance and EMF/WMF. Still open: CPAL palette variables, scripts/text inside SVG glyph documents.
+ - Text placed from `.txt`, `.rtf` and Word `.docx` as area type with formatting (`crates/engine/src/cmd/place/`).
### Effects and 3D
- - **All 57 Photoshop-style raster filters** now ship (Conté Crayon was the last), each live and editable, plus **Effect › Effect Gallery…** (`ui.effectGalleryDialog`): browse six raster submenus (Artistic, Brush Strokes, Distort, Sketch, Stylize, Texture), Add to Stack, reorder/remove, per-effect params and visibility, live canvas preview, OK applies the stack as separate appearance effects in one undo step. The gallery does not list the Blur, Pixelate, Sharpen or Video groups (those filters remain in the Effect menu) (`crates/effects/src/pixel/`; `crates/ui-egui/src/dialogs/effect_gallery.rs`; tests `stack_preview_is_one_interaction`, `stack_ok_is_one_undo_step`).
- - Illustrator-style vector and raster effects catalogue: `crates/effects/src/lib.rs` (`effect_catalog()`); the holes are the **SVG Filters submenu** (Apply SVG Filter; menu stub) and Pathfinder **Trap** (no catalogue entry). Pathfinder **Hard Mix and Soft Mix do exist** as live effects (`crates/effects/src/group.rs` `PATHFINDER_EFFECTS`).
- - Initial 3D: live **Revolve, Extrude & Bevel, Inflate, Rotate** with caps, bevels, twist/taper, perspective and **1–10 coloured lights** (`MAX_LIGHTS = 10`); four original lighting presets (Standard, Diffuse, Top Left, Right) via `effect.lightingPreset`; faces export as vector art. No materials, no shadows, painter's algorithm rather than solid modelling (`crates/three-d/src/{lib.rs,lights.rs}`; `crates/effects/src/lighting_presets.rs`; `docs/three-d.md`).
+ - **All 57 Photoshop-style raster filters** ship live and editable, plus **Effect › Effect Gallery…** (`ui.effectGalleryDialog`): six raster submenus (Artistic, Brush Strokes, Distort, Sketch, Stylize, Texture), Add to Stack, reorder/remove, per-effect params, live canvas preview, OK applies the stack as separate appearance effects in one undo step (`crates/effects/src/pixel/mod.rs` L47; `crates/ui-egui/src/dialogs/effect_gallery.rs` `CATEGORIES` L17). The gallery does not list the Blur, Pixelate, Sharpen or Video groups (those stay in the Effect menu).
+ - Illustrator-style vector/raster effects catalogue: `crates/effects/src/lib.rs` (`effect_catalog()`, ~116 entries). Pathfinder group: 12 live effects (`crates/effects/src/group.rs` `PATHFINDER_EFFECTS`, incl. Hard Mix and Soft Mix) **plus Trap** = 13. Remaining hole: **Apply SVG Filter** (menu stub only).
+ - Initial 3D: live **Revolve, Extrude & Bevel, Inflate, Rotate** with caps, bevels, twist/taper, perspective and **1–10 coloured lights** (`MAX_LIGHTS = 10`); four lighting presets via `effect.lightingPreset`; faces export as vector art. **No materials** — the 3D and Materials submenu's `Materials…` entry is a placeholder (`crates/three-d/src/lights.rs` L4; `crates/engine/src/cmd/effectcmd.rs` L59; `crates/ui-egui/src/menus.rs` L4160; `docs/three-d.md`).
- Image Trace (raster → vector) with presets, Shapes/Auto-Grouping/Gradients options and measured quality (`crates/trace/src/lib.rs`; `docs/image-trace-quality.md`).
- ### Files — open/read (implemented)
- `document.open` / File › Open reads 31 extensions — authoritative list `OPEN_EXTS` in `crates/engine/src/cmd/fileio/mod.rs` (L673): `.vectorcraft`, `.drawcraft`, `.svg`, `.svgz`, `.pdf`, `.ai`, `.ait`, `.png`, `.jpg/.jpeg`, `.gif`, `.webp`, `.tif/.tiff`, `.bmp`, `.tga/.vda/.icb/.vst` (Targa), `.psd`, `.psb`, `.vctemplate`, `.dxf`, `.emf`, `.wmf`, `.eps/.epsf`, `.ps`, `.af`, `.afdesign`, `.afpub`. File › Place additionally reads `.txt`, `.rtf`, `.docx` (`TEXT_EXTS`/`RTF_EXTS`/`DOCX_EXTS`, L728-736).
- - **SVG/SVGZ** — strongest format both ways; symbols, patterns, CSS, filters mapped to live effects, Inkscape extensions and multi-page artboards; unsupported filters are named in `warnings`; `preserveEditing` SVGs reopen as the full document (`docs/file-format-parity.md`).
- - **PDF and `.ai`** — own reader (shared `craft-pdf` interpret backend, `docs/pdf-backend.md`); PDF opens with layers, editable text, masks, security, overprint; `.ai` reads Illustrator's private editing-data *structure* and legacy PostScript-form `.ai` via a PostScript Level 3 interpreter; a multi-page `.ai` can open a named page from its editing data; Illustrator EPS opens as editable vector art (`docs/file-format-parity.md`; `docs/mcp.md` L646-709).
- - **EPS/PS** — own PostScript L2/L3 interpreter and editing-data reader (`crates/eps/`); `.ps` opens (the file-format summary still lists PS as missing — code wins).
- - **Affinity** `.af` (Affinity 3), `.afdesign`, `.afpub` and, by content, `.afphoto` — native read-only import (no write); at this tag AF.5 adds master pages, tables, paragraph formats, shadows/glows/outlines/overlays, editable embedded documents, CMYK pixel layers through the document profile and Affinity-style text placement; 51 pinned corpus documents (33 current `.af`) (`crates/affinity/README.md`; `docs/affinity-validation.md`; `.github/workflows/affinity-corpus.yml`).
- - **PSD/PSB** open as their **merged image only** (every mode/depth); placing as layers is not implemented (`FORMATS` in `crates/engine/src/cmd/fileio/mod.rs`; `docs/file-format-parity.md`).
- - **DXF** (R12–2018; circles/arcs as native entities), **EMF/WMF**, rasters incl. TIFF with CCITT Group 3/4 and CMYK ink preservation (`crates/cad/`, `crates/metafile/`).
+ ### Files — open / read (implemented)
+ `document.open` / File › Open reads 31 extensions — authoritative list `OPEN_EXTS` in `crates/engine/src/cmd/fileio/mod.rs` L674: `.vectorcraft`, `.drawcraft`, `.svg`, `.svgz`, `.pdf`, `.ai`, `.ait`, `.png`, `.jpg/.jpeg`, `.gif`, `.webp`, `.tif/.tiff`, `.bmp`, `.tga/.vda/.icb/.vst`, `.psd`, `.psb`, `.vctemplate`, `.dxf`, `.emf`, `.wmf`, `.eps/.epsf`, `.ps`, `.af`, `.afdesign`, `.afpub`. File › Place additionally reads `.txt`, `.rtf`, `.docx` (`TEXT_EXTS`/`RTF_EXTS`/`DOCX_EXTS`).
+ - **SVG/SVGZ** — strongest interchange both ways; symbols, patterns, CSS, filters mapped to live effects, Inkscape extensions, multi-page artboards; unsupported filters are named in `warnings`; attributes in other applications' XML namespaces now round-trip (new at this tag) (`crates/svg/src/export.rs` L668; `docs/file-format-parity.md` 2026-10-23).
+ - **PDF and `.ai`** — own reader; PDF opens with layers, editable text, masks, security, overprint; `.ai` reads Illustrator's private editing-data structure and legacy PostScript-form `.ai` via a PostScript Level 3 interpreter; a multi-page `.ai` can open a named page from its editing data (`docs/file-format-parity.md`; `docs/mcp.md`).
+ - **EPS/PS** — own PostScript L2/L3 interpreter and editing-data reader (`crates/eps/`); `.ps` opens (the file-format summary's "PS missing" row is stale).
+ - **Affinity** `.af` (Affinity 3), `.afdesign`, `.afpub` and, by content, `.afphoto` — native **read-only** import (no write); 51 pinned corpus documents, 33 current `.af` (`crates/affinity/README.md`; `docs/affinity-validation.md`).
+ - **PSD/PSB** open as their **merged image only**; placing as layers is not implemented (`FORMATS` in `crates/engine/src/cmd/fileio/mod.rs`).
+ - **DXF** (R12–2018), **EMF/WMF**, rasters incl. TIFF with CCITT Group 3/4 (`crates/cad/`, `crates/metafile/`).
### Files — save / export (implemented)
- `SAVE_FORMATS` = `vectorcraft`, `template` (`.vctemplate`), `pdf`, `svg`, `svgz`, `ai` (`crates/engine/src/cmd/fileio/save.rs` L23). Save As `.ai` writes a **PDF-compatible** file by default (carrying the native document when every artboard is written in order), or **legacy version 7** (`aiVersion: "7"` / `convert --ai-version 7`) which keeps layers, groups, compound paths and editable type, one artboard per file; transparency, live effects and object names don't survive it, and Illustrator's private editing data is never written (`docs/file-format-parity.md`). Save as Template writes `.vctemplate`; `file.saveAsTemplate` also writes a PDF-compatible `.ait` (legacy v7 is refused).
+ `SAVE_FORMATS` = `vectorcraft`, `template` (`.vctemplate`), `pdf`, `svg`, `svgz`, `ai` (`crates/engine/src/cmd/fileio/save.rs` L24); `TEMPLATE_FORMATS` = `template`, `ait` (L28). Save As `.ai` writes a **PDF-compatible** file by default (carrying the native document when every artboard is written in order), or **legacy version 7** (`aiVersion: "7"` / `convert --ai-version 7`) which keeps layers, groups, compound paths and editable type, one artboard per file; transparency, live effects and object names don't survive it, and Illustrator's private editing data is never written (`docs/file-format-parity.md`).
- Extension-driven `document.export` (`export_extensions()`, L716; details in `docs/mcp.md` › export): `.vectorcraft`, `.vctemplate`, `.svg`, `.svgz`, `.pdf` (presets, PDF/A-2b, PDF/X-1a/3/4, layers, marks/bleed, ICC, security, `/DisplayDocTitle` when titled), `.ai`, `.eps`, `.dxf` (R12–2018), `.emf`, `.wmf`, `.png`, `.png8` (indexed), `.jpg`, `.webp` (**lossless only**; a lossy request is written lossless with a warning), `.gif`, `.tif`, `.bmp`, `.tga`, `.psd` (**layered**), `.txt`. Exporter **plug-ins** add their own formats (`plugin.<id>`). Plus Export for Screens / Asset Export incl. TIFF, Export Selection, Export As with `rect` page-area rasters, CSS Properties export, Save for Office, Print/Print Tiling through the shared `craft-print` spooler, Package (the document plus its linked files), and PostScript only via Print to PostScript (`crates/engine/src/cmd/{print.rs,css.rs,package.rs}`; `crates/engine/src/cmd/fileio/screens.rs`).
+ Extension-driven `document.export` (`export_extensions()`): `.vectorcraft`, `.vctemplate`, `.svg`, `.svgz`, `.pdf` (presets, PDF/A-2b, PDF/X-1a/3/4, layers, marks/bleed, ICC, security, `/DisplayDocTitle`), `.ai`, `.eps`, `.dxf` (R12–2018), `.emf`, `.wmf`, `.png`, `.png8` (indexed), `.jpg`, `.webp` (**lossless only** — a lossy request is written lossless with a warning), `.gif`, `.tif`, `.bmp`, `.tga`, `.psd` (**layered**), `.txt`. Exporter **plug-ins** add their own formats (`plugin.<id>`). Pattern fills/strokes are now written as real PDF tiling patterns (`crates/pdf/src/export.rs` L624-637; new at this tag). Plus Export for Screens / Asset Export, Export Selection, Export As with `rect` page-area rasters, CSS Properties export, Save for Office, Print/Print Tiling and Package (`crates/engine/src/cmd/print.rs`, `crates/engine/src/cmd/css.rs`, `crates/engine/src/cmd/package.rs`, `crates/engine/src/cmd/printtiling.rs`, `crates/engine/src/cmd/fileio/screens.rs`).
### Automation and extensions (implemented)
- - **MCP server** (stdio, newline JSON-RPC 2.0): `vectorcraft-cli mcp` — remote backend (default: connect to `127.0.0.1:7979`, fall back to headless) or `--headless`. **32 tools** (`crates/mcp/src/tools.rs`), including `command_run`/`run_command`/`invoke_menu`, `command_batch` (≤256 steps, `atomic`, `$N.path`), `command_list`, `doc_inspect` (scoped by `ids`/`kind`/`limit`/`offset`), `ui_inspect`, `draw_path`, `draw_shape`, `set_paint`, `add_text`, `apply_effect`, `pathfinder`, `transform`, `create_graph`, `text_wrap`, `export` (selection/`rect`/cancellable, progress), `render_preview`, `select_tool`, `pointer_gesture`, `press_key`, `type_text`, `open_panel`, `screenshot`, `open_file`, `save_file`, `undo`, `redo`. Plus **5 prompts**, **3 fixed resources + 4 URI templates** (`vectorcraft://object/{id}`, `command/{id}`, `effect/{id}`, `swatch/{name}`), completions, logging, cancellation and a 2 s busy guard. Caps: 16 MiB lines, 64-message batches, 8 MiB kept step results, 256 MiB app replies. Protocol `2025-06-18`; clients asking for `2026-07-28` also get `resultType: complete`, `ttlMs` and `cacheScope` on list/read results (`crates/mcp/src/server.rs` L21-23; `docs/mcp.md`).
- - **Control channel** — `vectorcraft --control <port>` listens on `127.0.0.1` only, one JSON request per line. 28 methods: `engine.execute`, `engine.commands`, `document.inspect`, `ui.inspect`, `ui.menu.list`/`ui.menu.invoke`, `ui.contextMenu.list`, `ui.tool.select`/`ui.tool.list`, `ui.pointer`, `ui.key`/`ui.text`/`ui.move`/`ui.click`/`ui.drag`/`ui.wheel`, `ui.set`, `ui.dialog.set`/`confirm`/`cancel`, `ui.resize`, `ui.focus`, `ui.screenshot`, `ui.render`, `app.open`/`save`/`export`/`quit` (`crates/ui-egui/src/control.rs`; `docs/control-protocol.md`). No authentication — loopback only; 4 MiB request line, 16 connections, 60 s reply wait, 300 s idle. Confine reads/writes with repeatable `--automation-read-root`/`--automation-write-root`.
- - **Browser API** — the web build exposes 9 calls as promises on `window.vectorcraft`: `request`, `execute`, `commands`, `inspect`, `screenshot`, `openFile`, `captureDownloads`, `files`, `readFile` (`apps/vectorcraft-web/src/api.rs`; `docs/control-protocol.md` › In the browser).
- - **CLI** `vectorcraft-cli` (`apps/vectorcraft-cli/src/main.rs`): `mcp`, `run` (headless batch; `--in FILE`, repeatable `--cmd ID --params JSON`, repeatable `--export FILE`, `--scale`; `--commands FILE|-` reads a JSON array or JSON Lines of steps, 64 MiB/100,000 steps; a step's result is referencable as `$N.path`), `commands` (full catalogue as JSON — authoritative command ids, params and shortcuts), `convert IN OUT` (`--artboard/--range/--outline-text/--decimals/--replace-lossy/--editing-data/--ai-version 7|pdf/--hidden-objects layer|omit|visible/--transparent-images flatten|omit`; refuses to overwrite its input when reading it left things out unless `--replace-lossy`; reports `importWarnings`), `info FILE`, `bench FILE`, `perf` (performance budgets).
- - **Plug-ins**: sandboxed WebAssembly modules (ABI v1, no host imports, fuel + memory caps) as object **filters**, live **effects**, or **exporters** that add formats to Export As / `document.export`; typed parameters up to 256; install via `plugin.install`, File › Open of a `.wasm`, or an *Additional Plug-ins Folder* preference (`docs/plugins.md`; `crates/plugins/`).
- - **Actions** record/play through the Actions panel and `command.batch`; the Batch… dialog (`ui.batchDialog`) runs an action over files or data sets (`action.batch`); datasets via `dataset.import` (CSV/TSV; header cells define text/visibility/image/graph variables) (`crates/ui-egui/src/panels/actions.rs`; `crates/engine/src/cmd/{fileio/action_batch.rs,variablecmds.rs}`; `crates/doc/src/variables.rs`).
- - **Script checking**: `script.check` statically analyses reference-app scripts (`.jsx`, `.jsxinc`, `.js`, `.jsxbin`) — it checks, never runs them (`crates/scriptcheck/src/lib.rs`; `crates/engine/src/cmd/scripts.rs`).
+ - **MCP server** (stdio, newline JSON-RPC 2.0): `vectorcraft-cli mcp` — remote backend (default: connect to `127.0.0.1:7979`, fall back to headless) or `--headless`. **32 tools** (`crates/mcp/src/tools.rs::tool_definitions`): `command_list`, `command_run`, `run_command`, `command_batch` (≤256 steps, `atomic`, `$N.path`), `doc_inspect`, `inspect_document`, `ui_inspect`, `inspect_ui`, `ui_screenshot`, `list_commands`, `select_tool`, `pointer_gesture`, `draw_path`, `draw_shape`, `set_paint`, `press_key`, `type_text`, `invoke_menu`, `open_panel`, `screenshot`, `open_file`, `save_file`, `export`, `add_text`, `apply_effect`, `pathfinder`, `transform`, `create_graph`, `text_wrap`, `render_preview`, `undo`, `redo`. Plus **5 prompts**, **3 fixed resources + 4 URI templates** (`vectorcraft://object/{id}`, `command/{id}`, `effect/{id}`, `swatch/{name}`), completions, logging, cancellation and a 2 s busy guard. Caps: 16 MiB lines, 64-message batches, 8 MiB kept step results, 256 MiB app replies. Protocol `2025-06-18`; clients asking for `2026-07-28` also get `resultType: complete`, `ttlMs` and `cacheScope` (`crates/mcp/src/server.rs` L21-23; `crates/mcp/src/prompts.rs`; `crates/mcp/src/resources.rs`; `docs/mcp.md`).
+ - **Control channel** — `vectorcraft --control <port>` listens on `127.0.0.1` only, one JSON request per line. 28 methods: `engine.execute`, `engine.commands`, `document.inspect`, `ui.inspect`, `ui.menu.list`/`ui.menu.invoke`, `ui.contextMenu.list`, `ui.tool.select`/`ui.tool.list`, `ui.pointer`, `ui.key`/`ui.text`/`ui.move`/`ui.click`/`ui.drag`/`ui.wheel`, `ui.set`, `ui.dialog.set`/`confirm`/`cancel`, `ui.resize`, `ui.focus`, `ui.screenshot`, `ui.render`, `app.open`/`save`/`export`/`quit` (`crates/ui-egui/src/control.rs`; `docs/control-protocol.md` L92-109). No authentication — loopback only; 4 MiB request line, 16 connections, 60 s reply wait, 300 s idle (`apps/vectorcraft/src/control_server.rs` L26-56). Confine reads/writes with repeatable `--automation-read-root`/`--automation-write-root`.
+ - **Browser API** — the web build exposes 9 calls as promises on `window.vectorcraft`: `request`, `execute`, `commands`, `inspect`, `screenshot`, `openFile`, `captureDownloads`, `files`, `readFile` (`apps/vectorcraft-web/src/api.rs::install`).
+ - **CLI** `vectorcraft-cli` (`apps/vectorcraft-cli/src/main.rs`): `mcp` (`--connect ADDR | --headless`, repeatable `--automation-read-root`/`--automation-write-root`, also `--flag=DIR`), `run` (headless batch; `--in FILE`, repeatable `--cmd ID --params JSON`, repeatable `--export FILE`, `--scale`; `--commands FILE|-` reads a JSON array or JSON Lines, 64 MiB/100,000 steps; a step's result is referencable as `$N.path`), `commands` (full catalogue as JSON), `convert IN OUT` (`--artboard/--range/--outline-text/--decimals/--replace-lossy/--editing-data/--ai-version 7|pdf/--hidden-objects layer|omit|visible/--transparent-images flatten|omit`; refuses to overwrite its input when reading it left things out unless `--replace-lossy`; reports `importWarnings`), `info FILE`, `bench FILE [--size WxH] [--iters N]`, `perf [--paths N] [--deep]`.
+ - **Plug-ins**: sandboxed WebAssembly modules (ABI v1, no host imports, fuel + memory caps) as object **filters**, live **effects**, or **exporters** that add formats; up to **256** typed parameters (`crates/plugins/src/manifest.rs` L13; `docs/plugins.md`).
+ - **Actions** record/play through the Actions panel and `command.batch`; the Batch… dialog (`ui.batchDialog`) runs an action over files or data sets (`action.batch`); datasets via `dataset.import` (CSV/TSV; header cells define text/visibility/image/graph variables) (`crates/engine/src/cmd/variablecmds.rs` L780; `crates/doc/src/variables.rs`).
+ - **Script checking**: `script.check` statically analyses reference-app scripts and never runs them — `EXTS` = `.jsx`, `.jsxinc`, `.jsxbin`, and its documentation also covers plain `.js` text (`crates/engine/src/cmd/scripts.rs` L17; `crates/scriptcheck/src/lib.rs`).
### Platform
- Web build: `apps/vectorcraft-web/` (Trunk; `cargo xtask wasm` gates it). Wasm aborts on panic — the native `guard` safety net does not apply there (`crates/engine/src/guard.rs`).
- - Localized UI: 25 interface languages (24 `.tsv` catalogues + English) under `crates/ui-egui/src/i18n/`; **Turkish** was added at this tag. 12-key-language score **~82%** measured (`docs/localization-parity.md`; `ROADMAP.md` still says 74% — stale). Only Georgian has had a native-speaker review; Hindi and Arabic have no catalogue (no right-to-left interface).
- - Experimental, unsupported 64-bit Windows 7 build (`docs/windows7.md`); Linux Wayland pen and drag-and-drop caveats in `README.md`.
+ - Localized UI: 25 interface languages (24 `.tsv` catalogues + English) under `crates/ui-egui/src/i18n/`; **12-key-language score ~82% measured** (`docs/localization-parity.md` L42; `ROADMAP.md` still says 74% — stale). Only Georgian has had a native-speaker review; Hindi and Arabic have no catalogue (no right-to-left interface).
+ - **macOS pen pressure and the pen's eraser end** now read AppKit tablet events (`apps/vectorcraft/src/mac_tablet.rs`) — implemented but per `docs/gaps.md` G14 "not yet tried on a Mac". Experimental, unsupported 64-bit Windows 7 build (`docs/windows7.md`); Linux Wayland drag-and-drop and pen caveats in `README.md`.
## Known limitations and not-implemented
- Label guide: repo-admitted gaps (`docs/gaps.md`, `README.md`) — treat them as work the app cannot be assigned yet. Where docs and code disagree, code wins; the main disagreements are listed at the end.
+ Label guide: repo-admitted gaps (`docs/gaps.md` ranked G1–G19, `README.md`) — treat them as work the app cannot be assigned yet. Where docs and code disagree, code wins; the main disagreements are listed at the end.
- - **Stage alpha; not a daily driver yet** (~62% ready for real work; ~65% mainstream, ~75% essentials). The ranked gaps (`docs/gaps.md`): #1 G1 interaction-fidelity pass over every tool modifier and small behaviour — **never** checked side by side with the real app (clean-room forbids it, so "done" means "matches the documentation"); #2 G9 Illustrator `.ai`/EPS exchange — layer structure in real users' files is flattened or multiplied (#951), guides are lost (#779), some files open slowly (#758), live effects/brushes/symbols come in as plain art (#637), and Illustrator's own editing data is never written; #3 G10 launch/stability on some Windows 11 and Linux machines; #4 G8 hardening at scale (no real-world SVG/PDF/EPS corpus); #5 G11 correctness bugs (Shape Builder planar regions #937, PDF text boxes moving #722, SVG units #864). Beta also waits on G12 (preferences/panels that don't act), the type-core part of G4 and macOS pen pressure (~170–270 h total).
- - **Effect Gallery status**: it ships at this tag (6 of 10 raster submenus; see Capabilities). `docs/gaps.md` G2, `docs/effects-parity.md` and `README.md` still call the dialog missing — do not repeat that; the gaps are the Blur/Pixelate/Sharpen/Video groups (10 of the 57 filters stay in the Effect menu) and a fuller gallery UI than the plain filter list.
- - **Formats not supported at all**: FreeHand, CorelDRAW, DWG (use DXF), HEIC/HEIF, JPEG 2000, PICT/PCX/Pixar, Word `.doc`, and 3D export (OBJ/USDA/glTF). No Affinity **write**. PSD/PSB open as merged images only; PSD export is layered. No PDF editing beyond VectorCraft's own round-trip. `document.export` writes no `.ps` (PostScript is print-only output).
- - **3D and Materials**: four initial live types, **no materials, shadows or ray tracing**; ~25% depth; painter's algorithm, not solid modelling (`docs/effects-parity.md`; `docs/gaps.md` G3).
- - **Illustrator effects**: the SVG Filters submenu (Apply SVG Filter) and Pathfinder Trap are absent; the parity docs disagree on the vector-effect count (44/50 vs 46/50) and `docs/effects-parity.md` still lists Hard Mix as missing although `pathfinder.hardMix` is implemented — check the catalogue, not the count.
- - **Type**: CJK vertical composition is incomplete (Mojikumi Settings dialog and custom kinsoku sets missing), spell check (menu stubs, needs an open dictionary), Retype, COLR/OpenType-SVG colour fonts, the font menu's variable-font filter, and preserving font sizes while scaling a group are missing or partial; Ruby has no UI panel/type-on-path yet; emoji in ruby/envelopes/warps and some bitmap formats are unsupported (`docs/type-parity.md`; `docs/gaps.md` G4).
- - **Scripting**: reference-app scripting does **not** run — VectorCraft has no script engine (`README.md` "What's missing"); `.jsx` files can only be statically checked (`crates/scriptcheck`). Automation is MCP/control-channel/CLI instead.
+ - **Stage alpha; not a daily driver yet** (~62% ready for real work; ~65% mainstream, ~75% essentials; ~170–270 h to beta). The ranked gaps: #1 **G1** interaction-fidelity pass over every tool modifier — **never** checked side by side with Illustrator (clean-room forbids it, so "done" means "matches the documentation"); #2 **G9** Illustrator `.ai`/EPS exchange — faithful layer/group structure from the editing data in real files (#951), guides (#779), open speed on large files (#758), and live effects/brushes/symbols as live objects (#637, partly improved), and Illustrator's own editing data is never written; #3 **G10** launch/stability on some Windows 11 and Linux machines; #4 **G8** hardening at scale; #5 **G11** correctness bugs in core tools (the live list is `docs/gaps.md` › G11).
+ - **3D and Materials**: four initial live types, **no materials, shadows or ray tracing** (~25% depth; painter's algorithm, not solid modelling). The `Materials…` menu entry is a placeholder (`crates/ui-egui/src/menus.rs` L4160; `docs/gaps.md` G3).
+ - **Illustrator effects**: only the **SVG Filters** submenu (Apply SVG Filter) is missing now — it is a menu stub (`todo("Apply SVG Filter…")`, `crates/ui-egui/src/menus.rs` L4147). Pathfinder **Trap**, Hard Mix and Soft Mix all exist (13/13 per `docs/effects-parity.md`); the parity docs disagree on the vector-effect total (`44/50` in `docs/target-app-parity.md`; `46/50` and `49/50` also appear in `docs/effects-parity.md`) — check the catalogue, not the count.
+ - **Formats not supported at all**: FreeHand, CorelDRAW, DWG (use DXF), HEIC/HEIF, JPEG 2000, PICT/PCX/Pixar, Word `.doc`, and 3D export (OBJ/USDA/glTF). No Affinity **write**. PSD/PSB open as merged images only (PSD export is layered). `document.export` writes no `.ps` (PostScript is print-only output).
+ - **Type still partial**: CJK vertical composition (Mojikumi Settings dialog, custom kinsoku sets), spell check (menu stubs only: `todo("Auto Spell Check")`, `todo("Check Spelling…")`, `todo("Edit Custom Dictionary…")` — `crates/ui-egui/src/menus.rs` L2698), Retype, CPAL palette variables, and preserving font sizes while scaling a group; Ruby has no UI panel or type-on-a-path (`docs/type-parity.md`; `docs/gaps.md` G4).
+ - **Scripting**: reference-app scripting does **not** run — VectorCraft has no script engine (`README.md` "What's missing"). `.jsx` files can only be statically checked (`crates/scriptcheck`). Automation is MCP/control-channel/CLI instead.
- **Generative AI features**: none (0%, `docs/gaps.md` G18).
- **MCP limits**: stdio only — no Streamable HTTP/SSE, no `resources/subscribe`, no `sampling/createMessage` or `elicitation/create`; document reads are refused as busy while a long call runs (`docs/mcp.md` › Not implemented).
- **Control port has no authentication** — loopback only; disable it when not in use (`docs/control-protocol.md`).
- - **Artboard background colours** draw on the canvas but not in exports or print yet (`crates/doc/src/lib.rs` L454-456; `docs/gaps.md` G13).
+ - **Artboard background colours** draw on the canvas but are left out of exports and print (documented in the `artboard.setProps` param doc, `crates/engine/src/cmd/layer.rs` L146).
- **Accessibility** is limited: AccessKit reaches egui widgets, but the canvas/custom panels are not described and nothing is tested with VoiceOver/Narrator/Orca (`docs/gaps.md` G19).
- - **Claimed but unverified in this pass**: parity percentages, "done" checklist rows and hours are documentation-based self-assessments, never measured against Illustrator; localization catalogues other than Georgian have had no native review; the README's "20,000 shapes in ~27 ms" is a project self-report — measure with `vectorcraft-cli perf` on your machine.
- - **Doc/code contradictions found at this tag** (code treated as authoritative): (a) `docs/gaps.md` G4 still lists Touch Type and Snap to Glyph as missing, but `text.touchType` exists and `view.snapToGlyph` is implemented with tests; (b) `docs/type-parity.md` has a duplicate stale "CJK: ruby | missing" row beside the "partial" row, and `type.ruby` exists; (c) `docs/file-format-parity.md` lists PS as missing while `FORMATS`/`OPEN_EXTS` read `.ps`; (d) `README.md` "What's missing" still lists 3D beyond Revolve, the Effect Gallery and the rest of Variables — the three 3D types, the gallery and all four variable kinds plus `dataset.import` ship (materials do not); (e) `ROADMAP.md` still prints 348/375, 46/50 and 74% where the authoritative docs say 353/375, 44/50 and 82%.
+ - **Claimed but unverified in this pass**: parity percentages, "done" checklist rows and hours are self-assessments from code against public documentation, never measured against Illustrator; localization catalogues other than Georgian have had no native review; the README's "20,000 shapes in ~27 ms" is a project self-report — measure with `vectorcraft-cli perf` on your machine; macOS pen pressure is implemented but untried on hardware.
+ - **Doc/code contradictions found at this tag** (code treated as authoritative): (a) `README.md` "What's missing" still lists "scripting, and the rest of Variables (image and graph kinds, dataset import)" although `dataset.import` and all four `VariableKind`s exist, and still lists 3D beyond Revolve although Extrude & Bevel/Inflate/Rotate ship (materials genuinely do not); (b) `ROADMAP.md` prints 348/375, 46/50 and 74% localization where `docs/target-app-parity.md` says 353/375 and 44/50 and `docs/localization-parity.md` measures ~82%; (c) `docs/file-format-parity.md` lists PS as missing while `FORMATS`/`OPEN_EXTS` read `.ps`; (d) `docs/effects-parity.md` carries several conflicting vector-effect totals.
## How to operate
**Launch (macOS):**
```sh
open -a VectorCraft # or: open -a VectorCraft --args --control 7979
open -a VectorCraft --args --control 7979 --automation-read-root DIR --automation-write-root DIR
```
- Desktop flags (`apps/vectorcraft/src/main.rs` L735-800): `--control <port>` (or `VECTORCRAFT_CONTROL_PORT`; a bad port stops the app with an error), repeatable `--automation-read-root <dir>` / `--automation-write-root <dir>` (confine everything an agent reads/writes; env equivalents `VECTORCRAFT_AUTOMATION_READ_ROOT`/`_WRITE_ROOT`), `--in-window-menus` (`VECTORCRAFT_IN_WINDOW_MENUS=1`), `--version`, `-h/--help`; extra arguments are files to open as tabs. Env: `VECTORCRAFT_CONFIG_DIR` (isolated profile — use this for agent runs), `VECTORCRAFT_NO_PREFS` (no preference reads/writes), `WGPU_POWER_PREF=high|low` / `WGPU_ADAPTER_NAME=<substr>` to pick the GPU (`README.md`).
+ Desktop flags (`apps/vectorcraft/src/main.rs`; `apps/vectorcraft/src/automation_args.rs`): `--control <port>` (or `VECTORCRAFT_CONTROL_PORT`; a bad port stops the app with an error), repeatable `--automation-read-root <dir>` / `--automation-write-root <dir>` (confine everything an agent reads/writes; `--flag=DIR` also works, and the roots are ignored with a warning when `--control` is absent), `--in-window-menus` (`VECTORCRAFT_IN_WINDOW_MENUS=1`), `--version`, `-h/--help`; extra arguments are files to open as tabs. Env: `VECTORCRAFT_CONFIG_DIR` (isolated profile — use this for agent runs), `VECTORCRAFT_NO_PREFS` (no preference reads/writes), `WGPU_POWER_PREF=high|low` / `WGPU_ADAPTER_NAME=<substr>` to pick the GPU (`README.md`).
- **The CLI is not inside the `.app` on macOS.** It ships as a separate release asset (`docs/mcp.md` › From an installed release); the bundle holds only the desktop binary. Build with `cargo build --release -p vectorcraft-cli`, `cargo install --path apps/vectorcraft-cli --locked`, or unzip the asset. Update the app only **between** projects.
+ **The CLI is not inside the `.app` on macOS.** It ships as a separate release asset (`docs/mcp.md` › From an installed release); the bundle holds only the desktop binary, and `vectorcraft-cli` is not installed on a stock launcher install. Build with `cargo build --release -p vectorcraft-cli`, `cargo install --path apps/vectorcraft-cli --locked`, or unzip the asset. Update the app only **between** projects.
- **Core workflow concepts:** one document per tab (`ui.inspect` lists `documents`/`activeDocument`); each document has artboards, layers, objects addressed by stable ids; units are points, y down, origin at the first artboard's top-left; a new document is 612 × 792 (`docs/mcp.md`). Selection + key object drive most commands; most commands accept explicit `ids`. New at this tag: panels dock into any group or the icon column and collapse to tabs; workspaces keep their layout across restarts; Artboard Options offers Fit to Artwork Bounds / Fit to Selected Art; dragging a selection over another tab copies it there.
+ **Core workflow concepts:** one document per tab (`ui.inspect` lists `documents`/`activeDocument`); each document has artboards, layers, objects addressed by stable ids; units are points, y down, origin at the first artboard's top-left; a new document is 612 × 792 (`docs/mcp.md`). Selection plus a key object drive most commands; most commands accept explicit `ids`. Artboards carry per-artboard options (background colour, lock, center mark, video safe areas) through `artboard.setProps`.
- **Open → edit → save/export:** open with File › Open / `app.open` / `open_file` (any `OPEN_EXTS`); save with Save/Save As (`SAVE_FORMATS` above) — a document opened from or saved as SVG/PDF keeps that format on Save, and the result's `warnings` say what the format loses. Export with `document.export` (extension or `format` picks the format; PDF/`.ai` write one page per artboard, SVG/SVGZ/EPS one file per chosen artboard, rasters one artboard unless `useArtboards`, with optional `rect` crops). **Always read `warnings`** — on import (EPS preview fallback, unsupported SVG filters, Affinity losses…) and on export: they are the loss report. The Save dialog now offers `.ai` (and `.ait` for templates) and replaces an extension the chosen format doesn't list.
+ **Open → edit → save/export:** open with File › Open / `app.open` / `open_file` (any `OPEN_EXTS`); save with Save/Save As (`SAVE_FORMATS` above) — a document opened from or saved as SVG/PDF keeps that format on Save, and the result's `warnings` say what the format loses. Export with `document.export` (extension or `format` picks the format; PDF/`.ai` write one page per artboard, SVG/SVGZ/EPS one file per chosen artboard, rasters one artboard unless `useArtboards`, with optional `rect` crops). **Always read `warnings`** — on import (EPS preview fallback, unsupported SVG filters, Affinity losses…) and on export: they are the loss report.
**Keyboard shortcuts:** never guess them. The command catalogue carries each command's shortcut: `vectorcraft-cli commands`, MCP `list_commands`, control `engine.commands` (`crates/ui-egui/src/shortcuts.rs` resolves them). Shortcut sets import/export as `.kys` (`shortcutset` commands).
**Preferences / agent-visible folders (macOS):** `Application Support/VectorCraft/` under the user's home (`ui.json` plus sibling folders Swatches, Graphic Styles, Fonts, Plug-ins, PDF Presets, Color Profiles, Data Recovery, logs) (`apps/vectorcraft/src/prefs_dir.rs`; `apps/vectorcraft/src/profile.rs`).
## Working with an AI agent
Prefer the automation surfaces over GUI automation; they are the same engine the UI uses.
- **Live session:** start the app with `--control 7979 [--automation-read-root DIR --automation-write-root DIR]` (each root may repeat), then either talk the control protocol directly or register the MCP bridge: `claude mcp add vectorcraft -- vectorcraft-cli mcp --connect 127.0.0.1:7979` (the bridge forwards each tool call as one control request, so you watch changes live).
- **Headless:** `vectorcraft-cli mcp --headless` or `vectorcraft-cli run --in FILE --cmd … --export OUT`; for long step lists use `run --in FILE --commands steps.json --export OUT` (stdin with `-`). The confinement flags imply `--headless` and refuse `--connect`, so a live app must confine itself with the same flags.
- - **Inspect before editing**: `doc_inspect {depth: 0}` for the skeleton, then scope with `ids`/`kind`/`limit`/`offset`; use `document.find {name?, kind?, text?}` to locate nodes, `document.node {id, summary: true}` to slice one; read paint with `paint.proxies`; list formats/options with `document.formats`. On large documents drill — never dump `document.json`.
- - **Draw/edit**: `draw_path` (SVG `d` or points), `draw_shape`, `add_text` (point/area/path, `vertical`, `justify`), `set_paint`, `apply_effect`, `pathfinder`, `transform`, `text_wrap`, `create_graph`, or any command id via `command_run`. `draw_path`/`draw_shape` style and apply effects in the same atomic batch: a refused paint leaves no object and no undo step. Group edits with `command_batch {atomic: true}` so one undo step is recorded. Get exact ids/params from `commands`/`list_commands` — unknown param keys are rejected with a did-you-mean before anything runs.
- - **Use the new type/effect commands**: `type.ruby` for furigana, `effect.lightingPreset` after a 3D effect, `paint.editGradient {method: "perceptual"}` / `{dither: true}` for print-safe ramps (SVG/PDF rasterise those fills), and `ui.effectGalleryDialog` + `ui.dialog.set {field: "stack", value: [...]}` + `ui.dialog.confirm` to apply a stack of raster filters in one undo step (live app only).
- - **Prepare inputs for the app**: SVG (cleanest interchange), PDF, EPS, DXF, PNG/JPEG/WebP/TIFF/BMP/Targa, PSD/PSB merged images, CSV/TSV for graphs and Variables data sets, `.rtf`/`.docx` for area type. Fonts: `text.addFontFiles` copies files into the app's Fonts folder; Japanese/Chinese/Arabic/Thai faces also come from the optional craft-fonts build input (`README.md`). Reusable logic can ship as a `.wasm` plug-in (ABI v1, no imports; `docs/plugins.md`).
- - **Inspect/repair native files**: `.vectorcraft` is documented, versioned JSON (v4; optional gzip detected by content; unknown keys from newer versions are preserved by save). Prefer `document.save {version: 1|2, compress}` for downgrades over hand-editing; for repairs, open → inspect → command → save, and round-trip verify.
- - **Verify outputs**: render previews (`render_preview`, `ui.render`, `screenshot`), reopen the export (`app.open`, `vectorcraft-cli info`) and diff warnings; `vectorcraft-cli bench/perf` for timing budgets. Never trust a silent export.
- - **Must NOT**: drive the GUI blind (use control/MCP; `ui.screenshot` needs a presented frame and fails after ~8 s when the screen is locked, the window is minimized or covered; window geometry is not stable across machines); write `.ai` private editing data or Affinity files (not implemented — don't promise them); assume PSD opens with layers; run reference-app scripts (not supported); use Adobe apps to create or verify anything (repo clean-room rule; produce test art in-repo instead, `AGENTS.md`).
+ - **Inspect before editing:** `doc_inspect {depth: 0}` for the skeleton, then scope with `ids`/`kind`/`limit`/`offset`; `document.find` locates nodes (name/kind/text plus `within`, `intersects`, size, thickness, area and anchor-count filters) and `document.node {id, summary: true}` slices one; read paint with `paint.proxies`; list formats and their options with `document.formats`. On large documents drill — never dump `document.json`.
+ - **Draw/edit:** `draw_path` (SVG `d` or points), `draw_shape`, `add_text` (point/area/path, `vertical`, `justify`), `set_paint`, `apply_effect`, `pathfinder`, `transform`, `text_wrap`, `create_graph`, or any command id via `command_run`. `draw_path`/`draw_shape` style and apply effects in the same atomic batch: a refused paint leaves no object and no undo step. Group edits with `command_batch {atomic: true}` so one undo step is recorded. Get exact ids/params from `commands`/`list_commands` — unknown param keys are rejected with a did-you-mean before anything runs.
+ - **Use the newest commands:** `pathfinder.trap` for print traps, `select.globalEdit` for appearance/size-matched edits, `window.symbolLibrary` / `ui.saveSymbolLibrary` for symbol libraries, `artboard.setProps {showCenterMark|showCrossHairs|showVideoSafeAreas}` for canvas-only artboard guides, `type.ruby` for furigana, `effect.lightingPreset` after a 3D effect, `paint.editGradient {method: "perceptual"}` / `{dither: true}` for print-safe ramps (SVG/PDF rasterise those fills), and `ui.effectGalleryDialog` + `ui.dialog.set {field: "stack", value: [...]}` + `ui.dialog.confirm` to apply a stack of raster filters in one undo step (live app only).
+ - **Prepare inputs for the app:** SVG (cleanest interchange), PDF, EPS, DXF, PNG/JPEG/WebP/TIFF/BMP/Targa, PSD/PSB merged images, CSV/TSV for graphs and Variables data sets, `.rtf`/`.docx` for area type. Fonts: `text.addFontFiles` copies files into the app's Fonts folder; Japanese/Chinese/Arabic faces also come from the optional craft-fonts build input (`README.md`). Reusable logic can ship as a `.wasm` plug-in (ABI v1, no imports; `docs/plugins.md`).
+ - **Inspect/repair native files:** `.vectorcraft` is documented, versioned JSON (v4; optional gzip detected by content; unknown keys from newer versions are preserved by save). Prefer `document.save {version: 1|2, compress}` for downgrades over hand-editing; for repairs, open → inspect → command → save, and round-trip verify.
+ - **Verify outputs:** render previews (`render_preview`, `ui.render`, `screenshot`), reopen the export (`app.open`, `vectorcraft-cli info`) and diff warnings; `vectorcraft-cli bench`/`perf` for timings. Never trust a silent export.
+ - **Must NOT:** drive the GUI blind (use control/MCP; `ui.screenshot` needs a presented frame and fails after ~8 s when the screen is locked, the window is minimized or covered; window geometry is not stable across machines); write `.ai` private editing data or Affinity files (not implemented — don't promise them); assume PSD opens with layers; run reference-app scripts (not supported); use Adobe apps to create or verify anything (repo clean-room rule; produce test art in-repo instead, `AGENTS.md`).
## Verification protocol
Alpha software: verify by round-trip, never by assumption.
- 1. **Throwaway round-trip test** before any real job: new document → one edit per feature you plan to use (including ruby, emoji type, perceptual/dithered gradients and a 3D lighting preset if relevant) → save `.vectorcraft` → export the target format → reopen the export in VectorCraft *and* in the consuming app (browser for SVG, reader for PDF) → compare. Check `warnings` on open **and** export at every step (`convert` returns `importWarnings` beside export warnings).
+ 1. **Throwaway round-trip test** before any real job: new document → one edit per feature you plan to use (including ruby, colour-font type, perceptual/dithered gradients, a 3D lighting preset and a Pathfinder Trap if relevant) → save `.vectorcraft` → export the target format → reopen the export in VectorCraft *and* in the consuming app (browser for SVG, reader for PDF) → compare. Check `warnings` on open **and** export at every step (`convert` returns `importWarnings` beside export warnings).
2. **Master in native, deliver in exchange formats.** Keep the working file as `.vectorcraft` and treat SVG/PDF/EPS/`.ai` as deliverables: formats lose data (PDF-compatible `.ai` carries no Illustrator editing data; legacy v7 loses transparency/effects/names; EPS flattens opacity; DXF approximates gradients/patterns; perceptual/dithered gradients become images in SVG/PDF).
- 3. **Version and back up per session.** Saves are atomic and failed saves keep the old file, but a format conversion rewrites your project — keep a dated copy of the native file. `convert` refuses to overwrite its input when reading it left things out unless `--replace-lossy` is given; take that gate seriously.
- 4. **Pin versions per project.** The launcher auto-updates the app; alpha behaviour changes between releases. Update only between projects, and re-run your round-trip before trusting a pipeline after an update.
- 5. **Guard automation**: run agent sessions with `--automation-read-root/--automation-write-root` (repeatable; both MCP and app), `VECTORCRAFT_CONFIG_DIR` for an isolated profile, and the control port on loopback only while in use (it has no authentication).
- 6. **Reproducible comparisons**: set `SOURCE_DATE_EPOCH` when diffing exported bytes; without it PNG/PDF/EPS/`.ai`/zips/native saves record the wall clock.
+ 3. **Version and back up per session.** Saves are atomic and failed saves keep the old file, but a format conversion rewrites your project — keep a dated copy of the native file. `convert` refuses to overwrite its input when reading it left things out unless `--replace-lossy`; take that gate seriously.
+ 4. **Pin versions per project.** The launcher auto-updates the app; alpha behaviour changes between releases (this skill covers v0.17.0 only — the previous skill covered v0.15.0 and its counts are already stale). Update only between projects, and re-run your round-trip before trusting a pipeline after an update.
+ 5. **Guard automation:** run agent sessions with `--automation-read-root/--automation-write-root` (repeatable; both MCP and app), `VECTORCRAFT_CONFIG_DIR` for an isolated profile, and the control port on loopback only while in use (it has no authentication).
+ 6. **Reproducible comparisons:** set `SOURCE_DATE_EPOCH` when diffing exported bytes; without it PNG/PDF/EPS/`.ai`/zips/native saves record the wall clock.
+ 7. **Re-measure counts, don't trust this file's:** `vectorcraft-cli commands | jq length`, MCP `tools/list`, control `engine.commands` give the live registry for whatever build you actually run.
## Sources & evidence
- - Repo: https://github.com/storytold/vectorcraft — inspected at tag **v0.15.0**, commit `705eda5dc8cb06fb665a7d6e3d32176c25f8742a` ("Release 0.15.0", 2026-10-22), detached worktree, clean tree. Installed app verified as the same release (`vectorcraft 0.15.0`); `CFBundleIdentifier` `ai.storyteller.vectorcraft`.
- - Docs read: `README.md`, `ROADMAP.md`, `AGENTS.md`, `Cargo.toml`, `docs/gaps.md`, `docs/target-app-parity.md`, `docs/file-format-parity.md`, `docs/mcp.md`, `docs/control-protocol.md`, `docs/plugins.md`, `docs/ui-parity.md`, `docs/type-parity.md`, `docs/effects-parity.md`, `docs/localization-parity.md`, `docs/pdf-backend.md`, `docs/three-d.md`, `docs/development.md`, `crates/affinity/README.md`.
- - Code read: `apps/vectorcraft-cli/src/main.rs`, `apps/vectorcraft/src/{main.rs,prefs_dir.rs,profile.rs,automation_args.rs,control_server.rs}`, `crates/mcp/src/{tools.rs,server.rs,resources.rs,prompts.rs}`, `crates/engine/src/cmd/{mod.rs,typecmd.rs,effectcmd.rs,gradient.rs,print.rs,brushsym.rs,variablecmds.rs,scripts.rs,fileio/{mod.rs,save.rs,encode.rs,batch.rs}}`, `crates/engine/src/guard.rs`, `crates/ui-egui/src/{control.rs,menus.rs,state.rs,workspaces.rs}`, `crates/ui-egui/src/panels/`, `crates/ui-egui/src/dialogs/effect_gallery.rs`, `crates/ui-egui/src/i18n/`, `crates/format/src/lib.rs`, `crates/three-d/src/{lib.rs,lights.rs}`, `crates/effects/src/{lib.rs,lighting_presets.rs,group.rs,pixel/}`, `crates/text/src/bitmap.rs`, `crates/tools/src/{catalog.rs,lib.rs}`, `crates/affinity/`, `apps/vectorcraft-web/src/api.rs`.
- - Date: 2026-10-23. Companion file: `evidence.md` (claim → evidence map).
+ - Repo: https://github.com/storytold/vectorcraft — inspected at tag **v0.17.0**, commit `43313f9451de7ab5b909801006b8881458f2bf04` ("Release 0.17.0", 2026-10-25), detached shallow worktree, clean tree. Installed app verified as the same release (`vectorcraft 0.17.0`); `CFBundleIdentifier` `ai.storyteller.vectorcraft`; date of audit **2026-10-26**.
+ - Docs read: `README.md`, `ROADMAP.md`, `AGENTS.md`, `Cargo.toml`, `docs/gaps.md`, `docs/target-app-parity.md`, `docs/file-format-parity.md`, `docs/mcp.md`, `docs/control-protocol.md`, `docs/plugins.md`, `docs/ui-parity.md`, `docs/type-parity.md`, `docs/effects-parity.md`, `docs/localization-parity.md`, `docs/pdf-backend.md`, `docs/three-d.md`, `docs/development.md`, `docs/affinity-validation.md`, `docs/architecture.md`, `docs/windows7.md`, `docs/hardware-parity.md`, `docs/roadmap.md`, `crates/affinity/README.md`.
+ - Code read: `apps/vectorcraft-cli/src/main.rs`, `apps/vectorcraft-cli/src/perf.rs`, `apps/vectorcraft/src/main.rs`, `apps/vectorcraft/src/automation_args.rs`, `apps/vectorcraft/src/control_server.rs`, `apps/vectorcraft/src/prefs_dir.rs`, `apps/vectorcraft/src/profile.rs`, `apps/vectorcraft/src/mac_tablet.rs`, `apps/vectorcraft-web/src/api.rs`, `crates/mcp/src/tools.rs`, `crates/mcp/src/server.rs`, `crates/mcp/src/prompts.rs`, `crates/mcp/src/resources.rs`, `crates/mcp/src/backend.rs`, `crates/engine/src/cmd/mod.rs`, `crates/engine/src/cmd/textstyles.rs`, `crates/engine/src/cmd/layer.rs`, `crates/engine/src/cmd/pathops.rs`, `crates/engine/src/cmd/gradient.rs`, `crates/engine/src/cmd/effectcmd.rs`, `crates/engine/src/cmd/globaledit.rs`, `crates/engine/src/cmd/variablecmds.rs`, `crates/engine/src/cmd/scripts.rs`, `crates/engine/src/cmd/prefscmds.rs`, `crates/engine/src/cmd/fileio/mod.rs`, `crates/engine/src/cmd/fileio/save.rs`, `crates/engine/src/guard.rs`, `crates/ui-egui/src/control.rs`, `crates/ui-egui/src/menus.rs`, `crates/ui-egui/src/panels/mod.rs`, `crates/ui-egui/src/dialogs/effect_gallery.rs`, `crates/ui-egui/src/i18n/`, `crates/format/src/lib.rs`, `crates/doc/src/metadata.rs`, `crates/doc/src/variables.rs`, `crates/effects/src/lib.rs`, `crates/effects/src/group.rs`, `crates/effects/src/trap.rs`, `crates/effects/src/pixel/mod.rs`, `crates/text/src/colr.rs`, `crates/text/src/svg_glyph.rs`, `crates/text/src/bitmap.rs`, `crates/three-d/src/lights.rs`, `crates/tools/src/catalog.rs`, `crates/tools/src/lib.rs`, `crates/plugins/src/manifest.rs`, `crates/scriptcheck/src/`, `crates/pdf/src/export.rs`, `crates/svg/src/export.rs`, `crates/affinity/`.
+ - Method: `git rev-parse HEAD` for the pin; `cmd!`/`tool(`/`UI_COMMANDS` entries and format arrays parsed from source with scripts; docs' dated revision rows (2026-10-23/24) used to locate what changed after v0.15.0, then each change re-verified in code. No build, no test run, no GUI launch; the installed bundle was only read (`Info.plist`, `--version`).
+ - Companion file: `evidence.md` (claim → evidence path → tier).