A grants.json entry this version can't use (a permission it doesn't know,
an invalid id) is now skipped on its own instead of dropping every grant in
the file, and recording or removing a grant writes it back unchanged,
except an entry for that plug-in. A grants.json that is too large, can't be
read or is not a JSON list is left as it is, and a rewrite that would pass
the 1 MiB read limit is written compactly, or not at all.
A manifest may list `permissions` (doc.read, doc.write, state,
effect.render, export.write) and an `api` level. doc.read, doc.write
and state follow the capability model proposed in
storytold/photocraft#662; the other names are VectorCraft's own. An
unknown, reserved, duplicate or wrong-kind name is refused by name. A
manifest without the key gets the permissions its kind implies and
installs as before.
- Install Plug-in... and File > Open show the name, id, version, file
SHA-256 and each permission in plain words, with control and
bidirectional characters escaped and each string cut to 64
characters. OK installs the module only if it still has the SHA-256
shown; Cancel installs nothing. The heavy-budget prompt and the
status line show the escaped name too, and OK keeps the `replace` it
was given.
- `plugin.install` needs `grant` listing every permission, and
`plugin.inspect` reports `needsApproval`. `hash` pins the module:
one with another SHA-256 is refused. The grant is kept with the
module's hash in the store's `grants.json`, and only that store's
grants count while it is attached; the same set does not ask again,
more permissions do, and `plugin.remove` forgets it.
- The Additional Plug-ins Folder and `plugin.reload` install only
plug-ins the attached store has granted and report the others as
needing approval. At startup the store skips an ungranted plug-in.
- A filter run without doc.read is given no objects; without state it
neither reads nor writes `documentData`; without doc.write an output
that changes the document is refused and the document is unchanged.
Docs: docs/plugins.md, docs/mcp.md, docs/target-app-parity.md.
- ui-egui: the font-install poll (#2576) only runs on native builds, but its
timestamp field, its initializer and FONT_INSTALL_POLL were compiled for
wasm too, where nothing read them. They're gated like the code that reads
them.
- engine: `Session::store_profile` is only called by the native Load
Profile (cmd/colormgmt.rs); gated the same way.
- app (macOS): `App::logic_frame` checked `!file_dialog_open()` twice, one
`if` nested in an identical one, with the comment repeated. One check.
`cargo xtask wasm` runs `cargo check` without `-D warnings`, so these
warnings didn't fail CI; after this change it prints none.
Renaming a saved PDF preset (pdf.preset.save with newName) removed
the old file from the PDF Presets folder before it wrote the new one.
When that write failed, for example on a full disk, the folder held no
file for the preset, and the preset was gone at the next start.
The store now writes the new file first and removes the old one only
when that write succeeded. A failed write leaves the preset in the
folder under its old name. A rename that changes only the case of the
name writes the old file and then renames it, and the old file gets
its content back when the rename fails. The command still succeeds
when the folder can't be written, and the failure is logged, as
before.
Install Plug-in (plugin.install) now keeps the plug-in's module in a
Plug-ins folder next to the preferences, as Illustrator keeps plug-ins in
its Plug-ins folder, and the desktop app and vectorcraft-cli install the
ones there at startup (a module that doesn't load is skipped with a log
record, at most 512 MB are read). Remove Plug-in deletes it from the
folder. The Additional Plug-ins Folder preference is still loaded from
where it is. Confined MCP servers and VECTORCRAFT_NO_PREFS keep nothing,
as with the PDF preset and colour profile stores.
Docs: docs/mcp.md, docs/plugins.md, docs/target-app-parity.md.
PDF presets are kept one file each in a PDF Presets folder, ICC profiles as copies in a Color Profiles folder, next to the preferences; the desktop app and vectorcraft-cli use them. Adds color.removeProfile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>