> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use the mods API

> Chame a mods API de um mod Claude Code para adicionar comandos e ferramentas, chamar um modelo, executar trabalho em um temporizador, enviar mensagens para outras sessões e acessar arquivos e a rede.

A mods API é o conjunto de métodos que um mod chama para agir: adicionar comandos e ferramentas, chamar um modelo, executar trabalho entre eventos e acessar o sistema de arquivos, processos e a rede. Cada hook a recebe como seu primeiro argumento, `$`, com os métodos agrupados em namespaces como `$.ui` e `$.fs`. [Events](/docs/pt/plugins/mods/events) decidem quando um hook é executado, e a mods API é o que o hook chama uma vez que o faz.

Construa seu [primeiro mod](/docs/pt/plugins/mods/create) antes de começar aqui. Para cada método, veja [mods API methods](/docs/pt/plugins/mods/reference#mods-api-methods) ou leia [os tipos para sua compilação](/docs/pt/plugins/mods/create#get-the-types-for-your-build).

<h2 id="add-a-command-or-a-tool">
  Adicione um comando ou uma ferramenta
</h2>

Um mod pode adicionar um comando para o usuário executar e uma ferramenta para Claude chamar. Registre ambos em um hook [`session.start`](/docs/pt/plugins/mods/reference#session). Claude Code aguarda esse hook antes do primeiro prompt, então o que você registra está disponível desde o primeiro turno.

<h3 id="add-a-command">
  Adicione um comando
</h3>

Um comando é para o usuário. Registre-o e, em seguida, manipule [`command.run`](/docs/pt/plugins/mods/reference#commands-and-configuration) para seu nome. Este exemplo adiciona um comando `/standup` que leva um número opcional de dias:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // Add /standup to the command list, with the description the user sees there
  await $.command.register({ name: 'standup', description: 'Summarize what changed today', argumentHint: '[days]' })
  return next(e)
})

// The matcher limits the hook to /standup, so other commands don't reach it
on('command.run', { command: 'standup' }, async ($, e) => {
  // e.args is the text typed after the command name, or an empty string
  return { text: 'Summary for the last ' + (e.args || '1') + ' day(s): ...' }
})
```

Após a sessão iniciar, `/standup` aparece com sua descrição na lista que você vê quando digita `/`. O `argumentHint` aparece no prompt após você digitar o comando e um espaço, como em `/standup [days]`. Quando você executa `/standup 3`, o segundo hook retorna `Summary for the last 3 day(s): ...`, e a transcrição mostra esse texto após o nome do plugin. O hook nunca chama `next`, porque o comando não tem comportamento além do seu.

O `text` que você retorna é impresso na transcrição e Claude o lê. Para não imprimir nada, como um comando que apenas abre um [pane](/docs/pt/plugins/mods/interface#pick-where-to-draw), retorne `{}`. Para permitir que o comando seja executado enquanto Claude está trabalhando, adicione `immediate: true` ao registro.

Escolha um nome que nenhum comando integrado use. Digite `/` em uma sessão para vê-los. `$.command.register` lança uma exceção para um nome ocupado, com uma mensagem como `"/focus" refused: it is the built-in /focus"`. Um hook que lança uma exceção é ignorado, então o resto do seu hook `session.start` também não é executado. Registre comandos por último nesse hook ou envolva a chamada em `try` e `catch`.

<h3 id="add-a-tool">
  Adicione uma ferramenta
</h3>

Uma ferramenta é para Claude. Registre-a com um nome, uma descrição que Claude lê e um JSON Schema para sua entrada. Claude a vê sob um nome mais longo feito de `mcp__`, o nome do seu plugin, dois sublinhados e o nome que você registrou. Você manipula suas chamadas em um hook [`tool.call`](/docs/pt/plugins/mods/events#guard-or-change-a-tool-call) filtrado para esse nome completo. Este exemplo, de um plugin chamado `my-mod`, registra `ticket`, então o nome completo é `mcp__my-mod__ticket`. Ele dá a Claude uma ferramenta que procura um ticket em um rastreador de problemas:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  await $.tool.register({
    name: 'ticket',
    // Claude decides when to call the tool from this description
    description: 'Look up a ticket by its id and return its title and status',
    // The arguments Claude has to send: one required string named id
    inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
  })
  return next(e)
})

// The full tool name is mcp__, the plugin's name, and the registered name
on('tool.call', { tool: 'mcp__my-mod__ticket' }, async ($, e) => {
  // The tool's arguments are fields of e, so the id is e.id
  const response = await $.http.fetch('https://tickets.example.com/api/' + encodeURIComponent(e.id))
  // Return a result either way, so Claude learns when the lookup failed
  return { result: response.ok ? response.text : 'Lookup failed with status ' + response.status }
})
```

Quando você pergunta sobre um ticket, Claude pode chamar `mcp__my-mod__ticket` com seu id. O segundo hook busca o ticket e retorna o corpo da resposta, que Claude lê como o resultado da ferramenta. Quando o servidor responde com um status de erro, Claude lê `Lookup failed with status` e o número.

<h2 id="call-a-model">
  Chame um modelo
</h2>

Um mod pode fazer uma pergunta a um modelo por conta própria, fora da conversa, para um pequeno trabalho como classificar ou resumir um pedaço de texto. `$.model.complete` envia um prompt para um modelo com as credenciais da sua sessão e resolve para a resposta. Ele não tem histórico de conversa.

Este hook responde a um comando `/triage`, [registrado como um comando](#add-a-command), pedindo a um pequeno modelo para rotular o texto digitado após ele:

```javascript theme={null}
on('command.run', { command: 'triage' }, async ($, e) => {
  const r = await $.model.complete({
    model: 'haiku',
    // The system prompt sets the job, and the prompt carries the text to label
    system: 'Reply with one word: bug, feature, or question.',
    prompt: e.args,
    // One word needs few tokens, and the call gives up after 15 seconds
    maxTokens: 20,
    timeoutMs: 15000,
  })
  // r.text exists only when the model answered, so check r.isAnswered first
  const label = r.isAnswered ? r.text.trim() : 'unknown'
  return { text: 'Label: ' + label }
})
```

Quando você executa `/triage the export button does nothing`, o mod envia esse texto para o modelo e imprime sua resposta, como `Label: bug`. A conversa de Claude não faz parte da solicitação. Quando o modelo não responde, o rótulo é `unknown`.

Uma falha da Claude API não rejeita a chamada, então verifique `r.isAnswered` e leia `r.reason` quando for `false`. A chamada rejeita apenas para uma solicitação que Claude Code não enviará, como um modelo que sua organização bloqueia. [Os tipos para sua compilação](/docs/pt/plugins/mods/create#get-the-types-for-your-build) listam as outras opções, como `effort`, e os [limites](/docs/pt/plugins/mods/reference#limits) fornecem o padrão `maxTokens`.

`$.model.fork({ prompt })` faz uma pergunta sobre a conversa atual, com o mesmo modelo e prompt do sistema, então a Claude API serve a maior parte dela do cache de prompt.

Essas chamadas usam o plano ou chave de API do usuário.

<h2 id="run-work-in-the-background">
  Execute trabalho em segundo plano
</h2>

Trabalho que sobrevive a um evento, como verificar algo uma vez por minuto, é executado em um temporizador que você inicia a partir de `session.start`. Um hook em si é executado para um evento e tem um limite de tempo de 10 segundos de seu próprio tempo de execução. O tempo gasto aguardando `next` ou uma chamada da mods API não conta, exceto um `$.clock.sleep`. `$.clock.every` e `$.clock.after` substituem `setInterval` e `setTimeout`, com o atraso em milissegundos primeiro: `$.clock.after(5000, fn)` chama `fn` uma vez, cinco segundos a partir de agora. Cada um retorna um temporizador com um método `cancel()`, e `await $.clock.now()` fornece a hora em milissegundos.

Este hook procura as verificações de uma solicitação de pull uma vez por minuto e mostra o resultado sob o prompt. `summarize` é uma função sua que transforma a saída JSON do comando em algumas palavras:

```javascript theme={null}
on('session.start', async ($, e, next) => {
  // Call the function every 60,000 milliseconds, starting one minute from now
  $.clock.every(60_000, async () => {
    const status = await $.process.run(['gh', 'pr', 'checks', '--json', 'state'])
    // Replace the line under the prompt with the latest summary
    $.ui.status('checks: ' + summarize(status.stdout))
  })
  // Return without waiting for the timer, so the session starts right away
  return next(e)
})
```

A sessão inicia como de costume. Um minuto depois, uma linha aparece sob o prompt com um `⚠`, o nome do mod e depois `checks:` e seu resumo. É substituído uma vez por minuto depois disso. O callback do temporizador é executado fora de qualquer evento, então continua funcionando entre turnos e não inicia um. Se o callback lançar uma exceção, o erro vai para o [debug log](/docs/pt/plugins/mods/troubleshoot#read-the-debug-log) e o temporizador é executado novamente no próximo intervalo.

<h3 id="show-something-without-starting-a-turn">
  Mostre algo sem iniciar um turno
</h3>

Um trabalho em segundo plano pode mostrar ao usuário algo sem iniciar um turno. Cada uma dessas chamadas coloca texto em um lugar diferente:

| Chamada | O que o usuário vê |
| :- | :- |
| `$.ui.status(text)` | Uma linha sob o prompt que permanece até você alterá-la. Começa com `⚠` e o nome do mod, como em `⚠ my-mod: checks: 3 passing`. |
| `$.ui.toast(text)` | Uma pequena caixa no canto superior direito, com o nome do mod acima do texto, que desaparece após alguns segundos |
| `$.ui.log(text)` | Uma linha fraca na transcrição que Claude não lê. Começa com `●` e o nome do mod, como em `● my-mod: build finished`. |

<h3 id="start-a-turn-from-a-background-job">
  Inicie um turno a partir de um trabalho em segundo plano
</h3>

Quando um trabalho em segundo plano encontra algo que precisa da atenção de Claude, ele pode iniciar um turno enviando um prompt com `$.prompt.submit({ text })`. Claude lê o texto após uma frase que nomeia seu mod como o remetente. Para enviá-lo como as próprias palavras do usuário, sem essa frase, adicione `asUser: true`. A chamada aguarda até que a sessão esteja ociosa e depois inicia um novo turno. Ela resolve quando esse turno inicia, então não `await` em um manipulador que é executado enquanto Claude está trabalhando.

<h3 id="stop-background-work">
  Pare o trabalho em segundo plano
</h3>

O trabalho em segundo plano para de duas maneiras. Os temporizadores param quando o módulo é recarregado. Para trabalho de longa duração dentro de um hook, [`next.signal`](/docs/pt/plugins/mods/reference#the-hook-function) é um `AbortSignal` que aborta quando o evento que seu hook está manipulando é abandonado, por exemplo quando o usuário interrompe, então passe-o para qualquer coisa de longa duração.

<h2 id="send-and-receive-messages-between-sessions">
  Envie e receba mensagens entre sessões
</h2>

Um mod pode enviar uma mensagem em texto simples para outra de suas sessões ou para um dos subagentes desta sessão e observar as mensagens que chegam e saem. `$.session.send({ to, text })` envia uma, a mesma entrega que a ferramenta SendMessage faz. `to` é `{ sessionId }` para uma sessão, `{ agentId }` para um subagente de `$.agent.list()` ou o endereço de string de onde uma mensagem recebida veio. A chamada resolve uma vez que a mensagem é enfileirada, com `{ isDelivered: true }`. Quando nada foi entregue, ela resolve com `{ isDelivered: false, reason }`, e `reason` diz por quê.

Este hook responde a um comando `/ping`, [registrado como um comando](#add-a-command), pedindo à sessão cujo id você digita após ele um status:

```javascript theme={null}
on('command.run', { command: 'ping' }, async ($, e) => {
  // e.args is the session id typed after /ping
  const sent = await $.session.send({ to: { sessionId: e.args }, text: 'Status? One line.' })
  // The call resolves either way, so check isDelivered to learn what happened
  if (!sent.isDelivered) $.ui.toast('Not delivered: ' + sent.reason)
  // An empty result prints nothing in this session's transcript
  return {}
})
```

Quando a mensagem é enfileirada, nada aparece em sua sessão e o Claude da outra sessão lê `Status? One line.` Quando nada foi entregue, uma pequena caixa no canto superior direito fornece o motivo e desaparece após alguns segundos.

Dois eventos permitem que um mod observe as mensagens. Retorne `next(e)` de ambos para passar cada mensagem inalterada:

| Evento | Dispara quando | Campos úteis |
| :- | :- | :- |
| `session.receive` | Uma mensagem chega para esta sessão, antes de Claude lê-la | `e.text` e `e.origin.kind`, como `peer` ou `peer-send-message` para outra sessão ou agente, `task-notification` ou `scheduled-trigger`. Retorne `{ consumed: reason }` para mantê-la longe de Claude. |
| `session.send` | Uma mensagem está prestes a sair, da ferramenta SendMessage ou de um mod | `e.to`, `e.text` e `e.origin.kind`, que é `model` ou `plugin` |

Uma sessão definida para [recusar mensagens de entrada](/docs/pt/cross-session-messaging#control-inbound-messages) recusa uma mensagem antes de `session.receive` disparar, então um hook nunca a vê. Uma mensagem que é mantida para sua aprovação chega ao hook primeiro, então um mod pode ler uma mensagem que você ainda não aprovou. O `next(e)` do hook rejeita quando a mensagem não é entregue.

O nome do remetente em uma mensagem recebida é o que o remetente escreveu, então não baseie uma decisão nele.

<h2 id="reach-files-processes-and-the-network">
  Acesse arquivos, processos e a rede
</h2>

Um mod acessa o sistema de arquivos, processos e a rede através da mods API, com as mesmas permissões do usuário executando Claude Code. O próprio módulo de hooks não tem APIs Node.js, nenhum global de temporizador como `setTimeout` e nenhum acesso à rede ou arquivo próprio. APIs JavaScript padrão e web como `URL`, `TextEncoder`, `AbortController` e `crypto.subtle` estão disponíveis. Cada namespace abaixo cobre um tipo de acesso:

| Namespace | O que faz |
| :- | :- |
| `$.fs` | `read(path)`, `write(path, text)`, `exists(path)`, `stat(path)` e `list(path)` funcionam em arquivos e diretórios |
| `$.process` | `run(['git', 'status'])` inicia um comando e resolve quando ele sai. `spawn` transmite a saída de um comando de longa duração. |
| `$.http` | `fetch(url, init)` sobre `http` ou `https`. Ele resolve para `{ status, ok, headers, text }` uma vez que o corpo é lido. |
| `$.store` | Um armazenamento de chave-valor JSON do seu próprio plugin, mantido entre sessões |
| `$.env` | `get` e `set` variáveis de ambiente. Escreva o nome como uma string literal. |
| `$.settings` | `read` o que os arquivos de configurações e a política gerenciada contêm |
| `$.session` | `messages()` retorna a transcrição como uma lista de `{ role, text, toolUses }`. Também o diretório de trabalho, modelo e mais. [`usage()`](/docs/pt/plugins/mods/reference#mods-api-methods) retorna o uso da janela de contexto e limites de plano. |
| `$.mcp` | `call` uma ferramenta em um servidor MCP conectado |

Arquivos e processos têm algumas regras próprias:

* **Paths**: um caminho relativo está sob o diretório de trabalho da sessão
* **`$.fs.list`**: retorna as entradas de um diretório como `{ name, kind, size, isLink }` e não desce em subdiretórios
* **`$.process.run`**: leva uma lista de argumentos e não usa shell. Ele resolve para `{ exitCode, stdout, stderr }` qualquer que seja o código de saída. Ele rejeita se o programa não puder iniciar ou ainda estiver em execução no tempo limite, que é 30 segundos por padrão, então envolva em `try` e `catch`.

Cada uma dessas chamadas é em si um evento, nomeado para seu namespace e método sem o `$.`, como `fs.read` para `$.fs.read`. Um mod [anterior na cadeia](/docs/pt/plugins/mods/events#the-order-mods-run-in) pode observar, reescrever ou recusar sua chamada, que é como uma organização restringe o que os mods alcançam.

<h2 id="next-steps">
  Próximas etapas
</h2>

* [React to events](/docs/pt/plugins/mods/events): hook tool calls, prompts, and turns
* [Draw in the interface](/docs/pt/plugins/mods/interface): show what your mod collects in a pane or above the prompt
* [Test a mod](/docs/pt/plugins/mods/test): stub any of these calls in a test
* [Mods reference](/docs/pt/plugins/mods/reference): every event, every mods API method, and the limits
