# Extensões: evolua o programa com a sua própria IA, sem mexer no código dele

Este guia é para duas pessoas: você, que usa o programa, e a **IA que você contratou** (Claude, ChatGPT, Gemini ou outra) e vai escrever o código. Dê este arquivo para ela.

## Para que serve

Uma extensão é um arquivo `.mjs` que acrescenta ferramentas ao programa: um relatório do seu jeito, uma conferência que só a sua operação faz, um cálculo de margem com as suas regras. O assistente passa a enxergar essas ferramentas ao lado das do programa.

**Por que extensão e não mexer no código do programa?** Porque o código do programa muda a cada atualização (quando o Bling, o Mercado Livre ou o WooCommerce alteram a API, por exemplo). Uma alteração feita dentro dele se perde, ou conflita, na próxima atualização. A extensão fica numa pasta sua, fora do programa, e continua valendo depois de atualizar.

## Onde o arquivo fica

Uma pasta por programa, dentro da pasta de dados do programa (`DATA_DIR`; o padrão é `.alcateia-mcp` na sua pasta de usuário):

| Programa | Pasta |
|---|---|
| Alpha ERP | `~/.alcateia-mcp/extensoes/erps/` (no Windows: `C:\Users\SEU_USUARIO\.alcateia-mcp\extensoes\erps\`) |
| Alpha Commerce | `~/.alcateia-mcp/extensoes/ecommerces/` (no Windows: `C:\Users\SEU_USUARIO\.alcateia-mcp\extensoes\ecommerces\`) |

Crie a pasta se ela não existir. Um arquivo = uma extensão. Nome de arquivo que começa com `_` ou `.` é ignorado (use para rascunho). Depois de criar ou mudar um arquivo, **feche e abra o assistente** (Claude Desktop, por exemplo) para o programa ler de novo.

## O formato

```js
// ~/.alcateia-mcp/extensoes/erps/margem.mjs
export default {
	nome: 'margem',            // minúsculas, números e _ (2 a 25 caracteres); entra no nome das ferramentas
	versaoApi: 1,              // a versão deste formato; hoje é 1
	instrucoes: 'Para calcular a margem de um produto use erp_x_margem_do_produto.', // opcional, curto, para o assistente
	ferramentas: [
		{
			name: 'do_produto',        // vira erp_x_margem_do_produto (<prefixo>_x_<nome>_<name>)
			description: 'Calcula a margem de um produto: (preço - custo) / preço. Use quando o usuário perguntar quanto sobra por produto.', // mínimo 10 letras; é o que o assistente lê para decidir quando usar
			write: false,              // true SÓ se a ferramenta altera dados (veja "Escrever com segurança")
			params: {                  // os campos que o assistente preenche
				id: { type: 'string', required: true, description: 'ID do produto no ERP.' },
			},
			async run(args, api, ctx) {
				// O caminho e os nomes dos campos (aqui "preco" e "custo") dependem do provedor da conta: confira o que ele devolve chamando erp_api.
				const produto = await api.get(`/produtos/${encodeURIComponent(args.id)}`);
				const { preco, custo } = produto.data ?? produto;
				return { id: args.id, preco, custo, margem: preco ? (preco - custo) / preco : null };
			},
		},
	],
};
```

- **`params`**: cada campo tem `type` (`string`, `number`, `integer`, `boolean`, `object` ou `array`) e `description`; `required: true` torna o campo obrigatório. Não use os nomes `account` e `confirm`: são do programa.
- **`run(args, api, ctx)`**: devolve qualquer coisa que vire JSON (objeto, lista, número). Se lançar um erro, o assistente recebe a mensagem. `ctx` traz `account` (a conta usada), `provider` e `plan` (veja abaixo).
- **`api`**: fala com o provedor **como a conta escolhida** (o programa cuida do login, da renovação do acesso e do limite de chamadas). Você nunca vê token nem chave.

| `api.…` | O que faz |
|---|---|
| `api.get(caminho, query)` | GET; devolve o JSON |
| `api.page(caminho, query)` | GET; devolve `{ data, headers }` (para paginar pelos cabeçalhos do provedor) |
| `api.check(caminho, corpo, query)` | POST que só **consulta** (ex.: validar), permitido em qualquer ferramenta |
| `api.post / put / patch / del(caminho, corpo, query)` | alteram dados: **só funcionam em ferramenta com `write: true` e já confirmada** |
| `api.vars` | valores da conta (por exemplo o endereço da loja) |

`caminho` é o da API nativa do provedor (veja o que o `erp_api`, ou `ecommerce_api`, aceita). `query` é um objeto; listas repetem a chave.

## Escrever com segurança

O programa faz valer estas regras e a extensão não consegue afrouxá-las:

1. **A ferramenta que não declara `write: true` nunca escreve.** Se `run` tentar `api.post`, `api.put`, `api.patch` ou `api.del`, a chamada é recusada com um erro claro.
2. **A ferramenta com `write: true` ganha o campo `confirm`.** Sem `confirm: true`, nada é enviado: o assistente recebe `applied: false` e a mensagem para mostrar o plano ao usuário. Só com a confirmação dele, o assistente chama de novo com `confirm: true`. Boa prática: em `run`, olhe `ctx.plan` e, se for `true`, **devolva o que você vai fazer** (antes/depois) em vez de chamar `api.put`.
3. As contas só aceitam escrita se o programa deixar (`READ_ONLY`, `WRITE_ACCOUNTS`), como nas ferramentas do próprio programa.
4. Toda chamada ao provedor passa pelo mesmo caminho do programa, inclusive a verificação da assinatura.
5. Cada chamada tem prazo (60 s por padrão; `EXTENSION_TIMEOUT_MS` muda, de 1 a 600 s).

## Se der errado

Peça ao assistente para chamar **`erp_diagnostics`** (no Alpha Commerce, `ecommerce_diagnostics`). Ele mostra quais extensões foram carregadas e, para cada arquivo ignorado, o motivo em português (nome fora do padrão, JavaScript quebrado, ferramenta repetida...). Um arquivo com problema é ignorado, e o programa abre normalmente. O diagnóstico não traz senha, token nem dados da sua operação, e pode ser mostrado ao suporte.

## Regras de ouro (para a IA que escreve)

- Use só o que está neste guia. **Não** edite nenhum arquivo do programa, **não** importe arquivos do programa, **não** leia a pasta de dados nem o `.env`.
- **Não** guarde chave, senha ou token no código; **não** envie dados para nenhum endereço de fora (nenhum `fetch` para outro lugar): a extensão existe para falar com o provedor **pela `api`**.
- Devolva respostas curtas (o assistente tem limite de leitura): filtre campos e pagine.
- Prefira ferramentas de leitura. Escreva só quando o usuário pediu e só com `write: true`.
- Uma extensão é código que roda **com as mesmas permissões do programa, neste computador**. Só coloque na pasta o que você leu e entendeu. Código de terceiros: não.

## Um pedido pronto para colar na sua IA

> Leia o guia de extensões que estou enviando. Escreva uma extensão do Alpha ERP (arquivo `.mjs` em `~/.alcateia-mcp/extensoes/erps/`) que \<descreva em uma frase o que você quer\>. Use só a `api` do guia, declare `write: true` apenas se for preciso alterar dados, devolva respostas curtas e me explique, em linguagem simples, o que o código faz antes de eu salvar.

## O que muda quando o programa atualiza

Nada na sua extensão. O formato `versaoApi: 1` não muda de forma incompatível: se um dia for preciso mudar, o programa passa a aceitar uma `versaoApi` nova e continua aceitando a 1. O que pode mudar com o tempo é a API do provedor (o Bling, o Mercado Livre e o WooCommerce mudam): o que a sua extensão chama por `api.get('/...')` é responsabilidade dela, e as atualizações do programa trazem as correções para as ferramentas do próprio programa.

## Licença

O código da extensão é seu. O programa continua sob a Business Source License 1.1 (veja `LICENSE.md`); a extensão é só um arquivo seu, na sua pasta.
