Passer au contenu principal
Référence pour le packaging de Plugin (métadonnées package.json), les manifestes (openclaw.plugin.json), les entrées de configuration initiale et les schémas de configuration.
Vous cherchez un guide pas à pas ? Les guides pratiques couvrent le packaging en contexte : Plugins de canal et Plugins fournisseur.

Métadonnées de package

Votre package.json doit contenir un champ openclaw qui indique au système de Plugins ce que fournit votre Plugin :
{
  "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."
    }
  }
}
Si vous publiez le Plugin en externe sur ClawHub, ces champs compat et build sont obligatoires. Les extraits de publication canoniques se trouvent dans docs/snippets/plugin-publish/.

Champs openclaw

extensions
string[]
Fichiers de point d’entrée (relatifs à la racine du package).
setupEntry
string
Entrée légère réservée à la configuration initiale (facultative).
channel
object
Métadonnées du catalogue de canaux pour les surfaces de configuration initiale, de sélection, de démarrage rapide et d’état.
providers
string[]
Identifiants de fournisseurs enregistrés par ce Plugin.
install
object
Indications d’installation : npmSpec, localPath, defaultChoice, minHostVersion, expectedIntegrity, allowInvalidConfigRecovery.
startup
object
Indicateurs de comportement au démarrage.

openclaw.channel

openclaw.channel correspond à des métadonnées de package peu coûteuses pour la découverte des canaux et les surfaces de configuration initiale avant le chargement du runtime.
ChampTypeSignification
idstringIdentifiant canonique du canal.
labelstringLibellé principal du canal.
selectionLabelstringLibellé de sélection/configuration initiale lorsqu’il doit différer de label.
detailLabelstringLibellé de détail secondaire pour des catalogues de canaux et surfaces d’état plus riches.
docsPathstringChemin de documentation pour les liens de configuration initiale et de sélection.
docsLabelstringLibellé de remplacement utilisé pour les liens de documentation lorsqu’il doit différer de l’identifiant du canal.
blurbstringBrève description d’onboarding/de catalogue.
ordernumberOrdre de tri dans les catalogues de canaux.
aliasesstring[]Alias de recherche supplémentaires pour la sélection du canal.
preferOverstring[]Identifiants de Plugin/canal de priorité inférieure que ce canal doit devancer.
systemImagestringNom facultatif d’icône/image système pour les catalogues d’interface de canaux.
selectionDocsPrefixstringTexte de préfixe avant les liens de documentation dans les surfaces de sélection.
selectionDocsOmitLabelbooleanAffiche directement le chemin de documentation au lieu d’un lien de documentation libellé dans le texte de sélection.
selectionExtrasstring[]Courtes chaînes supplémentaires ajoutées au texte de sélection.
markdownCapablebooleanMarque le canal comme compatible Markdown pour les décisions de mise en forme sortante.
exposureobjectContrôles de visibilité du canal pour la configuration initiale, les listes configurées et les surfaces de documentation.
quickstartAllowFrombooleanActive ce canal dans le flux standard de démarrage rapide allowFrom.
forceAccountBindingbooleanExige une liaison explicite du compte même lorsqu’un seul compte existe.
preferSessionLookupForAnnounceTargetbooleanPréfère la recherche de session lors de la résolution des cibles d’annonce pour ce canal.
Exemple :
{
  "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,
      "exposure": {
        "configured": true,
        "setup": true,
        "docs": true
      },
      "quickstartAllowFrom": true
    }
  }
}
exposure prend en charge :
  • configured : inclure le canal dans les surfaces de liste de type configuré/état
  • setup : inclure le canal dans les sélecteurs interactifs de configuration initiale/configuration
  • docs : marquer le canal comme public dans les surfaces de documentation/navigation
showConfigured et showInSetup restent pris en charge comme alias hérités. Préférez exposure.

openclaw.install

openclaw.install correspond à des métadonnées de package, pas à des métadonnées de manifeste.
ChampTypeSignification
clawhubSpecstringSpécification ClawHub canonique pour les flux d’installation/mise à jour et d’installation à la demande lors de l’onboarding.
npmSpecstringSpécification npm canonique pour les flux de secours d’installation/mise à jour.
localPathstringChemin d’installation local de développement ou groupé.
defaultChoice"clawhub" | "npm" | "local"Source d’installation préférée lorsque plusieurs sources sont disponibles.
minHostVersionstringVersion minimale prise en charge d’OpenClaw sous la forme >=x.y.z ou >=x.y.z-prerelease.
expectedIntegritystringChaîne d’intégrité npm dist attendue, généralement sha512-..., pour les installations épinglées.
allowInvalidConfigRecoverybooleanPermet aux flux de réinstallation de Plugins groupés de récupérer après certaines défaillances de configuration obsolète.
requiredPlatformPackagesstring[]Alias npm propres à la plateforme requis et vérifiés pendant l’installation npm.
L’onboarding interactif utilise également openclaw.install pour les surfaces d’installation à la demande. Si votre Plugin expose des choix d’authentification fournisseur ou des métadonnées de configuration initiale/catalogue de canal avant le chargement du runtime, l’onboarding peut afficher ce choix, demander une installation via ClawHub, npm ou locale, installer ou activer le Plugin, puis poursuivre le flux sélectionné. Les choix d’onboarding ClawHub utilisent clawhubSpec et sont préférés lorsqu’ils sont présents ; les choix npm nécessitent des métadonnées de catalogue approuvées avec un npmSpec de registre ; les versions exactes et expectedIntegrity sont des épinglages npm facultatifs. Si expectedIntegrity est présent, les flux d’installation/mise à jour l’appliquent pour npm. Conservez les métadonnées « quoi afficher » dans openclaw.plugin.json et les métadonnées « comment l’installer » dans package.json.
Si minHostVersion est défini, l’installation et le chargement non groupé depuis le registre de manifestes l’appliquent tous les deux. Les hôtes plus anciens ignorent les Plugins externes ; les chaînes de version invalides sont rejetées. Les Plugins source groupés sont supposés être co-versionnés avec le checkout de l’hôte.
Pour les installations npm épinglées, conservez la version exacte dans npmSpec et ajoutez l’intégrité attendue de l’artefact :
{
  "openclaw": {
    "install": {
      "npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3",
      "expectedIntegrity": "sha512-REPLACE_WITH_NPM_DIST_INTEGRITY",
      "defaultChoice": "npm"
    }
  }
}
allowInvalidConfigRecovery n’est pas un contournement général pour les configurations cassées. Il est réservé à une récupération étroite des Plugins groupés, afin que la réinstallation/configuration initiale puisse réparer des restes de mise à niveau connus, comme un chemin de Plugin groupé manquant ou une entrée channels.<id> obsolète pour ce même Plugin. Si la configuration est cassée pour des raisons sans rapport, l’installation échoue toujours de manière fermée et indique à l’opérateur d’exécuter openclaw doctor --fix.

Chargement complet différé

Les Plugins de canal peuvent opter pour le chargement différé avec :
{
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "startup": {
      "deferConfiguredChannelFullLoadUntilAfterListen": true
    }
  }
}
Lorsque cette option est activée, OpenClaw charge uniquement setupEntry pendant la phase de démarrage avant écoute, même pour les canaux déjà configurés. L’entrée complète se charge après que le Gateway commence à écouter.
N’activez le chargement différé que lorsque votre setupEntry enregistre tout ce dont le Gateway a besoin avant de commencer à écouter (enregistrement du canal, routes HTTP, méthodes du Gateway). Si l’entrée complète possède des capacités de démarrage requises, conservez le comportement par défaut.
Si votre entrée de configuration initiale/complète enregistre des méthodes RPC du Gateway, gardez-les sur un préfixe propre au Plugin. Les espaces de noms d’administration centrale réservés (config.*, exec.approvals.*, wizard.*, update.*) restent détenus par le cœur et se résolvent toujours vers operator.admin.

Manifeste de Plugin

Chaque Plugin natif doit fournir un openclaw.plugin.json à la racine du package. OpenClaw l’utilise pour valider la configuration sans exécuter le code du 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"
      }
    }
  }
}
Pour les Plugins de canal, ajoutez kind et channels :
{
  "id": "my-channel",
  "kind": "channel",
  "channels": ["my-channel"],
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
Même les plugins sans configuration doivent livrer un schéma. Un schéma vide est valide :
{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false
  }
}
Consultez Manifeste de Plugin pour la référence complète du schéma.

Publication ClawHub

Pour les packages de plugins, utilisez la commande ClawHub propre au package :
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
L’ancien alias de publication réservé aux Skills concerne les Skills. Les packages de plugins doivent toujours utiliser clawhub package publish.

Point d’entrée de configuration

Le fichier setup-entry.ts est une alternative légère à index.ts qu’OpenClaw charge lorsqu’il n’a besoin que des surfaces de configuration (intégration, réparation de configuration, inspection des canaux désactivés).
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";

export default defineSetupPluginEntry(myChannelPlugin);
Cela évite de charger du code d’exécution lourd (bibliothèques de chiffrement, enregistrements CLI, services d’arrière-plan) pendant les flux de configuration. Les canaux d’espace de travail groupés qui conservent des exports compatibles avec la configuration dans des modules annexes peuvent utiliser defineBundledChannelSetupEntry(...) depuis openclaw/plugin-sdk/channel-entry-contract au lieu de defineSetupPluginEntry(...). Ce contrat groupé prend aussi en charge un export runtime facultatif afin que le câblage d’exécution au moment de la configuration reste léger et explicite.
  • Le canal est désactivé mais nécessite des surfaces de configuration/intégration.
  • Le canal est activé mais non configuré.
  • Le chargement différé est activé (deferConfiguredChannelFullLoadUntilAfterListen).
  • L’objet plugin de canal (via defineSetupPluginEntry).
  • Toute route HTTP requise avant l’écoute du Gateway.
  • Toute méthode Gateway nécessaire pendant le démarrage.
Ces méthodes Gateway de démarrage doivent quand même éviter les espaces de noms d’administration réservés du noyau, comme config.* ou update.*.
  • Les enregistrements CLI.
  • Les services d’arrière-plan.
  • Les imports d’exécution lourds (chiffrement, SDK).
  • Les méthodes Gateway nécessaires uniquement après le démarrage.

Imports étroits des assistants de configuration

Pour les chemins chauds uniquement liés à la configuration, préférez les surfaces étroites d’assistants de configuration au module global plus large plugin-sdk/setup lorsque vous n’avez besoin que d’une partie de la surface de configuration :
Chemin d’importÀ utiliser pourExports clés
plugin-sdk/setup-runtimeassistants d’exécution au moment de la configuration qui restent disponibles dans setupEntry / démarrage différé des canauxcreateSetupTranslator, createPatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy
plugin-sdk/setup-adapter-runtimealias de compatibilité obsolète ; utilisez plugin-sdk/setup-runtimecreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolsassistants CLI/archive/docs pour la configuration/l’installationformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR
Utilisez la surface plus large plugin-sdk/setup lorsque vous voulez la boîte à outils de configuration partagée complète, y compris les assistants de correctifs de configuration tels que moveSingleAccountChannelSectionToDefaultAccount(...). Utilisez createSetupTranslator(...) pour les textes fixes de l’assistant de configuration. Il suit la locale de l’assistant CLI (OPENCLAW_LOCALE, puis les variables de locale du système) et revient à l’anglais par défaut. Conservez le texte de configuration propre au plugin dans le code appartenant au plugin et utilisez les clés de catalogue partagées uniquement pour les libellés de configuration communs, le texte d’état et le texte de configuration des plugins groupés officiels. Les adaptateurs de correctifs de configuration restent sûrs à importer dans les chemins chauds. Leur recherche de surface de contrat de promotion groupée à compte unique est paresseuse, donc importer plugin-sdk/setup-runtime ne charge pas avidement la découverte des surfaces de contrat groupées avant que l’adaptateur ne soit réellement utilisé.

Promotion de compte unique appartenant au canal

Lorsqu’un canal passe d’une configuration de premier niveau à compte unique à channels.<id>.accounts.*, le comportement partagé par défaut consiste à déplacer les valeurs promues liées au compte dans accounts.default. Les canaux groupés peuvent restreindre ou remplacer cette promotion via leur surface de contrat de configuration :
  • singleAccountKeysToMove : clés de premier niveau supplémentaires qui doivent être déplacées dans le compte promu
  • namedAccountPromotionKeys : lorsque des comptes nommés existent déjà, seules ces clés sont déplacées dans le compte promu ; les clés de stratégie/livraison partagées restent à la racine du canal
  • resolveSingleAccountPromotionTarget(...) : choisir quel compte existant reçoit les valeurs promues
Matrix est l’exemple groupé actuel. Si exactement un compte Matrix nommé existe déjà, ou si defaultAccount pointe vers une clé non canonique existante comme Ops, la promotion préserve ce compte au lieu de créer une nouvelle entrée accounts.default.

Schéma de configuration

La configuration du plugin est validée avec le JSON Schema dans votre manifeste. Les utilisateurs configurent les plugins via :
{
  plugins: {
    entries: {
      "my-plugin": {
        config: {
          webhookSecret: "abc123",
        },
      },
    },
  },
}
Votre plugin reçoit cette configuration sous la forme api.pluginConfig pendant l’enregistrement. Pour une configuration propre à un canal, utilisez plutôt la section de configuration du canal :
{
  channels: {
    "my-channel": {
      token: "bot-token",
      allowFrom: ["user1", "user2"],
    },
  },
}

Construction de schémas de configuration de canal

Utilisez buildChannelConfigSchema pour convertir un schéma Zod en enveloppe ChannelConfigSchema utilisée par les artefacts de configuration appartenant au plugin :
import { z } from "zod";
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";

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);
Si vous rédigez déjà le contrat en JSON Schema ou TypeBox, utilisez l’assistant direct afin qu’OpenClaw puisse ignorer la conversion Zod vers JSON Schema sur les chemins de métadonnées :
import { Type } from "typebox";
import { buildJsonChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";

const configSchema = buildJsonChannelConfigSchema(
  Type.Object({
    token: Type.Optional(Type.String()),
    allowFrom: Type.Optional(Type.Array(Type.String())),
  }),
);
Pour les plugins tiers, le contrat du chemin froid reste le manifeste du plugin : reproduisez le JSON Schema généré dans openclaw.plugin.json#channelConfigs afin que les surfaces de schéma de configuration, de configuration et d’interface puissent inspecter channels.<id> sans charger le code d’exécution.

Assistants de configuration

Les plugins de canal peuvent fournir des assistants de configuration interactifs pour openclaw onboard. L’assistant est un objet ChannelSetupWizard sur le 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),
        };
      },
    },
  ],
};
Le type ChannelSetupWizard prend en charge credentials, textInputs, dmPolicy, allowFrom, groupAccess, prepare, finalize, et plus encore. Consultez les packages de plugins groupés (par exemple le plugin Discord src/channel.setup.ts) pour des exemples complets.
Pour les invites de liste d’autorisation de DM qui n’ont besoin que du flux standard note -> prompt -> parse -> merge -> patch, préférez les assistants de configuration partagés de openclaw/plugin-sdk/setup : createPromptParsedAllowFromForAccount(...), createTopLevelChannelParsedAllowFromPrompt(...) et createNestedChannelParsedAllowFromPrompt(...).
Pour les blocs d’état de configuration de canal qui ne varient que par les libellés, les scores et les lignes supplémentaires facultatives, préférez createStandardChannelSetupStatus(...) depuis openclaw/plugin-sdk/setup au lieu de recréer manuellement le même objet status dans chaque plugin.
Pour les surfaces de configuration facultatives qui ne doivent apparaître que dans certains contextes, utilisez createOptionalChannelSetupSurface depuis 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",
});
// Returns { setupAdapter, setupWizard }
plugin-sdk/channel-setup expose aussi les constructeurs de plus bas niveau createOptionalChannelSetupAdapter(...) et createOptionalChannelSetupWizard(...) lorsque vous n’avez besoin que d’une moitié de cette surface d’installation facultative.L’adaptateur/l’assistant facultatif généré échoue de manière fermée lors de vraies écritures de configuration. Ils réutilisent un message d’installation requise unique dans validateInput, applyAccountConfig et finalize, et ajoutent un lien vers la documentation lorsque docsPath est défini.
Pour les interfaces de configuration adossées à un binaire, préférez les assistants délégués partagés au lieu de copier le même raccordement binaire/état dans chaque canal :
  • createDetectedBinaryStatus(...) pour les blocs d’état qui ne varient que par les libellés, les indications, les scores et la détection binaire
  • createCliPathTextInput(...) pour les champs de texte adossés à des chemins
  • createDelegatedSetupWizardStatusResolvers(...), createDelegatedPrepare(...), createDelegatedFinalize(...) et createDelegatedResolveConfigured(...) lorsque setupEntry doit transférer paresseusement vers un assistant complet plus lourd
  • createDelegatedTextInputShouldPrompt(...) lorsque setupEntry doit uniquement déléguer une décision textInputs[*].shouldPrompt

Publication et installation

Plugins externes : publiez sur ClawHub, puis installez :
openclaw plugins install @myorg/openclaw-my-plugin
Les spécifications de paquets nues s’installent depuis npm pendant le basculement de lancement.
Plugins dans le dépôt : placez-les sous l’arborescence de l’espace de travail des plugins intégrés ; ils seront automatiquement découverts pendant la compilation. Les utilisateurs peuvent installer :
openclaw plugins install <package-name>
Pour les installations provenant de npm, openclaw plugins install installe le paquet dans un projet propre à chaque plugin sous ~/.openclaw/npm/projects, avec les scripts de cycle de vie désactivés. Gardez les arborescences de dépendances des plugins en JS/TS pur et évitez les paquets qui nécessitent des compilations postinstall.
Le démarrage du Gateway n’installe pas les dépendances des plugins. Les flux d’installation npm/git/ClawHub sont responsables de la convergence des dépendances ; les dépendances des plugins locaux doivent déjà être installées.
Les métadonnées des paquets intégrés sont explicites, et non déduites du JavaScript compilé au démarrage du Gateway. Les dépendances d’exécution appartiennent au paquet de plugin qui les possède ; le démarrage d’OpenClaw empaqueté ne répare ni ne duplique jamais les dépendances des plugins.

Associé