Skill Manager for Copilot
Gerencie, sincronize e descubra skills do GitHub Copilot a partir de múltiplos repositórios Git.
Features
- Multi-repo — Configure quantos repositórios de skills quiser (público ou privado)
- Sync automático — Pull periódico com detecção de divergência via SHA-256
- Push de melhorias — Envie feedback e melhorias de skills de volta ao repo via branch + PR
- Prioridade configurável — Quando a mesma skill existe em 2+ repos, a prioridade decide
- Edição local segura — Edite skills localmente sem perder suas mudanças no próximo sync
- Sidebar dedicada — Activity bar com TreeView agrupada por repositório
- Status bar — Indicador de estado de sync sempre visível
- Init Repository — Scaffold automático para criar seu próprio repo de skills
- AI-Assisted (opt-in) — Otimizar SKILL.md, pontuar qualidade da
description e detectar padrões de uso recorrentes para sugerir novas skills
- Copilot Chat tools (LM Tools API) — 14 ferramentas
skillManager_* registradas via vscode.lm.registerTool permitem que o Copilot Chat (ou qualquer cliente LM) consulte estado (status, repos, skills, agents, hooks, audit summary, repo trust), execute pull_all, habilite/desabilite skills/agents globais, rode testes de skill, re-avalie ou destrate repositórios e prune o log de auditoria. Operações destrutivas (untrust_repo, run_audit_retention) carregam a tag destructive e exigem confirmação modal antes de executar. Veja docs/privacy.md §4 para o contrato de dados (resultados são texto plano com allowlist estrita — sem segredos, sem conteúdo de arquivos, sem eventos brutos de auditoria).
- IDE bridges — Mirror automático de skills (e em alguns casos agents/instructions) para outras IDEs e CLIs. Dois grupos:
- Group A (home global, opt-in por flag): Aider (
~/.aider/skills/skill-manager/ + bloco gerenciado em ~/.aider.conf.yml), Continue.dev (~/.continue/prompts/skill-manager/*.prompt.md + experimental.promptPath injetado só se ausente).
- Group B (per workspace folder, re-roda em
onDidChangeWorkspaceFolders): Windsurf (<folder>/.windsurfrules), Cursor (<folder>/.cursor/rules/<name>.mdc), Zed (opportunistic: no-op se .github/copilot-instructions.md existir; senão escreve <folder>/.rules quando zedBridge.writeRulesFile=true).
- Também: Kiro (
~/.kiro/skills + steering) e Antigravity (~/.gemini/antigravity/skills + rules/workflows). Todas as bridges novas vêm desligadas por default — habilite em skillManager.<bridge>.enabled.
Quality Score & Testing
Cada skill pode ter cenários de teste em tests/<nome>.md (## Prompt + ## Expected Behavior, com ## Anti-Patterns opcional). O SkillTestRunner executa cada cenário via LLM (Ollama local ou VS Code Language Model API), um juiz LLM emite veredicto {pass, reason}, e o SkillScoreService combina o resultado dos testes com findings do auditor determinístico para gerar uma nota 0–100:
score = round((0.6 * testPassRate + 0.4 * auditorPassRate) * 100)
Onde auditorPassRate = 1 − min(findings / 10, 1). O resultado é cacheado em globalState com hash de conteúdo (SKILL.md + tests/*.md) e invalida automaticamente quando o conteúdo muda.
A árvore de skills mostra um badge [NN] colorido (verde ≥80, amarelo 50–79, vermelho <50, laranja ⚠ untested). Comandos: Skills: Run Tests (All), Skills: Run Tests for Skill (também no menu de contexto), Skills: Clear Test Cache.
Configuração em skillManager.testing.* (enabled, ollama.enabled/endpoint/model, judgeModel, timeoutMs).
Discovery & Catalog
Browse e instale skills/agents/hooks de múltiplos repos através de um catálogo curado.
- Comando
Skill Manager: Browse Catalog abre o painel com busca, filtros por tipo (skill/agent/hook) e ação de instalar (copia a URL do repo para a área de transferência + dispara o addRepo).
- Busca com fallback de 3 níveis:
semantic (embeddings locais via @huggingface/transformers) → fts (sql.js FTS4) → substring (sempre disponível). Os dois primeiros são optionalDependencies — sem eles o catálogo continua funcional no nível mais baixo.
- Stack-aware ranking — detecta linguagens abertas, dependências do
package.json e extensões ativas para reordenar resultados (skillManager.discovery.stackBoost.enabled, default true).
- Registry configurável via
skillManager.discovery.registryUrl (default: skill-kit/main/registry/index.json). Cache local em <globalStorage>/discovery/.
- Telemetria opt-in e agregada — desligada por default; quando ligada envia apenas
{ installId, extVersion, registryVersion, counts: { installed, type } }. Detalhes em docs/privacy.md.
Documentação completa: docs/discovery.md.
AI-Assisted Features (opt-in)
Três comandos baseados em LLM, todos sob consentimento explícito (Art. 8 LGPD) e com cache local persistente:
| Comando |
ID |
Descrição |
| Skills: Optimize with AI |
skillManager.ai.optimizeSkill |
Reescreve uma SKILL.md priorizando descoberta. Mostra diff lado a lado antes de aplicar (Accept/Reject). |
| Skills: Score with AI |
skillManager.ai.scoreSkill |
Avalia a description em uma rubrica 0-100 (5 dimensões) e exibe em painel webview. |
| Skills: Analyze Recent Activity (AI) |
skillManager.ai.analyzeActivity |
Lê transcripts recentes do Copilot Chat e propõe uma nova skill quando detecta padrão repetido. Opt-in. |
Provedores suportados (configurável via skillManager.ai.provider):
vscode-lm (padrão) — usa o modelo já autenticado do VS Code Copilot via Language Model API.
ollama — usa um servidor Ollama local. Habilite com skillManager.ai.ollama.enabled e configure endpoint/model.
Privacidade: nada sai sem o seu consentimento explícito. Revogue a qualquer momento com Skill Repo: Revoke AI Consent. Detalhes completos em docs/privacy.md.
AI Settings
| Setting |
Default |
Descrição |
skillManager.ai.provider |
vscode-lm |
Provedor ativo: vscode-lm ou ollama. |
skillManager.ai.ollama.enabled |
false |
Habilita o provedor Ollama. |
skillManager.ai.ollama.endpoint |
http://localhost:11434 |
URL base do servidor Ollama. |
skillManager.ai.ollama.model |
llama3.1 |
Modelo Ollama. |
skillManager.ai.cache.ttlDays |
30 |
TTL do cache de respostas (entradas com mesmo input não disparam nova chamada). |
skillManager.ai.optimize.enabled |
true |
Habilita o comando Optimize. |
skillManager.ai.score.enabled |
true |
Habilita o comando Score. |
skillManager.ai.autoSkill.enabled |
false |
Opt-in. Habilita a análise de transcripts. |
skillManager.ai.autoSkill.threshold |
0.7 |
Confiança mínima (0-1) para sugerir uma nova skill. |
Hooks Engine (windowless dispatcher)
O motor de hooks é um dispatcher node puro e windowless: para cada evento de ciclo de vida ele consolida os múltiplos hooks gerenciados numa única entrada e os executa sem abrir janela de console (no Windows, N janelas viram 1). É o único caminho, sempre ativo — sem modo a ligar.
Dois tiers:
- Determinístico — hooks de segurança/gate rodam sempre, nunca são pulados adaptativamente.
- Adaptativo — hooks consultivos são pontuados por um scorer logístico local (CPU, sem GPU) que calibra os pesos pela própria execução; falha sempre aberta (nunca bloqueia sua ação).
Agnóstico de IDE — roda igual no Copilot CLI, no desktop e no VS Code (node do sistema, sem acoplamento com o Electron).
Visibilidade — a view Hooks na sidebar mostra, por evento, os sub-hooks consolidados com o badge de tier; a status bar mostra a saúde do motor.
Os hooks de frontmatter dos agentes também passam pelo mesmo dispatcher, com um manifesto por agente que preserva os sub-hooks originais.
Proteção de runtime: registros gerenciados, inclusive hooks únicos, incorporam um supervisor autocontido. Runtime/manifesto ausente, crash ou timeout gera aviso e pula a infraestrutura indisponível; denies saudáveis continuam válidos, mesmo com um peer quebrado. O orçamento de execução preserva a soma dos timeouts dos sub-hooks, adicionando a reserva do supervisor ao teto externo.
Escolhas e dados preservados: markers .disabled/.disable do dispatcher impedem reinstalação automática e execução, mesmo se houver também um arquivo ativo. Comandos complexos preservam argumentos, aspas e env; manifestos ausentes/corrompidos não viram eventos vazios — são mantidos para reparo explícito, com diagnóstico não bloqueante.
Enable Hook sem perda de deny: ao habilitar explicitamente o dispatcher padrão 0.26.0, o código é preparado ainda OFF antes do rename. A primeira execução já funciona sem novo refresh/consolidate. Código custom compatível é preservado; código desconhecido/incompatível permanece OFF com erro explícito, sem sobrescrita.
Coexistência: a migração legada nunca apaga ~/.copilot/neural-link (runtime, pesos e logs compartilhados com o engine-registry). Somente agentes com manifesto de propriedade, marker antigo e backup são migrados. Consulte contrato, limites e gates.
Verificações pendentes (Skill Engine)
Uma versão nova baixada em quarentena vira uma pendência em ~/.skill-engine/pending.json. Um único hook de sessão (~/.skill-engine/hooks/session-hook.js), fora do dispatcher acima e registrado pela extensão no Claude Code (~/.claude/settings.json), no Codex (~/.codex/hooks.json) e no Copilot CLI (~/.copilot/hooks/skill-engine.json), avisa o agente da sessão e garante a pergunta:
| Estado na sessão |
Stop (Claude, Codex e Copilot) |
| aviso dado, ferramenta de opções não chamada |
segura o fim do turno (no máximo 3 vezes por sessão e pendência, abaixo do teto de 8 do Copilot) |
ferramenta de opções chamada (AskUserQuestion, request_user_input, ask_user), sem resposta ainda |
deixa terminar; a pendência continua e volta no próximo prompt ou sessão |
Sem ferramenta de opções (Codex fora do modo Plan), a pergunta escrita com a marca [skill-engine:ask <id>] conta como oferecida. O Codex pede uma confiança única do hook novo em /hooks. No Copilot o hook é registrado como Stop, o nome PascalCase do evento agentStop, que recebe a entrada no formato compatível com o VS Code (transcript_path em snake_case).
O painel Skill Engine: Pending Verifications (status bar N pending) mostra cada pendência com o estado, e por item: Copy request copia o pedido de verificação; Send to session o coloca na fila e a próxima sessão em que você digitar (Claude Code, Codex) ou abrir (Copilot CLI) o recebe e roda a verificação. O painel mostra quando o pedido foi entregue e a qual sessão.
Instalação
Marketplace
Busque por "Skill Manager for Copilot" no VS Code Extensions.
Manual (VSIX)
npx vsce package
code --install-extension copilot-skill-manager-0.19.0.vsix
Atualização automática
Ao ativar, a extensão consulta a versão publicada no Open VSX. Se houver uma mais nova, mostra o aviso
"Skill Manager X is available" e instala na hora; depois de recarregar a janela, o aviso
"Skill Manager updated to X" confirma a atualização. Com SKILL_MANAGER_AUTO_UPDATE=0 no ambiente,
o aviso aparece com o botão Update e nada é instalado sem o clique. Falha na consulta vai para o
canal de saída do Skill Manager.
Uso
1. Adicionar repositório
Ctrl+Shift+P → Skills: Add Repository → Cole a URL do repo Git.
Ou adicione o repo oficial:
Ctrl+Shift+P → Skills: Add Official Repository
2. Pull de skills
As skills são sincronizadas automaticamente ao abrir o VS Code. Para sync manual:
Ctrl+Shift+P → Skills: Pull All
3. Push de melhorias
Clique com botão direito em uma skill na sidebar → Push Improvement, ou:
Ctrl+Shift+P → Skills: Push Improvement
Cria uma branch, commita as mudanças e mostra o link para abrir o PR.
4. Status e diff
Ctrl+Shift+P → Skills: Show Status
Mostra QuickPick com todas as skills e abre diff visual (local ↔ repo).
Configurações
| Propriedade |
Default |
Descrição |
skillManager.repos |
[] |
Repositórios Git de skills |
skillManager.syncInterval |
3600 |
Intervalo de sync automático em segundos (0 = desabilitado) |
skillManager.conflictStrategy |
"highest-priority" |
Estratégia quando a mesma skill existe em múltiplos repos |
skillManager.autoSync |
true |
Sync automático ao iniciar o VS Code |
skillManager.skillsPath |
"" |
Caminho para pasta de skills (vazio = auto-detect ~/.copilot/skills/) |
skillManager.localEditStrategy |
"ask" |
O que fazer quando repo tem versão nova mas local foi editado |
conflictStrategy
| Valor |
Comportamento |
highest-priority |
Skill do repo com menor priority vence (silencioso) |
ask |
Pergunta ao usuário qual versão manter |
keep-local |
Mantém a versão já instalada |
localEditStrategy
| Valor |
Comportamento |
ask |
Pergunta: manter local, atualizar, ou ver diff |
keep-local |
Mantém edições locais, marca como divergente |
overwrite |
Substitui pelo repo (edições locais perdidas) |
Comandos
| Comando |
Descrição |
Skills: Pull All |
Sincroniza todas as skills de todos os repos |
Skills: Pull From... |
Sincroniza de um repo específico |
Skills: Push Improvement |
Envia melhorias via branch + PR |
Skills: Show Status |
Status de todas as skills com diff visual |
Skills: Add Repository |
Adiciona um repo de skills |
Skills: Remove Repository |
Remove um repo configurado |
Skills: Add Official Repository |
Adiciona o repo oficial de skills |
Skills: Browse Catalog |
Navega skills do repo oficial |
Skills: Init Repository |
Cria scaffold de um novo repositório de skills |
Skills: Disable Skill |
Desabilita uma skill (rename com .disabled) |
Skills: Enable Skill |
Reabilita uma skill desabilitada |
Skills: Remove Skill |
Remove uma skill local permanentemente |
Skills: Switch Profile |
Alterna o profile ativo (status bar) |
Skills: Create Profile |
Cria um profile (workspace ou global) |
Skills: Edit Active Profile |
Abre o JSON do profile ativo no editor |
Skills: Delete Profile |
Remove um profile (com confirmação modal) |
Skills: Configure Selective Sync |
Multi-select por repo: oculta no workspace o que não foi marcado |
Profiles & Bundles
Equipes podem versionar profiles (subconjuntos curados de skills/agents/hooks/bundles)
no workspace ou globalmente.
Workflow típico de equipe:
- Tech lead cria
profile-react.json em .skillmanager/profiles/ e commita no repo da equipe.
- Dev clica no indicador de profile no status bar (
🎯 No profile) → escolhe profile-react.
- Apenas as skills/agents/hooks listadas (e os membros dos bundles citados) ficam ativos.
Resolução:
- Workspace > Global (mesmo nome): o profile em
.skillmanager/profiles/ sobrescreve o global.
bundles[] é expandido via manifests bundle.json encontrados nos repos sincronizados.
- Sem profile ativo, o comportamento atual é preservado (placement-mode).
Bundle manifest (<repo>/bundles/<name>/bundle.json):
{
"name": "react-essentials",
"description": "skills + agents para projetos React",
"members": [
{ "type": "skill", "path": "skills/jsx-best-practices" },
{ "type": "agent", "path": "agents/react-reviewer.agent.md" }
]
}
Profile schema (.skillmanager/profiles/<name>.json ou storage global):
{
"name": "react-fullstack",
"description": "Stack React + Node",
"skills": ["repo-slug/skill-name"],
"agents": ["repo-slug/agent-name"],
"hooks": ["repo-slug/hook-name"],
"bundles": ["repo-slug/react-essentials"],
"createdAt": "2026-…",
"updatedAt": "2026-…"
}
Selective sync (alternativa a profiles): Skills: Configure Selective Sync
mostra um QuickPick multi-select dos itens de um repo; itens desmarcados são
workspace-disabled via PlacementService (skills/agents apenas — hooks
não são rastreados ali e passam direto).
Settings de profiles
| Setting |
Default |
Descrição |
skillManager.profiles.activeProfile |
"" |
Nome do profile ativo (vazio = sem profile) |
skillManager.profiles.showStatusBar |
true |
Mostra o indicador no status bar |
skillManager.profiles.workspaceScope |
true |
Workspace > Global quando ambos existem |
Keybindings sugeridas
A extensão não registra keybindings por padrão (para não conflitar com seu setup). Se quiser atalhos para os comandos mais usados, adicione ao seu keybindings.json (Preferences → Keyboard Shortcuts → Open Keyboard Shortcuts (JSON)):
[
{ "key": "ctrl+alt+s p", "command": "skillManager.pullAll" },
{ "key": "ctrl+alt+s a", "command": "skillManager.audit.workspace" },
{ "key": "ctrl+alt+s f", "command": "skillManager.audit.activeFile" },
{ "key": "ctrl+alt+s s", "command": "skillManager.status" },
{ "key": "ctrl+alt+s c", "command": "skillManager.copilot.focus" }
]
Estrutura de um repo de skills
meu-repo/
├── .skillmanager.json # (opcional) config do repo
├── skills/
│ ├── minha-skill/
│ │ ├── SKILL.md # (obrigatório) definição da skill
│ │ ├── FEEDBACK.md # (opcional) template de feedback
│ │ └── references/ # (opcional) arquivos de referência
│ └── outra-skill/
│ └── SKILL.md
├── agents/ # (opcional) agents customizados
│ └── meu-agent.agent.md
└── hooks/ # (opcional) hooks para agentes
└── scripts/
└── meu-hook.ps1
Para um guia completo, veja o Tutorial: Criando seu Repo de Skills.
Segurança
- Zero dados sensíveis — A extensão é open-source, sem segredos embarcados
- Auth via Git nativo — Credenciais delegadas ao credential manager do OS
- Push apenas via branch — Toda mudança passa por PR review
- Path traversal protection — Validação de paths de
.skillmanager.json contra traversal
- Sem telemetria remota — Nenhum dado deixa sua máquina. O recurso opt-in "Local Observability" (ver abaixo) grava apenas em disco local.
Local Observability (opt-in, off by default)
Para inspecionar localmente o uso de skills, hooks e syncs, ative em settings:
"skillManager.observability.enabled": true
O que é coletado (formato JSONL append-only em <globalStorage>/usage/events.jsonl):
skill_invoked: t, type, ok, name, agent, durationMs
hook_executed: t, type, ok, name, phase, latencyMs, exitCode
sync_completed: t, type, ok, repo, durationMs, added, removed, changed
O que NÃO é coletado: conteúdo de prompts, paths de arquivos, parâmetros de tools, output de comandos, qualquer PII. O store rejeita silenciosamente eventos com campos fora da allowlist.
Comandos:
Usage: Open Local Observability Panel — top skills, latência de hooks (p50/p95/p99), timeline de sync
Usage: Export Events (JSON/CSV) — exporta todo o arquivo
Usage: Clear All Local Data — apaga events.jsonl (confirmação modal)
Usage: Open Raw Data File — abre o JSONL no editor
Retenção: configurável via skillManager.observability.retentionDays (default 30, max 365, 0 = ilimitado). Aplicada na ativação da extensão.
Para o contrato completo de dados, veja docs/privacy.md.
Trust pipeline para repositórios de skills
Cada repositório que você adiciona passa por um pipeline de confiança:
- Workspace Trust —
pullAll / addRepo / sync são bloqueados em workspaces não confiáveis (vscode.workspace.isTrusted).
- Auditoria estática — toda skill / agent / hook é avaliada (
auditFile) antes do primeiro uso e o resultado é apresentado num modal de confiança.
- Hook permissions — hooks JS podem declarar
@permissions fs.read,fs.write,net,exec; usos estáticos perigosos (child_process.exec, eval, new Function) disparam um modal por hook na primeira sincronização. A decisão (always / once) é persistida.
- Owner-change detection — a cada
sync o owner / visibility / archived do repo é re-verificado via GitHub REST API; qualquer mudança revoga a confiança e exige re-grant.
- Assinatura GPG opcional — quando
skillManager.security.gpgRequired é true, o commit HEAD é verificado via git verify-commit (execFile, nunca shell).
- Audit log append-only — todos os eventos relevantes (
trust_granted, trust_revoked, owner_changed, hook_install_decision, static_finding, gpg_verified, untrust) ficam em <globalStorage>/security/audit.jsonl com retenção configurável (skillManager.security.auditLogRetentionDays).
- Untrust atômico — o comando Security: Untrust Repository revoga a confiança, varre skills/agents/hooks sincronizados (matched por
SyncManifest.repoUrl), apaga o clone local e remove o repo da config — tudo numa operação confirmada por modal.
Veja docs/security-model.md para o threat model completo, limites conhecidos e formato do audit log.
Monorepo
Este repositório também publica três pacotes companheiros que reutilizam a mesma lógica da extensão sem acoplamento com a API do VS Code:
A migração é incremental: utilitários, constantes, configService, lintService e EntryPointGenerator já vivem em core; serviços ainda acoplados ao VS Code (sync, conflict resolver, customizations-auditor) permanecem em src/ até refatoração. Plano e progresso completos em docs/monorepo-migration.md.
Build do monorepo:
npm ci
npx tsc -b # constrói core, cli, action via project references
npm run lint
npm test
License
MIT