Commit Graph
85 Commits
Author SHA1 Message Date
dotCooCoo 811c21e7c2 Plug-ins: calls need doc.read, and an edit in progress is kept before a calling run
A command's result describes the document, so a plug-in without doc.read
gets -6 for every call, whether or not the id names a command. A run that
calls commands commits an edit still in progress first and prepares its
input again when that changed the document or the selection.
2026-11-10 11:26:10 -08:00
dotCooCoo f921a6923d Plug-ins: an API level 2 plug-in calls the commands its manifest lists
A filter at plug-in API level 2 with the new `commands` permission names
the commands it may run in its manifest's `commandAllowlist` and runs
them with `env.vc_call`, reading each result with `env.vc_call_result`.
Each call runs through Session::execute on the run's document and sees
what earlier calls changed; the calls and the filter's output are one
undo step, and a run that fails, is cancelled or makes a failed call
leaves the documents, their history and the session state the commands
change as they were.

Commands that touch files, the clipboard, preferences, the view,
scripts, actions, plug-ins, open documents or the undo history are never
callable, and every other command must be listed as allowed in
cmd/plugin_call/reviewed.rs, so a new command is refused until placed.
Calls are capped at 1,000 a run, 8 MiB a call and 64 MiB a run, and each
costs instructions from the run's budget. plugin.install refuses a
manifest that lists a refused command and reports unknown ids;
plugin.inspect lists both, and the approval dialog lists the commands.

Refs #2186
2026-11-10 10:16:28 -08:00
dotCooCoo f688129ef2 Merge main into feat/command-param-schemas 2026-11-09 12:34:02 -08:00
dotCooCoo eebbe496d4 Merge main into fix/plugin-grant-app-approval 2026-11-08 23:53:57 -08:00
BFlat 0f2857e1a1 Merge pull request #6286 from dotCooCoo/fix/plugin-stale-grant
Plug-ins: replacing a granted plug-in with one that lists no permissions removes the grant
2026-11-09 15:41:04 +08:00
dotCooCoo 0efd9a9ccc Merge main into fix/plugin-grant-app-approval 2026-11-08 23:26:53 -08:00
dotCooCoo 65ff9df849 Plug-ins: a grant left behind stops counting when its module can't go back
plugin.install and plugin.remove count an entry of grants.json that this
version can't use when it can't be removed. plugin.install stops counting
a grant it can't remove when the old module can't be written back to the
Plug-ins folder.
2026-11-08 22:00:26 -08:00
dotCooCoo 7177438feb Plug-ins: plugin.install's params text and docs/mcp.md state when a grant is kept
A refused install keeps the grant, a failed write of the module to the
plug-in store leaves the grant in the store, and a stored module that is
disabled or not read in Safe Mode keeps the grant for its id. This
matches docs/plugins.md.
2026-11-08 21:26:13 -08:00
dotCooCoo 9ae57b03c0 Plug-ins: the texts say a grant accepted under the flag stays recorded
A grant accepted under --allow-plugin-grants is written to grants.json like a
person's approval and counts as approved in later sessions and in the desktop
app. The CLI usage text, the plugin.install params text and docs/plugins.md and
docs/mcp.md said only a person's approval in the desktop app records one.
2026-11-08 21:10:26 -08:00
dotCooCoo 0e1aa5cc2e Plug-ins: a filter's read-only objects stay in its input and failed decodes count
A filter run kept a second copy of every read-only object as JSON values.
The run now keeps where each object is in the input, and checks an output
entry against it by parsing that one object, unless the entry is `{"id": …}`
alone.

An image that reaches the decoder now counts toward the 16 MiB pixel total
even when decoding fails, so broken images use up the same total as images
that decode.

The plugin.run text, docs/mcp.md and the progress line state the paint
order and that rule, and docs/plugins.md states that a CMYK image's pixels
are sRGB. New tests cover the per-image 1 MiB, the 16 MiB pixel total and
the 16 MiB text total at and one past their values, memory-budget failures
before the plug-in starts, images that are not decoded, CMYK images
included, and leading per run.
2026-11-08 20:54:02 -08:00
dotCooCoo 9e655ae2e6 Merge main into fix/plugin-stale-grant 2026-11-08 20:38:46 -08:00
dotCooCoo 6cce39dd7f Plug-ins: a grant that can't be removed stops counting for the session
When loading the plug-in store can't remove the grant of an id whose stored
module lists no permissions, or can't read grants.json, the entry stays on
disk and still approved the bytes it covers. plugin.install has the same case
when the grant can't be removed and no earlier module can be put back.

The session now keeps those ids and does not count their grants in
plugin.inspect, plugin.install, plugin.reload or a later load of the store. A
successful update of the grant for the id ends that, and so does attaching a
different store.
2026-11-08 20:38:03 -08:00
dotCooCoo bff7f0ad54 Merge main into fix/plugin-grant-app-approval 2026-11-08 20:16:56 -08:00
dotCooCoo 529dcb5c64 Merge main into feat/plugin-filter-inputs 2026-11-08 19:06:11 -08:00
dotCooCoo 4941b377f9 Merge main into fix/plugin-grant-app-approval 2026-11-08 19:01:49 -08:00
dotCooCoo e1281c0266 Merge main into fix/plugin-stale-grant 2026-11-08 18:59:23 -08:00
dotCooCoo 63a483492b Plug-ins: a grants file that can't be read keeps the grant it may hold
A grants file that can't be opened or read may name the old module once
it reads again. plugin.remove and an install of a module listing no
permissions now fail on it and keep the module. A file over 1 MiB or one
that doesn't hold a list still approves nothing and doesn't stop them.
2026-11-08 18:59:22 -08:00
dotCooCoo bd5ea2a1bf Merge main into feat/plugin-effect-paint 2026-11-08 17:59:33 -08:00
dotCooCoo e82ed4642e Merge main into feat/plugin-filter-inputs 2026-11-08 17:50:28 -08:00
dotCooCoo 969d1cb725 Merge main into fix/plugin-stale-grant 2026-11-08 17:45:48 -08:00
dotCooCoo d6a91b6142 Merge main into feat/plugin-effect-paint 2026-11-08 17:26:35 -08:00
dotCooCoo b79e89de1d Plug-ins: a grant that can't be removed keeps the module it covers
plugin.install of a module that lists no permissions ignored the result
of removing the id's grant. When grants.json could not be updated, the
formerly approved bytes could still be installed without approval. The
store now gets the old module back, so the grant and the module it
covers stay together. The new module stays when the old one can't be
read back and when grants.json can't be read, since such a file approves
nothing. Deleting the last grant now reports a failure.

plugin.remove had the same fault. It now moves the settings and cache
aside and removes the grant before anything is deleted. When the grant
can't be removed, the folder is moved back, the command returns an
error and the plug-in stays installed.
2026-11-08 17:25:09 -08:00
BFlat b652599548 Merge pull request #6264 from dotCooCoo/feat/plugin-importers
Plug-ins: importer plug-ins open file types VectorCraft does not read
2026-11-09 09:24:07 +08:00
dotCooCoo 80558fa273 Merge main into feat/plugin-filter-inputs 2026-11-08 17:09:58 -08:00
dotCooCoo 918ef940cb Merge main into feat/plugin-importers 2026-11-08 16:45:20 -08:00
dotCooCoo 727a611ef7 Merge fix/plugin-grant-module-hash into fix/plugin-grant-app-approval 2026-11-08 16:35:45 -08:00
dotCooCoo efe204bb55 Merge main into feat/plugin-filter-inputs 2026-11-08 16:20:15 -08:00
dotCooCoo 627a40ec36 Merge fix/plugin-grant-module-hash into fix/plugin-grant-app-approval 2026-11-08 16:19:43 -08:00
dotCooCoo 9b0ab19e3a Merge main into fix/plugin-stale-grant 2026-11-08 16:05:50 -08:00
dotCooCoo 9511d24ff6 Merge fix/plugin-grant-module-hash into fix/plugin-stale-grant 2026-11-08 15:56:42 -08:00
dotCooCoo 988da4538a Merge main into fix/plugin-grant-module-hash 2026-11-08 15:55:53 -08:00
dotCooCoo 027dc8894d Plug-ins: a filter run given more read-only objects than an output lists fails up front
An output lists at most 100,000 objects and must return every read-only object, so an input with
more than that many is now an object-budget limit before the plug-in starts.
2026-11-08 15:37:36 -08:00
dotCooCoo 5540a5e797 Plug-ins: an oversized path fails a filter run, and objects that clip stay out of its input
A path or compound path that doesn't fit what is left of the input now fails the run with the
runtime's own "selection is too large to hand over" limit before the rest of the selection is
written, instead of later read-only objects reporting a size error. Objects that clip a clip
group are left out for every filter: compound paths and paths inside a group that clips one
reached filters before, as type, images and symbol instances did.
2026-11-08 15:37:36 -08:00
dotCooCoo 6326d1c4ff Plug-ins: the install comment states what a failed module restore leaves 2026-11-08 15:07:20 -08:00
dotCooCoo 64c7c2703e Merge main into feat/plugin-menu-commands 2026-11-08 14:41:13 -08:00
dotCooCoo 5366b9e323 Merge main into feat/plugin-filter-inputs 2026-11-08 14:19:35 -08:00
dotCooCoo 11703bd350 Merge main into feat/plugin-effect-paint 2026-11-08 12:56:42 -08:00
dotCooCoo a717e34f02 Merge main into fix/plugin-grant-module-hash 2026-11-08 12:55:59 -08:00
dotCooCoo 9518dc0e3a Merge main into feat/plugin-importers 2026-11-08 12:33:17 -08:00
dotCooCoo c396ad104a Plug-ins: an update the store can't take keeps the stored grant 2026-11-08 12:24:12 -08:00
dotCooCoo b33b452539 Plug-ins: an install with invalid params spends its approval 2026-11-08 12:12:57 -08:00
dotCooCoo a224331554 Plug-ins: a failed store write keeps the stored module and its grant together
plugin.install wrote the grant and the module as two separate writes,
and either could fail with only a log record. With a grant tied to the
module's hash, the stored pair then no longer matched and the plug-in
was skipped at the next start.

The module is now written first and its grant only once it is there.
When the grant can't be written, the store gets its old module back, or
loses the new one on a first install, and a disabled plug-in stays
disabled. A stored module that can't be read back is not replaced by
one that needs a grant.
2026-11-08 12:04:03 -08:00
dotCooCoo 218c711181 Plug-ins: a plug-in keeps settings and a cache of its own
Squashed from #6228 onto main.
2026-11-09 02:54:33 +07:00
dotCooCoo 1f38a16329 Commands: an ids list with an entry that is not an id is refused instead of dropping the entry
Squashed from #6179 onto main.
2026-11-09 02:54:32 +07:00
dotCooCoo 1b30f960e6 Merge main into fix/plugin-grant-app-approval 2026-11-08 11:27:11 -08:00
dotCooCoo cb3108a9b4 Plug-ins: a failed store write keeps the stored grant
A module that lists no permissions now removes the grant from grants.json only after it has replaced the stored module. When the write fails, the old module stays stored and keeps the grant it needs at the next launch.
2026-11-08 11:05:25 -08:00
dotCooCoo a4a516e82f Plug-ins: only a person can approve a plug-in's permissions and heavy budget
`plugin.install` accepted `grant` and `allowHeavy` from any client, so
the program installing a plug-in could answer its own permission
prompt.

The desktop app now shows an approval dialog that names the module,
its hash and what it asks for. Confirming it gives the engine a
one-use approval tied to that module id, hash and permission list. A
control or MCP request and a frame of synthetic input cannot confirm
the dialog, and Enter does not confirm it.

Without such an approval, `grant` and `allowHeavy` are refused. The
new `--allow-plugin-grants` flag on `mcp` and `run` lets a person who
starts a headless session accept them from requests. The flag cannot
be combined with `--connect`. A module already approved in the desktop
app still installs through its stored grant.
2026-11-08 11:03:38 -08:00
dotCooCoo 64817c2e8c Merge main into feat/plugin-effect-paint 2026-11-08 10:46:47 -08:00
dotCooCoo 79351d7063 Merge main into feat/plugin-importers 2026-11-08 10:25:28 -08:00
dotCooCoo f2e18da4fa Merge main into fix/plugin-grant-module-hash 2026-11-08 10:25:03 -08:00