1 pontos por GN⁺ 4 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • 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, plan e review, 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 code
    zerostack  
    
  • No modo de execução única, passe o prompt com -p
    zerostack -p "Explain this project"  
    
  • A última sessão pode ser retomada com -c
    zerostack -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 TDD
    • plan é um modo exclusivo de planejamento, que explora o contexto e cria um plano sem escrever código
    • review é o modo de revisão de código que analisa exatidão, design, testes e impacto
    • debug é o modo de depuração que busca a causa raiz antes de propor correções
    • ask é um modo somente leitura, permitindo apenas read, grep e glob, sem escrita nem Bash
    • brainstorm é um modo exclusivo de design para explorar ideias e propor arquiteturas sem escrever código
    • frontend-design é um modo de design frontend para UIs diferenciadas e em nível de produção
    • review-security é um modo de revisão de segurança para encontrar vulnerabilidades exploráveis
    • simplify é um modo de simplificação de código para aumentar a clareza sem mudar o comportamento
    • write-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.md ou CLAUDE.md na raiz do projeto ou em diretórios superiores são lidos automaticamente e inseridos no prompt do sistema; isso pode ser desativado com -n ou --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

    • restrictive ou -R solicita aprovação para toda ação de ferramenta que não esteja explicitamente permitida na configuração
    • standard é o padrão e aprova automaticamente comandos seguros como ls, cd, git log e cargo check, pedindo confirmação para gravações e operações destrutivas
    • accept-all ou --accept-all aprova automaticamente todas as operações dentro do diretório de trabalho e pede confirmação para caminhos externos
    • yolo ou --yolo aprova 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 **.rs pode 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
  • /model troca o modelo, e /thinking define o nível de raciocínio
  • /clear limpa a conversa, e /session lista, salva e carrega sessões
  • /loop agenda um prompt iterativo, e /prompt lista ou altera o prompt do agente
  • /mode define 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/
  • -c retoma a sessão mais recente, -r permite 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 system inicia o loop com o prompt especificado
    • /loop stop interrompe o loop ativo
    • /loop status mostra o estado atual do loop
    • Cada iteração inclui a tarefa original, o LOOP_PLAN.md em 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"  
      
    • --loop ativa 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

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-exit retorna ao repositório principal sem fazer merge
  • Fluxo de trabalho de exemplo

    • /worktree feature-x cria 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-merge faz o agente executar merge da branch, push, limpeza e retorno ao repositório principal
    • /wt-exit retorna 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.json com qualquer base URL e variável de ambiente para chave de API
  • A licença é GPL-3.0-only

1 comentários

 
GN⁺ 4 시간 전
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 via bash
    Claro, se tiver acesso a edit e cargo run, ainda dá para executar código arbitrário, mas quando surge algo que um agente sem bash precisa fazer, prefiro criar ferramentas conforme a necessidade

    • Pensei nesse problema, mas o Pi é baseado em TypeScript, então pode ter um ambiente parecido com script, enquanto Rust é uma linguagem compilada, o que impõe limitações
      Entã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 Claude
      Recursos 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 executar zerostack -R para forçar todas as ferramentas a pedir permissão
      Também estou trabalhando em recursos de agente programável, mas ainda não é hora de anunciar
    • Eu também estou fazendo a mesma coisa em Zig
  • 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

    • 200 linhas, ou melhor, só 190 linhas, é realmente impressionante
      Eu também fiz um por diversão e aprendizado na semana passada, e ele até funciona com integração com mcpServers configurados, como a maioria dos agentes de código
      Organizei 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

    • Estou criando um framework de agentes em Go e ele é extremamente leve
      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
    • Estou pensando em migrar para o Zed, e o Agent Client Protocol parece bem interessante. Fico curioso para saber o quanto a pressão de memória cairia se o Claude Code passasse por esse caminho
      1: https://zed.dev/acp
    • Sim. Só esse fato já deve fazer muita gente pelo menos testar uma vez
    • O uso de memória é excelente, então agora dá para rodar agentes de código até em instâncias minúsculas, como a x1 da shellbox.dev
    • Talvez valha conferir se não tem algo como plugin de LSP rodando junto
  • 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 problema
    Quando 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 bash com outro prompt, talvez chegasse perto disso, mas parece um pouco menos fluido, então vou ter que testar por conta própria

    • Na maior parte, funciona como skills, mas é melhor pensar nisso como um ambiente do que como um “comando”
      Por 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 code
      Quanto 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?

    • Além de ser leve, recursos interessantes que coloquei foram a biblioteca de prompts, integração com Git worktree e integração com o loop Ralph Wiggum
    • Fiquei curioso se isso está público no GitHub
  • 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_tokens foi trocado por max_completion_tokens
    Também não parece haver uma forma de passar headers customizados, então não consegui definir reasoning_effort para modelos da DeepSeek

    • Aceito PRs, sim
      O 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

    • O datacenter roda com linha elétrica dedicada, mas meu notebook roda com bateria
      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
    • Claro que as pessoas focam no software que roda no próprio computador
      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
    • Isso simplifica demais a questão
      É 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

    • Como o OP disse que uma parte considerável do código foi gerada pelo DeepSeek V4 Flash, fui verificar se havia dependências desatualizadas
      Em projetos Rust, se você não instruir o modelo a usar cargo add em vez de editar Cargo.toml diretamente, na minha experiência até o Claude 4.7 Opus quase sempre adiciona dependências antigas
      Verifiquei 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] do strum. Em vez de adicionar um crate sem dependências, provider.rs poderia ficar bem mais conciso
      Por 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 forte
      Imagino que isso tenha sido para evitar linkar libunwind e 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 panic
      Alé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
    • Uma parte bem grande do código foi escrita pelo DeepSeek v4 Flash, e eu mesmo escrevi parte da lógica da TUI
      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
    • Esse método de “passar para o DeepSeek v4 Flash dentro do Pi para ver se há algo perigoso” não é uma investigação bem frágil por causa de prompt injection?
  • É 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

    • Exato. Este projeto começou depois que, num notebook antigo, eu deixei o Firefox e mais de 2 instâncias do opencode abertos ao mesmo tempo e o OOM killer entrou em ação