Langsung ke konten utama

Penyiapan dan Config Plugin

Referensi untuk packaging plugin (metadata package.json), manifest (openclaw.plugin.json), entri penyiapan, dan schema config.
Mencari panduan langkah demi langkah? Panduan cara melakukannya mencakup packaging dalam konteks: Channel Plugins dan Provider Plugins.

Metadata paket

package.json Anda memerlukan field openclaw yang memberi tahu sistem plugin apa yang disediakan plugin Anda: Plugin channel:
{
  "name": "@myorg/openclaw-my-channel",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "channel": {
      "id": "my-channel",
      "label": "My Channel",
      "blurb": "Short description of the channel."
    }
  }
}
Plugin provider / baseline publikasi ClawHub:
openclaw-clawhub-package.json
{
  "name": "@myorg/openclaw-my-plugin",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "compat": {
      "pluginApi": ">=2026.3.24-beta.2",
      "minGatewayVersion": "2026.3.24-beta.2"
    },
    "build": {
      "openclawVersion": "2026.3.24-beta.2",
      "pluginSdkVersion": "2026.3.24-beta.2"
    }
  }
}
Jika Anda memublikasikan plugin secara eksternal di ClawHub, field compat dan build tersebut wajib ada. Snippet publikasi kanonis berada di docs/snippets/plugin-publish/.

Field openclaw

FieldTypeDeskripsi
extensionsstring[]File entry point (relatif terhadap root paket)
setupEntrystringEntry ringan khusus penyiapan (opsional)
channelobjectMetadata katalog channel untuk permukaan penyiapan, picker, quickstart, dan status
providersstring[]Id provider yang didaftarkan oleh plugin ini
installobjectPetunjuk instalasi: npmSpec, localPath, defaultChoice, minHostVersion, allowInvalidConfigRecovery
startupobjectFlag perilaku startup

openclaw.channel

openclaw.channel adalah metadata paket yang ringan untuk penemuan channel dan permukaan penyiapan sebelum runtime dimuat.
FieldTypeArtinya
idstringId channel kanonis.
labelstringLabel channel utama.
selectionLabelstringLabel picker/penyiapan saat perlu berbeda dari label.
detailLabelstringLabel detail sekunder untuk katalog channel dan permukaan status yang lebih kaya.
docsPathstringPath dokumentasi untuk tautan penyiapan dan pemilihan.
docsLabelstringLabel override yang digunakan untuk tautan dokumentasi saat perlu berbeda dari id channel.
blurbstringDeskripsi singkat onboarding/katalog.
ordernumberUrutan penyortiran dalam katalog channel.
aliasesstring[]Alias lookup tambahan untuk pemilihan channel.
preferOverstring[]Id plugin/channel prioritas lebih rendah yang harus dikalahkan channel ini.
systemImagestringNama ikon/system-image opsional untuk katalog UI channel.
selectionDocsPrefixstringTeks awalan sebelum tautan dokumentasi di permukaan pemilihan.
selectionDocsOmitLabelbooleanTampilkan path dokumentasi secara langsung alih-alih tautan dokumentasi berlabel dalam copy pemilihan.
selectionExtrasstring[]String pendek tambahan yang ditambahkan dalam copy pemilihan.
markdownCapablebooleanMenandai channel sebagai mampu markdown untuk keputusan format keluaran.
showConfiguredbooleanMengontrol apakah permukaan daftar channel yang dikonfigurasi menampilkan channel ini.
quickstartAllowFrombooleanMenjadikan channel ini ikut serta dalam alur penyiapan allowFrom quickstart standar.
forceAccountBindingbooleanWajibkan binding akun eksplisit meskipun hanya ada satu akun.
preferSessionLookupForAnnounceTargetbooleanLebih memilih lookup sesi saat menyelesaikan target announce untuk channel ini.
Contoh:
{
  "openclaw": {
    "channel": {
      "id": "my-channel",
      "label": "My Channel",
      "selectionLabel": "My Channel (self-hosted)",
      "detailLabel": "My Channel Bot",
      "docsPath": "/channels/my-channel",
      "docsLabel": "my-channel",
      "blurb": "Webhook-based self-hosted chat integration.",
      "order": 80,
      "aliases": ["mc"],
      "preferOver": ["my-channel-legacy"],
      "selectionDocsPrefix": "Guide:",
      "selectionExtras": ["Markdown"],
      "markdownCapable": true,
      "quickstartAllowFrom": true
    }
  }
}

openclaw.install

openclaw.install adalah metadata paket, bukan metadata manifest.
FieldTypeArtinya
npmSpecstringSpesifikasi npm kanonis untuk alur install/update.
localPathstringPath instalasi bundled atau pengembangan lokal.
defaultChoice"npm" | "local"Sumber instalasi yang diutamakan saat keduanya tersedia.
minHostVersionstringVersi OpenClaw minimum yang didukung dalam format >=x.y.z.
allowInvalidConfigRecoverybooleanMengizinkan alur instal ulang bundled-plugin memulihkan kegagalan config basi tertentu.
Jika minHostVersion disetel, instalasi dan pemuatan manifest-registry sama-sama menegakkannya. Host yang lebih lama melewati plugin; string versi yang tidak valid ditolak. allowInvalidConfigRecovery bukan bypass umum untuk config yang rusak. Ini untuk pemulihan bundled-plugin yang sempit saja, sehingga instal ulang/penyiapan dapat memperbaiki sisa upgrade tertentu yang diketahui seperti path bundled plugin yang hilang atau entri channels.<id> yang basi untuk plugin yang sama. Jika config rusak karena alasan yang tidak terkait, instalasi tetap gagal tertutup dan memberi tahu operator untuk menjalankan openclaw doctor --fix. Plugin channel dapat memilih pemuatan tertunda dengan:
{
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "startup": {
      "deferConfiguredChannelFullLoadUntilAfterListen": true
    }
  }
}
Saat diaktifkan, OpenClaw hanya memuat setupEntry selama fase startup pra-listen, bahkan untuk channel yang sudah dikonfigurasi. Entry penuh dimuat setelah gateway mulai listening.
Aktifkan pemuatan tertunda hanya jika setupEntry Anda mendaftarkan semua yang dibutuhkan gateway sebelum mulai listening (pendaftaran channel, rute HTTP, metode gateway). Jika entry penuh memiliki kemampuan startup yang wajib, pertahankan perilaku default.
Jika setup/full entry Anda mendaftarkan metode RPC gateway, simpan semuanya pada awalan khusus plugin. Namespace admin inti yang dicadangkan (config.*, exec.approvals.*, wizard.*, update.*) tetap dimiliki inti dan selalu diresolve ke operator.admin.

Manifest plugin

Setiap plugin native harus menyertakan openclaw.plugin.json di root paket. OpenClaw menggunakannya untuk memvalidasi config tanpa mengeksekusi kode plugin.
{
  "id": "my-plugin",
  "name": "My Plugin",
  "description": "Adds My Plugin capabilities to OpenClaw",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "webhookSecret": {
        "type": "string",
        "description": "Webhook verification secret"
      }
    }
  }
}
Untuk plugin channel, tambahkan kind dan channels:
{
  "id": "my-channel",
  "kind": "channel",
  "channels": ["my-channel"],
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
Bahkan plugin tanpa config pun harus menyertakan schema. Schema kosong valid:
{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false
  }
}
Lihat Plugin Manifest untuk referensi schema lengkap.

Publikasi ClawHub

Untuk paket plugin, gunakan perintah ClawHub khusus paket:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
Alias publikasi khusus Skills yang lama adalah untuk Skills. Paket plugin harus selalu menggunakan clawhub package publish.

Entry penyiapan

File setup-entry.ts adalah alternatif ringan untuk index.ts yang dimuat OpenClaw saat hanya memerlukan permukaan penyiapan (onboarding, perbaikan config, pemeriksaan channel yang dinonaktifkan).
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";

export default defineSetupPluginEntry(myChannelPlugin);
Ini menghindari pemuatan kode runtime yang berat (pustaka crypto, registrasi CLI, layanan latar belakang) selama alur penyiapan. Saat OpenClaw menggunakan setupEntry alih-alih entry penuh:
  • Channel dinonaktifkan tetapi memerlukan permukaan setup/onboarding
  • Channel diaktifkan tetapi belum dikonfigurasi
  • Pemuatan tertunda diaktifkan (deferConfiguredChannelFullLoadUntilAfterListen)
Apa yang harus didaftarkan setupEntry:
  • Objek plugin channel (melalui defineSetupPluginEntry)
  • Rute HTTP apa pun yang diperlukan sebelum gateway listen
  • Metode gateway apa pun yang diperlukan selama startup
Metode gateway startup tersebut tetap harus menghindari namespace admin inti yang dicadangkan seperti config.* atau update.*. Apa yang TIDAK boleh disertakan setupEntry:
  • Registrasi CLI
  • Layanan latar belakang
  • Import runtime yang berat (crypto, SDK)
  • Metode gateway yang hanya diperlukan setelah startup

Import helper penyiapan yang sempit

Untuk path setup-only panas, utamakan seam helper penyiapan yang sempit daripada payung plugin-sdk/setup yang lebih luas saat Anda hanya memerlukan sebagian dari permukaan penyiapan:
Import pathGunakan untukExport utama
plugin-sdk/setup-runtimehelper runtime saat setup yang tetap tersedia di setupEntry / startup channel tertundacreatePatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy
plugin-sdk/setup-adapter-runtimeadapter setup akun yang sadar environmentcreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolshelper CLI/archive/dokumentasi/install saat setupformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR
Gunakan seam plugin-sdk/setup yang lebih luas saat Anda menginginkan kotak peralatan penyiapan bersama penuh, termasuk helper patch config seperti moveSingleAccountChannelSectionToDefaultAccount(...). Adapter patch setup tetap aman untuk import pada hot-path. Lookup contract-surface promosi single-account bundled yang dibawanya bersifat lazy, jadi mengimpor plugin-sdk/setup-runtime tidak secara eager memuat penemuan contract-surface bundled sebelum adapter benar-benar digunakan.

Promosi single-account yang dimiliki channel

Saat sebuah channel ditingkatkan dari config tingkat atas single-account ke channels.<id>.accounts.*, perilaku bersama default adalah memindahkan nilai bercakupan akun yang dipromosikan ke accounts.default. Bundled channel dapat mempersempit atau menimpa promosi itu melalui setup contract surface mereka:
  • singleAccountKeysToMove: key tingkat atas tambahan yang harus dipindahkan ke akun yang dipromosikan
  • namedAccountPromotionKeys: saat akun bernama sudah ada, hanya key ini yang dipindahkan ke akun yang dipromosikan; key kebijakan/pengiriman bersama tetap di root channel
  • resolveSingleAccountPromotionTarget(...): memilih akun yang ada mana yang menerima nilai yang dipromosikan
Matrix adalah contoh bundled saat ini. Jika tepat satu akun Matrix bernama sudah ada, atau jika defaultAccount menunjuk ke key non-kanonis yang sudah ada seperti Ops, promosi mempertahankan akun tersebut alih-alih membuat entri accounts.default baru.

Schema config

Config plugin divalidasi terhadap JSON Schema di manifest Anda. Pengguna mengonfigurasi plugin melalui:
{
  plugins: {
    entries: {
      "my-plugin": {
        config: {
          webhookSecret: "abc123",
        },
      },
    },
  },
}
Plugin Anda menerima config ini sebagai api.pluginConfig saat pendaftaran. Untuk config khusus channel, gunakan bagian config channel sebagai gantinya:
{
  channels: {
    "my-channel": {
      token: "bot-token",
      allowFrom: ["user1", "user2"],
    },
  },
}

Membangun schema config channel

Gunakan buildChannelConfigSchema dari openclaw/plugin-sdk/core untuk mengubah schema Zod menjadi wrapper ChannelConfigSchema yang divalidasi OpenClaw:
import { z } from "zod";
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/core";

const accountSchema = z.object({
  token: z.string().optional(),
  allowFrom: z.array(z.string()).optional(),
  accounts: z.object({}).catchall(z.any()).optional(),
  defaultAccount: z.string().optional(),
});

const configSchema = buildChannelConfigSchema(accountSchema);

Wizard penyiapan

Plugin channel dapat menyediakan wizard penyiapan interaktif untuk openclaw onboard. Wizard tersebut adalah objek ChannelSetupWizard pada ChannelPlugin:
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/channel-setup";

const setupWizard: ChannelSetupWizard = {
  channel: "my-channel",
  status: {
    configuredLabel: "Connected",
    unconfiguredLabel: "Not configured",
    resolveConfigured: ({ cfg }) => Boolean((cfg.channels as any)?.["my-channel"]?.token),
  },
  credentials: [
    {
      inputKey: "token",
      providerHint: "my-channel",
      credentialLabel: "Bot token",
      preferredEnvVar: "MY_CHANNEL_BOT_TOKEN",
      envPrompt: "Use MY_CHANNEL_BOT_TOKEN from environment?",
      keepPrompt: "Keep current token?",
      inputPrompt: "Enter your bot token:",
      inspect: ({ cfg, accountId }) => {
        const token = (cfg.channels as any)?.["my-channel"]?.token;
        return {
          accountConfigured: Boolean(token),
          hasConfiguredValue: Boolean(token),
        };
      },
    },
  ],
};
Tipe ChannelSetupWizard mendukung credentials, textInputs, dmPolicy, allowFrom, groupAccess, prepare, finalize, dan lainnya. Lihat paket bundled plugin (misalnya plugin Discord src/channel.setup.ts) untuk contoh lengkap. Untuk prompt allowlist DM yang hanya memerlukan alur standar note -> prompt -> parse -> merge -> patch, utamakan helper setup bersama dari openclaw/plugin-sdk/setup: createPromptParsedAllowFromForAccount(...), createTopLevelChannelParsedAllowFromPrompt(...), dan createNestedChannelParsedAllowFromPrompt(...). Untuk blok status setup channel yang hanya berbeda pada label, skor, dan baris tambahan opsional, utamakan createStandardChannelSetupStatus(...) dari openclaw/plugin-sdk/setup alih-alih membuat sendiri objek status yang sama di setiap plugin. Untuk permukaan penyiapan opsional yang hanya boleh muncul dalam konteks tertentu, gunakan createOptionalChannelSetupSurface dari openclaw/plugin-sdk/channel-setup:
import { createOptionalChannelSetupSurface } from "openclaw/plugin-sdk/channel-setup";

const setupSurface = createOptionalChannelSetupSurface({
  channel: "my-channel",
  label: "My Channel",
  npmSpec: "@myorg/openclaw-my-channel",
  docsPath: "/channels/my-channel",
});
// Mengembalikan { setupAdapter, setupWizard }
plugin-sdk/channel-setup juga mengekspos builder tingkat lebih rendah createOptionalChannelSetupAdapter(...) dan createOptionalChannelSetupWizard(...) saat Anda hanya memerlukan salah satu sisi dari permukaan instalasi opsional tersebut. Adapter/wizard opsional yang dihasilkan gagal tertutup pada penulisan config nyata. Mereka menggunakan kembali satu pesan install-required di validateInput, applyAccountConfig, dan finalize, serta menambahkan tautan dokumentasi saat docsPath disetel. Untuk UI setup berbasis biner, utamakan helper delegasi bersama daripada menyalin glue biner/status yang sama ke setiap channel:
  • createDetectedBinaryStatus(...) untuk blok status yang hanya berbeda pada label, hint, skor, dan deteksi biner
  • createCliPathTextInput(...) untuk input teks berbasis path
  • createDelegatedSetupWizardStatusResolvers(...), createDelegatedPrepare(...), createDelegatedFinalize(...), dan createDelegatedResolveConfigured(...) saat setupEntry perlu meneruskan ke wizard penuh yang lebih berat secara lazy
  • createDelegatedTextInputShouldPrompt(...) saat setupEntry hanya perlu mendelegasikan keputusan textInputs[*].shouldPrompt

Memublikasikan dan menginstal

Plugin eksternal: publikasikan ke ClawHub atau npm, lalu instal:
openclaw plugins install @myorg/openclaw-my-plugin
OpenClaw mencoba ClawHub terlebih dahulu dan otomatis fallback ke npm. Anda juga dapat memaksa ClawHub secara eksplisit:
openclaw plugins install clawhub:@myorg/openclaw-my-plugin   # ClawHub saja
Tidak ada override npm: yang cocok. Gunakan spesifikasi paket npm normal saat Anda menginginkan jalur npm setelah fallback ClawHub:
openclaw plugins install @myorg/openclaw-my-plugin
Plugin dalam repo: letakkan di bawah bundled plugin workspace tree dan plugin akan otomatis ditemukan selama build. Pengguna dapat menginstal:
openclaw plugins install <package-name>
Untuk instalasi yang bersumber dari npm, openclaw plugins install menjalankan npm install --ignore-scripts (tanpa lifecycle scripts). Jaga dependency tree plugin tetap JS/TS murni dan hindari paket yang memerlukan build postinstall.

Terkait