

























@@ -97,40 +97,62 @@ and provider plugins have dedicated guides linked above.
97979898Every plugin needs a manifest, even with no config. Runtime-registered tools
9999must be listed in `contracts.tools` so OpenClaw can discover the owning
100-plugin without loading every plugin runtime. Plugins should also declare
101-`activation.onStartup` intentionally. This example sets it to `true`. See
102-[Manifest](/plugins/manifest) for the full schema. The canonical ClawHub
103-publish snippets live in `docs/snippets/plugin-publish/`.
100+plugin without loading every plugin runtime. For simple tool-only plugins,
101+prefer `defineToolPlugin` plus `openclaw plugins build` so tool names and
102+the empty config schema are generated from one source of truth. Plugins
103+should also declare `activation.onStartup` intentionally. This example sets
104+it to `true`. See [Manifest](/plugins/manifest) for the full schema. The
105+canonical ClawHub publish snippets live in `docs/snippets/plugin-publish/`.
104106105107</Step>
106108107109<Step title="Write the entry point">
108110109111```typescript
110112// index.ts
111-import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
112-import { Type } from "@sinclair/typebox";
113+import { Type } from "typebox";
114+import { defineToolPlugin } from "openclaw/plugin-sdk/tool-plugin";
113115114-export default definePluginEntry({
116+export default defineToolPlugin({
115117 id: "my-plugin",
116118 name: "My Plugin",
117119 description: "Adds a custom tool to OpenClaw",
118- register(api) {
119- api.registerTool({
120+ tools: (tool) => [
121+ tool({
120122 name: "my_tool",
121123 description: "Do a thing",
122124 parameters: Type.Object({ input: Type.String() }),
123- async execute(_id, params) {
124- return { content: [{ type: "text", text: `Got: ${params.input}` }] };
125+ async execute({ input }) {
126+ return { message: `Got: ${input}` };
125127 },
126- });
127- },
128+ }),
129+ ],
128130});
129131```
130132131-`definePluginEntry` is for non-channel plugins. For channels, use
132-`defineChannelPluginEntry` - see [Channel Plugins](/plugins/sdk-channel-plugins).
133-For full entry point options, see [Entry Points](/plugins/sdk-entrypoints).
133+`defineToolPlugin` is for simple agent-tool plugins. For providers, hooks,
134+services, and other advanced non-channel plugins, use `definePluginEntry`.
135+For channels, use `defineChannelPluginEntry` - see
136+[Channel Plugins](/plugins/sdk-channel-plugins). For full entry point
137+options, see [Entry Points](/plugins/sdk-entrypoints).
138+139+</Step>
140+141+<Step title="Generate and validate metadata">
142+143+```bash
144+npm run build
145+openclaw plugins build --entry ./dist/index.js
146+openclaw plugins validate --entry ./dist/index.js
147+```
148+149+`openclaw plugins build` writes `openclaw.plugin.json` and keeps
150+`package.json` `openclaw.extensions` pointed at the entry module. For
151+published packages, point it at built JavaScript such as `./dist/index.js`.
152+The generated manifest is the cold-load contract that OpenClaw reads before
153+runtime import. `openclaw plugins validate` imports the entry only during
154+author validation and checks that the manifest and package metadata match
155+the static `defineToolPlugin` metadata.
134156135157</Step>
136158@@ -374,7 +396,7 @@ reserved surfaces, not as the default pattern for new third-party plugins.
374396375397<Check>**package.json** has correct `openclaw` metadata</Check>
376398<Check>**openclaw.plugin.json** manifest is present and valid</Check>
377-<Check>Entry point uses `defineChannelPluginEntry` or `definePluginEntry`</Check>
399+<Check>Entry point uses `defineToolPlugin`, `defineChannelPluginEntry`, or `definePluginEntry`</Check>
378400<Check>All imports use focused `plugin-sdk/<subpath>` paths</Check>
379401<Check>Internal imports use local modules, not SDK self-imports</Check>
380402<Check>Tests pass (`pnpm test -- <bundled-plugin-root>/my-plugin/`)</Check>
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。