- Início
- Documentation
- Extensões
- Carregamento de Extensões (Módulos TypeScript/JavaScript)
Carregamento de Extensões (Módulos TypeScript/JavaScript)
Este documento aborda como o agente de codificação descobre e carrega módulos de extensão (.ts/.js) na inicialização.
Ele não aborda extensões de manifesto gemini-extension.json (documentadas separadamente).
O que este subsistema faz
Seção intitulada “O que este subsistema faz”O carregamento de extensões constrói uma lista de arquivos de entrada de módulos, importa cada módulo com Bun, executa sua factory e retorna:
- definições de extensão carregadas
- erros de carregamento por caminho (sem abortar todo o carregamento)
- um objeto compartilhado de runtime de extensão usado posteriormente pelo
ExtensionRunner
Arquivos de implementação principais
Seção intitulada “Arquivos de implementação principais”src/extensibility/extensions/loader.ts— descoberta de caminhos + importação/execuçãosrc/extensibility/extensions/index.ts— exportações públicassrc/extensibility/extensions/runner.ts— runtime/execução de eventos após o carregamentosrc/discovery/builtin.ts— provedor nativo de autodescoberta para módulos de extensãosrc/config/settings.ts— carrega configurações mescladas deextensions/disabledExtensions
Entradas para o carregamento de extensões
Seção intitulada “Entradas para o carregamento de extensões”1) Módulos de extensão nativos autodescobertos
Seção intitulada “1) Módulos de extensão nativos autodescobertos”discoverAndLoadExtensions() primeiro solicita aos provedores de descoberta itens com capacidade extension-module, depois mantém apenas os itens do provedor native.
Localizações nativas efetivas:
- Projeto:
<cwd>/.xcsh/extensions - Usuário:
~/.xcsh/agent/extensions
As raízes de caminho vêm do provedor nativo (SOURCE_PATHS.native).
Notas:
- A autodescoberta nativa atualmente é baseada em
.xcsh. - O legado
.piainda é aceito nas chaves de manifesto dopackage.json(pi.extensions), mas não como raiz nativa aqui.
2) Caminhos explicitamente configurados
Seção intitulada “2) Caminhos explicitamente configurados”Após a autodescoberta, os caminhos configurados são adicionados e resolvidos.
Fontes de caminhos configurados no caminho de inicialização da sessão principal (sdk.ts):
- Caminhos fornecidos via CLI (
--extension/-e, e--hooktambém é tratado como um caminho de extensão) - Array
extensionsnas configurações (configurações globais + projeto mescladas)
Arquivo de configurações globais:
~/.xcsh/agent/config.yml(ou diretório de agente personalizado viaPI_CODING_AGENT_DIR)
Arquivo de configurações do projeto:
<cwd>/.xcsh/settings.json
Exemplos:
extensions: - ~/my-exts/safety.ts - ./local/ext-pack{ "extensions": ["./.xcsh/extensions/my-extra"]}Controles de ativação/desativação
Seção intitulada “Controles de ativação/desativação”Desativar descoberta
Seção intitulada “Desativar descoberta”- CLI:
--no-extensions - Opção do SDK:
disableExtensionDiscovery
Divisão de comportamento:
- SDK: quando
disableExtensionDiscovery=true, ainda carregaadditionalExtensionPathsvialoadExtensions(). - A construção de caminhos do CLI (
main.ts) atualmente limpa os caminhos de extensão do CLI quando--no-extensionsestá definido, então-e/--hookexplícitos não são encaminhados nesse modo.
Desativar módulos de extensão específicos
Seção intitulada “Desativar módulos de extensão específicos”A configuração disabledExtensions filtra pelo formato de id da extensão:
extension-module:<derivedName>
derivedName é baseado no caminho de entrada (getExtensionNameFromPath), por exemplo:
/x/foo.ts->foo/x/bar/index.ts->bar
Exemplo:
disabledExtensions: - extension-module:fooResolução de caminhos e entradas
Seção intitulada “Resolução de caminhos e entradas”Normalização de caminhos
Seção intitulada “Normalização de caminhos”Para caminhos configurados:
- Normalizar espaços unicode
- Expandir
~ - Se relativo, resolver em relação ao
cwdatual
Se o caminho configurado é um arquivo
Seção intitulada “Se o caminho configurado é um arquivo”Ele é usado diretamente como candidato a entrada de módulo.
Se o caminho configurado é um diretório
Seção intitulada “Se o caminho configurado é um diretório”Ordem de resolução:
package.jsonnesse diretório comxcsh.extensions(ou legadopi.extensions) -> usar entradas declaradasindex.tsindex.js- Caso contrário, varrer um nível em busca de entradas de extensão:
*.ts/*.jsdiretos- subdiretório
index.ts/index.js - subdiretório
package.jsoncomxcsh.extensions/pi.extensions
Regras e restrições:
- sem descoberta recursiva além de um nível de subdiretório
- entradas de manifesto
extensionsdeclaradas são resolvidas em relação ao diretório do pacote - entradas declaradas são incluídas apenas se o arquivo existir/acesso for permitido
- em pares
*/index.{ts,js}, TypeScript é preferido em relação a JavaScript - links simbólicos são tratados como arquivos/diretórios elegíveis
O comportamento de ignorar difere por fonte
Seção intitulada “O comportamento de ignorar difere por fonte”- A autodescoberta nativa (
discoverExtensionModulePathsnos helpers de descoberta) usa glob nativo comgitignore: trueehidden: false. - A varredura explícita de diretórios configurados em
loader.tsusa regras dereaddire não aplica filtragem de gitignore.
Ordem de carregamento e precedência
Seção intitulada “Ordem de carregamento e precedência”discoverAndLoadExtensions() constrói uma lista ordenada e então chama loadExtensions().
Ordem:
- Módulos nativos autodescobertos
- Caminhos explicitamente configurados (na ordem fornecida)
Em sdk.ts, a ordem configurada é:
- Caminhos adicionais do CLI
extensionsdas configurações
Deduplicação:
- baseada em caminho absoluto
- o primeiro caminho encontrado prevalece
- duplicatas posteriores são ignoradas
Implicação: se o mesmo caminho de módulo for autodescoberto e explicitamente configurado, ele é carregado uma vez na primeira posição (estágio de autodescoberta).
Importação de módulo e contrato da factory
Seção intitulada “Importação de módulo e contrato da factory”Cada caminho candidato é carregado com importação dinâmica:
await import(resolvedPath)- a factory é
module.default ?? module - a factory deve ser uma função (
ExtensionFactory)
Se a exportação não for uma função, esse caminho falha com um erro estruturado e o carregamento continua.
Tratamento de falhas e isolamento
Seção intitulada “Tratamento de falhas e isolamento”Durante o carregamento
Seção intitulada “Durante o carregamento”Por caminho de extensão, falhas são capturadas como { path, error } e não impedem o carregamento de outros caminhos.
Casos comuns:
- falha na importação / arquivo ausente
- exportação de factory inválida (não é função)
- exceção lançada durante a execução da factory
Modelo de isolamento em runtime
Seção intitulada “Modelo de isolamento em runtime”- As extensões não são sandboxed (mesmo processo/runtime).
- Elas compartilham um
EventBuse uma instância deExtensionRuntime. - Durante o carregamento, os métodos de ação do runtime intencionalmente lançam
ExtensionRuntimeNotInitializedError; a vinculação de ações acontece posteriormente emExtensionRunner.initialize().
Após o carregamento
Seção intitulada “Após o carregamento”Quando eventos são executados através do ExtensionRunner, exceções nos handlers são capturadas e emitidas como erros de extensão em vez de causar crash no loop do runner.
Exemplos mínimos de layout de usuário/projeto
Seção intitulada “Exemplos mínimos de layout de usuário/projeto”Nível de usuário
Seção intitulada “Nível de usuário”~/.xcsh/agent/ config.yml extensions/ guardrails.ts audit/ index.tsNível de projeto
Seção intitulada “Nível de projeto”<repo>/ .xcsh/ settings.json extensions/ checks/ package.json lint-gates.tschecks/package.json:
{ "xcsh": { "extensions": ["./src/check-a.ts", "./src/check-b.js"] }}Chave de manifesto legada ainda aceita:
{ "pi": { "extensions": ["./index.ts"] }}