coldstart

Memória de codebase para agentes de codificação, sem embeddings e sem chave de API. Um índice AST determinístico responde "quais arquivos são relevantes para esta tarefa?" em milissegundos, e agentes escrevem notas duráveis sobre o repositório que são verificadas por hash de conteúdo — uma nota se marca como desatualizada no momento em que o código que ela descreve muda. As notas são markdown dentro do repositório, então elas são commitadas e revisadas junto com seu código.

Documentação

coldstart

coldstart

Conhecimento de base de código autossustentável para agentes de codificação de IA.
Notas escritas por agentes que permanecem ancoradas ao seu código — além de navegação rápida e determinística — para que Claude Code, Codex e Cursor parem de redescobrir o repositório a cada sessão.

npm version node >= 18 MIT license for Claude Code, Codex, Cursor

Site  ·  Documentação  ·  Blog  ·  Filosofia  ·  npm

Duas camadas, uma ferramenta:

  • O notebook (coldstart kb) — notas duráveis, escritas por agentes, sobre como este código realmente funciona: para que serve um arquivo, como um fluxo atravessa arquivos, quais invariantes se sustentam. Capturadas após tarefas reais, recuperadas quando uma tarefa posterior corresponde e mantidas honestas pelo índice — cada nota é ancorada em arquivos reais, e uma nota cuja evidência se desviou é sinalizada, não servida como verdade.
  • Navegação (coldstart find / coldstart gs) — um índice estático rápido sobre caminhos de arquivo, nomes de símbolos, exports e o grafo de import/chamada. Ele responde "quais arquivos são relevantes para esta tarefa?" em milissegundos, com evidência verificável em vez de uma pontuação de similaridade.

Sem embeddings, sem modelo para executar, sem serviço para monitorar. Agentes já são bons em ler e raciocinar sobre código; o que eles desperdiçam tokens é encontrar o arquivo certo e re-derivar o que a última sessão já descobriu. coldstart faz essas duas partes e sai do caminho.


Instalação

Requer Node.js 18+.

npm install -g @cstart/coldstart
cd your-project
coldstart init   # coldstart.md + client wiring + notebook + background index warm-up

Um único coldstart init faz tudo — navegação e o notebook. Ele pede duas coisas — a experiência (cli, recomendada, ou mcp) e o cliente — e então escreve as orientações voltadas ao agente no próprio arquivo de regras do cliente (como um coldstart.md importado para Claude Code; embutido diretamente para Cursor e Codex, que não resolvem referências @file), conecta o cliente e configura o notebook (esqueleto, integração com git e — para Claude Code, Codex e Cursor — os hooks de captura/recuperação). Passe --experience / --client para pular os prompts. O cliente nunca é detectado automaticamente; você sempre o escolhe.

  • Claude Code → escreve coldstart.md e garante que CLAUDE.md o importe via @coldstart.md, e registra tanto os hooks de busca find/gs (um lembrete PostToolUse + uma proteção de deduplicação PreToolUse) quanto os hooks de recuperação/captura do notebook (UserPromptSubmit + Stop/SubagentStop) em .claude/settings.json — mesclados em quaisquer configurações existentes, nunca as sobrescrevendo. A experiência mcp também escreve .mcp.json.
  • Codex → embute as orientações completas do coldstart inline em um bloco marcado em AGENTS.md (Codex não tem include @file, então não há um coldstart.md separado), atualizado no lugar em re-execuções, e registra navegação específica do Codex além dos hooks do notebook em .codex/hooks.json. O hook de captura entende os transcripts de rollout e subagentes do Codex. A experiência mcp também escreve [mcp_servers.coldstart] em .codex/config.toml.
  • Cursor → escreve .cursor/rules/coldstart.mdc — uma regra sempre aplicada que carrega as orientações completas do coldstart inline (Cursor não resolve referências @file de forma confiável em regras), reescrita a cada init — e registra navegação específica do Cursor além dos hooks do notebook em .cursor/hooks.json (uma proteção de deduplicação preToolUse, um lembrete postToolUse, recuperação beforeSubmitPrompt e captura stop/subagentStop — mesclados em quaisquer hooks existentes). O hook de captura analisa o transcript de conversa do próprio Cursor. A experiência mcp também escreve .cursor/mcp.json.
  • Outro → escreve apenas coldstart.md e imprime as instruções de conexão (além da entrada do servidor MCP para a experiência mcp).

init então aquece o índice em segundo plano, para que sua primeira consulta seja instantânea. Re-executar init é seguro — ele nunca duplica entradas.

Atualização

npm install -g @cstart/coldstart@latest
coldstart init   # re-run in each project to refresh coldstart.md

Um carimbo de versão no lockfile do keeper faz o keeper em segundo plano antigo ser encerrado na próxima consulta; um novo é iniciado a partir do novo binário. Nenhum reinício manual é necessário.

[!NOTE] Migrando de coldstart-mcp: o pacote foi renomeado de coldstart-mcp@cstart/coldstart na versão 2.0.0 (a CLI agora é a superfície principal). coldstart-mcp está obsoleto, mas ainda instala; troque com npm uninstall -g coldstart-mcp && npm install -g @cstart/coldstart && coldstart init. O nome do binário coldstart-mcp é mantido como alias, para que configurações MCP existentes continuem funcionando.

Removendo o coldstart

init escreve configurações por repositório que um npm uninstall global não consegue alcançar (o npm não dispara um hook de desinstalação confiável e não tem registro de em quais repositórios você executou init). Então — como o husky — o coldstart inclui um reverso explícito:

coldstart unwire          # strip coldstart's wiring from this repo (notebook kept)
coldstart unwire --purge  # also delete .coldstart/notebook/ and its git plumbing

unwire remove apenas marcadores de propriedade do coldstart dos arquivos que init tocou — entradas de hook, o import @coldstart.md, o bloco AGENTS.md, a entrada do servidor MCP e arquivos que o coldstart possui integralmente (coldstart.md, .cursor/rules/coldstart.mdc) — nunca seu próprio conteúdo em arquivos compartilhados. Ele varre todos os quatro clientes, é idempotente (uma segunda execução informa que tudo já foi removido) e mantém o notebook por padrão, já que são dados commitados e compartilhados. Execute-o em cada projeto primeiro, depois npm uninstall -g @cstart/coldstart para remover o pacote.


O notebook

Uma base de conhecimento local ao repositório, escrita e lida por agentes, em .coldstart/notebook/:

coldstart kb search tile save lifecycle   # plain task words, symbols, or file names
coldstart kb lookup src/models.py Tile    # everything known at one exact address
coldstart kb write spec.json              # the write gate (two-phase dedup)
coldstart kb commit                       # publish notes to git, nothing else rides along
coldstart kb view                         # open a single-file HTML browser of the notebook
coldstart kb repair                       # worklist of notes that are written but unfindable
coldstart kb repair-aliases                # worklist of aliases that may no longer be true
coldstart kb status / lint / render / init / migrate

O que é uma nota. Três formatos: uma nota de arquivo (para que serve um arquivo — um único resumo, ou facetas por símbolo para arquivos hub), uma nota de fluxo (uma história entre arquivos: etapas ordenadas, invariantes) e uma lição (uma armadilha, regra, causa de bug, justificativa ou ausência confirmada). Cada nota carrega âncoras — caminhos de arquivo e símbolos concretos nos quais suas afirmações se apoiam.

Onde as notas chegam ao agente. Três superfícies, sem novos hábitos necessários:

  1. Linhas Summary: nos resultados de find — uma visão geral verificada de um arquivo por um agente anterior, exatamente onde o arquivo aparece no ranking. [fresh] significa que o arquivo está byte-idêntico a quando o resumo foi verificado — o agente pode confiar nele sem reler o arquivo.
  2. Recuperação no momento do prompt (hook opcional) — notas cujos títulos, aliases ou âncoras correspondem ao prompt recebido são exibidas como um bloco compacto de título + resumo + caminho, com limite rígido, apresentado como dados de referência. Nada corresponde → nada é injetado.
  3. kb search / kb lookup — um mecanismo de busca sobre o notebook para mudanças de vocabulário no meio da tarefa, e uma consulta por endereço exato (path [symbol]) antes de editar um arquivo.

Por que ele pode ser confiável. Esta é a parte que exigiu o trabalho de design:

  • A atualidade é mecânica, não esperada. Cada âncora é carimbada com um hash de conteúdo no momento da escrita; o índice re-verifica os carimbos conforme o código muda. Uma nota divergente renderiza [evidence changed: <path>] e a orientação diz para re-verificar — conhecimento desatualizado degrada em uma hipótese rotulada em vez de uma mentira confiante.
  • O log é a verdade. As notas vivem em um log de eventos .raw somente-append (faça commit dele — merges são uniões, então ramos paralelos de notas se reconciliam sem conflitos). As notas Markdown são derivadas, regeneradas mecanicamente e ignoradas pelo git.
  • Escritas passam por um portão. O conceito de uma nova nota é primeiro buscado contra notas existentes — o agente deve explicitamente mesclar em uma correspondência (--into <id>) ou declará-la nova (--new). Duplicatas são bloqueadas no momento da escrita, não limpas depois.
  • Sessões concorrentes são seguras. Múltiplos agentes podem escrever ao mesmo tempo: logs somente-append por nota, criação exclusiva para novos ids de nota (uma duplicata no mesmo momento vira duas notas visíveis, nunca uma mesclagem silenciosa), mesclagem sem perdas para notas de arquivo compartilhadas e renderizações atômicas (um leitor nunca vê uma nota pela metade).
  • Correções acontecem na sessão. Se um agente encontrar uma nota errada enquanto a evidência está em seu contexto, a orientação diz para corrigir ou retratar a nota naquele momento — não existe um agente futuro melhor posicionado.

Configuração: o notebook vem com coldstart init — sem etapa separada. Ele cria o esqueleto do notebook, define union-merge para os logs e (em Claude Code, Codex e Cursor) conecta os dois hooks — captura no fim da sessão, recuperação no momento do prompt. (coldstart kb init ainda existe como alias se você quiser (re)conectar apenas o notebook.) Outros hosts podem usar o notebook sem os hooks: via a CLI completa kb, ou — para clientes sem shell — as ferramentas MCP kb_search / kb_lookup / kb_write / kb_status / kb_repair / kb_repair_aliases.

Agnóstico de linguagem. O mecanismo de atualidade do notebook é baseado em hash de conteúdo, então funciona em qualquer base de código — incluindo linguagens que o índice de navegação não analisa. Onde o índice analisa, as notas também recebem atualidade em nível de símbolo.

[!NOTE] O notebook é jovem. O que está verificado hoje: notas escritas por agentes em sessões reais se mostraram precisas em relação ao código; o ciclo de nota desatualizada se fecha de ponta a ponta (sinalizar → reler → corrigir); captura, recuperação e escritas concorrentes se sustentam sob estresse. A aposta — declarada como aposta — é que um corpus como este se acumula ao longo da vida do repositório: na segunda vez que qualquer pergunta surgir, a resposta está a um Read de distância em vez de uma re-derivação.


Navegação: as duas operações

O que respondeSubstitui
find <terms>"Quais arquivos são sobre isso?" — classifica arquivos por quantos dos seus termos de consulta eles cobrem (nomes de arquivo, segmentos de caminho, símbolos exportados, além de uma passada de referência de nomes em todo o repositório).uma enxurrada de grep/glob durante a orientação
gs <file>"O que é este arquivo?" — símbolos de nível superior com intervalos de linha, quem o importa, quem chama cada símbolo e vizinhos relacionados por nome.ler um arquivo inteiro apenas para aprender sua forma e uso

O fluxo pretendido: find um conceito → escolha o melhor caminho → gs esse arquivo para sua forma e quem o usa → Read apenas para a implementação dentro do corpo de um método. Resumos do notebook acompanham os resultados de find, então muitas vezes a etapa de orientação se responde sozinha.

flowchart LR
    A["coldstart find<br/>which files?"] --> B["coldstart gs<br/>what is it? who uses it?"] --> C["Read<br/>just the method body"]
    class A,B cold
    class C warm
    classDef cold stroke:#16708f,stroke-width:2px
    classDef warm stroke:#c26714,stroke-width:2px

find — localize os arquivos para um conceito

coldstart find auth session cookie

[!TIP] Passe cada identificador saliente da sua tarefa — o símbolo, o substantivo do domínio, o token raro que você lembra pela metade — não uma única palavra-chave destilada. find classifica arquivos por quantos dos seus termos cada um cobre e mostra, por arquivo, quais termos ele define vs. importa e uma prévia das linhas onde eles se agrupam. Muitas vezes isso é suficiente para responder sem abrir nada.

Em termos de velocidade, find compete com grep puro: sua passada de referência em todo o repositório roda em ripgrep — o seu do PATH, a cópia incluída ou a de um editor (COLDSTART_RG substitui) — com fallbacks git grep/grep, e a página classificada vem do índice pré-construído, não de uma varredura. Flags: --path GLOB (escopo; combine com vírgula, ! exclui) · --tests (inclui arquivos de teste) · --via (mostra relações de referência por nome) · --json

gs — aprofunde-se em um arquivo

coldstart gs src/auth/service.ts

Retorna os símbolos do arquivo (com intervalos de linha), seus imports internos de 1 salto, quem o importa e os chamadores entre arquivos por símbolo — em uma única chamada. Esta é a resposta para "quem usa este arquivo / quem chama este símbolo"; não é um grep.

Flags: --symbol a,b (entrega corpos de métodos nomeados inline) · --match TERM (filtra um god-file para uma área; a|b = OR, /regex/ = regex) · --view symbols|imports|importers|callers · --json

Consultas independentes em lote em uma única chamada de shell

coldstart find auth; coldstart find 'session cookie'; coldstart gs src/auth/service.ts

Duas maneiras de chamar, saída idêntica

coldstart é distribuído como um único binário com duas portas de entrada:

  • CLI (principal)coldstart find … / coldstart gs … / coldstart kb …. Para qualquer agente com suporte a shell (Claude Code, Cursor, uso em terminal). Este é o caminho rápido.
  • MCP (para clientes sem shell) — as ferramentas find e gs, além do notebook como kb_search / kb_lookup / kb_write / kb_status / kb_repair / kb_repair_aliases, todas byte-idênticas à CLI. Para clientes como Claude Desktop que não têm shell. (kb commit permanece apenas CLI/humano — publicar notas no git nunca é uma ação de agente.)

Mesmo motor, mesmo índice, mesmos resultados. Escolha o que seu agente conseguir acessar.

Funciona melhor com Claude Code, Codex e Cursor: os três recebem hooks específicos de plataforma para find/gs e hooks de captura/recuperação do notebook via coldstart init. Qualquer outro cliente recebe coldstart.md além de instruções impressas de conexão.


Traga sua própria semântica

coldstart não tem embeddings, nem resumos gerados, nem camada semântica calculada no momento da indexação — de propósito. A camada semântica é o agente. Todo consumidor já é um modelo de fronteira; pré-computar significado no momento da indexação apenas duplica isso, de forma pior e desatualizada. Então o índice mantém o que é barato manter exato — caminhos, símbolos, exports, o grafo de import/call — e retorna por que cada arquivo foi ranqueado.

O notebook é a mesma filosofia aplicada à memória: coldstart ainda não calcula significado próprio. Ele armazena, ancora e verifica a frescor do significado que agentes escrevem — escrito no momento da tarefa, pelo raciocinador que tinha o contexto completo, sobre a pergunta que realmente importava. O argumento completo está em PHILOSOPHY.md.


Como o índice se mantém atualizado

coldstart é um keeper, leitores finos:

flowchart TD
    K["keeper — coldstart --daemon<br/>watches repo, patches/rebuilds, saves cache<br/>serves nothing"] -->|debounced save| C[("on-disk cache")]
    C --> F["coldstart find<br/>reads cache, prints"]
    C --> G["coldstart gs<br/>reads cache, prints"]
    C --> M["MCP server<br/>reads cache, stdio"]
    class K cold
    classDef cold stroke:#16708f,stroke-width:2px
  • Um único processo keeper por repositório observa o sistema de arquivos e mantém o cache em disco atualizado. Ele não responde consultas.
  • Os leitores CLI (find/gs) e o servidor MCP são leitores sem estado sobre esse cache. O primeiro leitor de um repositório inicia o keeper de forma lazy, então até edições não commitadas permanecem ativas.
  • Leitores nunca constroem o índice. Em cache miss, eles aguardam a construção do keeper (progresso no stderr) em vez de iniciar silenciosamente uma construção de vários minutos inline — ou três delas concorrentemente.
  • Sem HTTP, sem portas, sem ponte. O keeper registra logs em ~/.coldstart/daemon/<root>.log e sai quando seu arquivo de lock é removido.

Não há TTL de cache. O índice nunca é descartado por ser antigo — ele é mantido correto em vez disso:

  • Enquanto o keeper está em execução: edições são debounced (400 ms), depois aplicadas incrementalmente (~2–5 ms/arquivo, até 30 arquivos ou 20% do repositório, o que for maior) ou disparam uma reconstrução completa em segundo plano acima disso (servida do último índice bom até a troca). O cache é re-salvo ~5 s após as edições estabilizarem, em gerações atômicas — um leitor nunca pode carregar uma mistura parcialmente escrita de antigo e novo.
  • Quando o keeper inicia: ele faz reconciliação — verifica stat de cada arquivo indexado contra sua impressão digital armazenada (~150 ms mesmo com 16k arquivos) além de um git diff contra o HEAD indexado — e aplica exatamente o que mudou enquanto nada estava observando. Uma troca de branch que costumava forçar uma reconstrução de 96 segundos em um repositório de 16k arquivos agora é um patch de ~3 segundos.
  • Como rede de segurança: cada patch é verificado por lint contra invariantes do índice (uma violação dispara uma reconstrução automática e cai em um log de reparo que status mostra), e uma auditoria rotativa de impressões digitais após cada salvamento captura eventos perdidos pelo watcher.

O keeper também carimba a frescor das âncoras do notebook (um sidecar pequeno, derivado single-flight) — o notebook nunca carrega o índice de código para responder uma consulta.

Comandos de ciclo de vida

coldstart status              # keepers on this machine: alive? fresh? last patch/rebuild/save? repairs?
coldstart restart             # kill the current repo's keeper (respawns on next lookup)
coldstart restart --root DIR  # kill a specific repo's keeper from anywhere
coldstart restart --all       # kill every keeper
coldstart index               # build + save the cache once, up front (single-writer prep)

restart é a ação certa sempre que algo parecer desatualizado — um keeper novo reconcilia no início, então ele volta correto, não apenas vivo. status responde "meu índice está atualizado, e por quê?": liveness, idade do cache, carimbos do último reconcile/patch/rebuild/save do keeper e o final do log de reparo — sem sonda de rede.


Linguagens suportadas

Índice de navegação: TypeScript, JavaScript, JSX/TSX, Vue, Svelte, Astro, AngularJS 1.x, Java, Kotlin, Ruby (ciente de Rails: associações has_many/belongs_to, recursos routes.rb, arestas controller↔view), Python (arestas de convenção Django), Go, Rust, C#, PHP (arestas de convenção Laravel), C++, Groovy (incl. DSL do Gradle), GraphQL, YAML, TOML, XML e arquivos .env.

Não indexados: Swift, Dart — sem mapeamento de extensão; esses arquivos não são percorridos nem analisados.

O notebook funciona independentemente — seus carimbos de frescor são baseados em hash de conteúdo, então notas em um repositório Swift são tão confiáveis quanto notas em um TypeScript (apenas sem detalhe de frescor no nível de símbolo).


Quando não usar

  • Uma string literal / frase / regex dentro de corpos de arquivo → Grep.
  • Ler uma implementação → Read, depois que gs te der a forma.
  • find diz "nenhum arquivo indexado contém qualquer um de […]" → esses identificadores não estão no repositório. Não faça grep de variações de grafia.

Desenvolvimento

npm install
npm run build
npm test

# run a query from your build:
node dist/index.js find auth --root .

# run the MCP server in a single process (no background keeper) for debugging:
node dist/index.js --root . --no-daemon

Veja PHILOSOPHY.md para entender por que coldstart não calcula semântica própria, ARCHITECTURE.md para o pipeline do índice, modelo de processos e internals do notebook, e TROUBLESHOOTING.md para procedimentos de recuperação.


Limitações

  1. É uma camada de roteamento mais um notebook escrito por agentes — sem análise semântica ou resumos de código gerados. Isso é deliberado: o agente consumidor é a camada semântica (veja PHILOSOPHY.md).
  2. Chamadas gs são de um salto e com escopo de arquivo. Chamadas de expressão de membro (this.method(), api.method()) não são resolvidas entre arquivos; chamadas de função/constante nomeada são. Persiga mais saltos chamando gs nos arquivos dos chamadores.
  3. Imports dinâmicos/computados (import(variable)) e referências de DSL em runtime (associações polimórficas, modelos baseados em gem/reflexão) permanecem não resolvidos.
  4. Diretórios ocultos e arquivos acima de 1 MB são ignorados pelo índice.
  5. O keeper é por repositório e por máquina — sem compartilhamento entre projetos ou hosts. O notebook viaja: seus logs .raw são commitados e fazem merge por união entre branches e máquinas.
  6. A qualidade do notebook é limitada pelo que os agentes escritores realmente leem — notas são precisas sobre o que afirmam, mas uma nota não é prova de completude.

Escrita

Peças mais longas sobre os problemas por trás desta ferramenta — o que sessões de agente realmente custam, e o que aconteceu com o design quando as medições discordaram do plano.

Licença

MIT — veja LICENSE.


coldstart MCP server