Merge main into feat/script-include-directives

This commit is contained in:
dotCooCoo
2026-11-10 22:39:32 -08:00
59 changed files with 1787 additions and 56 deletions
+3 -2
View File
@@ -689,8 +689,9 @@ macOS cursor delivery (#2292) is narrowed to a native host adapter using the exi
## G6 Automation and scripting
- **Missing:** the document object model for scripts, the Scripts folder and script directives (#1183 is
open). File › Scripts › Other Script… and `script.run` run JavaScript files over the command registry, and
- **Missing:** the document object model for scripts and script directives (#1183 is
open). File › Scripts › Other Script… and `script.run` run JavaScript files over the command registry,
File › Scripts lists the scripts of the Scripts folder, and
Window › Script Console shows their output, errors and run reports. Actions, Batch, Variables (text, visibility, image and graph), data set CSV import and
export, and full agent control over MCP are done.
- **Estimate:** 4–8 h.
+49
View File
@@ -1682,6 +1682,55 @@ at the bottom of the panel and in its menu. Output goes on while the panel is cl
vectorcraft-cli run --cmd script.run --params '{"source": "$.writeln(\"layers: \", 3);"}'
```
File › Scripts lists the scripts of the `Scripts` folder next to the preferences: `~/Library/Application
Support/VectorCraft/Scripts` on macOS, `%APPDATA%\VectorCraft\Scripts` on Windows, and
`$XDG_CONFIG_HOME/vectorcraft/Scripts` or `~/.config/vectorcraft/Scripts` on Linux and BSD. VectorCraft does not make
the folder: create it, and put `.js` or `.jsx` files in it. Each file is a menu item named after the file without its
extension, and each subfolder is a submenu that holds the scripts in it. The help page
https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/install-and-run-scripts.html and
the page https://ai-scripting.docsforadobe.dev/introduction/executingScripts/ describe a Scripts folder listed this
way. The listed scripts come first in the menu, above Check Script… and Other Script…. Choosing one runs the file as
`script.run` runs a file, without the warning that Other Script… shows.
The rest of this section is VectorCraft's own rules:
- The folder is read when the app starts, each time its window becomes the active one, and, where the menus are in
the window (Windows, Linux and BSD), each time the File menu opens. A script added while VectorCraft runs is listed
after the next of these. A read takes names only, never a script's text, and runs off the UI thread, one read at a
time.
- Each level is sorted by label without regard to case, with scripts and subfolders mixed. A script whose label
another row of its folder has (`Tidy.js` beside `Tidy.jsx`, or beside a subfolder `Tidy`) shows its whole file name.
- A symbolic link or a Windows junction is never followed: a linked file or subfolder is left out, and a `Scripts`
folder that is itself a link is not read. Names that start with a dot, files and folders Windows marks hidden or
system, names that are not Unicode, names longer than 255 bytes and subfolders without a script are left out too,
and a listed script that is marked hidden or system, or lies in a folder marked so, by the time it is chosen does
not run.
- One read looks at 2,048 folder entries at most, lists 512 scripts and reads 128 subfolders, 4 levels deep, for at
most 250 ms. A label longer than 128 characters is cut, and control and bidirectional formatting characters in a
name are shown as `\u{…}` escapes. When a read stops at a limit or cannot read a subfolder, the menu keeps what it
found and shows `Some scripts were not listed`. The menu also shows that note, and leaves the rows out, when a
read finds new names after the menus have shown 16,384 different script and folder names since VectorCraft started.
When the folder is there and cannot be read, the menu shows
`The Scripts folder cannot be read`.
- A listed file is checked again when it is chosen. A file that is gone, is no longer a `.js` or `.jsx` file under
the folder, or is or lies behind a link ends with `the script is no longer in the Scripts folder`, and nothing runs.
- The web build has no Scripts folder, and neither has a run with `VECTORCRAFT_NO_PREFS` set.
`script.listInstalled {}` returns the same listing: `{folder, scripts: [{path, label, folders}], truncated,
unreadable}`, with the scripts in menu order and `folders` the labels of the subfolders a script is in. `folder` is
`null` without a Scripts folder. `ui.runInstalledScript {path}` runs one of them by the `path` the listing gave, as
its menu item does. Under `--automation-read-root`, `script.listInstalled` lists the folder only when the folder lies
inside a read root, `ui.runInstalledScript` runs a script only when the script lies inside one, and `ui.menu.list`
leaves out the listed scripts outside the read roots.
```json
{"name":"run_command","arguments":{"command":"script.listInstalled","params":{}}}
```
```sh
vectorcraft-cli run --cmd script.listInstalled --params '{}'
```
## Transparency and opacity masks
Transparency and opacity-mask commands take `ids` (or `id`), so they need no selection. Opacity is a percentage
+1
View File
@@ -729,6 +729,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
- Scripts: File › Scripts › Other Script… and `script.run` run a JavaScript file against the open documents as one transaction with one undo step for each changed document. A failed or stopped run puts every document back. `crates/engine/src/tests/script_run.rs`.
- Scripts: Window › Script Console shows each run's `$.write` and `$.writeln` output, `vc.log` entries, uncaught error with the script's name, line and column, and a report of its time, host calls and slowest commands, keeping at most 2,048 lines and counting the lines it dropped. `script.run`'s report carries the same data, and `script.console`, `script.console.clear` and `ui.copyScriptConsole` read, clear and copy it. `crates/engine/src/tests/script_console.rs`.
- Scripts: a run reads its preprocessor lines before any of it runs: `#include` and `//@include` put another file in place of the line, looked for beside the including file, in the `#includepath` folders and in `JSINCLUDE`; `#script` names the run; `#target` and `#strict off` are taken, and `#strict on`, `#targetengine` and `#engine` are refused. `$.evalFile` runs a file with the same globals and returns its last value, and `$.fileName` and `$.includePath` give the file being run and the include folders. A script run from a file reads these files only in its folder and below, without `..` names or links that lead out, and an error in one is reported at its own file, line and column ([preprocessor directives](https://extendscript.docsforadobe.dev/extendscript-tools-features/preprocessor-directives/), [the `$` object](https://extendscript.docsforadobe.dev/extendscript-tools-features/dollar-object/); `crates/engine/src/tests/script_include.rs`).
- Scripts folder: File › Scripts lists the `.js` and `.jsx` files of the `Scripts` folder next to the preferences, each named after its file without the extension, with each subfolder as a submenu, above Check Script… and Other Script… (https://helpx.adobe.com/illustrator/desktop/automate-visualize-data/automate-actions/install-and-run-scripts.html). VectorCraft's own rules: the folder is read again when the window becomes active and when the File menu opens, links are not followed, and one read stops at 2,048 entries, 512 scripts, 128 subfolders, 4 levels or 250 ms. `script.listInstalled` returns the listing. `crates/engine/src/tests/script_folder.rs`, `crates/ui-egui/src/tests/scripts_menu.rs`.
- Parameter keys: the engine refuses a key that a command's params description doesn't name before the command runs, in every build and for every caller, including the app's own calls, the commands a command runs and the steps of `command.batch` and `action.batch`. An action recorded by an older version still plays from the Actions panel and the Batch dialog (`Session::replay`). `crates/engine/tests/it/param_keys.rs`.
- MCP server with 25 tools (drawing, text, effects, Pathfinder, transforms, graphs, text wrap, export, screenshots, any command), attached to the running app or headless. Tool descriptions and replies agree with the engine: format lists come from its format table, `save_file` says it keeps the document's own format, `inspect_document` reports the paint type's characters show, and selection exports report the encoder's warnings. `--automation-read-root` / `--automation-write-root` (on `vectorcraft-cli mcp` and on `vectorcraft --control`) confine the files commands read and write to chosen folders, links followed, with the flags PhotoCraft takes (#832); each flag may be given more than once, a path inside any of its folders being allowed (#3546, `file_access::tests::several_roots_of_a_kind_each_grant_their_access`, `cli::mcp_automation_roots_take_several_folders`). A long export can be cancelled (`notifications/cancelled` stops it at the next page or group and writes nothing), reports page progress to a client that sent a progress token, and does not make other requests wait: engine-free ones answer at once, the rest are refused as busy after two seconds (#2165, #2171, #2172).
- MCP protocol: five prompts (`prompts/list` / `prompts/get`: poster, icon set, recolour, trace-and-style, export set), `completion/complete` for prompt arguments and template variables read from the live catalogues (formats, effect ids, command ids, trace presets, swatch and object ids), four resource templates (`vectorcraft://object/{id}`, `//command/{id}`, `//effect/{id}`, `//swatch/{name}`) so an agent reads one thing instead of the whole document, and `logging/setLevel` with `notifications/message`. `window.panel` ids are case-insensitive (display labels work too), `vectorcraft://object/{id}` reads through `document.node {summary: true}` (the same reply bytes from one lookup instead of summarizing the whole document: a leaf read on a 2,000-object document drops from ~20 ms to ~0.06 ms), large containers slice with `document.node {depth?, childLimit?}` (truncated levels report `childCount`), `document.inspect` and the `inspect_document` tool slice the same way so a depth-0 read is the layer skeleton (~9.7 KB instead of ~2 MB on a 2,000-object document), `document.find` locates nodes by name/kind/text with ancestor paths, and the CLI sweeps the protocol surface over stdio against the compiled binary. `docs/mcp.md` has a Protocol section covering the capability table and what is deliberately absent (subscriptions, progress, cancellation, sampling, elicitation, Streamable HTTP — all of which need the transport to interleave reads).