mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 11:54:03 +00:00
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.
This commit is contained in:
@@ -88,8 +88,10 @@ USAGE:
|
||||
enforces its own (vectorcraft --control PORT --automation-read-root DIR …).
|
||||
--allow-plugin-grants lets plugin.install's grant and allowHeavy take effect in this session,
|
||||
so whoever sends the commands can give a plug-in the permissions it lists, and a heavy budget,
|
||||
with nobody approving them. Without it they are refused, and a plug-in installs only when a
|
||||
person already approved its hash in the desktop app. It implies --headless.
|
||||
with nobody approving them. Without it they are refused, and a plug-in that lists permissions
|
||||
installs only when its hash is already recorded in grants.json, by a person's approval in the
|
||||
desktop app or by a grant accepted under this flag. A grant accepted under this flag stays
|
||||
recorded and counts as approved in later sessions. It implies --headless.
|
||||
|
||||
vectorcraft-cli run [--in FILE] [--cmd ID [--params JSON] | --commands FILE|-]... [--export FILE]... [--scale N] [--ppi N] [--allow-plugin-grants]
|
||||
Headless batch: open FILE (any readable format) or start a new document, run commands in
|
||||
|
||||
@@ -665,8 +665,8 @@ fn install(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
),
|
||||
));
|
||||
}
|
||||
// A plug-in that lists permissions installs once a person grants them, unless they already
|
||||
// granted this very module all of them.
|
||||
// A plug-in that lists permissions installs once they are granted, unless a grant recorded for
|
||||
// this very module already covers all of them.
|
||||
let m = plugin.manifest();
|
||||
let wanted = m.permissions();
|
||||
if !s.plugin_approved(&plugin) && !grant.as_ref().is_some_and(|g| wanted.iter().all(|w| g.contains(w))) {
|
||||
@@ -976,7 +976,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Install Plug-in",
|
||||
[],
|
||||
None,
|
||||
"{path: a .wasm file (desktop) | dataBase64: the module (+ name?: shown as its source), replace?: bool (true once the user agreed: a module with other bytes than the plug-in installed with its id, or with none installed, one whose id has settings or a cache in the plug-in store, installs only with it, takes that plug-in's place and gets its settings and cache; false: one whose id is installed is refused; left out, the same module installs again), name?: file name (with dataBase64), allowHeavy?: bool (a filter whose manifest asks for a heavy budget, budget \"heavy\" in plugin.inspect, installs only with it), grant?: [permission] (a plug-in whose manifest lists permissions, needsApproval in plugin.inspect, installs only when grant holds every one of them; the grant is recorded with the module's hash and covers only that module, so a module with other bytes needs a new grant even when it lists the same permissions; with a plug-in store attached, only the grants kept there count; a request's allowHeavy and grant are refused unless the session was started with vectorcraft-cli --allow-plugin-grants: in the desktop app a person approves the install, see ui.installPlugin, and a module whose hash a person already approved needs no grant), hash?: string (the module's SHA-256 as plugin.inspect gave it: a module with other bytes is refused)} validate and install a WebAssembly plug-in for this session → its plugin.list entry",
|
||||
"{path: a .wasm file (desktop) | dataBase64: the module (+ name?: shown as its source), replace?: bool (true once the user agreed: a module with other bytes than the plug-in installed with its id, or with none installed, one whose id has settings or a cache in the plug-in store, installs only with it, takes that plug-in's place and gets its settings and cache; false: one whose id is installed is refused; left out, the same module installs again), name?: file name (with dataBase64), allowHeavy?: bool (a filter whose manifest asks for a heavy budget, budget \"heavy\" in plugin.inspect, installs only with it), grant?: [permission] (a plug-in whose manifest lists permissions, needsApproval in plugin.inspect, installs only when grant holds every one of them; the grant is recorded with the module's hash and covers only that module, so a module with other bytes needs a new grant even when it lists the same permissions; with a plug-in store attached, only the grants kept there count; a request's allowHeavy and grant are refused unless the session was started with vectorcraft-cli --allow-plugin-grants: in the desktop app a person approves the install, see ui.installPlugin, and a module whose hash is already recorded, by a person's approval or by a grant accepted under that flag, needs no grant), hash?: string (the module's SHA-256 as plugin.inspect gave it: a module with other bytes is refused)} validate and install a WebAssembly plug-in for this session → its plugin.list entry",
|
||||
always,
|
||||
install
|
||||
),
|
||||
|
||||
+3
-2
@@ -6709,8 +6709,9 @@ needs a person's approval too, and `plugin.install` refuses `grant: [permission]
|
||||
app connected, `ui.installPlugin` opens the approval dialog and returns `{pending: "pluginInstall"}`; `answer_dialog`,
|
||||
`ui.dialog.confirm` and injected input can't confirm it. A `vectorcraft-cli mcp` started with `--allow-plugin-grants`
|
||||
accepts `grant` and `allowHeavy` from any request, in that session only (headless; it can't be combined with
|
||||
`--connect`). Without `--allow-plugin-grants` and without a desktop approval, `plugin.install` returns
|
||||
an error naming the permissions needed. The approval is kept with the module's hash and covers only that module: the
|
||||
`--connect`). Without `--allow-plugin-grants` and without a recorded grant for the module, `plugin.install` returns
|
||||
an error naming the permissions needed. The approval, or a `grant` accepted under the flag, is kept with the module's
|
||||
hash, counts as approved in later sessions and in the desktop app, and covers only that module: the
|
||||
same bytes install again without one, also from a headless session that reads the same `grants.json`, and a module
|
||||
with other bytes has `needsApproval: true` and needs a new one even when it lists the same permissions. `plugin.remove`
|
||||
forgets the approval. A
|
||||
|
||||
+5
-3
@@ -30,7 +30,7 @@ This page is the contract for plug-in authors and the reference for the host (`c
|
||||
| `plugin.list` | `{}` | `{"plugins": [{id, name, version, kind, author, description, params, paramsSchema, effect?, format?, extensions?, budget?, commands?, size, source, api, paintOutput?, permissions, hash, cacheBytes}], "folder": report}` (`api` is the manifest's [plug-in API level](#permissions); `budget: "heavy"` for a [heavy filter](#heavy-filters); `commands` lists its [commands](#commands); `paintOutput: true` marks a [painted live effect](#painted-live-effects); `permissions` lists what it [may do](#permissions), `hash` is the module's SHA-256; `cacheBytes` is the size of its [cache](#settings-and-cache)) |
|
||||
| `plugin.info` | `{"id"}` | One plug-in: the `plugin.list` entry plus `manifest`, `defaults` and `lastError` (a live effect's last failure). |
|
||||
| `plugin.run` | `{"id", "params"?: {…}, "ids"?: [...]}` (plug-in params may also be top-level keys) | Runs an object filter on the selection (or `ids`; an `ids` that is not a list of object ids is an error). One undo step; the result is selected, except the objects it locked or made guides. |
|
||||
| `plugin.install` | `{"path": "/x/y.wasm"}` (desktop) or `{"dataBase64": "…", "name"?}`, `"replace"?: bool`, `"allowHeavy": bool = false`, `"grant"?: [permission]`, `"hash"?: "sha256 hex"` | Validates and installs a module; returns its `plugin.list` entry. The desktop app and `vectorcraft-cli` keep it in the `Plug-ins` folder next to the preferences, so it is installed again after a restart (#2541). A module with other bytes than the plug-in installed with its id, or, with none installed, one whose id has [settings and a cache](#settings-and-cache) in the `Plug-ins` folder, installs only with `replace: true`, once the user agreed; it takes that plug-in's place and gets its settings and cache. The same module installs again without `replace`, and `replace: false` refuses a module whose id is installed. A [heavy filter](#heavy-filters) installs only with `allowHeavy: true`. A plug-in whose manifest lists [permissions](#permissions) installs only when `grant` lists every one of them, unless a person already granted a module with the same SHA-256. A request's `grant` and `allowHeavy` are refused except in a session started with `vectorcraft-cli --allow-plugin-grants`. With `hash`, a module whose SHA-256 differs is refused. |
|
||||
| `plugin.install` | `{"path": "/x/y.wasm"}` (desktop) or `{"dataBase64": "…", "name"?}`, `"replace"?: bool`, `"allowHeavy": bool = false`, `"grant"?: [permission]`, `"hash"?: "sha256 hex"` | Validates and installs a module; returns its `plugin.list` entry. The desktop app and `vectorcraft-cli` keep it in the `Plug-ins` folder next to the preferences, so it is installed again after a restart (#2541). A module with other bytes than the plug-in installed with its id, or, with none installed, one whose id has [settings and a cache](#settings-and-cache) in the `Plug-ins` folder, installs only with `replace: true`, once the user agreed; it takes that plug-in's place and gets its settings and cache. The same module installs again without `replace`, and `replace: false` refuses a module whose id is installed. A [heavy filter](#heavy-filters) installs only with `allowHeavy: true`. A plug-in whose manifest lists [permissions](#permissions) installs only when `grant` lists every one of them, unless a grant is already recorded for a module with the same SHA-256. A request's `grant` and `allowHeavy` are refused except in a session started with `vectorcraft-cli --allow-plugin-grants`. With `hash`, a module whose SHA-256 differs is refused. |
|
||||
| `plugin.inspect` | as `plugin.install`: `{"path"}` or `{"dataBase64", "name"?}` | Validates a module without installing it; returns the `plugin.list` entry it would have, plus `needsApproval` (true when installing it needs a person's approval) and `needsReplace` (true when `plugin.install` needs `replace: true`). |
|
||||
| `plugin.remove` | `{"id"}` | Uninstalls, and deletes it from the `Plug-ins` folder with its [settings and cache](#settings-and-cache). |
|
||||
| `plugin.clearCache` | `{"id"?}` | Deletes every entry in the [cache](#settings-and-cache) of plug-in `id`, or of every installed plug-in; settings stay. Returns `{"cleared": [id], "bytesFreed"}`. |
|
||||
@@ -198,12 +198,14 @@ capability model proposed for PhotoCraft plug-ins
|
||||
Only a person can press its OK: `ui.dialog.confirm`, MCP's `answer_dialog` and injected input (`ui.key`, `ui.click`)
|
||||
are refused and the dialog stays open. Enter confirms it only when OK has the keyboard focus. `ui.dialog.set` can't
|
||||
change what it installs.
|
||||
- `plugin.install` refuses the module, naming the permissions it needs, unless a person already granted this module
|
||||
- `plugin.install` refuses the module, naming the permissions it needs, unless this module already has a recorded grant
|
||||
(`plugin.inspect`'s `needsApproval` tells it beforehand). A request's `grant` is refused too: `plugin.install` takes
|
||||
it only with the approval the dialog gives. A `vectorcraft-cli mcp` or `run` started with `--allow-plugin-grants`
|
||||
takes `grant` and `allowHeavy` from any request; only the person starting the process can set that flag, and it
|
||||
doesn't apply to a running app. Without it, MCP in headless mode and the CLI install a module that lists
|
||||
permissions only when a person approved its hash in the desktop app, which they read from the shared `grants.json`.
|
||||
permissions only when its hash is recorded in the shared `grants.json`. A person's approval in the desktop app
|
||||
records it, and so does a `grant` accepted under `--allow-plugin-grants`. A recorded grant counts as approved in
|
||||
later sessions without the flag and in the desktop app.
|
||||
With `--allow-plugin-grants`, pass `hash` set to the `plugin.inspect` entry's `hash` so that the module installed is
|
||||
the one the user saw.
|
||||
- **Replacing asks first.** When the file is another module than the plug-in installed with its id, or, with none
|
||||
|
||||
Reference in New Issue
Block a user