docs: rewrite sdk-migration and bundles, fold agent-tools into building-plugins, remove cookbook from nav, remove dead WeChat listing
This commit is contained in:
parent
2e0b445b46
commit
483926a6fb
@ -68,6 +68,14 @@
|
||||
"source": "/plugins/building-extensions",
|
||||
"destination": "/plugins/building-plugins"
|
||||
},
|
||||
{
|
||||
"source": "/plugins/agent-tools",
|
||||
"destination": "/plugins/building-plugins#registering-agent-tools"
|
||||
},
|
||||
{
|
||||
"source": "/tools/capability-cookbook",
|
||||
"destination": "/plugins/architecture"
|
||||
},
|
||||
{
|
||||
"source": "/brave-search",
|
||||
"destination": "/tools/brave-search"
|
||||
@ -1033,10 +1041,8 @@
|
||||
"plugins/community",
|
||||
"plugins/bundles",
|
||||
"plugins/manifest",
|
||||
"plugins/agent-tools",
|
||||
"plugins/sdk-migration",
|
||||
"plugins/architecture",
|
||||
"tools/capability-cookbook"
|
||||
"plugins/architecture"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,103 +1,10 @@
|
||||
---
|
||||
summary: "Register custom agent tools in a plugin with schemas, optional opt-in, and allowlists"
|
||||
summary: "Redirects to Building Plugins (registering tools section)"
|
||||
read_when:
|
||||
- You want to add a new agent tool in a plugin
|
||||
- You need to make a tool opt-in via allowlists
|
||||
title: "Registering Tools in Plugins"
|
||||
sidebarTitle: "Registering Tools"
|
||||
- Legacy link to agent-tools
|
||||
title: "Registering Tools"
|
||||
---
|
||||
|
||||
# Registering Tools in Plugins
|
||||
|
||||
Plugins can register **agent tools** — typed functions that the LLM can call
|
||||
during agent runs. Tools can be **required** (always available) or
|
||||
**optional** (users opt in via allowlists).
|
||||
|
||||
See [Building Plugins](/plugins/building-plugins) for the full plugin creation
|
||||
guide. This page focuses on the tool registration API.
|
||||
|
||||
Agent tools are configured under `tools` in the main config, or per‑agent under
|
||||
`agents.list[].tools`. The allowlist/denylist policy controls which tools the agent
|
||||
can call.
|
||||
|
||||
## Basic tool
|
||||
|
||||
```ts
|
||||
import { Type } from "@sinclair/typebox";
|
||||
|
||||
export default function (api) {
|
||||
api.registerTool({
|
||||
name: "my_tool",
|
||||
description: "Do a thing",
|
||||
parameters: Type.Object({
|
||||
input: Type.String(),
|
||||
}),
|
||||
async execute(_id, params) {
|
||||
return { content: [{ type: "text", text: params.input }] };
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Optional tool (opt-in)
|
||||
|
||||
Optional tools are **never** auto‑enabled. Users must add them to an agent
|
||||
allowlist.
|
||||
|
||||
```ts
|
||||
export default function (api) {
|
||||
api.registerTool(
|
||||
{
|
||||
name: "workflow_tool",
|
||||
description: "Run a local workflow",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
pipeline: { type: "string" },
|
||||
},
|
||||
required: ["pipeline"],
|
||||
},
|
||||
async execute(_id, params) {
|
||||
return { content: [{ type: "text", text: params.pipeline }] };
|
||||
},
|
||||
},
|
||||
{ optional: true },
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Enable optional tools in `agents.list[].tools.allow` (or global `tools.allow`):
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "main",
|
||||
tools: {
|
||||
allow: [
|
||||
"workflow_tool", // specific tool name
|
||||
"workflow", // plugin id (enables all tools from that plugin)
|
||||
"group:plugins", // all plugin tools
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Other config knobs that affect tool availability:
|
||||
|
||||
- Allowlists that only name plugin tools are treated as plugin opt-ins; core tools remain
|
||||
enabled unless you also include core tools or groups in the allowlist.
|
||||
- `tools.profile` / `agents.list[].tools.profile` (base allowlist)
|
||||
- `tools.byProvider` / `agents.list[].tools.byProvider` (provider‑specific allow/deny)
|
||||
- `tools.sandbox.tools.*` (sandbox tool policy when sandboxed)
|
||||
|
||||
## Rules + tips
|
||||
|
||||
- Tool names must **not** clash with core tool names; conflicting tools are skipped.
|
||||
- Plugin ids used in allowlists must not clash with core tool names.
|
||||
- Prefer `optional: true` for tools that trigger side effects or require extra
|
||||
binaries/credentials.
|
||||
This page has moved. See [Building Plugins: Registering agent tools](/plugins/building-plugins#registering-agent-tools).
|
||||
|
||||
@ -285,6 +285,58 @@ my-plugin/
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Registering agent tools
|
||||
|
||||
Plugins can register **agent tools** — typed functions the LLM can call. Tools
|
||||
can be required (always available) or optional (users opt in via allowlists).
|
||||
|
||||
```typescript
|
||||
import { Type } from "@sinclair/typebox";
|
||||
|
||||
export default definePluginEntry({
|
||||
id: "my-plugin",
|
||||
name: "My Plugin",
|
||||
register(api) {
|
||||
// Required tool (always available)
|
||||
api.registerTool({
|
||||
name: "my_tool",
|
||||
description: "Do a thing",
|
||||
parameters: Type.Object({ input: Type.String() }),
|
||||
async execute(_id, params) {
|
||||
return { content: [{ type: "text", text: params.input }] };
|
||||
},
|
||||
});
|
||||
|
||||
// Optional tool (user must add to allowlist)
|
||||
api.registerTool(
|
||||
{
|
||||
name: "workflow_tool",
|
||||
description: "Run a workflow",
|
||||
parameters: Type.Object({ pipeline: Type.String() }),
|
||||
async execute(_id, params) {
|
||||
return { content: [{ type: "text", text: params.pipeline }] };
|
||||
},
|
||||
},
|
||||
{ optional: true },
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Enable optional tools in config:
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: { allow: ["workflow_tool"] },
|
||||
}
|
||||
```
|
||||
|
||||
Tips:
|
||||
|
||||
- Tool names must not clash with core tool names (conflicts are skipped)
|
||||
- Use `optional: true` for tools that trigger side effects or require extra binaries
|
||||
- Users can enable all tools from a plugin by adding the plugin id to `tools.allow`
|
||||
|
||||
## Lint enforcement (in-repo plugins)
|
||||
|
||||
Three scripts enforce SDK boundaries for plugins in the OpenClaw repository:
|
||||
|
||||
@ -1,307 +1,181 @@
|
||||
---
|
||||
summary: "Unified bundle format guide for Codex, Claude, and Cursor bundles in OpenClaw"
|
||||
summary: "Install and use Codex, Claude, and Cursor bundles as OpenClaw plugins"
|
||||
read_when:
|
||||
- You want to install or debug a Codex, Claude, or Cursor-compatible bundle
|
||||
- You want to install a Codex, Claude, or Cursor-compatible bundle
|
||||
- You need to understand how OpenClaw maps bundle content into native features
|
||||
- You are documenting bundle compatibility or current support limits
|
||||
- You are debugging bundle detection or missing capabilities
|
||||
title: "Plugin Bundles"
|
||||
---
|
||||
|
||||
# Plugin bundles
|
||||
# Plugin Bundles
|
||||
|
||||
OpenClaw supports one shared class of external plugin package: **bundle
|
||||
plugins**.
|
||||
OpenClaw can install plugins from three external ecosystems: **Codex**, **Claude**,
|
||||
and **Cursor**. These are called **bundles** — content and metadata packs that
|
||||
OpenClaw maps into native features like skills, hooks, and MCP tools.
|
||||
|
||||
Today that means three closely related ecosystems:
|
||||
<Info>
|
||||
Bundles are **not** the same as native OpenClaw plugins. Native plugins run
|
||||
in-process and can register any capability. Bundles are content packs with
|
||||
selective feature mapping and a narrower trust boundary.
|
||||
</Info>
|
||||
|
||||
- Codex bundles
|
||||
- Claude bundles
|
||||
- Cursor bundles
|
||||
## Why bundles exist
|
||||
|
||||
OpenClaw shows all of them as `Format: bundle` in `openclaw plugins list`.
|
||||
Verbose output and `openclaw plugins inspect <id>` also show the subtype
|
||||
(`codex`, `claude`, or `cursor`).
|
||||
Many useful plugins are published in Codex, Claude, or Cursor format. Instead
|
||||
of requiring authors to rewrite them as native OpenClaw plugins, OpenClaw
|
||||
detects these formats and maps their supported content into the native feature
|
||||
set. This means you can install a Claude command pack or a Codex skill bundle
|
||||
and use it immediately.
|
||||
|
||||
Related:
|
||||
## Install a bundle
|
||||
|
||||
- Plugin system overview: [Plugins](/tools/plugin)
|
||||
- CLI install/list flows: [plugins](/cli/plugins)
|
||||
- Native manifest schema: [Plugin manifest](/plugins/manifest)
|
||||
<Steps>
|
||||
<Step title="Install from a directory, archive, or marketplace">
|
||||
```bash
|
||||
# Local directory
|
||||
openclaw plugins install ./my-bundle
|
||||
|
||||
## What a bundle is
|
||||
# Archive
|
||||
openclaw plugins install ./my-bundle.tgz
|
||||
|
||||
A bundle is a **content/metadata pack**, not a native in-process OpenClaw
|
||||
plugin.
|
||||
# Claude marketplace
|
||||
openclaw plugins marketplace list <marketplace-name>
|
||||
openclaw plugins install <plugin-name>@<marketplace-name>
|
||||
```
|
||||
|
||||
Today, OpenClaw does **not** execute bundle runtime code in-process. Instead,
|
||||
it detects known bundle files, reads the metadata, and maps supported bundle
|
||||
content into native OpenClaw surfaces such as skills, hook packs, MCP config,
|
||||
and embedded Pi settings.
|
||||
</Step>
|
||||
|
||||
That is the main trust boundary:
|
||||
<Step title="Verify detection">
|
||||
```bash
|
||||
openclaw plugins list
|
||||
openclaw plugins inspect <id>
|
||||
```
|
||||
|
||||
- native OpenClaw plugin: runtime module executes in-process
|
||||
- bundle: metadata/content pack, with selective feature mapping
|
||||
Bundles show as `Format: bundle` with a subtype of `codex`, `claude`, or `cursor`.
|
||||
|
||||
## Shared bundle model
|
||||
</Step>
|
||||
|
||||
Codex, Claude, and Cursor bundles are similar enough that OpenClaw treats them
|
||||
as one normalized model.
|
||||
<Step title="Restart and use">
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Shared idea:
|
||||
Mapped features (skills, hooks, MCP tools) are available in the next session.
|
||||
|
||||
- a small manifest file, or a default directory layout
|
||||
- one or more content roots such as `skills/` or `commands/`
|
||||
- optional tool/runtime metadata such as MCP, hooks, agents, or LSP
|
||||
- install as a directory or archive, then enable in the normal plugin list
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
Common OpenClaw behavior:
|
||||
## What OpenClaw maps from bundles
|
||||
|
||||
- detect the bundle subtype
|
||||
- normalize it into one internal bundle record
|
||||
- map supported parts into native OpenClaw features
|
||||
- report unsupported parts as detected-but-not-wired capabilities
|
||||
|
||||
In practice, most users do not need to think about the vendor-specific format
|
||||
first. The more useful question is: which bundle surfaces does OpenClaw map
|
||||
today?
|
||||
|
||||
## Detection order
|
||||
|
||||
OpenClaw prefers native OpenClaw plugin/package layouts before bundle handling.
|
||||
|
||||
Practical effect:
|
||||
|
||||
- `openclaw.plugin.json` wins over bundle detection
|
||||
- package installs with valid `package.json` + `openclaw.extensions` use the
|
||||
native install path
|
||||
- if a directory contains both native and bundle metadata, OpenClaw treats it
|
||||
as native first
|
||||
|
||||
That avoids partially installing a dual-format package as a bundle and then
|
||||
loading it later as a native plugin.
|
||||
|
||||
## What works today
|
||||
|
||||
OpenClaw normalizes bundle metadata into one internal bundle record, then maps
|
||||
supported surfaces into existing native behavior.
|
||||
Not every bundle feature runs in OpenClaw today. Here is what works and what
|
||||
is detected but not yet wired.
|
||||
|
||||
### Supported now
|
||||
|
||||
#### Skill content
|
||||
|
||||
- bundle skill roots load as normal OpenClaw skill roots
|
||||
- Claude `commands` roots are treated as additional skill roots
|
||||
- Cursor `.cursor/commands` roots are treated as additional skill roots
|
||||
|
||||
This means Claude markdown command files work through the normal OpenClaw skill
|
||||
loader. Cursor command markdown works through the same path.
|
||||
|
||||
#### Hook packs
|
||||
|
||||
- bundle hook roots work **only** when they use the normal OpenClaw hook-pack
|
||||
layout. Today this is primarily the Codex-compatible case:
|
||||
- `HOOK.md`
|
||||
- `handler.ts` or `handler.js`
|
||||
|
||||
#### MCP for Pi
|
||||
|
||||
- enabled bundles can contribute MCP server config
|
||||
- OpenClaw merges bundle MCP config into the effective embedded Pi settings as
|
||||
`mcpServers`
|
||||
- OpenClaw also exposes supported bundle MCP tools during embedded Pi agent
|
||||
turns by launching supported stdio MCP servers as subprocesses
|
||||
- project-local Pi settings still apply after bundle defaults, so workspace
|
||||
settings can override bundle MCP entries when needed
|
||||
|
||||
#### Embedded Pi settings
|
||||
|
||||
- Claude `settings.json` is imported as default embedded Pi settings when the
|
||||
bundle is enabled
|
||||
- OpenClaw sanitizes shell override keys before applying them
|
||||
|
||||
Sanitized keys:
|
||||
|
||||
- `shellPath`
|
||||
- `shellCommandPrefix`
|
||||
| Feature | How it maps | Applies to |
|
||||
| ------------- | ---------------------------------------------------------------------------------------------------- | -------------- |
|
||||
| Skill content | Bundle skill roots load as normal OpenClaw skills | All formats |
|
||||
| Commands | `commands/` and `.cursor/commands/` treated as skill roots | Claude, Cursor |
|
||||
| Hook packs | OpenClaw-style `HOOK.md` + `handler.ts` layouts | Codex |
|
||||
| MCP tools | Bundle MCP config merged into embedded Pi settings; supported stdio servers launched as subprocesses | All formats |
|
||||
| Settings | Claude `settings.json` imported as embedded Pi defaults | Claude |
|
||||
|
||||
### Detected but not executed
|
||||
|
||||
These surfaces are detected, shown in bundle capabilities, and may appear in
|
||||
diagnostics/info output, but OpenClaw does not run them yet:
|
||||
These are recognized and shown in diagnostics, but OpenClaw does not run them:
|
||||
|
||||
- Claude `agents`
|
||||
- Claude `hooks.json` automation
|
||||
- Claude `lspServers`
|
||||
- Claude `outputStyles`
|
||||
- Cursor `.cursor/agents`
|
||||
- Cursor `.cursor/hooks.json`
|
||||
- Cursor `.cursor/rules`
|
||||
- Claude `agents`, `hooks.json` automation, `lspServers`, `outputStyles`
|
||||
- Cursor `.cursor/agents`, `.cursor/hooks.json`, `.cursor/rules`
|
||||
- Codex inline/app metadata beyond capability reporting
|
||||
|
||||
## Capability reporting
|
||||
## Bundle formats
|
||||
|
||||
`openclaw plugins inspect <id>` shows bundle capabilities from the normalized
|
||||
bundle record.
|
||||
<AccordionGroup>
|
||||
<Accordion title="Codex bundles">
|
||||
Markers: `.codex-plugin/plugin.json`
|
||||
|
||||
Supported capabilities are loaded quietly. Unsupported capabilities produce a
|
||||
warning such as:
|
||||
Optional content: `skills/`, `hooks/`, `.mcp.json`, `.app.json`
|
||||
|
||||
```text
|
||||
bundle capability detected but not wired into OpenClaw yet: agents
|
||||
```
|
||||
Codex bundles fit OpenClaw best when they use skill roots and OpenClaw-style
|
||||
hook-pack directories (`HOOK.md` + `handler.ts`).
|
||||
|
||||
Current exceptions:
|
||||
</Accordion>
|
||||
|
||||
- Claude `commands` is considered supported because it maps to skills
|
||||
- Claude `settings` is considered supported because it maps to embedded Pi settings
|
||||
- Cursor `commands` is considered supported because it maps to skills
|
||||
- bundle MCP is considered supported because it maps into embedded Pi settings
|
||||
and exposes supported stdio tools to embedded Pi
|
||||
- Codex `hooks` is considered supported only for OpenClaw hook-pack layouts
|
||||
<Accordion title="Claude bundles">
|
||||
Two detection modes:
|
||||
|
||||
## Format differences
|
||||
- **Manifest-based:** `.claude-plugin/plugin.json`
|
||||
- **Manifestless:** default Claude layout (`skills/`, `commands/`, `agents/`, `hooks/`, `.mcp.json`, `settings.json`)
|
||||
|
||||
The formats are close, but not byte-for-byte identical. These are the practical
|
||||
differences that matter in OpenClaw.
|
||||
Claude-specific behavior:
|
||||
|
||||
### Codex
|
||||
- `commands/` is treated as skill content
|
||||
- `settings.json` is imported into embedded Pi settings (shell override keys are sanitized)
|
||||
- `.mcp.json` exposes supported stdio tools to embedded Pi
|
||||
- `hooks/hooks.json` is detected but not executed
|
||||
- Custom component paths in the manifest are additive (they extend defaults, not replace them)
|
||||
|
||||
Typical markers:
|
||||
</Accordion>
|
||||
|
||||
- `.codex-plugin/plugin.json`
|
||||
- optional `skills/`
|
||||
- optional `hooks/`
|
||||
- optional `.mcp.json`
|
||||
- optional `.app.json`
|
||||
<Accordion title="Cursor bundles">
|
||||
Markers: `.cursor-plugin/plugin.json`
|
||||
|
||||
Codex bundles fit OpenClaw best when they use skill roots and OpenClaw-style
|
||||
hook-pack directories.
|
||||
Optional content: `skills/`, `.cursor/commands/`, `.cursor/agents/`, `.cursor/rules/`, `.cursor/hooks.json`, `.mcp.json`
|
||||
|
||||
### Claude
|
||||
- `.cursor/commands/` is treated as skill content
|
||||
- `.cursor/rules/`, `.cursor/agents/`, and `.cursor/hooks.json` are detect-only
|
||||
|
||||
OpenClaw supports both:
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
- manifest-based Claude bundles: `.claude-plugin/plugin.json`
|
||||
- manifestless Claude bundles that use the default Claude layout
|
||||
## Detection precedence
|
||||
|
||||
Default Claude layout markers OpenClaw recognizes:
|
||||
OpenClaw checks for native plugin format first:
|
||||
|
||||
- `skills/`
|
||||
- `commands/`
|
||||
- `agents/`
|
||||
- `hooks/hooks.json`
|
||||
- `.mcp.json`
|
||||
- `.lsp.json`
|
||||
- `settings.json`
|
||||
1. `openclaw.plugin.json` or valid `package.json` with `openclaw.extensions` — treated as **native plugin**
|
||||
2. Bundle markers (`.codex-plugin/`, `.claude-plugin/`, or default Claude/Cursor layout) — treated as **bundle**
|
||||
|
||||
Claude-specific notes:
|
||||
If a directory contains both, OpenClaw uses the native path. This prevents
|
||||
dual-format packages from being partially installed as bundles.
|
||||
|
||||
- `commands/` is treated like skill content
|
||||
- `settings.json` is imported into embedded Pi settings
|
||||
- `.mcp.json` and manifest `mcpServers` can expose supported stdio tools to
|
||||
embedded Pi
|
||||
- `hooks/hooks.json` is detected, but not executed as Claude automation
|
||||
## Security
|
||||
|
||||
### Cursor
|
||||
Bundles have a narrower trust boundary than native plugins:
|
||||
|
||||
Typical markers:
|
||||
- OpenClaw does **not** load arbitrary bundle runtime modules in-process
|
||||
- Skills and hook-pack paths must stay inside the plugin root (boundary-checked)
|
||||
- Settings files are read with the same boundary checks
|
||||
- Supported stdio MCP servers may be launched as subprocesses
|
||||
|
||||
- `.cursor-plugin/plugin.json`
|
||||
- optional `skills/`
|
||||
- optional `.cursor/commands/`
|
||||
- optional `.cursor/agents/`
|
||||
- optional `.cursor/rules/`
|
||||
- optional `.cursor/hooks.json`
|
||||
- optional `.mcp.json`
|
||||
|
||||
Cursor-specific notes:
|
||||
|
||||
- `.cursor/commands/` is treated like skill content
|
||||
- `.cursor/rules/`, `.cursor/agents/`, and `.cursor/hooks.json` are
|
||||
detect-only today
|
||||
|
||||
## Claude custom paths
|
||||
|
||||
Claude bundle manifests can declare custom component paths. OpenClaw treats
|
||||
those paths as **additive**, not replacing defaults.
|
||||
|
||||
Currently recognized custom path keys:
|
||||
|
||||
- `skills`
|
||||
- `commands`
|
||||
- `agents`
|
||||
- `hooks`
|
||||
- `mcpServers`
|
||||
- `lspServers`
|
||||
- `outputStyles`
|
||||
|
||||
Examples:
|
||||
|
||||
- default `commands/` plus manifest `commands: "extra-commands"` =>
|
||||
OpenClaw scans both
|
||||
- default `skills/` plus manifest `skills: ["team-skills"]` =>
|
||||
OpenClaw scans both
|
||||
|
||||
## Security model
|
||||
|
||||
Bundle support is intentionally narrower than native plugin support.
|
||||
|
||||
Current behavior:
|
||||
|
||||
- bundle discovery reads files inside the plugin root with boundary checks
|
||||
- skills and hook-pack paths must stay inside the plugin root
|
||||
- bundle settings files are read with the same boundary checks
|
||||
- supported stdio bundle MCP servers may be launched as subprocesses for
|
||||
embedded Pi tool calls
|
||||
- OpenClaw does not load arbitrary bundle runtime modules in-process
|
||||
|
||||
This makes bundle support safer by default than native plugin modules, but you
|
||||
should still treat third-party bundles as trusted content for the features they
|
||||
do expose.
|
||||
|
||||
## Install examples
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./my-codex-bundle
|
||||
openclaw plugins install ./my-claude-bundle
|
||||
openclaw plugins install ./my-cursor-bundle
|
||||
openclaw plugins install ./my-bundle.tgz
|
||||
openclaw plugins marketplace list <marketplace-name>
|
||||
openclaw plugins install <plugin-name>@<marketplace-name>
|
||||
openclaw plugins inspect my-bundle
|
||||
```
|
||||
|
||||
If the directory is a native OpenClaw plugin/package, the native install path
|
||||
still wins.
|
||||
|
||||
For Claude marketplace names, OpenClaw reads the local Claude known-marketplace
|
||||
registry at `~/.claude/plugins/known_marketplaces.json`. Marketplace entries
|
||||
can resolve to bundle-compatible directories/archives or to native plugin
|
||||
sources; after resolution, the normal install rules still apply.
|
||||
This makes bundles safer by default, but you should still treat third-party
|
||||
bundles as trusted content for the features they do expose.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Bundle is detected but capabilities do not run
|
||||
<AccordionGroup>
|
||||
<Accordion title="Bundle is detected but capabilities do not run">
|
||||
Run `openclaw plugins inspect <id>`. If a capability is listed but marked as
|
||||
not wired, that is a product limit — not a broken install.
|
||||
</Accordion>
|
||||
|
||||
Check `openclaw plugins inspect <id>`.
|
||||
<Accordion title="Claude command files do not appear">
|
||||
Make sure the bundle is enabled and the markdown files are inside a detected
|
||||
`commands/` or `skills/` root.
|
||||
</Accordion>
|
||||
|
||||
If the capability is listed but OpenClaw says it is not wired yet, that is a
|
||||
real product limit, not a broken install.
|
||||
<Accordion title="Claude settings do not apply">
|
||||
Only embedded Pi settings from `settings.json` are supported. OpenClaw does
|
||||
not treat bundle settings as raw config patches.
|
||||
</Accordion>
|
||||
|
||||
### Claude command files do not appear
|
||||
<Accordion title="Claude hooks do not execute">
|
||||
`hooks/hooks.json` is detect-only. If you need runnable hooks, use the
|
||||
OpenClaw hook-pack layout or ship a native plugin.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
Make sure the bundle is enabled and the markdown files are inside a detected
|
||||
`commands` root or `skills` root.
|
||||
## Related
|
||||
|
||||
### Claude settings do not apply
|
||||
|
||||
Current support is limited to embedded Pi settings from `settings.json`.
|
||||
OpenClaw does not treat bundle settings as raw OpenClaw config patches.
|
||||
|
||||
### Claude hooks do not execute
|
||||
|
||||
`hooks/hooks.json` is only detected today.
|
||||
|
||||
If you need runnable bundle hooks today, use the normal OpenClaw hook-pack
|
||||
layout through a supported Codex hook root or ship a native OpenClaw plugin.
|
||||
- [Install and Configure Plugins](/tools/plugin)
|
||||
- [Building Plugins](/plugins/building-plugins) — create a native plugin
|
||||
- [Plugin Manifest](/plugins/manifest) — native manifest schema
|
||||
|
||||
@ -45,17 +45,6 @@ openclaw plugins install <npm-spec>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="WeChat — Personal accounts via WeChatPadPro (iPad protocol)">
|
||||
Supports text, image, and file exchange with keyword-triggered conversations.
|
||||
|
||||
- **npm:** `@icesword760/openclaw-wechat`
|
||||
- **repo:** [github.com/icesword0760/openclaw-wechat](https://github.com/icesword0760/openclaw-wechat)
|
||||
|
||||
```bash
|
||||
openclaw plugins install @icesword760/openclaw-wechat
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Submit your plugin
|
||||
|
||||
@ -1,41 +1,52 @@
|
||||
---
|
||||
title: "Plugin SDK Migration"
|
||||
sidebarTitle: "SDK Migration"
|
||||
summary: "Migrate from legacy compat surfaces to focused plugin-sdk subpaths and injected runtime helpers"
|
||||
summary: "Migrate from the legacy backwards-compatibility layer to the modern plugin SDK"
|
||||
read_when:
|
||||
- You see the OPENCLAW_PLUGIN_SDK_COMPAT_DEPRECATED warning
|
||||
- You see the OPENCLAW_EXTENSION_API_DEPRECATED warning
|
||||
- You are updating a plugin from the monolithic plugin-sdk import to scoped subpaths
|
||||
- You are updating a plugin away from openclaw/extension-api
|
||||
- You are updating a plugin to the modern plugin architecture
|
||||
- You maintain an external OpenClaw plugin
|
||||
---
|
||||
|
||||
# Plugin SDK Migration
|
||||
|
||||
OpenClaw is migrating from broad compatibility surfaces to narrower, documented
|
||||
contracts:
|
||||
OpenClaw has moved from a broad backwards-compatibility layer to a modern plugin
|
||||
architecture with focused, documented imports. If your plugin was built before
|
||||
the new architecture, this guide helps you migrate.
|
||||
|
||||
- `openclaw/plugin-sdk/compat` -> focused `openclaw/plugin-sdk/<subpath>` imports
|
||||
- `openclaw/extension-api` -> injected runtime helpers such as `api.runtime.agent.*`
|
||||
## What is changing
|
||||
|
||||
This page explains what changed, why, and how to migrate.
|
||||
The old plugin system provided two wide-open surfaces that let plugins import
|
||||
anything they needed from a single entry point:
|
||||
|
||||
<Info>
|
||||
The compat import still works at runtime. This is a deprecation warning, not
|
||||
a breaking change yet. But new plugins **must not** use it, and existing
|
||||
plugins should migrate before the next major release removes it.
|
||||
</Info>
|
||||
- **`openclaw/plugin-sdk/compat`** — a single import that re-exported dozens of
|
||||
helpers. It was introduced to keep older hook-based plugins working while the
|
||||
new plugin architecture was being built.
|
||||
- **`openclaw/extension-api`** — a bridge that gave plugins direct access to
|
||||
host-side helpers like the embedded agent runner.
|
||||
|
||||
Both surfaces are now **deprecated**. They still work at runtime, but new
|
||||
plugins must not use them, and existing plugins should migrate before the next
|
||||
major release removes them.
|
||||
|
||||
<Warning>
|
||||
The backwards-compatibility layer will be removed in a future major release.
|
||||
Plugins that still import from these surfaces will break when that happens.
|
||||
</Warning>
|
||||
|
||||
## Why this changed
|
||||
|
||||
The old monolithic `openclaw/plugin-sdk/compat` re-exported everything from one
|
||||
entry point. This caused slow startup (importing one helper loaded dozens of
|
||||
unrelated modules), circular dependency risk, and an unclear API surface.
|
||||
The old approach caused problems:
|
||||
|
||||
Focused subpaths fix all three: each subpath is a small, self-contained module
|
||||
with a clear purpose.
|
||||
- **Slow startup** — importing one helper loaded dozens of unrelated modules
|
||||
- **Circular dependencies** — broad re-exports made it easy to create import cycles
|
||||
- **Unclear API surface** — no way to tell which exports were stable vs internal
|
||||
|
||||
## Migration steps
|
||||
The modern plugin SDK fixes this: each import path (`openclaw/plugin-sdk/\<subpath\>`)
|
||||
is a small, self-contained module with a clear purpose and documented contract.
|
||||
|
||||
## How to migrate
|
||||
|
||||
<Steps>
|
||||
<Step title="Find deprecated imports">
|
||||
@ -43,91 +54,66 @@ with a clear purpose.
|
||||
|
||||
```bash
|
||||
grep -r "plugin-sdk/compat" my-plugin/
|
||||
grep -r "openclaw/extension-api" extensions/my-plugin/
|
||||
grep -r "openclaw/extension-api" my-plugin/
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Replace with focused subpaths or runtime injection">
|
||||
Each export from compat maps to a specific subpath. Replace the import
|
||||
source:
|
||||
<Step title="Replace with focused imports">
|
||||
Each export from the old surface maps to a specific modern import path:
|
||||
|
||||
```typescript
|
||||
// Before (compat entry)
|
||||
// Before (deprecated backwards-compatibility layer)
|
||||
import {
|
||||
createChannelReplyPipeline,
|
||||
createPluginRuntimeStore,
|
||||
resolveControlCommandGate,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
|
||||
// After (focused subpaths)
|
||||
// After (modern focused imports)
|
||||
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
||||
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
|
||||
```
|
||||
|
||||
If your plugin imports from `openclaw/extension-api`, you will now see:
|
||||
|
||||
```text
|
||||
[OPENCLAW_EXTENSION_API_DEPRECATED] Warning: openclaw/extension-api is deprecated.
|
||||
Migrate to api.runtime.agent.* or focused openclaw/plugin-sdk/<subpath> imports.
|
||||
```
|
||||
|
||||
That bridge also still works at runtime today. It exists to preserve older
|
||||
plugins while they migrate to the injected plugin runtime.
|
||||
|
||||
Move host-side helpers onto the injected plugin runtime instead of
|
||||
importing them directly:
|
||||
For host-side helpers, use the injected plugin runtime instead of importing
|
||||
directly:
|
||||
|
||||
```typescript
|
||||
// Before (deprecated extension-api bridge)
|
||||
import { runEmbeddedPiAgent } from "openclaw/extension-api";
|
||||
const result = await runEmbeddedPiAgent({ sessionId, prompt });
|
||||
|
||||
const result = await runEmbeddedPiAgent({
|
||||
sessionId,
|
||||
sessionFile,
|
||||
workspaceDir,
|
||||
prompt,
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
// After (preferred injected runtime)
|
||||
const result = await api.runtime.agent.runEmbeddedPiAgent({
|
||||
sessionId,
|
||||
sessionFile,
|
||||
workspaceDir,
|
||||
prompt,
|
||||
timeoutMs,
|
||||
});
|
||||
// After (injected runtime)
|
||||
const result = await api.runtime.agent.runEmbeddedPiAgent({ sessionId, prompt });
|
||||
```
|
||||
|
||||
The same pattern applies to the other legacy `extension-api` helpers:
|
||||
The same pattern applies to other legacy bridge helpers:
|
||||
|
||||
- `resolveAgentDir` -> `api.runtime.agent.resolveAgentDir`
|
||||
- `resolveAgentWorkspaceDir` -> `api.runtime.agent.resolveAgentWorkspaceDir`
|
||||
- `resolveAgentIdentity` -> `api.runtime.agent.resolveAgentIdentity`
|
||||
- `resolveThinkingDefault` -> `api.runtime.agent.resolveThinkingDefault`
|
||||
- `resolveAgentTimeoutMs` -> `api.runtime.agent.resolveAgentTimeoutMs`
|
||||
- `ensureAgentWorkspace` -> `api.runtime.agent.ensureAgentWorkspace`
|
||||
- session store helpers -> `api.runtime.agent.session.*`
|
||||
|
||||
See the [subpath reference](#subpath-reference) below for the scoped import
|
||||
mapping.
|
||||
| Old import | Modern equivalent |
|
||||
| --- | --- |
|
||||
| `resolveAgentDir` | `api.runtime.agent.resolveAgentDir` |
|
||||
| `resolveAgentWorkspaceDir` | `api.runtime.agent.resolveAgentWorkspaceDir` |
|
||||
| `resolveAgentIdentity` | `api.runtime.agent.resolveAgentIdentity` |
|
||||
| `resolveThinkingDefault` | `api.runtime.agent.resolveThinkingDefault` |
|
||||
| `resolveAgentTimeoutMs` | `api.runtime.agent.resolveAgentTimeoutMs` |
|
||||
| `ensureAgentWorkspace` | `api.runtime.agent.ensureAgentWorkspace` |
|
||||
| session store helpers | `api.runtime.agent.session.*` |
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Build and test">
|
||||
```bash
|
||||
pnpm build
|
||||
pnpm test -- extensions/my-plugin/
|
||||
pnpm test -- my-plugin/
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Subpath reference
|
||||
## Import path reference
|
||||
|
||||
<Accordion title="Full subpath table">
|
||||
| Subpath | Purpose | Key exports |
|
||||
<Accordion title="Full import path table">
|
||||
| Import path | Purpose | Key exports |
|
||||
| --- | --- | --- |
|
||||
| `plugin-sdk/core` | Plugin entry definitions, base types | `defineChannelPluginEntry`, `definePluginEntry` |
|
||||
| `plugin-sdk/channel-setup` | Setup wizard adapters | `createOptionalChannelSetupSurface` |
|
||||
@ -151,22 +137,22 @@ with a clear purpose.
|
||||
| `plugin-sdk/testing` | Test utilities | Test helpers and mocks |
|
||||
</Accordion>
|
||||
|
||||
Use the narrowest subpath that matches the job. If you cannot find an export,
|
||||
Use the narrowest import that matches the job. If you cannot find an export,
|
||||
check the source at `src/plugin-sdk/` or ask in Discord.
|
||||
|
||||
## Removal timeline
|
||||
|
||||
| When | What happens |
|
||||
| --- | --- |
|
||||
| **Now** | Compat import and `openclaw/extension-api` emit runtime warnings |
|
||||
| **Next major release** | These legacy bridges may be removed; plugins still using them will fail |
|
||||
| When | What happens |
|
||||
| ---------------------- | ----------------------------------------------------------------------- |
|
||||
| **Now** | Deprecated surfaces emit runtime warnings |
|
||||
| **Next major release** | Deprecated surfaces will be removed; plugins still using them will fail |
|
||||
|
||||
All core plugins have already been migrated. External plugins should migrate
|
||||
before the next major release.
|
||||
|
||||
## Suppressing the warning temporarily
|
||||
## Suppressing the warnings temporarily
|
||||
|
||||
Set this environment variable while you work on migrating:
|
||||
Set these environment variables while you work on migrating:
|
||||
|
||||
```bash
|
||||
OPENCLAW_SUPPRESS_PLUGIN_SDK_COMPAT_WARNING=1 openclaw gateway run
|
||||
@ -178,5 +164,5 @@ This is a temporary escape hatch, not a permanent solution.
|
||||
## Related
|
||||
|
||||
- [Building Plugins](/plugins/building-plugins)
|
||||
- [Plugin Architecture](/plugins/architecture)
|
||||
- [Plugin Internals](/plugins/architecture)
|
||||
- [Plugin Manifest](/plugins/manifest)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user