Pular para o conteúdo principal

Setup e configuração de plugins

Referência para empacotamento de plugins (metadados em package.json), manifestos (openclaw.plugin.json), entradas de setup e schemas de configuração.
Procurando um passo a passo? Os guias práticos abordam o empacotamento em contexto: Plugins de canal e Plugins de provedor.

Metadados do pacote

Seu package.json precisa de um campo openclaw que informa ao sistema de plugins o que seu plugin fornece: Plugin de canal:
{
  "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 de provedor / baseline de publicação do 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 você publicar o plugin externamente no ClawHub, esses campos compat e build serão obrigatórios. Os snippets canônicos de publicação ficam em docs/snippets/plugin-publish/.

Campos openclaw

CampoTipoDescrição
extensionsstring[]Arquivos de entry point (relativos à raiz do pacote)
setupEntrystringEntry leve apenas para setup (opcional)
channelobjectMetadados do catálogo de canais para superfícies de setup, seletor, quickstart e status
providersstring[]IDs de provedor registrados por este plugin
installobjectDicas de instalação: npmSpec, localPath, defaultChoice, minHostVersion, allowInvalidConfigRecovery
startupobjectFlags de comportamento de inicialização

openclaw.channel

openclaw.channel são metadados leves de pacote para descoberta de canal e superfícies de setup antes do carregamento do runtime.
CampoTipoO que significa
idstringID canônico do canal.
labelstringRótulo principal do canal.
selectionLabelstringRótulo no seletor/setup quando deve diferir de label.
detailLabelstringRótulo de detalhe secundário para catálogos de canais e superfícies de status mais ricos.
docsPathstringCaminho da documentação para links de setup e seleção.
docsLabelstringSubstitui o rótulo usado para links de documentação quando deve diferir do ID do canal.
blurbstringDescrição curta para onboarding/catálogo.
ordernumberOrdem de classificação em catálogos de canais.
aliasesstring[]Aliases extras de lookup para seleção de canal.
preferOverstring[]IDs de plugin/canal de prioridade inferior que este canal deve superar.
systemImagestringNome opcional de ícone/system image para catálogos de UI de canal.
selectionDocsPrefixstringTexto de prefixo antes dos links de documentação em superfícies de seleção.
selectionDocsOmitLabelbooleanMostra o caminho da documentação diretamente em vez de um link rotulado na cópia de seleção.
selectionExtrasstring[]Strings curtas extras acrescentadas na cópia de seleção.
markdownCapablebooleanMarca o canal como compatível com Markdown para decisões de formatação de saída.
showConfiguredbooleanControla se superfícies de listagem de canais configurados mostram este canal.
quickstartAllowFrombooleanInclui este canal no fluxo padrão de setup allowFrom do quickstart.
forceAccountBindingbooleanExige vinculação explícita de conta mesmo quando existe apenas uma conta.
preferSessionLookupForAnnounceTargetbooleanPrefere lookup de sessão ao resolver destinos de anúncio para este canal.
Exemplo:
{
  "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 é metadado do pacote, não metadado do manifesto.
CampoTipoO que significa
npmSpecstringSpec npm canônica para fluxos de instalação/atualização.
localPathstringCaminho de instalação local de desenvolvimento ou integrada.
defaultChoice"npm" | "local"Fonte de instalação preferida quando ambas estão disponíveis.
minHostVersionstringVersão mínima compatível do OpenClaw no formato >=x.y.z.
allowInvalidConfigRecoverybooleanPermite que fluxos de reinstalação de plugins integrados recuperem falhas específicas de configuração obsoleta.
Se minHostVersion estiver definido, tanto a instalação quanto o carregamento do registro de manifesto o aplicarão. Hosts mais antigos ignoram o plugin; strings de versão inválidas são rejeitadas. allowInvalidConfigRecovery não é um bypass geral para configurações quebradas. Ele é para recuperação estreita de plugins integrados apenas, para que reinstalação/setup possa reparar sobras conhecidas de upgrade como um caminho ausente de plugin integrado ou uma entrada obsoleta channels.<id> para esse mesmo plugin. Se a configuração estiver quebrada por motivos não relacionados, a instalação ainda falhará de forma fechada e orientará o operador a executar openclaw doctor --fix.

Carga completa adiada

Plugins de canal podem optar por carregamento adiado com:
{
  "openclaw": {
    "extensions": ["./index.ts"],
    "setupEntry": "./setup-entry.ts",
    "startup": {
      "deferConfiguredChannelFullLoadUntilAfterListen": true
    }
  }
}
Quando habilitado, o OpenClaw carrega apenas setupEntry durante a fase de inicialização pré-listen, mesmo para canais já configurados. A entrada completa é carregada depois que o gateway começa a escutar.
Ative o carregamento adiado somente quando seu setupEntry registrar tudo o que o gateway precisa antes de começar a escutar (registro de canal, rotas HTTP, métodos do gateway). Se a entrada completa for responsável por capacidades necessárias na inicialização, mantenha o comportamento padrão.
Se sua entrada de setup/completa registrar métodos RPC do gateway, mantenha-os em um prefixo específico do plugin. Namespaces administrativos reservados do core (config.*, exec.approvals.*, wizard.*, update.*) continuam pertencendo ao core e sempre resolvem para operator.admin.

Manifesto do plugin

Todo plugin nativo deve incluir um openclaw.plugin.json na raiz do pacote. O OpenClaw usa isso para validar a configuração sem executar o código do 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"
      }
    }
  }
}
Para plugins de canal, adicione kind e channels:
{
  "id": "my-channel",
  "kind": "channel",
  "channels": ["my-channel"],
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
Mesmo plugins sem configuração precisam incluir um schema. Um schema vazio é válido:
{
  "id": "my-plugin",
  "configSchema": {
    "type": "object",
    "additionalProperties": false
  }
}
Veja Manifesto do plugin para a referência completa do schema.

Publicação no ClawHub

Para pacotes de plugin, use o comando do ClawHub específico para pacote:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
O alias legado de publicação apenas de skill é para Skills. Pacotes de plugin devem sempre usar clawhub package publish.

Entry de setup

O arquivo setup-entry.ts é uma alternativa leve ao index.ts que o OpenClaw carrega quando precisa apenas de superfícies de setup (onboarding, reparo de configuração, inspeção de canal desativado).
// setup-entry.ts
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core";
import { myChannelPlugin } from "./src/channel.js";

export default defineSetupPluginEntry(myChannelPlugin);
Isso evita carregar código pesado de runtime (bibliotecas de criptografia, registros de CLI, serviços em segundo plano) durante fluxos de setup. Quando o OpenClaw usa setupEntry em vez da entrada completa:
  • O canal está desativado, mas precisa de superfícies de setup/onboarding
  • O canal está habilitado, mas não configurado
  • O carregamento adiado está habilitado (deferConfiguredChannelFullLoadUntilAfterListen)
O que setupEntry deve registrar:
  • O objeto do plugin de canal (via defineSetupPluginEntry)
  • Quaisquer rotas HTTP necessárias antes de o gateway começar a escutar
  • Quaisquer métodos do gateway necessários durante a inicialização
Esses métodos do gateway de inicialização ainda devem evitar namespaces administrativos reservados do core, como config.* ou update.*. O que setupEntry NÃO deve incluir:
  • Registros de CLI
  • Serviços em segundo plano
  • Imports pesados de runtime (crypto, SDKs)
  • Métodos do gateway necessários apenas após a inicialização

Imports estreitos de helpers de setup

Para caminhos quentes somente de setup, prefira as superfícies estreitas de helpers de setup em vez da superfície guarda-chuva mais ampla plugin-sdk/setup quando você precisar apenas de parte da superfície de setup:
Caminho de importaçãoUse paraExportações principais
plugin-sdk/setup-runtimehelpers de runtime em tempo de setup que continuam disponíveis em setupEntry / inicialização adiada de canalcreatePatchedAccountSetupAdapter, createEnvPatchedAccountSetupAdapter, createSetupInputPresenceValidator, noteChannelLookupFailure, noteChannelLookupSummary, promptResolvedAllowFrom, splitSetupEntries, createAllowlistSetupWizardProxy, createDelegatedSetupWizardProxy
plugin-sdk/setup-adapter-runtimeadaptadores de setup de conta compatíveis com ambientecreateEnvPatchedAccountSetupAdapter
plugin-sdk/setup-toolshelpers de CLI/arquivo/docs de setup/instalaçãoformatCliCommand, detectBinary, extractArchive, resolveBrewExecutable, formatDocsLink, CONFIG_DIR
Use a superfície mais ampla plugin-sdk/setup quando quiser a caixa de ferramentas completa de setup compartilhado, incluindo helpers de patch de configuração como moveSingleAccountChannelSectionToDefaultAccount(...). Os adaptadores de patch de setup continuam seguros para importação em caminho quente. O lookup da superfície de contrato integrada para promoção de conta única é lazy, então importar plugin-sdk/setup-runtime não carrega antecipadamente a descoberta da superfície de contrato integrada antes de o adaptador realmente ser usado.

Promoção de conta única pertencente ao canal

Quando um canal faz upgrade de uma configuração de nível superior de conta única para channels.<id>.accounts.*, o comportamento compartilhado padrão é mover valores promovidos com escopo de conta para accounts.default. Canais integrados podem restringir ou substituir essa promoção por meio de sua superfície de contrato de setup:
  • singleAccountKeysToMove: chaves extras de nível superior que devem ser movidas para a conta promovida
  • namedAccountPromotionKeys: quando contas nomeadas já existem, somente essas chaves são movidas para a conta promovida; chaves compartilhadas de política/entrega permanecem na raiz do canal
  • resolveSingleAccountPromotionTarget(...): escolhe qual conta existente recebe os valores promovidos
O Matrix é o exemplo integrado atual. Se já existir exatamente uma conta Matrix nomeada, ou se defaultAccount apontar para uma chave não canônica existente como Ops, a promoção preservará essa conta em vez de criar uma nova entrada accounts.default.

Schema de configuração

A configuração do plugin é validada em relação ao JSON Schema no seu manifesto. Os usuários configuram plugins via:
{
  plugins: {
    entries: {
      "my-plugin": {
        config: {
          webhookSecret: "abc123",
        },
      },
    },
  },
}
Seu plugin recebe essa configuração como api.pluginConfig durante o registro. Para configuração específica do canal, use a seção de configuração do canal:
{
  channels: {
    "my-channel": {
      token: "bot-token",
      allowFrom: ["user1", "user2"],
    },
  },
}

Criar schemas de configuração de canal

Use buildChannelConfigSchema de openclaw/plugin-sdk/core para converter um schema Zod no wrapper ChannelConfigSchema que o 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);

Assistentes de setup

Plugins de canal podem fornecer assistentes de setup interativos para openclaw onboard. O assistente é um objeto ChannelSetupWizard no 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),
        };
      },
    },
  ],
};
O tipo ChannelSetupWizard aceita credentials, textInputs, dmPolicy, allowFrom, groupAccess, prepare, finalize e mais. Veja pacotes de plugins integrados (por exemplo, o plugin Discord em src/channel.setup.ts) para exemplos completos. Para prompts de allowlist de DM que precisam apenas do fluxo padrão note -> prompt -> parse -> merge -> patch, prefira os helpers de setup compartilhados de openclaw/plugin-sdk/setup: createPromptParsedAllowFromForAccount(...), createTopLevelChannelParsedAllowFromPrompt(...) e createNestedChannelParsedAllowFromPrompt(...). Para blocos de status de setup de canal que variam apenas por rótulos, pontuações e linhas extras opcionais, prefira createStandardChannelSetupStatus(...) de openclaw/plugin-sdk/setup em vez de implementar manualmente o mesmo objeto status em cada plugin. Para superfícies de setup opcionais que devem aparecer apenas em certos contextos, use createOptionalChannelSetupSurface de 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 também expõe os construtores de nível mais baixo createOptionalChannelSetupAdapter(...) e createOptionalChannelSetupWizard(...) quando você precisa apenas de uma metade dessa superfície de instalação opcional. O adaptador/assistente opcional gerado falha de forma fechada em gravações reais de configuração. Eles reutilizam uma única mensagem de instalação obrigatória em validateInput, applyAccountConfig e finalize, e acrescentam um link para a documentação quando docsPath está definido. Para UIs de setup baseadas em binários, prefira os helpers delegados compartilhados em vez de copiar a mesma lógica de binário/status em cada canal:
  • createDetectedBinaryStatus(...) para blocos de status que variam apenas por rótulos, dicas, pontuações e detecção de binário
  • createCliPathTextInput(...) para entradas de texto baseadas em caminho
  • createDelegatedSetupWizardStatusResolvers(...), createDelegatedPrepare(...), createDelegatedFinalize(...) e createDelegatedResolveConfigured(...) quando setupEntry precisa encaminhar de forma lazy para um assistente completo mais pesado
  • createDelegatedTextInputShouldPrompt(...) quando setupEntry precisa apenas delegar uma decisão textInputs[*].shouldPrompt

Publicação e instalação

Plugins externos: publique no ClawHub ou npm e depois instale:
openclaw plugins install @myorg/openclaw-my-plugin
O OpenClaw tenta primeiro o ClawHub e faz fallback para npm automaticamente. Você também pode forçar o ClawHub explicitamente:
openclaw plugins install clawhub:@myorg/openclaw-my-plugin   # ClawHub only
Não existe um override correspondente npm:. Use o spec normal do pacote npm quando quiser o caminho npm após o fallback do ClawHub:
openclaw plugins install @myorg/openclaw-my-plugin
Plugins no repositório: coloque-os na árvore de workspace de plugins integrados e eles serão descobertos automaticamente durante o build. Os usuários podem instalar:
openclaw plugins install <package-name>
Para instalações vindas do npm, openclaw plugins install executa npm install --ignore-scripts (sem scripts de ciclo de vida). Mantenha a árvore de dependências do plugin em JS/TS puro e evite pacotes que exijam builds em postinstall.

Relacionado