- zerostack é um agente de programação minimalista escrito em Rust, com suporte a vários provedores de LLM e também provedores personalizados
- Oferece leitura, escrita e edição de arquivos, grep, busca de arquivos, listagem de diretórios, execução de Bash com controle de permissões, MCP e ferramentas web da Exa
- Tem cerca de 7 mil LoC, binário de 8,9 MB, uso de RAM de cerca de 8 MB em sessão vazia e 12 MB em uso, com CPU em 0,0% quando ocioso
- O provedor padrão é o OpenRouter, a instalação é feita com
cargo install zerostack, e para usar isolamento de Bash com--sandboxé necessário o bubblewrap - Inclui prompts embutidos como
code,planereview, 4 modos de permissão, retomada de sessão, loop iterativo e integração com Git worktrees
Visão geral do zerostack
- zerostack é um agente de programação minimalista escrito em Rust, inspirado em pi e opencode
- Tem uma arquitetura multifornecedor compatível com OpenRouter, OpenAI, Anthropic, Gemini, Ollama e provedores personalizados
- Oferece ferramentas de arquivo como leitura, escrita e edição de arquivos, grep, busca de arquivos e listagem de diretórios, além de execução de Bash com controle de permissões
- Inclui salvar, carregar e retomar sessões, compressão automática para manter a janela de contexto, interface de terminal baseada em crossterm, conexão com servidores MCP e ferramentas WebFetch e WebSearch baseadas em Exa
- É possível alternar entre Git worktrees com
/worktree, e também há um loop iterativo integrado para tarefas de longa duração
Desempenho e instalação
- O zerostack tem cerca de 7 mil LoC, e o tamanho do binário é de 8,9 MB
- O uso de RAM é de cerca de 8 MB em uma sessão vazia e cerca de 12 MB em uso, comparado a cerca de 300 MB do opencode e de outros agentes de programação baseados em JS
- O uso de CPU foi medido em 0,0% em modo ocioso e cerca de 1,5% durante o uso de ferramentas; em um Intel i5 de 7ª geração, o opencode foi comparado com cerca de 2% em modo ocioso e 20% em atividade
- A instalação requer Cargo e git, usando o seguinte comando
cargo install zerostack - Ao usar
--sandbox, é necessário instalar o bubblewrap para executar todos os comandos Bash em um ambiente isolado# Debian/Ubuntu apt install bubblewrap # Fedora dnf install bubblewrap # Arch pacman -S bubblewrap
Início rápido
- O provedor padrão é o OpenRouter, e a chave de API é configurada por variável de ambiente
export OPENROUTER_API_KEY="[api_key]" - A sessão interativa é executada com o prompt padrão
codezerostack - No modo de execução única, passe o prompt com
-pzerostack -p "Explain this project" - A última sessão pode ser retomada com
-czerostack -c - Também é possível especificar o provedor e o modelo
zerostack --provider openrouter --model deepseek/deepseek-v4-flash
Sistema de prompts
- O zerostack inclui um conjunto de prompts de sistema embutidos que alteram o comportamento e o tom do agente
- O objetivo é criar uma família de prompts que possa substituir o superpower ou as skills oficiais do Claude
- Com
/prompt, é possível listar os prompts registrados ou alternar para outro prompt -
Prompts embutidos
codeé o padrão e corresponde ao modo de programação com acesso completo a arquivos e ferramentas Bash, usando um fluxo de trabalho TDDplané um modo exclusivo de planejamento, que explora o contexto e cria um plano sem escrever códigoreviewé o modo de revisão de código que analisa exatidão, design, testes e impactodebugé o modo de depuração que busca a causa raiz antes de propor correçõesaské um modo somente leitura, permitindo apenasread,grepeglob, sem escrita nem Bashbrainstormé um modo exclusivo de design para explorar ideias e propor arquiteturas sem escrever códigofrontend-designé um modo de design frontend para UIs diferenciadas e em nível de produçãoreview-securityé um modo de revisão de segurança para encontrar vulnerabilidades exploráveissimplifyé um modo de simplificação de código para aumentar a clareza sem mudar o comportamentowrite-prompté um modo de escrita de prompts para criar e otimizar prompts de agente- Prompts personalizados podem ser criados colocando arquivos Markdown em
$XDG_CONFIG_HOME/zerostack/prompts/e referenciando-os pelo nome AGENTS.mdouCLAUDE.mdna raiz do projeto ou em diretórios superiores são lidos automaticamente e inseridos no prompt do sistema; isso pode ser desativado com-nou--no-context-files
Sistema de permissões
- O zerostack oferece 4 modos de permissão, do mais seguro ao mais permissivo
-
Modos de permissão
restrictiveou-Rsolicita aprovação para toda ação de ferramenta que não esteja explicitamente permitida na configuraçãostandardé o padrão e aprova automaticamente comandos seguros comols,cd,git logecargo check, pedindo confirmação para gravações e operações destrutivasaccept-allou--accept-allaprova automaticamente todas as operações dentro do diretório de trabalho e pede confirmação para caminhos externosyoloou--yoloaprova automaticamente todas as operações sem pedir confirmação- É possível configurar permissões de forma granular com padrões glob por ferramenta no arquivo de configuração
- Por exemplo,
write **.rspode ser permitido automaticamente enquanto a escrita em outros arquivos sempre exige confirmação - A allowlist da sessão mantém as decisões aprovadas durante a sessão, evitando confirmar repetidamente a mesma ação
- Se a mesma chamada de ferramenta se repetir 3 vezes ou mais, a detecção de doom loop exibe um prompt de alerta ou bloqueia a ação conforme a configuração, impedindo que o agente repita operações destrutivas
Comandos de barra e gerenciamento de sessão
- Os principais comandos de barra controlam modelo, nível de raciocínio, conversa, sessão, loop, prompts e modo de permissões
/modeltroca o modelo, e/thinkingdefine o nível de raciocínio/clearlimpa a conversa, e/sessionlista, salva e carrega sessões/loopagenda um prompt iterativo, e/promptlista ou altera o prompt do agente/modedefine o modo do sistema de permissões, e os comandos completos podem ser consultados com/help- As sessões são salvas em
$XDG_DATA_HOME/zerostack/sessions/ -cretoma a sessão mais recente,-rpermite navegar e escolher uma sessão, e--session <id>carrega uma sessão específica
Loop iterativo
- O zerostack inclui um loop iterativo de programação para tarefas longas
- O agente relê a tarefa repetidamente, escolhe itens do plano, executa o trabalho, roda testes, atualiza o plano e continua o loop até concluir a tarefa ou atingir o limite de iterações
- O sistema de loop é um recurso experimental
-
Como usar o loop
/loop Implement the user authentication systeminicia o loop com o prompt especificado/loop stopinterrompe o loop ativo/loop statusmostra o estado atual do loop- Cada iteração inclui a tarefa original, o
LOOP_PLAN.mdem evolução, o resumo da iteração anterior e a saída de validação - Enquanto o loop estiver ativo, entradas que não sejam comandos de barra serão bloqueadas
-
Loop headless via CLI
- É possível executar um loop headless com o seguinte comando
zerostack --loop --loop-prompt "Refactor the API" --loop-max 10 --loop-run "cargo test" --loopativa o modo de loop headless--loop-prompt <text>define o prompt usado em cada iteração--loop-plan <path>define o caminho de um arquivo de plano personalizado; o padrão éLOOP_PLAN.md--loop-max <N>define o número máximo de iterações; o padrão é sem limite--loop-run <cmd>define o comando de validação executado após cada iteração
- É possível executar um loop headless com o seguinte comando
Integração com Git worktrees
- O zerostack oferece um fluxo de trabalho por branch com git worktrees
- É possível criar um worktree, trabalhar nele, fazer merge e sair, tudo de dentro da interface de chat
- A integração com Git worktrees é um recurso experimental
-
Comandos de worktree
/worktree <name>cria um git worktree para a branch<name>e muda para ela; se já existir, a criação é ignorada/wt-merge [branch]faz merge da branch do worktree em[branch], faz push, limpa o ambiente e retorna ao repositório principal/wt-exitretorna ao repositório principal sem fazer merge
-
Fluxo de trabalho de exemplo
/worktree feature-xcria uma nova branch e diretório de worktree e muda para eles- Depois disso, basta usar o zerostack normalmente, e as alterações permanecerão na branch da feature
/wt-mergefaz o agente executar merge da branch, push, limpeza e retorno ao repositório principal/wt-exitretorna imediatamente ao repositório principal sem fazer merge
Provedores compatíveis e licença
- O provedor padrão é o OpenRouter
- São compatíveis provedores OpenAI-compatíveis como vLLM e LiteLLM
- Há suporte a Anthropic, Gemini e Ollama
- Provedores personalizados podem ser configurados em
$XDG_CONFIG_HOME/zerostack/config.jsoncom qualquer base URL e variável de ambiente para chave de API - A licença é GPL-3.0-only
1 comentários
Opiniões no Hacker News
Não conheço muito bem esse tipo de ferramenta, então fiquei curioso sobre quais seriam as vantagens em relação a modelos/ferramentas como o Claude Code
Eu estava fazendo algo parecido por conta própria no meu tempo livre, com o objetivo de entender agentes mais a fundo e também aprender Rust
Ainda assim, eu gostaria de manter a configurabilidade do
pi. A capacidade de se modificar sozinho e criar novas ferramentas é muito útil, e acho que esse tipo de ferramenta não deveria ter permissão de executar código arbitrário viabashClaro, se tiver acesso a
editecargo run, ainda dá para executar código arbitrário, mas quando surge algo que um agente sembashprecisa fazer, prefiro criar ferramentas conforme a necessidadeEntão decidi permitir personalização de outra forma. A biblioteca de prompts em
~/.config/hypernova/prompts/é uma alternativa simples às Skills, e os prompts embutidos devem substituir as superpowers e o frontend-design do ClaudeRecursos que podem deixar o agente pesado podem ser desligados com feature flags na compilação, e o código é curto e fácil de ler, então, se precisar, dá para rodar o zerostack no próprio código-fonte do zerostack e criar um fork customizado
Quanto ao modelo de permissões, depois de pensar bastante, fiz 4 níveis, como aparece no README: desde o “Restrictive”, sem comandos, até o “YOLO”, em que o agente faz o que quiser. Também é possível definir regex de permitir/perguntar/negar para chamadas de
bash. Nesse caso, basta executarzerostack -Rpara forçar todas as ferramentas a pedir permissãoTambém estou trabalhando em recursos de agente programável, mas ainda não é hora de anunciar
Recentemente fiz um de brincadeira, meio a sério, com menos de 200 linhas: https://github.com/pnegahdar/nano
Tem REPL, sessões, execução não interativa, aprovações e afins. À medida que os modelos ficam mais inteligentes, acho que a importância do harness vai diminuindo, exceto pela experiência de desenvolvimento
Talvez eu rode no SWE-bench algum dia
Eu também fiz um por diversão e aprendizado na semana passada, e ele até funciona com integração com
mcpServersconfigurados, como a maioria dos agentes de códigoOrganizei passo a passo o que é necessário e por quê: https://nb1t.sh/building-a-real-agent-step-by-step/
“RAM footprint: ~8MB on an empty session, ~12MB when working”
Gostei dessa parte. O Claude Code usa vários GB, então em notebook fraco isso é bem irritante
O tempo de inicialização é menor que 0,5 segundo e o uso de RAM também é muito baixo. Roda bem sem ficar lento até em notebook de 12 anos
Algo que essencialmente é próximo de um motor de concatenação de strings não deveria ficar lento em nenhum equipamento, inclusive hardware antigo
1: https://zed.dev/acp
Vou testar quando chegar em casa. Ferramentas leves e rápidas fazem uma grande diferença na experiência de programar
Fiquei curioso sobre como essa abordagem de prompts se compara na prática com a combinação mais comum de skills e subagentes. Eu costumo misturar bastante os dois: se houver falha de build, executo uma skill
/fix-ci, e um subagente extrai mensagens de erro, stack traces e logs relevantes para resolver o problemaQuando aparece problema de query de banco em teste de integração, o agente às vezes chama por conta própria, ou com um pequeno direcionamento meu, uma skill de acesso somente leitura ao banco para investigar. Quando precisa cavar fundo por bastante tempo, digo algo como “use um subagente Sonnet e peça para ele depurar esse comportamento com a skill de query de banco”
As skills dão capacidades extras na hora, e os subagentes isolam contexto para evitar inchaço. Se o agente executasse a si mesmo via
bashcom outro prompt, talvez chegasse perto disso, mas parece um pouco menos fluido, então vou ter que testar por conta própriaPor exemplo, um dos prompts integrados,
/prompt debug, abre um agente focado em depuração, e dali você pode conversar como faria com um agente normal e depois voltar ao agente padrão de programação com/prompt codeQuanto a subagentes, como atualmente todo o agente roda em um único buffer de contexto, ainda não ofereço isso para manter tudo leve. Mas tarefas com muita exploração costumam inflar bastante a janela de contexto, então é bem possível que subagentes sejam adicionados
Eu também pedi ao Claude Code para fazer algo assim, e na parte de edição coloquei também o hashing de linhas do Dirac
Usei Rust e também pensei em implementar hooks como plugins para permitir automodificação, mas no fim organizei tudo para que ele criasse um arquivo separado com informações detalhadas sobre as melhorias, atualizasse o código-fonte e depois recompilasse
Como a localização do código-fonte é fixa, o agente consegue reescrever a si mesmo e fazer o build. Estou usando com DeepSeek 4 Flash em 2x RTX 6000 Pro, e sai algo em torno de 138 tok/s
Sinceramente, eu basicamente copiei Pi, Dirac e OpenCode. Tem alguma técnica nova aqui que valha a pena roubar?
Testei rapidamente e realmente pareceu bem rápido
Fiquei curioso se você está procurando contribuidores ou se está fazendo isso como uma ferramenta pessoal
Mas encontrei alguns problemas ao tentar usar outros modelos. No Azure, o gpt-5.5 não funciona porque, mesmo usando um endpoint compatível com OpenAI,
max_tokensfoi trocado pormax_completion_tokensTambém não parece haver uma forma de passar headers customizados, então não consegui definir
reasoning_effortpara modelos da DeepSeekO que você mencionou é claramente bug no codebase, então, se puder, seria ótimo abrir issues no GitHub para cada bug separadamente
Claude Code e Opencode funcionam bem no meu ambiente
É meio engraçado que agentes de código rodem em datacenters consumindo mais de 1000W de energia e mais de 2TB de memória, enquanto as pessoas ficam focadas nos últimos poucos watts e algumas centenas de MB de memória do notebook
Isso provavelmente fica diluído perto do custo energético de compilar código de qualquer forma, mas ainda assim não faz mal deixá-los mais rápidos e leves
Hoje, quando uso agentes de código, a bateria acaba bem rápido, o que é surpreendente considerando que a maior parte do trabalho nem acontece no meu notebook
Tornar agentes de código no lado cliente mais eficientes não é sobre salvar o clima, e sim sobre estender meu horário de trabalho. Na prática, isso pode até ser pior para o clima
Software rodando no computador dos outros não é problema meu. Eu não tenho controle sobre o que roda no servidor alheio, e mesmo que tivesse, não sou eu que pago o custo daquela RAM, então não ligo
Já a RAM do meu equipamento sou eu que pago. Se uma TUI que exibe menos de 1KB de texto ocupa vários GB de memória, mata outros apps por OOM no Windows ou faz o Linux começar a swapar no HDD e travar a máquina inteira, eu vou me importar
Numa situação em que o preço da RAM subiu de fato 5x, e o de outros componentes 2x ou 3x, evitar desperdício de memória é especialmente importante
É verdade que o modelo é enorme e consome muitos recursos, mas o harness pode influenciar bastante o quanto o modelo é usado
Por exemplo, se o harness tiver um conjunto de ferramentas forte, o modelo pode trabalhar com muito mais eficiência
O codebase é pequeno, então passei para o DeepSeek v4 Flash dentro do Pi para ele dar uma olhada e ver se tinha algo perigoso, e ele não encontrou nada que me preocupasse. Ficou bem feito
Em projetos Rust, se você não instruir o modelo a usar
cargo addem vez de editarCargo.tomldiretamente, na minha experiência até o Claude 4.7 Opus quase sempre adiciona dependências antigasVerifiquei manualmente as dependências deste projeto e gostei de ver que todas estão nas versões mais recentes. Claro, isso não quer dizer que não haja problemas escondidos nas dependências transitivas
Fazer revisão de código com LLM pode virar disputa de gosto bem rápido. Por exemplo, olhando o código, achei que alguns métodos de ida e volta entre string e enum poderiam talvez ser resolvidos com um único
#[derive]dostrum. Em vez de adicionar um crate sem dependências,provider.rspoderia ficar bem mais concisoPor diversão, pedi ao DeepSeek V4 Pro com Max thinking para “auditar” o codebase, e ele disse que não viu nenhum sinal claro de telemetria oculta. Mas apontou que o projeto configura o panic handler como
abort, e nisso eu tenho opinião forteImagino que isso tenha sido para evitar linkar
libunwinde economizar alguns KB no binário, mas isso também significa que, em caso de falha, o binário aborta imediatamente sem dar stack trace ao usuário. Eu prefiro um binário uns 50KiB maior se isso permitir obter informações úteis de depuração em caso de panicAlém disso, se ocorrer panic em tarefa assíncrona, não é possível se recuperar e mostrar uma mensagem de erro normal; o processo inteiro é encerrado imediatamente
Isso porque o DeepSeek continuava falhando em certa lógica específica de movimentação de cursor. Todo o trabalho de otimização de memória foi feito por mim, e, como escrevi em outro comentário, combinei otimizações do compilador com o uso de crates Rust para aproveitar estruturas de dados mais eficientes
É engraçado isso ter saído justamente hoje. Eu estava exatamente começando a escrever um em Rust
É impressionante ver o opencode em projetos grandes lentamente vazando memória, subindo até 6GB e ficando cada vez mais lento
Vou dar uma olhada. Parece ótimo