Lição 5 de 6: Empacotar seu setup como plugin
- Plugin com
.claude-plugin/plugin.json(name, description, version) montado a partir do bucket "pessoal" do inventário (L01) - Pelo menos 1 skill real empacotada em
skills/(mais hooks/agents se você tiver) - Plugin testado localmente com
claude --plugin-dir ./<plugin> - Marketplace privado no GitHub:
.claude-plugin/marketplace.jsonapontando pro plugin - Instalação validada num segundo produto:
/plugin marketplace add+/plugin install
Esta lição pega o que você customizou nos módulos anteriores e empacota como um do Claude Code, a unidade oficial de distribuição.
Por que plugin, e não cp -r
No L01 você separou seu .claude/ em três buckets: canônico (do Starter), pessoal (que você criou), morto (deleta). O bucket pessoal é o material desta lição: as skills, as rules, o hook do L02, qualquer agent que você montou.
A maneira ingênua de reusar isso num próximo projeto é copiar arquivo a arquivo: cp -r .claude/skills/... pra cada projeto novo. Funciona uma vez. Mas não tem versão, não tem como atualizar sem recopiar, e duas skills com o mesmo nome colidem quando você junta material de origens diferentes.
O Claude Code resolve isso nativamente. A doc oficial separa os dois casos. Configuração standalone em .claude/ serve pra fluxo pessoal, ajuste de um projeto só, experimento rápido. Plugin serve pra compartilhar com o time, distribuir pra comunidade, versionar release e reusar entre projetos. E recomenda a ordem: comece standalone e converta em plugin quando tiver o que compartilhar.
A estrutura de um plugin
O manifesto mínimo tem três campos:
# meu-pack/.claude-plugin/plugin.json
{
"name": "meu-pack",
"description": "Skills e hooks que acumulei no Builder OS",
"version": "0.1.0"
}O name é o namespace: . Esse prefixo é o que resolve o problema de colisão que no formato antigo você tentava contornar com nome manual: agora o Claude Code namespaca pra você.
O version controla quando quem instalou recebe atualização. Regra de bolso: sempre preencha version. Com versão, quem instalou só recebe a nova quando você bumpar (de 0.1.0 pra 0.2.0). Se você omitir e distribuir via git, o Claude Code usa o SHA do commit e cada commit conta como versão nova: você perde o controle de quando o usuário atualiza. (Fonte: Create plugins)
Passo 1 — Monte o plugin a partir do inventário
Volta ao docs/personal-pack-inventory.md (do L01) e pega o bucket "pessoal". Cola no Claude:
Quero empacotar meu material pessoal como plugin do Claude Code. Lê `docs/personal-pack-inventory.md` e pega os itens do bucket "pessoal".
Cria a pasta `meu-pack/` (troca por um nome melhor: handle + propósito, ex. `jp-shipping-pack`) com:
1. `<nome-do-plugin>/.claude-plugin/plugin.json` com:
{ "name": "<nome>", "description": "<1 frase>", "version": "0.1.0", "author": { "name": "<meu nome>" } }
2. `<nome-do-plugin>/skills/<nome>/SKILL.md` pra cada skill pessoal: copia o conteúdo da skill atual em `.claude/skills/`.
3. Se eu tenho hook do L02 no `.claude/settings.json`, cria `<nome-do-plugin>/hooks/hooks.json` copiando o objeto `hooks` (o formato é o mesmo).
4. `<nome-do-plugin>/README.md` com o que o plugin faz e como instalar.
Lembra: só o plugin.json vai dentro de .claude-plugin/. skills/ e hooks/ ficam na raiz do plugin. Mostra a árvore de arquivos antes de criar e usa o mesmo nome de pasta em todos os caminhos.Aprove. Antes de testar, peça uma conferência rápida da árvore:
Mostra a árvore final do plugin que você criou e confirma que: o plugin.json está dentro de .claude-plugin/, e que skills/ (e hooks/, se houver) estão na raiz do plugin, não dentro de .claude-plugin/. Se tiver o CLI, roda `claude plugin validate ./<nome-do-plugin>` e me mostra a saída.Com a árvore conferida, você tem um plugin montado, ainda não publicado.
Passo 2 — Teste o plugin localmente
Antes de publicar, carregue o plugin direto do disco com a flag --plugin-dir. Isso roda o plugin sem instalar (troque meu-pack pelo nome que você deu à pasta):
claude --plugin-dir ./<nome-do-plugin>Com o Claude Code aberto, rode /help e procure suas skills sob o namespace do plugin: elas devem aparecer como /<nome-do-plugin>:<skill>. Depois invoque uma delas (por exemplo /<nome-do-plugin>:<skill>) pra confirmar que carrega.
Se aparecem prefixadas com o nome do plugin, o empacotamento está correto. Se não aparecem: o motivo quase sempre é estrutura. Abra /plugin, vá na aba Errors pra ler o erro, e confira o aninhamento: o caso mais comum é ter colocado skills/ dentro de .claude-plugin/ em vez da raiz do plugin. Corrija e rode /reload-plugins pra recarregar sem reiniciar.
Passo 3 — Publique como marketplace privado no GitHub
Um plugin sozinho não é instalável por outros projetos: ele precisa estar listado num . Um marketplace é um repositório do GitHub com um arquivo .claude-plugin/marketplace.json que aponta pros plugins. Pode ser o mesmo repo do plugin.
Quero distribuir meu plugin como marketplace privado no GitHub. Cria `.claude-plugin/marketplace.json` na raiz do repositório do plugin, listando o plugin que montei no Passo 1. Estrutura típica:
{
"name": "<meu-marketplace>",
"owner": { "name": "<meu nome>" },
"plugins": [
{ "name": "<nome-do-plugin>", "source": "./<pasta-do-plugin>", "description": "<1 frase>" }
]
}
Depois me dá os comandos git pra criar um repo PRIVADO no GitHub, commitar e dar push. Mostra os comandos antes de rodar.Aprove. Confira no GitHub que o repo existe e tem .claude-plugin/marketplace.json na raiz.
Passo 4 — Instale o plugin num segundo produto
Aqui o trabalho compensa. Abra o Claude Code dentro de outro projeto seu (qualquer um, um produto onde você quer as mesmas skills) e rode os dois comandos:
> /plugin marketplace add <owner/repo>
Marketplace adicionado. Catálogo registrado (nenhum plugin instalado ainda).
> /plugin install <nome-do-plugin>@<nome-do-marketplace>
Plugin instalado.O primeiro comando registra o catálogo; o segundo instala o plugin específico. Instalou no meio de uma sessão? Rode /reload-plugins pra ativar sem reiniciar; a doc traz esse passo logo depois do install. As skills aparecem namespacadas (/<plugin>:<skill>): as mesmas que você testou no Passo 2, agora num produto diferente, sem cp -r.
O /plugin mostra o custo antes de instalar
Esta parte vale quando você for instalar plugin dos outros (o oficial, o de um colega); pro seu, você já sabe o que botou dentro. Mas é o mesmo painel, então vale conhecer. Rode /plugin sem argumentos pra abrir o gerenciador. Ele tem abas que você cicla com Tab:
Discover: navega plugins de todos os marketplaces que você adicionou. É aqui que o seu plugin aparece depois do Passo 3.
Installed: vê, ativa, desativa ou desinstala os plugins instalados.
Marketplaces: adiciona, remove ou atualiza os marketplaces registrados.
Errors: mostra erros de carregamento de plugin. É a aba que você abre quando uma skill não aparece (foi o que usamos no Passo 2).
Quando você seleciona um plugin no Discover, o painel de detalhes mostra antes de instalar quanto ele custa. Isso conecta direto com o orçamento de contexto: cada skill, agent e MCP server que você carrega ocupa tokens na janela toda virada. O /plugin torna esse custo visível.
Esse custo é a razão de você ter feito o inventário do L01 com cuidado: plugin com skill morta dentro é peso morto na janela de todo projeto que instalar. Empacote só o que você usa.
O marketplace oficial já vem por padrão
Antes de montar o seu, vale saber que você não parte do zero. O marketplace oficial da Anthropic (claude-plugins-official) já vem disponível quando você abre o Claude Code: você roda /plugin, vai na aba Discover, e já tem plugins prontos pra instalar (integrações com GitHub, Vercel, Sentry, Slack, e os LSP de TypeScript/Python/Rust pra diagnósticos inline). Pra instalar de lá: /plugin install <nome>@claude-plugins-official.
O seu marketplace privado convive com o oficial. Você usa o oficial pra integrações genéricas e o seu pro material que é só seu.
Conexão com o resto do M5
Esta lição fecha o arco do módulo:
- L01 (inventário) te deu o bucket "pessoal": é exatamente o material que virou o
skills/do plugin. - L02 (hooks) te deu o hook que agora vai no
hooks/hooks.jsondo plugin, viajando junto com as skills. - L04 (atualizar o Starter) te ensinou a puxar atualização do upstream; o plugin tem o mecanismo equivalente:
versionno manifesto +/plugin marketplace updateno consumidor.
O resultado: você separa o seu material do canônico e reusa entre projetos com o mecanismo oficial: versão no manifesto, namespace automático, instalação por comando, custo de contexto visível antes de instalar.
Takeaways
- Plugin >
cp -r. O plugin tem versão, namespace e atualização por comando; copiar arquivo a arquivo não tem nenhum dos três e colide quando você junta material de origens diferentes. - Só o
plugin.jsonmora dentro de.claude-plugin/. As pastasskills/,hooks/,agents/e o.mcp.jsonficam na raiz do plugin. Aninhar errado é o motivo mais comum de o Claude Code não enxergar os componentes. - Sempre preencha
version. Com versão, quem instalou só recebe a nova quando você bumpa; sem ela, cada commit conta como versão e você perde o controle da atualização. - Instalar é dois passos:
/plugin marketplace add <owner/repo>registra o catálogo;/plugin install <plugin>@<marketplace>instala. Marketplace privado no GitHub é suportado. - O
/pluginmostra o custo de contexto antes de instalar: por isso o inventário do L01 importa. Empacote só o que você usa.
Você terminou quando
Cinco coisas:
- Plugin com
.claude-plugin/plugin.json(name, description, version) montado a partir do bucket "pessoal" - Pelo menos 1 skill real empacotada em
skills/(e o hook do L02 emhooks/hooks.json, se você tem) - Plugin testado com
claude --plugin-dir ./<plugin>: skills aparecem namespacadas - Marketplace privado no GitHub com
.claude-plugin/marketplace.json - Instalação validada num segundo produto:
/plugin marketplace add+/plugin installrodaram e as skills carregaram lá