Troubleshooting de indexação de catálogos de skills: do scan ao syscall mismatch#
Recentemente, precisei rodar uma extensão de catálogo de skills (skills-vscode) no meu ambiente Linux. A proposta da ferramenta é direta: ela recebe uma lista de fontes de catálogos (seja via Git remoto com SSH/HTTPS, repositórios de organização ou caminhos locais no sistema de arquivos), varre essas fontes em busca de arquivos de definição SKILL.md e monta um índice local estruturado para consumo na IDE.
Parece um fluxo simples de automação, mas a camada de abstração entre a aplicação e o sistema de arquivos sempre guarda surpresas. Compartilho aqui a anatomia do problema, a análise de logs, o diagnóstico na camada de sistema operacional e a solução prática para fazer a indexação funcionar.
O fluxo teórico de descoberta#
Por baixo do capô, um indexador desse tipo opera seguindo um ciclo de vida dividido entre rede e chamadas de sistema locais:
- Fontes Remotas (Git via HTTPS/SSH):
A extensão executa um clone raso (git clone --depth 1) ou faz fetch direcionado para um diretório temporário (como /tmp/skills-vscode-*), evitando o tráfego de todo o histórico de commits e economizando I/O de disco.
- Fontes Locais (Local Path):
O engine acessa caminhos absolutos ou relativos diretamente no filesystem via chamadas de sistema nativas (stat(), openat(), getdents64()).
- Varredura e Filtragem:
O scanner percorre a árvore de diretórios procurando estritamente pela assinatura de arquivo esperada: SKILL.md.
- Persistência de Metadados:
Ao encontrar os arquivos, o parser extrai o conteúdo e persiste o índice consolidado em um arquivo JSON de armazenamento global (catalog-index.json).
O problema: indexação concluída com 0 skills#
Após configurar uma fonte de repositório público para testes, disparei a rotina de scan. O processo finalizou sem erros fatais aparentes, mas o resultado final foi nulo.
Ao inspecionar o log detalhado de execução do dashboard, me deparei com a seguinte sequência:
[dashboard] search merged results=10 (returned=10)
[debug][discoverSkillsWithSubpathFallback] repoDir=/tmp/skills-vscode-kdDUha candidates=[null]
[debug][discoverSkills] basePath=/tmp/skills-vscode-kdDUha subpath=(none) searchPath=/tmp/skills-vscode-kdDUha
[debug][discoverSkills] priority dir hit: /tmp/skills-vscode-kdDUha (9 entries)
[debug][discoverSkills] after priority scan: 0 skills found
[debug][discoverSkills] falling back to findSkillDirs on: /tmp/skills-vscode-kdDUha
[debug][discoverSkills] findSkillDirs found dirs: []
[debug][discoverSkills] final result: (none)
[debug][discoverSkillsWithSubpathFallback] subpath=undefined => 0 skills
[debug][discoverSkillsWithSubpathFallback] all candidates exhausted, 0 skills
[info] catalog index saved: /root/.antigravity-server/data/User/globalStorage/gaoyuan.skills-vscode/catalog-index.json (0 skills)
Fui direto no diretório de armazenamento global verificar o arquivo gerado:
cd /root/.antigravity-server/data/User/globalStorage/gaoyuan.skills-vscode/
cat catalog-index.json
A saída confirmava o mismatch:
{
"updatedAt": "2026-03-28T21:52:00.511Z",
"sourcesHash": "b73bc4d67518db8629a8571df06fea1d3e7c5485",
"sources": [
{
"source": "https://github.com/example-org/catalog-templates.git",
"skillCount": 0,
"lastIndexedAt": "2026-03-28T21:52:00.510Z",
"availableRefs": [
"fix/example-branch",
"main",
"topic/feature"
],
"currentRef": "main"
}
],
"entries": []
}
Análise de causa raiz (root cause analysis)#
Analisando as evidências, isolei onde a esteira estava operando corretamente e onde ela quebrava:
- A camada de rede e Git funcionou perfeitamente: A extensão autenticou, consultou o repositório remoto, mapeou as branches remotas (
availableRefs) e fez o checkout da branchmainno diretório temporário/tmp/skills-vscode-kdDUha. - O I/O de disco respondeu: O log registrou
priority dir hit: /tmp/skills-vscode-kdDUha (9 entries). As 9 entradas eram os arquivos e pastas da raiz do repositório clonado (README.md,.git, licença, diretórios de templates, etc.). - O contrato de arquivo foi violado (Schema/Signature Mismatch): O repositório utilizado como teste estruturava suas definições em arquivos de outros ecossistemas (como
catalog-info.yamloutemplate.yaml). A extensão, no entanto, opera sob uma regra estrita: ela busca exclusivamente porSKILL.md.
Além disso, em sistemas Linux (com sistemas de arquivos como ext4 ou xfs), a resolução de nomes é estritamente case-sensitive. Se um repositório tiver skill.md, Skill.md ou SKILL.yaml, a chamada de sistema do runtime (Node.js/libuv) não fará o match, a menos que haja um fallback explícito no código do scanner. Sem o arquivo com a nomenclatura exata, findSkillDirs retorna vazio ([]) e o índice é salvo com entries: [].
Validando e corrigindo na prática#
Para isolar o comportamento do scanner e garantir que o problema era apenas a ausência do arquivo no contrato esperado, montei um teste com fonte local no próprio servidor.
1. Criando a estrutura com o contrato exato#
Criei uma árvore de diretórios local e injetei um SKILL.md formatado na estrutura esperada:
mkdir -p /root/my-catalog/linux-sre
Gerei o arquivo de skill:
cat <<EOF > /root/my-catalog/linux-sre/SKILL.md
# Linux SRE L3 Tuning
Description: Advanced kernel tuning and system optimization definitions.
---
## Skills
- sysctl-optimization
- io-scheduler-tuning
- oom-killer-config
EOF
2. Configurando o catalogSources#
Apontei a configuração de fontes da extensão diretamente para o caminho local absoluto:
{
"skills.catalogSources": [
"/root/my-catalog"
]
}
Também é possível utilizar múltiplos tipos de origens de acordo com a topologia do seu ambiente:
{
"skills.catalogSources": [
"https://github.com/my-org/skills-repo.git",
"[email protected]:my-org/private-skills.git",
"/root/my-catalog"
]
}
Diagnóstico rápido via CLI (cheat sheet)#
Para quem precisar debugar cenários semelhantes onde o indexador roda mas não encontra arquivos, estes comandos ajudam a validar o ambiente antes mesmo de acionar a extensão:
- Checar a existência do arquivo alvo no diretório temporário:
find /tmp/skills-vscode-* -name "SKILL.md"
- Rastrear as chamadas de abertura de arquivo da aplicação (
strace):
strace -f -e trace=openat,access -p <PID> 2>&1 | grep -i SKILL
- Testar permissão SSH para repositórios remotos sem interatividade:
ssh -vT [email protected]
Considerações práticas de indexação#
Quando ferramentas de catálogo e automação falham silenciosamente (ou finalizam com listas vazias), o primeiro passo é separar falhas de transporte/permissão de falhas de contrato de conteúdo.
Neste caso, a infraestrutura e o processo de clonagem estavam saudáveis; o gargalo era a expectativa rígida de nomenclatura (SKILL.md) em repositórios com outros padrões de catálogo. Adequando o repositório ao contrato esperado pelo indexador, a árvore de diretórios é percorrida corretamente e o índice local é populado conforme o esperado.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários