Tema
Criar plugins
Um plugin do Núcleo é um arquivo plugin.toml dentro de uma pasta na pasta de plugins. Ele pode:
- pôr um item no rodapé, com um menu de ações e um seletor (como a org do Salesforce);
- pôr ações no botão direito da árvore de arquivos, filtradas por pasta, nome ou final do arquivo;
- ligar recursos embutidos do app (o painel Git, os Dados e os Logs da Salesforce são plugins assim).
As ações rodam no terminal embutido, dentro da raiz do projeto, e você vê a saída. Plugins não rodam código dentro do app: só comandos do sistema que você pode ler no manifesto.
Onde ficam
Plugins → ícone de pasta abre a pasta. Cada plugin é uma subpasta com o plugin.toml:
plugins/
├── git/plugin.toml
├── salesforce/plugin.toml
└── meu-plugin/plugin.toml| Sistema | Pasta |
|---|---|
| Linux | ~/.config/nucleo/plugins |
| macOS | ~/Library/Application Support/nucleo/plugins |
| Windows | %APPDATA%\nucleo\plugins |
Depois de criar ou editar, clique em recarregar na seção Plugins.
Primeiro plugin: Prettier no botão direito
Crie plugins/prettier/plugin.toml:
toml
id = "prettier"
name = "Prettier"
version = "1.0.0"
description = "Formata o arquivo com o Prettier pelo botão direito."
requires = "npx"
[[file_actions]]
label = "Formatar com Prettier"
command = "npx prettier --write {path}"
suffix = ".js"
[[file_actions]]
label = "Formatar com Prettier"
command = "npx prettier --write {path}"
suffix = ".html"Recarregue a seção Plugins, clique com o botão direito num .js e escolha Formatar com Prettier. O comando roda no terminal, na raiz do projeto.
Um item no rodapé
O item do rodapé roda um comando que imprime JSON e mostra um campo dele. Os campos são indicados com JSON Pointer (/caminho/do/campo).
toml
id = "node"
name = "Node"
version = "1.0.0"
description = "Versão do Node no rodapé e scripts do package.json."
root_marker = "package.json"
requires = "node"
[status]
icon = "puzzle"
command = "node -p \"JSON.stringify({ version: process.version })\""
label = "/version"
refresh_secs = 600
[[status.actions]]
label = "Instalar dependências"
command = "npm install"
[[status.actions]]
label = "Rodar os testes"
command = "npm test"Com root_marker = "package.json", o plugin só aparece quando a pasta do chat (ou uma acima dela) tem esse arquivo, e os comandos rodam nessa pasta.
Referência do plugin.toml
Identificação
| Campo | Obrigatório | O quê |
|---|---|---|
id | sim | letras, números, - e _; vira o nome da pasta |
name | sim | nome mostrado no app |
version | não | 1.2.3; o app avisa quando o catálogo tem uma versão maior |
description | não | uma ou duas frases |
root_marker | não | arquivo que marca a raiz do projeto, procurado da pasta do chat para cima. Sem ele, o plugin vale em qualquer pasta |
requires | não | programa necessário; o app avisa quando não acha |
features | não | recursos embutidos que o plugin liga (abaixo) |
[status]: item do rodapé
| Campo | O quê |
|---|---|
command | comando que imprime JSON |
label | ponteiro do texto mostrado (ex.: /result/alias) |
label_fallback | ponteiro usado quando o label vem vazio |
tooltip | ponteiro do texto da dica |
empty_label | texto quando o comando falha ou não há valor |
icon | cloud ou puzzle |
refresh_secs | a cada quantos segundos lê de novo (padrão 120) |
[status.danger] deixa o item vermelho e faz as ações com confirm = "danger" pedirem confirmação:
| Campo | O quê |
|---|---|
pointer | campo avaliado |
unless_contains | lista de trechos; se o valor não contém nenhum, é perigoso |
[status.choices] põe um seletor no menu do rodapé:
| Campo | O quê |
|---|---|
title | título do seletor |
command | comando que imprime JSON com as opções |
lists | ponteiros para listas de objetos (podem ser várias) |
value / value_fallback | campo de cada objeto usado como valor |
detail | campo mostrado na dica |
on_choose | comando rodado ao escolher; {choice} é o valor |
[[status.actions]], uma por item do menu:
| Campo | O quê |
|---|---|
label | texto do item |
command | comando (roda no terminal) |
confirm | "always" ou "danger" (opcional) |
[[file_actions]]: botão direito da árvore
| Campo | O quê |
|---|---|
label | texto do item |
command | comando; aceita {path} (relativo à raiz), {abs}, {name}, {stem} (nome sem extensão) e {root} |
inside | só para caminhos que passam por esta pasta (ex.: force-app) |
suffix | só para arquivos terminados assim (ex.: Test.cls) |
name | só para arquivos com este nome exato (ex.: package.xml) |
confirm | "always" ou "danger" |
Sem filtro, a ação aparece em todo arquivo e pasta dentro da raiz. Os caminhos entram entre aspas quando precisam.
features: recursos embutidos
| Valor | O que liga |
|---|---|
git | painel Git e branch no rodapé |
data-inspector | seção Dados (SOQL, registros, lookups) |
apex-logs | debug logs na seção Logs |
nebula-logger | Nebula Logger na seção Logs |
Exemplo completo: o plugin Salesforce
O plugin que vem com o app é o melhor modelo: org no rodapé com seletor e alerta de produção, ações por tipo de arquivo e o inspetor de dados. Ver o plugin.toml.
Segurança
- Antes de instalar um plugin do catálogo, o app mostra todos os comandos que ele pode rodar.
- Plugins não têm acesso ao app nem aos seus tokens: só rodam os comandos do manifesto, como você rodaria no terminal.
- Use
confirm = "danger"em tudo o que altera um ambiente remoto (deploy, publicação, migração).
Publicar no catálogo
O catálogo fica em protoncode.com.br/nucleo/plugins e aparece na seção Plugins do app. Quer o seu lá? Mande o plugin.toml pelo contato. A gente revisa os comandos antes de publicar.