- Início
- Documentation
- Configuração
- Descoberta e Resolução de Configuração
Descoberta e Resolução de Configuração
Este documento descreve como o coding-agent resolve a configuração atualmente: quais raízes são escaneadas, como a precedência funciona e como a configuração resolvida é consumida por settings, skills, hooks, tools e extensões.
Implementação principal:
src/config.tssrc/config/settings.tssrc/config/settings-schema.tssrc/discovery/builtin.tssrc/discovery/helpers.ts
Pontos-chave de integração:
src/capability/index.tssrc/discovery/index.tssrc/extensibility/skills.tssrc/extensibility/hooks/loader.tssrc/extensibility/custom-tools/loader.tssrc/extensibility/extensions/loader.ts
Fluxo de resolução (visual)
Seção intitulada “Fluxo de resolução (visual)” Config roots (ordered)┌───────────────────────────────────────┐│ 1) ~/.xcsh/agent + <cwd>/.xcsh ││ 2) ~/.claude + <cwd>/.claude ││ 3) ~/.codex + <cwd>/.codex ││ 4) ~/.gemini + <cwd>/.gemini │└───────────────────────────────────────┘ │ ▼ config.ts helper resolution (getConfigDirs/findConfigFile/findNearest...) │ ▼ capability providers enumerate items (native, claude, codex, gemini, agents, etc.) │ ▼ priority sort + per-capability dedup │ ▼ subsystem-specific consumption (settings, skills, hooks, tools, extensions)1) Raízes de configuração e ordem de fontes
Seção intitulada “1) Raízes de configuração e ordem de fontes”Raízes canônicas
Seção intitulada “Raízes canônicas”src/config.ts define uma lista fixa de prioridade de fontes:
.xcsh(nativo).claude.codex.gemini
Bases de nível de usuário:
~/.xcsh/agent~/.claude~/.codex~/.gemini
Bases de nível de projeto:
<cwd>/.xcsh<cwd>/.claude<cwd>/.codex<cwd>/.gemini
CONFIG_DIR_NAME é .xcsh (packages/utils/src/dirs.ts).
Restrição importante
Seção intitulada “Restrição importante”Os helpers genéricos em src/config.ts não incluem .pi na ordem de descoberta de fontes.
2) Helpers principais de descoberta (src/config.ts)
Seção intitulada “2) Helpers principais de descoberta (src/config.ts)”getConfigDirs(subpath, options)
Seção intitulada “getConfigDirs(subpath, options)”Retorna entradas ordenadas:
- Entradas de nível de usuário primeiro (por prioridade de fonte)
- Depois entradas de nível de projeto (pela mesma prioridade de fonte)
Opções:
user(padrãotrue)project(padrãotrue)cwd(padrãogetProjectDir())existingOnly(padrãofalse)
Esta API é utilizada para buscas de configuração baseadas em diretórios (commands, hooks, tools, agents, etc.).
findConfigFile(subpath, options) / findConfigFileWithMeta(...)
Seção intitulada “findConfigFile(subpath, options) / findConfigFileWithMeta(...)”Busca o primeiro arquivo existente entre as bases ordenadas, retorna a primeira correspondência (apenas o caminho ou caminho+metadados).
findAllNearestProjectConfigDirs(subpath, cwd)
Seção intitulada “findAllNearestProjectConfigDirs(subpath, cwd)”Percorre os diretórios ancestrais para cima e retorna o diretório existente mais próximo por base de fonte (.xcsh, .claude, .codex, .gemini), depois ordena os resultados por prioridade de fonte.
Use isso quando a configuração de projeto deve ser herdada de diretórios ancestrais (comportamento de monorepo/workspace aninhado).
3) Wrapper de arquivo de configuração (ConfigFile<T> em src/config.ts)
Seção intitulada “3) Wrapper de arquivo de configuração (ConfigFile<T> em src/config.ts)”ConfigFile<T> é o carregador com validação de schema para arquivos de configuração únicos.
Formatos suportados:
.yml/.yaml.json/.jsonc
Comportamento:
- Valida os dados parseados com AJV contra um schema TypeBox fornecido.
- Armazena em cache o resultado do carregamento até
invalidate(). - Retorna resultado de três estados via
tryLoad():oknot-founderror(ConfigErrorcom contexto de schema/parse)
Migração legada ainda suportada:
- Se o caminho alvo é
.yml/.yaml, um.jsonadjacente é migrado automaticamente uma vez (migrateJsonToYml).
4) Modelo de resolução de settings (src/config/settings.ts)
Seção intitulada “4) Modelo de resolução de settings (src/config/settings.ts)”O modelo de settings em tempo de execução é organizado em camadas:
- Settings globais:
~/.xcsh/agent/config.yml - Settings de projeto: descobertas via capability de settings (
settings.jsondos providers) - Overrides em tempo de execução: em memória, não persistentes
- Valores padrão do schema: do
SETTINGS_SCHEMA
Caminho efetivo de leitura:
defaults <- global <- project <- overrides
Comportamento de escrita:
settings.set(...)escreve na camada global (config.yml) e enfileira salvamento em background.- Settings de projeto são somente leitura a partir da descoberta de capabilities.
Comportamento de migração ainda ativo
Seção intitulada “Comportamento de migração ainda ativo”Na inicialização, se config.yml não existe:
- Migra de
~/.xcsh/agent/settings.json(renomeado para.bakem caso de sucesso) - Mescla com settings legadas do DB de
agent.db - Escreve o resultado mesclado em
config.yml
Migrações em nível de campo em #migrateRawSettings:
queueMode->steeringModeask.timeoutmilissegundos -> segundos quando o valor antigo parece ser ms (> 1000)theme: "..."flat legado -> estruturatheme.dark/theme.light
5) Integração capability/discovery
Seção intitulada “5) Integração capability/discovery”A maioria dos fluxos de carregamento de configuração não-core passa pelo registro de capabilities (src/capability/index.ts + src/discovery/index.ts).
Ordenação de providers
Seção intitulada “Ordenação de providers”Providers são ordenados por prioridade numérica (maior primeiro). Exemplos de prioridades:
- Native OMP (
builtin.ts):100 - Claude:
80 - Codex / agents / Claude marketplace:
70 - Gemini:
60
Provider precedence (higher wins)
native (.xcsh) priority 100claude priority 80codex / agents / ... priority 70gemini priority 60Semântica de deduplicação
Seção intitulada “Semântica de deduplicação”Capabilities definem uma key(item):
- mesma chave => primeiro item vence (item de maior prioridade/carregado primeiro)
- sem chave (
undefined) => sem deduplicação, todos os itens são mantidos
Chaves relevantes:
- skills:
name - tools:
name - hooks:
${type}:${tool}:${name} - extension modules:
name - extensions:
name - settings: sem deduplicação (todos os itens são preservados)
6) Comportamento do provider nativo .xcsh (src/discovery/builtin.ts)
Seção intitulada “6) Comportamento do provider nativo .xcsh (src/discovery/builtin.ts)”O provider nativo (id: native) lê de:
- projeto:
<cwd>/.xcsh/... - usuário:
~/.xcsh/agent/...
Regra de admissão de diretório
Seção intitulada “Regra de admissão de diretório”builtin.ts só inclui uma raiz de configuração se o diretório existir e não estiver vazio (ifNonEmptyDir).
Carregamento específico por escopo
Seção intitulada “Carregamento específico por escopo”- Skills:
skills/*/SKILL.md - Slash commands:
commands/*.md - Rules:
rules/*.{md,mdc} - Prompts:
prompts/*.md - Instructions:
instructions/*.md - Hooks:
hooks/pre/*,hooks/post/* - Tools:
tools/*.json|*.mdetools/<name>/index.ts - Extension modules: descobertos em
extensions/(+ array de strings legadosettings.json.extensions) - Extensions:
extensions/<name>/gemini-extension.json - Settings capability:
settings.json
Nuance de busca de projeto mais próximo
Seção intitulada “Nuance de busca de projeto mais próximo”Para SYSTEM.md e XCSH.md, o provider nativo usa a busca de diretório .xcsh de projeto no ancestral mais próximo (subindo a árvore) mas ainda exige que o diretório .xcsh não esteja vazio.
7) Como os principais subsistemas consomem a configuração
Seção intitulada “7) Como os principais subsistemas consomem a configuração”Subsistema de settings
Seção intitulada “Subsistema de settings”Settings.init()carrega oconfig.ymlglobal + itens descobertos da capability de settings do projeto.- Apenas itens de capability com
level === "project"são mesclados na camada de projeto.
Subsistema de skills
Seção intitulada “Subsistema de skills”extensibility/skills.tscarrega vialoadCapability(skillCapability.id, { cwd }).- Aplica toggles e filtros de fonte (
ignoredSkills,includeSkills, diretórios customizados). - Toggles com nomes legados ainda existem (
skills.enablePiUser,skills.enablePiProject) mas controlam o provider nativo (provider === "native").
Subsistema de hooks
Seção intitulada “Subsistema de hooks”discoverAndLoadHooks()resolve caminhos de hooks a partir da capability de hooks + caminhos configurados explicitamente.- Depois carrega módulos via importação do Bun.
Subsistema de tools
Seção intitulada “Subsistema de tools”discoverAndLoadCustomTools()resolve caminhos de tools a partir da capability de tools + caminhos de tools de plugins + caminhos configurados explicitamente.- Arquivos de tools declarativos
.md/.jsonsão apenas metadados; o carregamento executável espera módulos de código.
Subsistema de extensões
Seção intitulada “Subsistema de extensões”discoverAndLoadExtensions()resolve módulos de extensão a partir da capability de extension-module mais caminhos explícitos.- A implementação atual intencionalmente mantém apenas itens de capability com
_source.provider === "native"antes do carregamento.
8) Regras de precedência nas quais confiar
Seção intitulada “8) Regras de precedência nas quais confiar”Use este modelo mental:
- A ordenação de diretórios de fonte do
config.tsdetermina a ordem dos caminhos candidatos. - A prioridade do provider de capability determina a precedência entre providers.
- A deduplicação por chave de capability determina o comportamento de colisão (primeiro vence para capabilities com chave).
- A lógica de merge específica do subsistema pode alterar ainda mais a precedência efetiva (especialmente settings).
Ressalva específica de settings
Seção intitulada “Ressalva específica de settings”Itens de capability de settings não são deduplicados; Settings.#loadProjectSettings() faz deep-merge dos itens de projeto na ordem retornada. Como o merge aplica valores de itens posteriores sobre valores anteriores, o comportamento efetivo de override depende da ordem de emissão do provider, não apenas da semântica de chave de capability.
9) Comportamentos de legado/compatibilidade ainda presentes
Seção intitulada “9) Comportamentos de legado/compatibilidade ainda presentes”- Migração de JSON -> YAML do
ConfigFilepara arquivos destinados a YAML. - Migração de settings de
settings.jsoneagent.dbparaconfig.yml. - Migrações de chaves de settings (
queueMode,ask.timeout,themeflat). - Compatibilidade de manifesto de extensão: o loader aceita tanto seções de manifesto
package.json.xcshquantopackage.json.pi. - Nomes de settings legados
skills.enablePiUser/skills.enablePiProjectainda são gates ativos para a fonte nativa de skills.
Se esses caminhos de compatibilidade forem removidos no código, atualize este documento imediatamente; vários comportamentos em tempo de execução ainda dependem deles hoje.