Tracks the platform WIT ABI rename. Plugin world package becomes chain:studio-plugin and host imports chain:platform/host. Crate name stays fai-plugin-sdk (vendor namespace) for now. Signed-off-by: flemming-it <sf@flemming.it>
117 lines
3.7 KiB
Markdown
117 lines
3.7 KiB
Markdown
# fai-plugin-sdk (Rust)
|
|
|
|
Rust SDK for writing F∆I plugins (Studio extensions). One of
|
|
three SDK families documented in
|
|
`fai/platform/docs/architecture/sdks.md`:
|
|
|
|
* `fai-module-sdk` (Rust) — building flow modules
|
|
* `fai-plugin-sdk` (Rust) — building plugins ← this crate
|
|
* `fai-client-sdk` (Dart) — building hub-talking clients
|
|
|
|
Each gets a language-suffix on its dir/repo so polyglot
|
|
variants can be added later without renaming the existing
|
|
ones (e.g. a future `fai-plugin-sdk-go`).
|
|
|
|
## Status
|
|
|
|
**v0.1 builds.** Studio plugins targeting the `studio-plugin`
|
|
world declared in `wit/studio-plugin.wit` can be compiled to
|
|
`wasm32-wasip2` against this crate today. The proof-of-
|
|
contract plugin is `studio-theme-solarized` in the
|
|
fai-plugins namespace.
|
|
|
|
What's NOT yet implemented:
|
|
|
|
- **Hub side**: a Component-Model loader path for
|
|
`studio-plugin`-world components + the `InvokePlugin`
|
|
gRPC RPC that Studio talks to. Tracked in
|
|
`fai/platform/docs/advanced/plugin-sdk.md`.
|
|
- **Studio side**: `plugin_host.dart` that discovers
|
|
installed `studio.*` capabilities and dispatches.
|
|
- **Per-hook worlds**: today's v0.1 ships a single world
|
|
(`studio-plugin`) that exports all three hooks
|
|
(`theme`, `translate`, `output-view`). A plugin only
|
|
caring about one hook still has to declare empty /
|
|
declined impls for the other two. v0.2 splits into one
|
|
world per hook.
|
|
- **`#[plugin(...)]` proc-macro**: v0.1 ships a plain
|
|
`export_plugin!` macro that wraps the wit-bindgen-emitted
|
|
`__export_studio_plugin_impl!`. The proc-macro that
|
|
generates the WIT bindings + the `Guest` impls in one
|
|
pass arrives in v0.2.
|
|
|
|
## Usage
|
|
|
|
```toml
|
|
# Cargo.toml of your plugin
|
|
[package]
|
|
name = "my_studio_plugin"
|
|
version = "0.1.0"
|
|
edition = "2021" # match SDK edition
|
|
|
|
[lib]
|
|
crate-type = ["cdylib"]
|
|
|
|
[dependencies]
|
|
fai-plugin-sdk = { git = "https://git.flemming.ai/fai/plugin-sdk-rust", branch = "main" }
|
|
```
|
|
|
|
```rust
|
|
// src/lib.rs of your plugin
|
|
use fai_plugin_sdk::{bindings, export_plugin};
|
|
|
|
type ColorScheme = bindings::chain::studio_plugin::plugin_types::ColorScheme;
|
|
type PluginError = bindings::chain::studio_plugin::plugin_types::PluginError;
|
|
type RenderedOutput = bindings::chain::studio_plugin::plugin_types::RenderedOutput;
|
|
|
|
struct MyPlugin;
|
|
|
|
impl bindings::exports::chain::studio_plugin::theme::Guest for MyPlugin {
|
|
fn theme_for(brightness: String) -> Result<ColorScheme, PluginError> {
|
|
// Return a ColorScheme or PluginError::Declined.
|
|
}
|
|
}
|
|
|
|
// v0.1: every plugin must declare all three hooks. Plugins
|
|
// that don't actually serve a hook return Declined.
|
|
impl bindings::exports::chain::studio_plugin::translate::Guest for MyPlugin {
|
|
fn translate(_: String, _: String, _: String) -> Result<String, PluginError> {
|
|
Err(PluginError::Declined("not a translate plugin".to_string()))
|
|
}
|
|
}
|
|
impl bindings::exports::chain::studio_plugin::output_view::Guest for MyPlugin {
|
|
fn render(_: String, _: Vec<u8>) -> Result<RenderedOutput, PluginError> {
|
|
Err(PluginError::Declined("not a view plugin".to_string()))
|
|
}
|
|
}
|
|
|
|
export_plugin!(MyPlugin);
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
cargo build --release --target wasm32-wasip2
|
|
fai pack . -o my-plugin-0.1.0.fai
|
|
```
|
|
|
|
## WIT layout
|
|
|
|
```
|
|
wit/
|
|
├── studio-plugin.wit # main world, chain:studio-plugin@0.1.0
|
|
└── deps/
|
|
└── platform/
|
|
└── world.wit # chain:platform@1.0.0 (host imports)
|
|
```
|
|
|
|
Both files are verbatim copies of the authoritative versions
|
|
in `fai/platform/wit/`. When the contract changes upstream,
|
|
re-copy here in lock-step.
|
|
|
|
## Why edition 2021
|
|
|
|
wit-bindgen 0.36 emits `#[link_section]` / unsafe-attribute
|
|
syntax that the edition-2024 compiler rejects. Bump when
|
|
moving to a wit-bindgen version with edition-2024-compatible
|
|
codegen.
|