plugin: add rust pdk template

This commit is contained in:
2026-06-20 14:15:20 +09:00
parent 5f7f81bdde
commit 06287aca40
17 changed files with 859 additions and 37 deletions
@@ -0,0 +1,17 @@
[package]
name = "yoi-rust-component-tool-template"
version = "0.1.0"
edition = "2024"
license = "MIT"
publish = false
[lib]
crate-type = ["cdylib"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
yoi-plugin-pdk = { path = "../../../../crates/plugin-pdk" }
# Future out-of-tree Plugin packages should pin the Yoi revision instead of
# relying on crates.io publication or remote template fetching, for example:
# yoi-plugin-pdk = { git = "https://github.com/example/yoi.git", package = "yoi-plugin-pdk", rev = "<pinned-yoi-revision>" }
@@ -0,0 +1,39 @@
# Rust Component Tool Template
This is the embedded starter template for a Yoi Component Model Tool Plugin written with the first-party Rust PDK.
## What this template demonstrates
- `wasm-component` runtime targeting `yoi:plugin/tool@1.0.0`.
- Guest-side WIT binding generation through the PDK's `wit_bindgen` re-export.
- Typed JSON input parsing through `run_json_tool` via `export_component_tool!`.
- Typed JSON output serialization with `ToolOutput::json`.
- Structured, bounded `ToolError` output for user-visible Tool failures.
The PDK is guest-side only. It does not grant filesystem, network, or environment authority. Host-side Plugin manifests and grants remain the authority boundary for Tool execution and host APIs.
## Checkout/development dependency
Inside the Yoi checkout this template uses a local path dependency:
```toml
yoi-plugin-pdk = { path = "../../../../crates/plugin-pdk" }
```
If this template is copied elsewhere before crates.io publication exists, pin a Yoi source revision instead of fetching an unpinned remote template:
```toml
yoi-plugin-pdk = { git = "https://github.com/example/yoi.git", package = "yoi-plugin-pdk", rev = "<pinned-yoi-revision>" }
```
Crates.io publication, remote template fetching, and `yoi plugin new/check/pack` are intentionally deferred to later authoring-tooling work.
## Next steps
1. Replace package/plugin ids, names, descriptions, and Tool schema.
2. Replace `EchoInput` / `EchoOutput` and `handle_echo` with your Tool logic.
3. Build a component for `wasm32-unknown-unknown` with the Component Model tooling used by your environment.
4. Package `plugin.toml` and `plugin.component.wasm` into a `.yoi-plugin` archive.
5. Use `yoi plugin list` / `yoi plugin show` plus focused runtime tests to inspect and validate the package.
The exact component build/pack command is not part of this template yet because deterministic `yoi plugin new/check/pack` authoring commands are a separate planned Ticket.
@@ -0,0 +1,20 @@
schema_version = 1
id = "example.rust_component_tool"
name = "Rust Component Tool Template"
version = "0.1.0"
surfaces = ["tool"]
permissions = [
{ kind = "surface", surface = "tool" },
{ kind = "tool", name = "example_echo" },
]
[runtime]
kind = "wasm-component"
component = "plugin.component.wasm"
world = "yoi:plugin/tool@1.0.0"
[[tools]]
name = "example_echo"
description = "Echo input text using the Rust PDK."
input_schema = { type = "object", properties = { text = { type = "string" } }, required = ["text"], additionalProperties = false }
external_write = false
@@ -0,0 +1,34 @@
use serde::{Deserialize, Serialize};
use yoi_plugin_pdk::{ToolContext, ToolError, ToolOutput};
yoi_plugin_pdk::wit_bindgen::generate!({
world: "tool",
path: "../../../../resources/plugin/wit",
});
#[derive(Debug, Deserialize)]
struct EchoInput {
text: String,
}
#[derive(Debug, Serialize)]
struct EchoOutput<'a> {
tool: &'a str,
text: String,
}
fn handle_echo(ctx: ToolContext, input: EchoInput) -> Result<ToolOutput, ToolError> {
if input.text.trim().is_empty() {
return Err(ToolError::invalid_input("`text` must not be empty"));
}
ToolOutput::json(
format!("{} echoed text", ctx.tool_name()),
EchoOutput {
tool: ctx.tool_name(),
text: input.text,
},
)
}
yoi_plugin_pdk::export_component_tool!(Plugin, handle_echo);