Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Augani/kael/llms.txt

Use this file to discover all available pages before exploring further.

Kael’s plugin architecture lets you extend any application with isolated, capability-gated components that run either as native child processes or inside a sandboxed WASM runtime. Every plugin is described by a PluginManifest, which declares the plugin’s identity, its execution model, the capabilities it needs from the host, and the UI contribution points it registers (commands, menu items, panels). The host validates manifests before activation and enforces the capability model at runtime through the permission broker.

PluginManifest

PluginManifest is the serializable root of every plugin description. It derives Debug, Clone, PartialEq, serde::Serialize, and serde::Deserialize.
rust
pub struct PluginManifest {
    pub id:              String,
    pub name:            String,
    pub version:         String,
    pub api_version:     String,
    pub description:     Option<String>,
    pub author:          Option<String>,
    pub entry_point:     String,
    pub execution_model: ExecutionModel,
    pub capabilities:    Vec<Capability>,
    pub args:            Vec<String>,
    pub contributions:   Contributions,
}
id
String
required
Plugin identifier. A reverse-DNS style string is recommended (e.g. "com.mycompany.my-plugin"). Must be non-empty.
name
String
required
Human-readable display name. Shown in plugin management UI. Must be non-empty.
version
String
required
Plugin version in semver format (e.g. "1.2.3"). Must be non-empty.
api_version
String
required
The Kael API version this plugin targets. The host may use this to gate compatibility.
description
Option<String>
A short human-readable description of what the plugin does.
author
Option<String>
The plugin author name or contact.
entry_point
String
required
Path to the executable or WASM module that the host launches. Must be non-empty.
execution_model
ExecutionModel
required
How the plugin code is executed. See ExecutionModel.
capabilities
Vec<Capability>
The list of Capability values the plugin requests from the host. The host validates and may prompt the user for high-risk capabilities.
args
Vec<String>
Command-line arguments passed to entry_point at launch. Omitted from serialization when empty.
contributions
Contributions
UI and behavior contribution points the plugin registers. See Contributions.

Parsing

You can deserialize a PluginManifest from JSON or TOML. Both methods call validate() before returning.
rust
// From JSON
let manifest = PluginManifest::from_json(json_str)?;

// From TOML
let manifest = PluginManifest::from_toml(toml_str)?;

// From a file (extension determines format: .json or .toml)
let manifest = PluginManifest::load("plugins/my-plugin/manifest.toml")?;
id            = "com.example.my-plugin"
name          = "My Plugin"
version       = "0.1.0"
api_version   = "1"
entry_point   = "bin/my-plugin"
execution_model = "ExternalProcess"

capabilities = ["ClipboardWrite", "Notification"]

[contributions]
[[contributions.commands]]
id    = "my-plugin.hello"
title = "My Plugin: Say Hello"

validate

rust
pub fn validate(&self) -> Result<()>
Checks that id, name, version, and entry_point are all non-empty. Returns an anyhow::Error with a descriptive message on the first failing field. Called automatically by from_json, from_toml, and load.

high_risk_capabilities

rust
pub fn high_risk_capabilities(&self) -> Vec<Capability>
Returns the subset of capabilities for which Capability::is_high_risk() returns true. Use this at load time to surface a user-facing prompt before granting dangerous permissions.
rust
let manifest = PluginManifest::load("manifest.toml")?;
let risky = manifest.high_risk_capabilities();
if !risky.is_empty() {
    // Show a confirmation dialog listing risky capabilities
}

PluginManifestBuilder

For programmatic manifest creation, use the fluent builder:
rust
let manifest = PluginManifest::builder(
    "com.example.my-plugin",
    "My Plugin",
    "0.1.0",
    "1",
    "bin/my-plugin",
    ExecutionModel::ExternalProcess,
)
.description("Does something useful")
.author("Alice")
.capability(Capability::ClipboardWrite)
.capability(Capability::Notification)
.command(ContributedCommand {
    id:          "my-plugin.hello".into(),
    title:       "Say Hello".into(),
    keybinding:  None,
})
.build()?;
.build() calls validate() and returns Result<PluginManifest>.

ExecutionModel

Controls how the host spawns and isolates the plugin.
rust
pub enum ExecutionModel {
    ExternalProcess,
    Wasm,
}
ExternalProcess
variant
The plugin runs as a separate native OS process. Communication with the host uses typed IPC. This model provides the strongest isolation but has higher startup overhead.
Wasm
variant
The plugin runs inside a sandboxed WASM runtime embedded in the host process. This model has lower startup overhead but depends on your WASM runtime’s sandbox guarantees.
ExternalProcess plugins that request Capability::ShellExecute can execute arbitrary commands on the host OS. Always call high_risk_capabilities() at load time and require explicit user confirmation before granting such capabilities.

Contributions

The Contributions struct groups all UI and behavior extension points a plugin may register.
rust
pub struct Contributions {
    pub commands:        Vec<ContributedCommand>,
    pub menu_items:      Vec<ContributedMenuItem>,
    pub panels:          Vec<ContributedPanel>,
    pub settings_schema: Option<serde_json::Value>,
}

ContributedCommand

A command palette entry contributed by the plugin.
rust
pub struct ContributedCommand {
    pub id:          String,          // unique within the plugin
    pub title:       String,          // display name in the command palette
    pub keybinding:  Option<String>,  // optional keyboard shortcut
}

ContributedMenuItem

A menu item inserted into an application menu.
rust
pub struct ContributedMenuItem {
    pub target_menu: String, // e.g. "file", "edit", "view"
    pub label:       String,
    pub command_id:  String, // references a ContributedCommand.id
}

ContributedPanel

A dockable panel contributed to the workspace.
rust
pub struct ContributedPanel {
    pub id:               String,
    pub title:            String,
    pub default_position: PanelPosition,
}
PanelPosition controls the default dock side:
VariantDescription
LeftDock to the left side of the workspace.
RightDock to the right side of the workspace.
BottomDock to the bottom of the workspace.
FloatingFloat as a separate window or overlay.

settings_schema

An optional serde_json::Value containing a JSON Schema that describes the plugin’s settings object. The host can use this to generate a settings UI or validate user configuration.

Capability

Capability is an enum of explicit grants for dangerous actions. The default for all high-risk capabilities is deny. Plugins declare the capabilities they need in their manifest; the host’s PermissionBroker enforces them at runtime.
rust
pub enum Capability {
    OpenExternalUrl,
    FilesystemRead  { scope: PathScope },
    FilesystemWrite { scope: PathScope },
    ShellExecute,
    ClipboardRead,
    ClipboardWrite,
    Notification,
    Network         { hosts: Vec<String> },
    Microphone,
    Camera,
    ScreenCapture,
}

PathScope

Scopes filesystem capabilities to limit blast radius.
rust
pub enum PathScope {
    AppData,      // restricted to the app's own data directory
    Downloads,    // restricted to the user's downloads directory
    UserSelected, // paths chosen via a platform file dialog
    Any,          // unrestricted (high-risk)
}

High-risk capabilities

Capability::is_high_risk() returns true for:
  • ShellExecute
  • ClipboardRead
  • Network { .. } (any hosts)
  • Camera
  • ScreenCapture
  • FilesystemRead { scope: PathScope::Any }
  • FilesystemWrite { scope: PathScope::Any }
rust
assert!(Capability::ShellExecute.is_high_risk());
assert!(Capability::ClipboardRead.is_high_risk());
assert!(!Capability::Notification.is_high_risk());
assert!(!Capability::OpenExternalUrl.is_high_risk());
FilesystemRead and FilesystemWrite with PathScope::AppData, Downloads, or UserSelected are not considered high-risk, because their scope is bounded by the platform’s sandbox.

ExtensionHost

ExtensionHost manages the lifecycle of all loaded plugins. It maintains an internal HashMap<String, ExtensionInfo> keyed by plugin id.
rust
let mut host = ExtensionHost::new();

// Load from a manifest value
host.load_manifest(manifest)?;

// Load directly from a file
host.load_manifest_path("plugins/my-plugin/manifest.toml")?;

// Activate and associate with a process
host.activate("com.example.my-plugin")?;
host.attach_process("com.example.my-plugin", process_id)?;

// Deactivate
host.deactivate("com.example.my-plugin")?;

// Unload (only allowed when inactive)
host.unload("com.example.my-plugin")?;

ExtensionInfo

The host stores one ExtensionInfo per loaded plugin:
rust
pub struct ExtensionInfo {
    pub manifest:   PluginManifest,
    pub is_active:  bool,
    pub process_id: Option<ProcessId>,
    pub load_path:  Option<PathBuf>,
    pub dev_mode:   bool,
}
is_active
bool
true after activate() or attach_process() has been called and before deactivate().
process_id
Option<ProcessId>
Set by attach_process() when the plugin runs as an ExternalProcess.
dev_mode
bool
When true, the extension was loaded in development mode (the host does not copy it to the extensions directory).
Use load_manifest_with_options(manifest, Some(path), true) during local development so the host resolves assets relative to your workspace rather than an installed location.

Build docs developers (and LLMs) love