sem-mcp
Inteligência de código em nível de entidade para agentes
Documentação
Parte da stack Ataraxy Labs — infraestrutura nativa para agentes de desenvolvimento de software. Veja também: weave (driver de merge git em nível de entidade) · inspect (revisão de código semântica) · opensessions (barra lateral tmux para agentes de codificação).
Leia o manifesto: https://ataraxy-labs.com/#thesis · Ensaios: https://ataraxy-labs.com/blogs · LLMs: https://ataraxy-labs.com/llms.txt
Controle de versão semântico construído sobre o Git.
Em vez de linhas alteradas, o sem informa quais entidades mudaram: funções, métodos, classes.
Por que sem? · Instalação · Comandos · Agentes (MCP) · Consentimento em nuvem · Lançamentos
sem é uma ferramenta de controle de versão semântico que funciona sobre o Git. Ele analisa seu código com tree-sitter, extrai cada função, classe e método como uma entidade e faz diff no nível de entidade em vez de linhas. Isso significa que você vê "função blahh foi modificada" em vez de "linhas x-y alteradas."
Funciona em qualquer repositório Git sem configuração.
Consultas com suporte em nuvem são opt-in por repositório: fazer login não envia um repositório nem uma consulta. Veja o fluxo de consentimento em nuvem para os estados de repositório público/privado, tela de pré-visualização, log de auditoria local e controles de esquecimento.
Instalação
curl -fsSL https://raw.githubusercontent.com/Ataraxy-Labs/sem/main/install.sh | sh
Ou via Homebrew:
brew install sem-cli
Ou via winget no Windows:
winget install AtaraxyLabs.sem
Ou instale o wrapper npm em node_modules:
npm install --save-dev @ataraxy-labs/sem
Com Bun, confie no pacote para que seu script postinstall possa baixar o binário:
bun add -d @ataraxy-labs/sem
bun pm trust @ataraxy-labs/sem
Uma vez instalado, atualize para a versão mais recente a qualquer momento:
sem update
Ou compile a partir do código-fonte (requer Rust):
cargo install --git https://github.com/Ataraxy-Labs/sem sem-cli
Ou pegue um binário em GitHub Releases.
Ou execute via Docker:
docker build -t sem .
docker run --rm -it -u "$(id -u):$(id -g)" -v "$(pwd):/repo" sem diff
Conflito de nome com GNU Parallel
GNU Parallel inclui um binário sem (/usr/bin/sem) como um symlink para parallel. Se você tiver ambos instalados, eles entrarão em conflito. Execute sem --version para verificar qual você está usando. (#77)
Correções rápidas:
# Option 1: alias in your shell profile (~/.bashrc, ~/.zshrc)
alias sem="$HOME/.cargo/bin/sem"
# Option 2: make sure cargo bin comes first in PATH
export PATH="$HOME/.cargo/bin:$PATH"
# Option 3: if installed via Homebrew
export PATH="$(brew --prefix)/bin:$PATH"
Se você instalou via npm/bun, o binário fica em node_modules/.bin/sem e é invocado via npx sem ou bunx sem, o que evita o conflito completamente.
Comandos
Funciona em qualquer repositório Git. Sem configuração necessária. Também funciona fora do Git para comparação arbitrária de arquivos.
sem armazena seu cache de entidades SQLite fora do repositório, no diretório de cache do sistema por padrão. Defina SEM_CACHE_DIR=/path/to/cache para sobrescrever a raiz do cache; sobrescritas locais do repositório são ignoradas para que os arquivos de cache não sujem a árvore de trabalho.
sem diff
Diff em nível de entidade com detecção de renomeação, hashing estrutural e realces inline palavra por palavra.
# Semantic diff of working changes
sem diff
# Staged changes only
sem diff --staged
# Specific commit
sem diff --commit abc1234
# Commit range
sem diff --from HEAD~5 --to HEAD
# Verbose mode (word-level inline diffs for each entity)
sem diff -v
# Plain text output (git status style)
sem diff --format plain
# JSON output (for AI agents, CI pipelines)
sem diff --format json
# Markdown output (for PRs, reports)
sem diff --format markdown
# Compare any two files (no git repo needed)
sem diff file1.ts file2.ts
# Read file changes from stdin (no git repo needed)
echo '[{"filePath":"src/main.rs","status":"modified","beforeContent":"...","afterContent":"..."}]' \
| sem diff --stdin --format json
# Only specific file types
sem diff --file-exts .py .rs
sem impact
Grafo de dependências entre arquivos mostra o que quebra se uma entidade mudar.
# Full impact analysis
sem impact authenticateUser
# Direct dependencies only
sem impact authenticateUser --deps
# Direct dependents only
sem impact authenticateUser --dependents
# Affected tests only
sem impact authenticateUser --tests
# JSON output
sem impact authenticateUser --json
# Disambiguate by file
sem impact authenticateUser --file src/auth.ts
# Include default-excluded paths such as generated, fixture, vendor, benchmark, and build trees
sem impact authenticateUser --no-default-excludes
sem blame
Blame em nível de entidade mostrando quem modificou por último cada função, classe ou método.
sem blame src/auth.ts
# JSON output
sem blame src/auth.ts --json
sem log
Acompanhe como uma única entidade evoluiu através do histórico do git.
sem log authenticateUser
# Verbose mode (show content diff between versions)
sem log authenticateUser -v
# Limit commits scanned
sem log authenticateUser --limit 20
# JSON output
sem log authenticateUser --json
Com nenhuma entidade, sem log analisa o histórico recente do repositório no nível de entidade: hotspots (funções/classes mais alteradas, com contagem de autores) e pares de co-mudança (entidades que mudam repetidamente nos mesmos commits — "se você tocar em uma, não esqueça a outra"):
sem log # repo hotspots + co-change pairs (last 50 commits)
sem log --limit 200 # deeper history
sem log --file src/auth.ts # scoped to one file
sem log --json # full data
sem entities
Lista todas as entidades sob um caminho de arquivo ou diretório. Sem caminho é o mesmo que ..
sem entities
sem entities .
sem entities src/auth.ts
# JSON output
sem entities --json
sem entities src/auth.ts --json
# Include default-excluded paths such as generated, fixture, vendor, benchmark, and build trees
sem entities --no-default-excludes
sem context
Contexto com orçamento de tokens para LLMs: a entidade, suas dependências e seus dependentes, ajustados a um orçamento estrito de tokens de conteúdo. Quando a assinatura alvo não cabe, a saída JSON relata target_omitted: true.
sem context authenticateUser
# Custom token budget
sem context authenticateUser --budget 4000
# JSON output
sem context authenticateUser --json
# Include default-excluded paths such as generated, fixture, vendor, benchmark, and build trees
sem context authenticateUser --no-default-excludes
Usar como diff padrão do Git
Substitua a saída de git diff por diffs em nível de entidade. Agentes e humanos recebem a saída do sem automaticamente sem mudar nenhum comando.
sem setup
Agora git diff mostra mudanças em nível de entidade em vez de nível de linha. Sem prompts, sem configuração de agente. Tudo que chama git diff recebe a saída do sem automaticamente. Também instala um hook de pre-commit que mostra o raio de impacto em nível de entidade das mudanças staged.
No macOS e Linux, sem setup também conecta o sem às suas sessões do Claude Code (grátis, local, sem login): um grafo residente quente para que consultas estruturais respondam em milissegundos de um dígito em vez de reconstruir a cada vez, e contexto no momento do prompt para que o código que um agente procuraria chegue no início da rodada. Ele edita ~/.claude/settings.json de forma idempotente, faz backup antes e deixa qualquer hook que você já tenha intacto.
Para desativar e voltar ao git diff normal (também remove os hooks de sessão):
sem unsetup
Diffs em nível de entidade em todo pull request
Adicione a GitHub Action e cada PR recebe um comentário fixo mostrando quais funções, classes e métodos mudaram — atualizado no local a cada push, e destacando PRs apenas cosméticos (formatação/comentários) explicitamente:
# .github/workflows/entity-diff.yml
name: Entity diff
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
entity-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Ataraxy-Labs/sem/action@v0.15.1
Sem configuração, sem chaves de API, nunca falha seu build. Veja action/ para detalhes.
Aceleração em nuvem (para escala e equipes)
Local é sempre grátis e, após sem setup, sempre quente — o grafo residente mantém seu repositório aquecido na sua própria máquina, então consultas do dia a dia são instantâneas sem login. Você não paga para deixar seu laptop rápido.
Nuvem é para o que um laptop não pode fazer. Em um monorepo muito grande, a primeira construção do grafo local pode levar alguns segundos; um grafo de equipe compartilhado não deve ser reconstruído por desenvolvedor; e CI quer o grafo sem fazer checkout de nada. sem login conecta esses casos ao sem cloud, que mantém um grafo quente e pré-construído para seus repositórios registrados e atende as consultas pesadas a partir dele (em um repositório grande como deno, uma consulta impact é ~86ms da nuvem vs ~573ms reconstruída localmente).
sem login # GitHub device flow, one time
sem impact myFunc --file src/foo.rs # served from the cloud's warm graph
É totalmente opcional e transparente:
- Não logado, ou a nuvem inacessível? sem calcula localmente e imprime exatamente a mesma saída. Sem falhas, sem diferença nos resultados.
SEM_LOCAL=1força o cálculo local mesmo quando logado.- Repositórios pequenos não veem mudança, local já é rápido. A vantagem é para bases de código grandes onde reconstruir o grafo a cada vez é o gargalo.
O que ele analisa
32 linguagens de programação com extração completa de entidades via tree-sitter:
| Linguagem | Extensões | Entidades |
|---|---|---|
| TypeScript | .ts .tsx .mts .cts | funções, classes, interfaces, tipos, enums, exportações |
| JavaScript | .js .jsx .mjs .cjs | funções, classes, variáveis, exportações |
| Python | .py | funções, classes, definições decoradas |
| Go | .go | funções, métodos, tipos, variáveis, constantes |
| Rust | .rs | funções, structs, enums, impls, traits, mods, consts |
| Java | .java | classes, métodos, interfaces, enums, campos, construtores |
| C | .c .h | funções, structs, enums, unions, typedefs |
| C++ | .cpp .cc .hpp | funções, classes, structs, enums, namespaces, templates |
| C# | .cs | classes, métodos, interfaces, enums, structs, propriedades |
| Ruby | .rb | métodos, classes, módulos |
| PHP | .php | funções, classes, métodos, interfaces, traits, enums |
| Swift | .swift | funções, classes, protocolos, structs, enums, propriedades |
| Elixir | .ex .exs | módulos, funções, macros, guards, protocolos |
| Bash | .sh | funções |
| Fish | .fish | funções |
| Lua | .lua | funções (formas global, local, tabela e método) |
| HCL/Terraform | .hcl .tf .tfvars | blocos, atributos (nomes qualificados para blocos aninhados) |
| Kotlin | .kt .kts | classes, interfaces, objetos, funções, propriedades, companion objects |
| Fortran | .f90 .f95 .f | funções, subrotinas, módulos, programas |
| Vue | .vue | blocos template/script/style + entidades TS/JS internas |
| XML | .xml .plist .svg .csproj | elementos (aninhados, identidade por nome de tag) |
| ERB | .erb .html.erb | blocos, expressões, tags de código |
| Svelte | .svelte .svelte.js .svelte.ts | blocos de componente + módulos JS/TS rune |
| Perl | .pl .pm .t | subrotinas, pacotes |
| Dart | .dart | classes, mixins, extensões, enums, aliases de tipo, funções |
| OCaml | .ml .mli | valores, módulos, tipos, classes, externals |
| Scala | .scala .sc .sbt | classes, objetos, traits, enums, funções, vals, extensões |
| Nix | .nix | bindings, declarações de herança |
| Haskell | .hs | funções, assinaturas, tipos de dados, newtypes, classes, instâncias, sinônimos de tipo |
| Elm | .elm | declarações de valor, aliases de tipo, declarações de tipo, anotações de porta, declarações infix |
| Clojure | .clj .cljs .cljc | vars, funções, macros, multimétodos, protocolos, registros, tipos |
| D | .d .di | módulos, funções, classes, structs, interfaces, unions, enums, templates, aliases, unittests |
| Zig | .zig | funções, testes, variáveis |
| SQL | .sql .psql .pgsql .ddl | tabelas, visões, funções, índices, tipos, esquemas, triggers, sequências |
Mais formatos de dados estruturados:
| Formato | Extensões | Entidades |
|---|---|---|
| JSON | .json | propriedades, objetos (caminhos RFC 6901) |
| YAML | .yml .yaml | seções, propriedades (caminhos de ponto) |
| TOML | .toml | seções, propriedades |
| EDN | .edn | entradas de mapa de nível superior (chaves de palavra-chave) |
| CSV | .csv .tsv | linhas (primeira coluna como identidade) |
| Markdown | .md .mdx | seções baseadas em cabeçalhos |
Todo o resto cai em diff baseado em chunks.
Extensões personalizadas e arquivos sem extensão
Para arquivos com extensões não padrão, crie um .semrc na raiz do seu projeto:
.xyz = cpp
.j = json
.mypy = python
sem também lê padrões .gitattributes (diff= e linguist-language=) se você já os tiver configurado. .semrc tem prioridade quando ambos definem a mesma extensão.
Para arquivos sem extensão, sem detecta a linguagem automaticamente a partir do conteúdo (imports, declarações, linhas shebang, modelines vim). Isso cobre 19 linguagens sem configuração.
Como funciona a correspondência
Correspondência de entidades em três fases:
- Correspondência exata de ID — mesma entidade antes/depois = modificada ou inalterada
- Correspondência de hash estrutural — mesma estrutura AST, nome diferente = renomeada ou movida (ignora espaços em branco/comentários)
- Similaridade difusa — sobreposição de tokens >80% = provável renomeação
Isso significa que sem detecta renomeações e movimentações, não apenas adições e exclusões. O hashing estrutural também distingue mudanças cosméticas (espaços em branco, formatação) de mudanças reais de lógica.
Uso com agentes de IA (MCP)
sem mcp inicia um servidor Model Context Protocol via stdin/stdout. Não é um comando que você executa e lê por conta própria: é um servidor que seu agente de codificação inicia em segundo plano para que ele possa fazer perguntas ao sem enquanto trabalha. É por isso que mcp fica junto aos comandos normais. O agente recebe 6 ferramentas, todas no nível de entidade: sem_impact, sem_context, sem_diff, sem_entities, sem_blame, sem_log.
Por que um agente quer isso: em vez de ler arquivos inteiros e gastar tokens, ele pode perguntar "o que quebra se eu mudar submitOrder" (sem_impact) ou "me dê apenas o contexto para refatorar esta função" (sem_context) e obter uma resposta precisa a partir do grafo de dependências.
Adicione uma vez e depois converse normalmente com seu agente. Ele chama as ferramentas por conta própria.
Claude Code:
claude mcp add sem -- sem mcp
Ou um único comando que também instala a skill, para o agente saber quando recorrer ao sem:
npx @ataraxy-labs/sem-skill
Cursor, Claude Desktop, ou qualquer cliente com config mcpServers:
{
"mcpServers": {
"sem": {
"command": "sem",
"args": ["mcp"]
}
}
}
Se sem não estiver no PATH do agente, use o caminho absoluto até o binário. Não é necessária instalação separada: sem mcp vem no mesmo binário de todos os outros comandos.
Saída JSON
sem diff --format json
{
"summary": {
"fileCount": 2,
"added": 1,
"modified": 1,
"deleted": 1,
"moved": 0,
"renamed": 0,
"reordered": 0,
"binary": 0,
"orphan": 0,
"total": 3
},
"changes": [
{
"entityId": "src/auth.ts::function::validateToken",
"changeType": "added",
"entityType": "function",
"entityName": "validateToken",
"startLine": 12,
"endLine": 18,
"oldStartLine": null,
"oldEndLine": null,
"filePath": "src/auth.ts"
}
],
"binaryChanges": []
}
Os buckets nomeados por tipo de mudança (added, modified, deleted, moved, renamed, reordered) sempre somam total. orphan é uma contagem de metadados transversal para mudanças no nível de módulo, e essas mudanças já estão incluídas nos buckets nomeados por tipo.
Como biblioteca
sem-core pode ser usado como dependência de biblioteca Rust:
[dependencies]
sem-core = { git = "https://github.com/Ataraxy-Labs/sem", version = "0.5" }
Usado por weave (driver de merge semântico) e inspect (revisão de código no nível de entidade).
Arquitetura
- tree-sitter para análise de código (Rust nativo, não WASM)
- git2 para operações Git
- rayon para processamento paralelo de arquivos
- xxhash para hash estrutural
- Sistema de plugins para adicionar novas linguagens e formatos
Telemetria
O sem coleta dados de uso anônimos: o nome do comando (ex.: diff, impact), versão da CLI e sistema operacional. Nada mais — nenhum código, caminhos de arquivos, nomes de repositórios ou identidade do usuário. Eventos são agrupados localmente e enviados em segundo plano, então os comandos nunca esperam pela rede.
Desative a qualquer momento:
export SEM_NO_TELEMETRY=1 # or DO_NOT_TRACK=1
Contribuindo
Quer adicionar uma nova linguagem? Veja CONTRIBUTING.md para um guia passo a passo.
Histórico de Estrelas
Licença
MIT OR Apache-2.0
