Vai al contenuto principale

Setup e configurazione dei plugin

Riferimento per il packaging dei plugin (metadati package.json), manifest (openclaw.plugin.json), setup entry e schemi di configurazione.
Cerchi una guida passo passo? Le guide pratiche coprono il packaging nel contesto: Plugin di canale e Plugin provider.

Metadati del pacchetto

Il tuo package.json ha bisogno di un campo openclaw che dica al sistema plugin cosa fornisce il tuo plugin: Plugin di canale:
{
  "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 di pubblicazione 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"
    }
  }
}
Se pubblichi il plugin esternamente su ClawHub, quei campi compat e build sono obbligatori. Gli snippet canonici di pubblicazione si trovano in docs/snippets/plugin-publish/.

Campi openclaw

CampoTipoDescrizione
extensionsstring[]File dei punti di ingresso (relativi alla root del pacchetto)
setupEntrystringEntry leggera solo setup (facoltativa)
channelobjectMetadati del catalogo canali per superfici di setup, picker, quickstart e stato
providersstring[]ID provider registrati da questo plugin
installobjectSuggerimenti di installazione: npmSpec, localPath, defaultChoice, minHostVersion, allowInvalidConfigRecovery
startupobjectFlag del comportamento di avvio

openclaw.channel

openclaw.channel è un metadato di pacchetto leggero per l’individuazione dei canali e le superfici di setup prima che il runtime venga caricato.
CampoTipoCosa significa
idstringID canale canonico.
labelstringEtichetta principale del canale.
selectionLabelstringEtichetta del picker/setup quando deve differire da label.
detailLabelstringEtichetta di dettaglio secondaria per cataloghi di canali e superfici di stato più ricchi.
docsPathstringPercorso documentazione per i link di setup e selezione.
docsLabelstringOverride dell’etichetta usata per i link alla documentazione quando deve differire dall’ID del canale.
blurbstringBreve descrizione per onboarding/catalogo.
ordernumberOrdine di ordinamento nei cataloghi dei canali.
aliasesstring[]Alias aggiuntivi per il lookup nella selezione del canale.
preferOverstring[]ID plugin/canale a priorità inferiore rispetto ai quali questo canale deve prevalere.
systemImagestringNome facoltativo di icona/immagine di sistema per cataloghi UI dei canali.
selectionDocsPrefixstringTesto prefisso prima dei link alla documentazione nelle superfici di selezione.
selectionDocsOmitLabelbooleanMostra direttamente il percorso documentazione invece di un link etichettato nella copia di selezione.
selectionExtrasstring[]Stringhe brevi aggiuntive aggiunte nella copia di selezione.
markdownCapablebooleanContrassegna il canale come compatibile con Markdown per le decisioni di formattazione in uscita.
showConfiguredbooleanControlla se le superfici che elencano i canali configurati mostrano questo canale.
quickstartAllowFrombooleanInclude questo canale nel flusso standard di setup quickstart allowFrom.
forceAccountBindingbooleanRichiede binding esplicito dell’account anche quando esiste un solo account.
preferSessionLookupForAnnounceTargetbooleanPreferisce la ricerca sessione quando risolve i target di annuncio per questo canale.
Esempio:
{
  "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 è un metadato di pacchetto, non un metadato di manifest.
CampoTipoCosa significa
npmSpecstringnpm spec canonica per i flussi di installazione/aggiornamento.
localPathstringPercorso di installazione locale di sviluppo o bundled.
defaultChoice"npm" | "local"Sorgente di installazione preferita quando entrambe sono disponibili.
minHostVersionstringVersione minima supportata di OpenClaw nel formato >=x.y.z.
allowInvalidConfigRecoverybooleanConsente ai flussi di reinstallazione dei plugin bundled di recuperare da specifici errori di configurazione obsoleta.
Se minHostVersion è impostato, sia l’installazione sia il caricamento del registro dei manifest lo applicano. Gli host più vecchi saltano il plugin; le stringhe di versione non valide vengono rifiutate. allowInvalidConfigRecovery non è un bypass generale per configurazioni non valide. Serve solo per il recupero ristretto dei plugin bundled, così reinstallazione/setup possono riparare residui di upgrade noti come un percorso mancante di plugin bundled o una voce obsoleta channels.<id> per quello stesso plugin. Se la configurazione è danneggiata per motivi non correlati, l’installazione continua comunque a fallire in chiusura e dice all’operatore di eseguire openclaw doctor --fix.

Caricamento completo differito

I plugin di canale possono scegliere il caricamento differito con:
{
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "startup": {
      "deferConfiguredChannelFullLoadUntilAfterListen": true
    }
  }
}
Quando abilitato, OpenClaw carica solo setupEntry durante la fase di avvio pre-listen, anche per canali già configurati. L’entry completa viene caricata dopo che il gateway inizia ad ascoltare.
Abilita il caricamento differito solo quando setupEntry registra tutto ciò di cui il gateway ha bisogno prima di iniziare ad ascoltare (registrazione del canale, route HTTP, metodi gateway). Se l’entry completa possiede capacità di avvio necessarie, mantieni il comportamento predefinito.
Se il tuo setup/full entry registra metodi RPC del gateway, mantienili su un prefisso specifico del plugin. Gli spazi dei nomi admin core riservati (config.*, exec.approvals.*, wizard.*, update.*) restano di proprietà del core e si risolvono sempre in operator.admin.

Manifest del plugin

Ogni plugin nativo deve includere un file openclaw.plugin.json nella root del pacchetto. OpenClaw lo usa per validare la configurazione senza eseguire il codice del 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"
      }
    }
  }
}
Per i plugin di canale, aggiungi kind e channels:
{
  "id": "my-channel",
  "kind": "channel",
  "channels": ["my-channel"],
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
Anche i plugin senza configurazione devono includere uno schema. Uno schema vuoto è valido:
{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false
  }
}
Vedi Manifest del plugin per il riferimento completo dello schema.

Pubblicazione su ClawHub

Per i pacchetti plugin, usa il comando ClawHub specifico del pacchetto:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
L’alias di pubblicazione legacy solo per Skills è destinato alle Skills. I pacchetti plugin dovrebbero usare sempre clawhub package publish.

Setup entry

Il file setup-entry.ts è un’alternativa leggera a index.ts che OpenClaw carica quando ha bisogno solo delle superfici di setup (onboarding, riparazione della configurazione, ispezione di canali disabilitati).
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";

export default defineSetupPluginEntry(myChannelPlugin);
Questo evita di caricare codice runtime pesante (librerie crittografiche, registrazioni CLI, servizi in background) durante i flussi di setup. Quando OpenClaw usa setupEntry invece dell’entry completa:
  • Il canale è disabilitato ma necessita di superfici setup/onboarding
  • Il canale è abilitato ma non configurato
  • Il caricamento differito è abilitato (deferConfiguredChannelFullLoadUntilAfterListen)
Cosa deve registrare setupEntry:
  • L’oggetto plugin del canale (tramite defineSetupPluginEntry)
  • Eventuali route HTTP richieste prima che il gateway inizi ad ascoltare
  • Eventuali metodi gateway necessari durante l’avvio
Quei metodi gateway di avvio dovrebbero comunque evitare gli spazi dei nomi admin core riservati come config.* o update.*. Cosa NON dovrebbe includere setupEntry:
  • Registrazioni CLI
  • Servizi in background
  • Import runtime pesanti (crypto, SDK)
  • Metodi gateway necessari solo dopo l’avvio

Import helper setup ristretti

Per i percorsi hot solo setup, preferisci le seam degli helper setup ristretti rispetto all’ombrello più ampio plugin-sdk/setup quando ti serve solo una parte della superficie setup:
Percorso di importUsalo perExport principali
plugin-sdk/setup-runtimehelper runtime in fase di setup che restano disponibili in setupEntry / avvio differito del canalecreatePatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy
plugin-sdk/setup-adapter-runtimeadapter di setup account consapevoli dell’ambientecreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolshelper CLI/archivio/documentazione per setup/installazioneformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR
Usa la seam più ampia plugin-sdk/setup quando vuoi l’intera cassetta degli attrezzi setup condivisa, inclusi helper di patch della configurazione come moveSingleAccountChannelSectionToDefaultAccount(...). Gli adapter di patch setup restano sicuri sul percorso hot all’importazione. Il loro lookup della surface di contratto bundled per la promozione single-account è lazy, quindi importare plugin-sdk/setup-runtime non carica eager la discovery della contract-surface bundled prima che l’adapter venga effettivamente usato.

Promozione single-account posseduta dal canale

Quando un canale passa da una configurazione top-level single-account a channels.<id>.accounts.*, il comportamento condiviso predefinito consiste nello spostare i valori account-scoped promossi in accounts.default. I canali bundled possono restringere o sovrascrivere quella promozione tramite la loro contract-surface di setup:
  • singleAccountKeysToMove: chiavi top-level aggiuntive che devono essere spostate nell’account promosso
  • namedAccountPromotionKeys: quando esistono già account nominati, solo queste chiavi vengono spostate nell’account promosso; le chiavi condivise di policy/delivery restano alla root del canale
  • resolveSingleAccountPromotionTarget(...): sceglie quale account esistente riceve i valori promossi
Matrix è l’esempio bundled attuale. Se esiste già esattamente un account Matrix nominato, oppure se defaultAccount punta a una chiave non canonica esistente come Ops, la promozione preserva quell’account invece di creare una nuova voce accounts.default.

Schema di configurazione

La configurazione del plugin viene validata rispetto allo JSON Schema nel tuo manifest. Gli utenti configurano i plugin tramite:
{
  plugins: {
    entries: {
      "my-plugin": {
        config: {
          webhookSecret: "abc123",
        },
      },
    },
  },
}
Il tuo plugin riceve questa configurazione come api.pluginConfig durante la registrazione. Per la configurazione specifica del canale, usa invece la sezione di configurazione del canale:
{
  channels: {
    "my-channel": {
      token: "bot-token",
      allowFrom: ["user1", "user2"],
    },
  },
}

Costruire schemi di configurazione del canale

Usa buildChannelConfigSchema da openclaw/plugin-sdk/core per convertire uno schema Zod nel wrapper ChannelConfigSchema che OpenClaw valida:
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);

Procedure guidate di setup

I plugin di canale possono fornire procedure guidate di setup interattive per openclaw onboard. La procedura guidata è un oggetto ChannelSetupWizard nel 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),
        };
      },
    },
  ],
};
Il tipo ChannelSetupWizard supporta credentials, textInputs, dmPolicy, allowFrom, groupAccess, prepare, finalize e altro ancora. Vedi i pacchetti plugin bundled (per esempio il plugin Discord src/channel.setup.ts) per esempi completi. Per prompt di allowlist DM che richiedono solo il flusso standard note -> prompt -> parse -> merge -> patch, preferisci gli helper setup condivisi di openclaw/plugin-sdk/setup: createPromptParsedAllowFromForAccount(...), createTopLevelChannelParsedAllowFromPrompt(...) e createNestedChannelParsedAllowFromPrompt(...). Per blocchi di stato del setup del canale che variano solo per etichette, punteggi e righe extra facoltative, preferisci createStandardChannelSetupStatus(...) da openclaw/plugin-sdk/setup invece di ricreare manualmente lo stesso oggetto status in ogni plugin. Per superfici di setup facoltative che dovrebbero apparire solo in certi contesti, usa createOptionalChannelSetupSurface da 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",
});
// Restituisce { setupAdapter, setupWizard }
plugin-sdk/channel-setup espone anche i builder di livello inferiore createOptionalChannelSetupAdapter(...) e createOptionalChannelSetupWizard(...) quando ti serve solo una metà di quella superficie di installazione facoltativa. L’adapter/procedura guidata facoltativi generati falliscono in chiusura sulle vere scritture di configurazione. Riutilizzano un unico messaggio “installazione richiesta” in validateInput, applyAccountConfig e finalize, e aggiungono un link alla documentazione quando docsPath è impostato. Per interfacce di setup basate su binari, preferisci gli helper delegati condivisi invece di copiare la stessa logica di stato/binario in ogni canale:
  • createDetectedBinaryStatus(...) per blocchi di stato che variano solo per etichette, hint, punteggi e rilevamento binari
  • createCliPathTextInput(...) per input testuali basati su percorso
  • createDelegatedSetupWizardStatusResolvers(...), createDelegatedPrepare(...), createDelegatedFinalize(...) e createDelegatedResolveConfigured(...) quando setupEntry deve inoltrare lazy a una procedura guidata completa più pesante
  • createDelegatedTextInputShouldPrompt(...) quando setupEntry deve solo delegare una decisione textInputs[*].shouldPrompt

Pubblicazione e installazione

Plugin esterni: pubblica su ClawHub o npm, poi installa:
openclaw plugins install @myorg/openclaw-my-plugin
OpenClaw prova prima ClawHub e torna automaticamente a npm in fallback. Puoi anche forzare esplicitamente ClawHub:
openclaw plugins install clawhub:@myorg/openclaw-my-plugin   # solo ClawHub
Non esiste un override corrispondente npm:. Usa la normale npm package spec quando vuoi il percorso npm dopo il fallback ClawHub:
openclaw plugins install @myorg/openclaw-my-plugin
Plugin nel repo: posizionali sotto l’albero workspace dei plugin bundled e verranno automaticamente rilevati durante la build. Gli utenti possono installare:
openclaw plugins install <package-name>
Per le installazioni da npm, openclaw plugins install esegue npm install --ignore-scripts (nessuno script lifecycle). Mantieni l’albero delle dipendenze dei plugin puro JS/TS ed evita pacchetti che richiedono build postinstall.

Correlati