Commit Graph
3858 Commits
Author SHA1 Message Date
dotCooCoo 00624da7ad MCP: preferences replies leave out folders outside the read roots
Under --automation-read-root, prefs.get, prefs.list, prefs.set and
prefs.reset returned the folder preferences (fontsFolder, pluginsFolder,
scratchPrimary, scratchSecondary, recoveryFolder, templatesFolder) and
the export presets' folder even when they were outside the read roots.
Such a folder preference is now null, as ui.inspect leaves it out, and
such a preset's folder is left out. An empty folder and the scratch disk
choices stay; without roots the replies are unchanged.
2026-11-11 22:13:53 -08:00
dotCooCoo d69e9c10d7 Brushes: Alt-drag art onto a brush to replace its art
Art Alt-dragged (Option-dragged on macOS) from the canvas onto a
scatter, art or pattern brush in the Brushes panel becomes its art
(brush.replaceArt). When strokes use the brush, the app checks the art
first, then a dialog offers Apply to Strokes, which redraws them with
the new art, Leave Strokes, which keeps the brush and its strokes as
they were and adds "<name> copy" with the new art as the current brush,
and Cancel. Each change is one undo step.

A pattern brush takes back the tile groups brush.placeArt places, frames
included, and takes other art as its side tile. Calligraphic and
bristle brushes, an empty selection and art with no width are refused.

Art Alt-dragged off the canvas now reaches the panels as the art the
drag started with. Before, the panels got the ids of the copy the drag
previews, which no longer exist once the release over a panel ends the
move.

brush.new now also measures a symbol instance in the selected art by its
symbol's art when it checks that the art has width.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 22:11:17 -08:00
dotCooCoo bcc9901419 Brushes: drag a brush onto the canvas to place a copy of its art
A scatter, art or pattern brush dragged from the Brushes panel onto an
empty part of the canvas places a copy of its art there to edit,
centered where it is dropped (brush.placeArt). Dropped on a path, a
brush is still applied to it. A pattern brush is placed as its tiles in
a row, 10 pt apart, each in a group named for its tile, with an
unpainted rectangle at the back of a tile that has a repeat frame.
Calligraphic and bristle brushes have no art and are refused. A symbol
instance in the art is measured by its symbol's art.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 22:09:58 -08:00
dotCooCoo 5be501e47f DXF: an open path's fill outline is closed, as the fill is
A filled open path wrote its outline as an open polyline, so with fill
hatches left out (and in R12, and in CNC / CAM) the area lost its closing
edge. Fill outlines now close each open subpath that can enclose an area;
strokes of the same path stay open.
2026-11-11 22:09:14 -08:00
dotCooCoo a755082607 MCP: an error from Export for Screens into a preset folder outside the read roots names that folder by its name
document.exportForScreens without a folder writes into the folder its
exportPreset keeps. When that folder is outside the client's read roots
and the export fails, for example because the folder is also outside the
write roots, the error now names the folder by its name, as the reply of
a successful export leaves it out. A granted root in the same message
stays whole, and a folder the client gives stays whole in the error.
2026-11-11 22:06:52 -08:00
dotCooCoo c6ea02c114 Merge main into feat/styles-painted-sketched-library 2026-11-11 22:03:33 -08:00
dotCooCoo 7222f43ecb Merge main into feat/e4x-xml-xpath 2026-11-11 22:03:32 -08:00
dotCooCoo 56f9b6181e Merge main into fix/e4x-scope-name-assign 2026-11-11 22:03:32 -08:00
dotCooCoo 1eb02f2f7a Merge main into fix/plugin-ignored-grants-shared 2026-11-11 22:03:31 -08:00
dotCooCoo 00b53a3222 Merge main into feat/dynamic-text-release-path 2026-11-11 22:03:30 -08:00
dotCooCoo 512627b39f Docs: the DXF CNC / CAM preset is listed as shipped
docs/gaps.md, docs/file-format-parity.md and docs/ui-parity.md still
listed the CNC preset as open after #5500 added it. They now name DXF
Options' Preset menu and dxfPreset: "cnc" on document.exportDxf; VCarve
QA stays open. The ui-parity row also no longer lists native CIRCLE/ARC
export as pending.
2026-11-11 21:59:27 -08:00
dotCooCoo ad05c3b99d Plug-ins: an install that automation asked for is not approved in its dialog
An approval question that a control request, MCP, injected input, or a
file dialog one of them opened leads to now keeps OK disabled and
refuses every confirm, a person's click included. The dialog says to
choose Object › Plug-ins › Install Plug-in…, and ui.installPlugin answers
approval: "personMustStartInstall". The person's own Install Plug-in…,
File › Open or drop inspects the module again and asks a new question
with its half-second delay.

The origin is fixed when the request is made and goes with a native
file dialog's deferred answer and the web picker's answers, which now
arrive apart from drops and from window.vectorcraft.openFile (always
automation). A question about taking another module's place now opens
in the approval dialog, and automation's replace: true no longer skips
it. A module that needs no approval still installs at once.
2026-11-11 21:56:58 -08:00
dotCooCoo c74821031e MCP: hidden library names follow the platform's path rules
- Outside Windows a `\` stays part of a hidden library's or sent path's
  file name; another platform's absolute path is still split on `\`.
- A hidden relative path is matched after leading `./` and `../` parts
  only when they start the path, so `/work/./data/icon.svg` keeps its
  text.
- `ui.inspect` and `ui.docking` replies are hidden once, so a library
  at the top of the file system shows as `loaded/<file name>` with its
  separator.
2026-11-11 21:56:02 -08:00
dotCooCoo c02f95aa31 Type: Convert To Point Type turns Dynamic Text off, keeping the sizes Block set
Convert To Point Type left Dynamic Text on when it turned Block area
type into point type. Point type has no Dynamic Text, but the flag was
saved, and converting the type back to area type turned Block on again
and fitted the lines to the new frame. The conversion now turns it off;
the point type keeps the sizes and leading Block wrote into the
characters, and the conversion is still one undo step.
2026-11-11 21:52:24 -08:00
dotCooCoo ae587e459f Docs: the File formats row lists DXF export's image and hatch options 2026-11-11 21:52:17 -08:00
dotCooCoo 283e1267f6 Script checker: names with escaped characters are read as names
- A name may hold \u{...} escapes with any number of hexadecimal digits
  up to U+10FFFF. An empty, unclosed, out-of-range or surrogate escape is
  not part of a name. Each \u{...} escape read in a name is reported as
  syntax newer than ES3, with the escape as written.
- # followed by an escaped name start is one private name, also in the
  code of an XML literal, and its escapes are read in the report
  (this.#app is #app).
- A # and a name at the start of a line is a private name, not a
  directive, when the name starts with an escape, or when the line is
  inside braces and the name is not a directive's. A private name whose
  decoded name would make the line a directive is reported as written.
- The identifier test against vectorcraft-js also compares braced
  escapes.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 21:50:55 -08:00
BFlat 485d4e3fff Merge pull request #6747 from dotCooCoo/fix/plugin-grant-sealed-api
Plug-ins: only an approval records a grant, and installs need one
2026-11-12 12:41:15 +07:00
BFlat a8ac772c53 Merge pull request #6753 from dotCooCoo/feat/pixel-align-new-objects
Transform: Align New Objects to Pixel Grid makes new paths pixel-aligned
2026-11-12 12:41:07 +07:00
dotCooCoo aeeb90e60c Save and Export: the hover's note list states its limits
The hover lists up to 30 notes, fewer when the window is small, and says how many were left out. The docs and command description said it lists them all.
2026-11-11 21:41:04 -08:00
BFlat 7e27e6e4c9 Merge pull request #6761 from dotCooCoo/feat/dynamic-text-path-presets
Type: Dynamic Text Presets put type on a circle, arch or bow
2026-11-12 12:40:55 +07:00
BFlat 4eb0915795 Merge pull request #6781 from dotCooCoo/feat/diamond-gradient
Gradients: diamond gradients run the stops from the center out to a square
2026-11-12 12:40:46 +07:00
BFlat 247f9e1569 Merge pull request #6763 from dotCooCoo/feat/styles-textures-library
Graphic Styles: built-in Textures library with grain, canvas, craquelure and tile styles
2026-11-12 12:40:38 +07:00
BFlat 105536fff4 Merge pull request #6765 from dotCooCoo/fix/js-finally-sites-gc-test
Scripts: a finally block left early drops its saved throw site
2026-11-12 12:40:29 +07:00
BFlat df41593465 Merge pull request #6772 from dotCooCoo/fix/e4x-xml-declaration-check
Scripts: E4X checks the XML declaration and takes fuel for every run the parser scans
2026-11-12 12:40:21 +07:00
BFlat 63bdfc1655 Merge pull request #6758 from dotCooCoo/test/select-skips-raster-effects
Selection: a click on a drop shadow or glow selects the object under it
2026-11-12 12:40:12 +07:00
BFlat 1f1e7354ea Merge pull request #6780 from dotCooCoo/fix/action-batch-param-types
Actions: Batch refuses options of the wrong type before it writes
2026-11-12 12:39:54 +07:00
BFlat fee2b1340a Merge pull request #6773 from dotCooCoo/perf/flatten-opaque-chain
Flatten Transparency: opaque art that touches only opaque art stays vector
2026-11-12 12:39:46 +07:00
BFlat 72adc36f55 Merge pull request #6767 from dotCooCoo/feat/document-setup-color
Document Setup: a Color tab sets the color mode and the assigned profiles
2026-11-12 12:39:38 +07:00
dotCooCoo 9fc4e3c5cf Swatch libraries: Patterns › Grit Textures adds seamless grain, speckle and stipple patterns
Window › Swatch Libraries › Patterns and the Swatches panel's library
menu gain a second built-in pattern library, Grit Textures, with eight
black textures on square grid tiles of 18 to 36 pt: Fine Grain, Coarse
Grit, Sand, Speckle, Stipple, Scratches, Sparse Flecks and Dense Flecks.
Each is drawn in code from a fixed seed, so it is the same every time.
Marks that reach past a tile edge are drawn on the next tile by the
tiling, so the tiles join without a seam.

Docs: docs/mcp.md, docs/target-app-parity.md, ROADMAP.
2026-11-11 21:30:00 -08:00
dotCooCoo 1e70274189 Swatch libraries: Gradients › Organic Fades adds soft multi-stop fades that thin out to transparent
Window › Swatch Libraries › Gradients gains Organic Fades, a gradient
library of fifteen fades (ten linear, five radial). Each runs through
three to five unevenly spaced stops with off-center midpoints, mixes
with the Perceptual method, and thins out to transparent at the end of
a linear fade or at the edge of a radial one. The colors are computed
from VectorCraft's own OKLCH anchors.

The library also lists in the Swatches panel's library menu, in
swatch.library.list (category "gradients") and in the Gradient panel's
Presets. swatch.library.add keeps each fade's stops, opacities,
midpoints and method in RGB and CMYK documents.

The other built-in libraries are unchanged: their gradients still mix
with Classic and keep centered midpoints, and a test checks it.

- Gradient previews in the Swatch Libraries panel, the Gradient
  panel's Presets menu, swatch tiles and the toolbar drew every stop
  opaque. Each chip vertex now takes the sampled opacity as its alpha
  (freeform points too), and a chip with any translucent vertex draws
  a white and gray checkerboard under the gradient. Opaque gradients
  draw as before.
- When the preferences are applied, a saved gradient preset whose name
  matches a built-in preset, or an earlier saved preset, in any case,
  is renamed to the first free "<name> N" (N from 2), so a saved
  preset named like a new built-in fade stays listed and can be
  applied and deleted.
2026-11-11 21:26:11 -08:00
dotCooCoo 832fad16e0 Merge main into feat/hang-report 2026-11-11 21:17:30 -08:00
dotCooCoo f82a31045c Blend: the Blend panel's Create Spine menu sets whether new blends get a spine
The Blend panel gets a Create Spine menu (Auto, Always, Never) under Make,
and object.blend.createSpine {mode?} sets or reads it. It is kept with the
preferences, is not an undo step and leaves blends already made as they are.
object.blend.make takes createSpine to choose for one new blend.

Auto and Always give every new blend a straight spine, as before. Never
makes a blend without one: its steps sit where a straight spine puts them,
object.blend.info reports hasSpine: false, easing is refused and dimmed,
Reverse Spine and the spine point commands refuse it, Release gives back
no spine path, and Replace Spine gives it a spine. A blend taking more keys
keeps whether it has a spine. Native files save noSpine; older files open
with their spines.

Builds on #5177 by adambelis.
2026-11-11 21:11:12 -08:00
dotCooCoo c4ace05dbf Graphic Styles: a built-in Painted and Sketched library adds watercolor, charcoal and ink styles
The Graphic Styles library menu lists nine libraries. Painted and
Sketched follows Hand-Drawn and holds Washed Blue, Bristle Ochre,
Pastel Heather, Charcoal Shade, Ink Contour, Wet Ink and Fine Pen. Each
style is a solid fill, two with a 1 pt stroke, under one watercolor,
dry brush, rough pastels, charcoal, ink outlines, sumi-e or graphic pen
effect with every setting given. The library and style names have rows
in all 27 catalogs, and docs/mcp.md describes the library.
2026-11-11 21:11:09 -08:00
dotCooCoo f1251af6e4 DXF: export options leave placed images and fill hatches out, and CNC / CAM turns both off
DXF Options gets Include Placed Images and Include Fill Hatches, and
document.exportDxf and document.export {format: dxf} take
includeImages and includeHatches. Both are VectorCraft's own options
and default to true, so Custom exports write what they wrote before.

- includeImages: false writes no IMAGE entity, IMAGEDEF, reactor or
  linked file for a placed image, and does not decode its pixels.
- includeHatches: false writes each filled area's outlines without the
  solid HATCH after them.
- Each adds one note to warnings when it left something out. R12,
  which has neither, keeps its own notes.
- The CNC / CAM preset sets both to false, so its drawing holds the
  cutting paths alone; the options given still override it, and
  changing either checkbox shows Custom.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 21:10:30 -08:00
dotCooCoo e83c36785e Commands: pointer events refuse pen values and spaces of the wrong type
ui.pointer and the headless pointer call read a pointer event's pressure,
holdMs, tiltX, tiltY and rotation with a default for any value that was not a
number, and treated any space other than screen as document space. Each event
is now checked before the packet runs: those values must be numbers and space
must be doc or screen, with null keeping the default. docs/mcp.md says so.
2026-11-11 21:04:01 -08:00
dotCooCoo 2f7c3854c7 Merge main into fix/script-sleep-reads-doc-cancel
# Conflicts:
#	docs/target-app-parity.md
2026-11-11 21:01:53 -08:00
dotCooCoo f526c5310c JS: XML and XMLList xpath evaluates XPath 1.0 expressions
xml.xpath(expression[, variables]) evaluates an XPath 1.0 expression
(https://www.w3.org/TR/1999/REC-xpath-19991116/) with the XML value as
the context node and returns the selected nodes as an XMLList, in
document order and without repeats. On an XMLList the expression runs
on each element in turn, and the results are joined.

- All 13 axes and the 27 core functions. id() selects nothing, since
  E4X trees carry no DTD data.
- Each property of `variables` binds the variable of its name. A
  prefix in a name test resolves through the context element's
  in-scope namespaces; `xml` is always bound.
- An expression that breaks the grammar gives a SyntaxError. An
  unknown function, a wrong argument count, an unbound prefix or
  variable, a result that is not a node-set, and a result that holds
  the root or a namespace node give a TypeError.
- The parser and the evaluator keep their state on their own stacks,
  so expressions of any depth use no native stack; nesting past
  Options::max_depth gives "nesting too deep". Traversal stacks, node
  lists, strings and the values that string functions build count
  against the heap limit, and every node visited and string read takes
  fuel.

Docs: docs/target-app-parity.md (E4X line), crate doc in lib.rs.
2026-11-11 21:01:32 -08:00
dotCooCoo 8e6a9e5b71 Merge main into fix/inspect-library-ids-whole 2026-11-11 20:54:59 -08:00
dotCooCoo 651041fc0c Merge main into fix/options-dialog-menus
# Conflicts:
#	docs/mcp.md
2026-11-11 20:48:58 -08:00
makesomethingshit 88894ef27c Merge latest main and retain Live Paint and Eyedropper evidence 2026-11-12 13:48:23 +09:00
dotCooCoo 35be7952c8 Save and Export: the status bar's hover lists every note
A save or an export with several notes named only the first of them in
the status bar, with the count, and the others could not be seen. The
status bar now keeps every note of a save or an export for the status
message's hover, as it does for an open's notes since #6752: resting
the pointer on the message lists them in the order the reply gives them
(a save's notes start with what the format loses), and screen readers
receive the list after the message. The status text is unchanged.

This covers Save, Save As, Save a Copy, Save as Template, Save a
Timestamped Copy, Save as PDF, Export As, Export Selection, Export for
Screens, Asset Export, Save for Web, Preview in Browser, Save for Office
Documents, Text Export Options, a print to a file and the CSS Properties
panel's export. The open, the saves and the exports read a reply's notes
through one helper.

Docs: docs/mcp.md and the css.exportFile params text,
docs/control-protocol.md, docs/target-app-parity.md.
2026-11-11 20:44:53 -08:00
BFlat aa4657e1ce Merge pull request #6704 from dotCooCoo/fix/shape-tool-handles-scale
Shape tools: a drag on a bounding-box handle scales the selection
2026-11-12 11:43:06 +07:00
dotCooCoo cd262fa6e8 MCP: save, export and package replies leave out paths outside a confined client's read roots
A client confined with --automation-read-root could learn paths it was
not given and may not read from the replies of several commands. Each
one now names such a path only when no read roots are in force or the
path is inside them:

- document.save and file.save, file.saveAs, file.saveCopy and
  file.saveAsTemplate (app.save and engine.execute) without a path:
  the document's own file, the files of separate artboards and linked
  files are left out or named by file name, and the folder a save
  suggests is left out.
- document.exportForScreens with the folder of an exportPreset: the
  ZIP path is left out and files are relative to that folder.
- document.exportSettings, document.exportPresets.list and
  document.exportPresets.export: a kept folder outside the read roots
  is left out of the reply and of the presets file the export writes.
- file.package: warnings, missingLinks and the report name a file
  outside the read roots by its file name. A link's stored path, read
  from the document's folder when it is relative, decides, also when
  its file was found under another path.
- document.info: an image linked to a file outside the read roots has
  link null, and its Linked Images row names the file alone.

docs/mcp.md and the params text describe the rule.
2026-11-11 20:42:57 -08:00
BFlat dec6717379 Merge pull request #6726 from dotCooCoo/feat/hpgl-import
File formats: HP-GL (.plt) plot files open and place
2026-11-12 11:42:46 +07:00
BFlat b93b6d6a4f Merge pull request #6729 from dotCooCoo/feat/control-bar-align-to
Control bar: an Align To menu follows the Align buttons
2026-11-12 11:42:38 +07:00
BFlat b945662f75 Merge pull request #6700 from dotCooCoo/fix/script-files-followups
Scripts: File and Folder exists checks the kind, encode keeps slashes, every call is counted
2026-11-12 11:42:26 +07:00
BFlat 3baa943174 Merge pull request #6693 from dotCooCoo/fix/pdfa-14-long-pages
PDF: a PDF/A-2b file at PDF 1.4 writes long pages as PDF 1.6 with a UserUnit
2026-11-12 11:42:17 +07:00
BFlat cd92345707 Merge pull request #6759 from dotCooCoo/fix/js-tosource-property-flags
Scripts: toSource refuses read-only, non-configurable and non-extensible data it cannot write back
2026-11-12 11:42:09 +07:00
BFlat d843a4f1ec Merge pull request #6670 from dotCooCoo/fix/plugin-put-back-result
Plug-ins: an update left in the store by a failed put-back turns a disabled plug-in on
2026-11-12 11:42:01 +07:00
BFlat 5e181e2aec Merge pull request #6699 from dotCooCoo/fix/links-read-roots
MCP: links.list, links.check, links.info and document.open leave out paths outside the read roots
2026-11-12 11:41:52 +07:00