mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 10:27:00 -06:00
M7: WASM plugins (#101)
Sandboxed WebAssembly plugins whose API is the command registry: - figcraft-plugin (new crate, L2): the figcraft-plugin.json manifest (menu commands with parameters, read/write access, command allowlist) and the sandbox: wasmi (pure Rust, no JIT, also in the web build) with fuel metering, a memory cap, no WASI and seven host functions (call, selection, reply_len, reply_read, log, notify, set_output). - Engine: plugin.list / plugin.import / plugin.remove / plugin.run, plugins.runLast (Alt+Cmd+P; Ctrl+Alt+Shift+P on Windows/Linux) and plugins.manage. A run is one undo step (Session::grouped, which command.batch now uses too) and is rolled back when it fails. Files, other documents, the undo history, dialogs and plugins are off limits; read-only plugins can't change the document. Installed plugins live in the preferences; development plugins re-read their module every run. - UI: installed plugins in the Plugins menu, a parameters form drawn from the manifest, Manage plugins, Plugins > Development > Import plugin from manifest. - plugins/: a no_std Rust SDK and two example plugins (Tidy names, Swatch grid), built for wasm32 by `cargo xtask plugins` (part of `cargo xtask wasm`). - Docs: docs/plugins.md (manifest, permissions, limits, ABI, SDK), docs/mcp.md, docs/control-protocol.md, README, ROADMAP, parity. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+13
@@ -477,6 +477,19 @@ closing or saving a version ends the preview first, and `version.list` marks the
|
||||
has unsaved changes since its last version; the app runs it every 30 minutes for each open document,
|
||||
and a file keeps the newest 20 autosaves (user versions are never dropped for them). `file.versionHistory` returns the same list and opens the panel in the app.
|
||||
|
||||
### Plugins
|
||||
|
||||
Sandboxed WebAssembly plugins act through the same commands (see [`plugins.md`](plugins.md) for the
|
||||
manifest, the ABI and the Rust SDK). Driven with `run_command`: `plugin.import {path}` (a
|
||||
`figcraft-plugin.json` or its folder) or `plugin.import {manifest, wasm}` (the manifest as an
|
||||
object or JSON text and the module as base64, for this session only), `plugin.list`,
|
||||
`plugin.remove {id}`, and `plugin.run {id, command?, params?, fuel?}`, which returns
|
||||
`{plugin, command, output, logs, calls, fuel}`. A run is one undo step and is rolled back when it
|
||||
fails; a plugin only reads the document unless its manifest asks for `write`, may be limited to
|
||||
some commands, and can never touch files, other documents, the undo history, dialogs or other
|
||||
plugins. A headless MCP session starts with no plugins: import them first. `plugins.runLast` runs
|
||||
the last plugin command again.
|
||||
|
||||
### Dev Mode
|
||||
|
||||
- **Component code:** `inspect.code {id, language: react|swiftui|compose}` on a component, a
|
||||
|
||||
Reference in New Issue
Block a user