Plugins
نقاط ورود Plugin
هر Plugin یک شیء ورودی پیشفرض صادر میکند. SDK سه helper برای ساخت آنها فراهم میکند.
برای Pluginهای نصبشده، package.json باید بارگذاری runtime را، در صورت
دردسترس بودن، به JavaScript ساختهشده اشاره دهد:
{
"openclaw": {
"extensions": ["./src/index.ts"],
"runtimeExtensions": ["./dist/index.js"],
"setupEntry": "./src/setup-entry.ts",
"runtimeSetupEntry": "./dist/setup-entry.js"
}
}
extensions و setupEntry همچنان ورودیهای source معتبری برای توسعه با workspace و
git checkout هستند. وقتی OpenClaw یک package نصبشده را بارگذاری میکند،
runtimeExtensions و runtimeSetupEntry ترجیح داده میشوند و به packageهای npm اجازه میدهند
از کامپایل TypeScript در runtime پرهیز کنند. ورودیهای runtime صریح الزامیاند:
runtimeSetupEntry به setupEntry نیاز دارد، و نبود artifactهای runtimeExtensions یا
runtimeSetupEntry باعث شکست نصب/کشف میشود، نه اینکه بیصدا به source برگردد. اگر
یک package نصبشده فقط یک ورودی source از نوع TypeScript اعلام کند، OpenClaw در صورت وجود
یک همتای ساختهشده مطابق dist/*.js از آن استفاده میکند و سپس به source نوع TypeScript
برمیگردد.
همه مسیرهای ورودی باید داخل دایرکتوری package متعلق به Plugin باقی بمانند. ورودیهای runtime
و همتاهای JavaScript ساختهشده استنباطشده، یک مسیر source خارجشونده در extensions یا
setupEntry را معتبر نمیکنند.
definePluginEntry
Import: openclaw/plugin-sdk/plugin-entry
برای Pluginهای ارائهدهنده، Pluginهای ابزار، Pluginهای hook، و هر چیزی که یک کانال پیامرسانی نیست.
export default definePluginEntry({
id: "my-plugin",
name: "My Plugin",
description: "Short summary",
register(api) {
api.registerProvider({
/* ... */
});
api.registerTool({
/* ... */
});
},
});
| فیلد | نوع | الزامی | پیشفرض |
|---|---|---|---|
id |
string |
بله | - |
name |
string |
بله | - |
description |
string |
بله | - |
kind |
string |
خیر | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
خیر | schema شیء خالی |
register |
(api: OpenClawPluginApi) => void |
بله | - |
idباید با manifestopenclaw.plugin.jsonشما مطابقت داشته باشد.kindبرای slotهای انحصاری است:"memory"یا"context-engine".configSchemaمیتواند برای ارزیابی تنبل یک function باشد.- OpenClaw آن schema را در نخستین دسترسی resolve و memoize میکند، بنابراین سازندههای schema پرهزینه فقط یکبار اجرا میشوند.
defineChannelPluginEntry
Import: openclaw/plugin-sdk/channel-core
definePluginEntry را با اتصالهای ویژه کانال wrap میکند. بهطور خودکار
api.registerChannel({ plugin }) را فراخوانی میکند، یک seam اختیاری metadata برای CLI راهنمای root
در معرض میگذارد، و registerFull را بر اساس حالت ثبت gate میکند.
export default defineChannelPluginEntry({
id: "my-channel",
name: "My Channel",
description: "Short summary",
plugin: myChannelPlugin,
setRuntime: setMyRuntime,
registerCliMetadata(api) {
api.registerCli(/* ... */);
},
registerFull(api) {
api.registerGatewayMethod(/* ... */);
},
});
| فیلد | نوع | الزامی | پیشفرض |
|---|---|---|---|
id |
string |
بله | - |
name |
string |
بله | - |
description |
string |
بله | - |
plugin |
ChannelPlugin |
بله | - |
configSchema |
OpenClawPluginConfigSchema | () => OpenClawPluginConfigSchema |
خیر | schema شیء خالی |
setRuntime |
(runtime: PluginRuntime) => void |
خیر | - |
registerCliMetadata |
(api: OpenClawPluginApi) => void |
خیر | - |
registerFull |
(api: OpenClawPluginApi) => void |
خیر | - |
setRuntimeهنگام ثبت فراخوانی میشود تا بتوانید reference مربوط به runtime را ذخیره کنید (معمولا از طریقcreatePluginRuntimeStore). هنگام capture کردن metadata مربوط به CLI از آن صرفنظر میشود.registerCliMetadataدر طولapi.registrationMode === "cli-metadata"،api.registrationMode === "discovery"، وapi.registrationMode === "full"اجرا میشود. از آن بهعنوان محل canonical برای descriptorهای CLI متعلق به کانال استفاده کنید تا راهنمای root غیرفعالساز بماند، snapshotهای کشف شامل metadata ایستای command باشند، و ثبت عادی commandهای CLI با بارگذاری کامل Plugin سازگار بماند.- ثبت discovery غیرفعالساز است، نه بدون import. OpenClaw ممکن است
ورودی Plugin مورد اعتماد و module مربوط به channel Plugin را برای ساختن
snapshot ارزیابی کند، بنابراین importهای سطح بالا را بدون side effect نگه دارید و socketها،
clientها، workerها و serviceها را پشت مسیرهای فقط
"full"قرار دهید. registerFullفقط وقتی اجرا میشود کهapi.registrationMode === "full"باشد. در بارگذاری setup-only از آن صرفنظر میشود.- مانند
definePluginEntry،configSchemaمیتواند یک factory تنبل باشد و OpenClaw schema resolveشده را در نخستین دسترسی memoize میکند. - برای commandهای CLI root متعلق به Plugin، وقتی میخواهید command بدون ناپدید شدن از
درخت parse مربوط به CLI root همچنان lazy-loaded بماند،
api.registerCli(..., { descriptors: [...] })را ترجیح دهید. برای Pluginهای کانال، ترجیح دهید آن descriptorها را ازregisterCliMetadata(...)ثبت کنید وregisterFull(...)را روی کارهای فقط runtime متمرکز نگه دارید. - اگر
registerFull(...)همچنین methodهای RPC مربوط به Gateway را ثبت میکند، آنها را روی یک prefix ویژه Plugin نگه دارید. namespaceهای admin هسته رزروشده (config.*,exec.approvals.*,wizard.*,update.*) همیشه بهoperator.admincoerced میشوند.
defineSetupPluginEntry
Import: openclaw/plugin-sdk/channel-core
برای فایل سبک setup-entry.ts. فقط { plugin } را بدون هیچ
اتصال runtime یا CLI برمیگرداند.
export default defineSetupPluginEntry(myChannelPlugin);
OpenClaw وقتی یک کانال غیرفعال، پیکربندینشده، یا وقتی بارگذاری deferred فعال است، این را بهجای ورودی کامل بارگذاری میکند. برای زمانهایی که این موضوع اهمیت دارد، Setup و Config را ببینید.
در عمل، defineSetupPluginEntry(...) را با خانوادههای helper محدود setup جفت کنید:
openclaw/plugin-sdk/setup-runtimeبرای helperهای setup امن برای runtime، مانند adapterهای patch مربوط به setup امن برای import، خروجی lookup-note،promptResolvedAllowFrom،splitSetupEntries، و proxyهای setup واگذارشدهopenclaw/plugin-sdk/channel-setupبرای سطحهای setup مربوط به نصب اختیاریopenclaw/plugin-sdk/setup-toolsبرای helperهای setup/install CLI/archive/docs
SDKهای سنگین، ثبت CLI، و serviceهای runtime طولانیعمر را در ورودی کامل نگه دارید.
کانالهای workspace باندلشدهای که سطحهای setup و runtime را جدا میکنند، میتوانند بهجای آن از
defineBundledChannelSetupEntry(...) از
openclaw/plugin-sdk/channel-entry-contract استفاده کنند. آن contract به
ورودی setup اجازه میدهد exportهای Plugin/secrets امن برای setup را نگه دارد و همچنان یک
runtime setter را در معرض بگذارد:
export default defineBundledChannelSetupEntry({
importMetaUrl: import.meta.url,
plugin: {
specifier: "./channel-plugin-api.js",
exportName: "myChannelPlugin",
},
runtime: {
specifier: "./runtime-api.js",
exportName: "setMyChannelRuntime",
},
});
فقط زمانی از آن contract باندلشده استفاده کنید که جریانهای setup واقعا پیش از بارگذاری ورودی کامل کانال به یک runtime setter سبک نیاز داشته باشند.
حالت ثبت
api.registrationMode به Plugin شما میگوید چگونه بارگذاری شده است:
| حالت | زمان | چه چیزی ثبت شود |
|---|---|---|
"full" |
راهاندازی عادی Gateway | همه چیز |
"discovery" |
کشف read-only قابلیتها | ثبت کانال بههمراه descriptorهای ایستای CLI؛ کد ورودی ممکن است بارگذاری شود، اما از socketها، workerها، clientها و serviceها صرفنظر کنید |
"setup-only" |
کانال غیرفعال/پیکربندینشده | فقط ثبت کانال |
"setup-runtime" |
جریان setup با runtime در دسترس | ثبت کانال بههمراه فقط runtime سبک موردنیاز پیش از بارگذاری ورودی کامل |
"cli-metadata" |
راهنمای root / capture کردن metadata مربوط به CLI | فقط descriptorهای CLI |
defineChannelPluginEntry این تفکیک را بهطور خودکار مدیریت میکند. اگر از
definePluginEntry بهطور مستقیم برای یک کانال استفاده میکنید، خودتان حالت را بررسی کنید:
register(api) {
if (
api.registrationMode === "cli-metadata" ||
api.registrationMode === "discovery" ||
api.registrationMode === "full"
) {
api.registerCli(/* ... */);
if (api.registrationMode === "cli-metadata") return;
}
api.registerChannel({ plugin: myPlugin });
if (api.registrationMode !== "full") return;
// Heavy runtime-only registrations
api.registerService(/* ... */);
}
حالت discovery یک snapshot رجیستری غیرفعالساز میسازد. ممکن است همچنان ورودی Plugin و شیء channel Plugin را ارزیابی کند تا OpenClaw بتواند قابلیتهای کانال و descriptorهای ایستای CLI را ثبت کند. ارزیابی module در discovery را مورد اعتماد اما سبک در نظر بگیرید: بدون clientهای شبکه، subprocessها، listenerها، اتصالهای database، workerهای پسزمینه، خواندن credentialها، یا دیگر side effectهای runtime زنده در سطح بالا.
"setup-runtime" را بهعنوان پنجرهای در نظر بگیرید که در آن سطحهای راهاندازی setup-only باید
بدون ورود دوباره به runtime کامل کانال باندلشده وجود داشته باشند. موارد مناسب شامل
ثبت کانال، routeهای HTTP امن برای setup، methodهای Gateway امن برای setup، و
helperهای setup واگذارشده هستند. serviceهای پسزمینه سنگین، registrarهای CLI، و
bootstrapهای SDK ارائهدهنده/client همچنان به "full" تعلق دارند.
بهطور خاص برای registrarهای CLI:
- وقتی registrar مالک یک یا چند command در root است و میخواهید OpenClaw در نخستین invocation
module واقعی CLI را lazy-load کند، از
descriptorsاستفاده کنید - مطمئن شوید آن descriptorها همه rootهای command سطح بالا را که registrar در معرض میگذارد پوشش میدهند
- نام commandهای descriptor را به حرفها، عددها، hyphen، و underscore محدود کنید، بهطوریکه با یک حرف یا عدد شروع شوند؛ OpenClaw نامهای descriptor خارج از این شکل را رد میکند و توالیهای کنترل terminal را پیش از render کردن help از descriptionها حذف میکند
- فقط برای مسیرهای سازگاری eager از
commandsبهتنهایی استفاده کنید
شکلهای Plugin
OpenClaw، Pluginهای بارگذاریشده را بر اساس رفتار ثبت آنها دستهبندی میکند:
| شکل | توضیح |
|---|---|
| plain-capability | یک نوع قابلیت (مثلاً فقط ارائهدهنده) |
| hybrid-capability | چند نوع قابلیت (مثلاً ارائهدهنده + گفتار) |
| hook-only | فقط هوکها، بدون قابلیت |
| non-capability | ابزارها/دستورها/سرویسها، اما بدون قابلیت |
برای دیدن شکل یک Plugin از openclaw plugins inspect <id> استفاده کنید.
مرتبط
- نمای کلی SDK - API ثبت و مرجع زیرمسیر
- کمککنندههای زمان اجرا -
api.runtimeوcreatePluginRuntimeStore - راهاندازی و پیکربندی - مانیفست، ورودی راهاندازی، بارگذاری بهتعویقافتاده
- Pluginهای کانال - ساخت شیء
ChannelPlugin - Pluginهای ارائهدهنده - ثبت ارائهدهنده و هوکها