1 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • zerostack est un agent de codage minimaliste écrit en Rust, qui prend en charge plusieurs fournisseurs de LLM ainsi que des fournisseurs personnalisés
  • Il fournit la lecture, l’écriture et l’édition de fichiers, grep, la recherche de fichiers, le listing de répertoires, l’exécution de Bash avec contrôle d’autorisation, MCP et les outils web Exa
  • Il compte environ 7 kLoC, produit un binaire de 8,9 Mo, et consomme environ 8 Mo de RAM à vide, 12 Mo en cours de travail, avec 0,0 % de CPU au repos
  • Le fournisseur par défaut est OpenRouter ; l’installation se fait avec cargo install zerostack, et bubblewrap est nécessaire pour isoler Bash avec --sandbox
  • Il inclut des prompts intégrés comme code, plan et review, 4 modes d’autorisation, la reprise de session, des boucles itératives et l’intégration des Git worktrees

Vue d’ensemble de zerostack

  • zerostack est un agent de codage minimaliste écrit en Rust, inspiré de pi et opencode
  • Il adopte une architecture multi-fournisseurs prenant en charge OpenRouter, OpenAI, Anthropic, Gemini, Ollama et des fournisseurs personnalisés
  • Il fournit des outils de fichiers comme la lecture, l’écriture et l’édition de fichiers, grep, la recherche de fichiers, le listing de répertoires, ainsi que l’exécution de Bash avec contrôle d’autorisation
  • Il inclut la sauvegarde, le chargement et la reprise de session, la compression automatique pour préserver la fenêtre de contexte, une interface terminal basée sur crossterm, la connexion à des serveurs MCP, et les outils WebFetch et WebSearch basés sur Exa
  • Il permet de naviguer entre des Git worktrees avec /worktree et intègre aussi des boucles itératives pour les tâches de longue durée

Performances et installation

  • zerostack représente environ 7 kLoC et la taille du binaire est de 8,9 Mo
  • L’utilisation mémoire est d’environ 8 Mo pour une session vide et 12 Mo en cours de travail, contre environ 300 Mo pour opencode ou d’autres agents de codage basés sur JS
  • L’utilisation CPU a été mesurée à 0,0 % au repos et environ 1,5 % pendant l’utilisation des outils ; sur un Intel i5 de 7e génération, opencode est comparé à environ 2 % au repos et 20 % en charge
  • L’installation nécessite Cargo et git, avec la commande suivante
    cargo install zerostack  
    
  • Lors de l’utilisation de --sandbox, il faut installer bubblewrap pour exécuter toutes les commandes Bash dans un environnement isolé
    # Debian/Ubuntu  
    apt install bubblewrap  
    
    # Fedora  
    dnf install bubblewrap  
    
    # Arch  
    pacman -S bubblewrap  
    

Démarrage rapide

  • Le fournisseur par défaut est OpenRouter, et la clé API se définit via une variable d’environnement
    export OPENROUTER_API_KEY="[api_key]"  
    
  • La session interactive s’exécute avec le prompt par défaut code
    zerostack  
    
  • Le mode d’exécution ponctuelle transmet un prompt avec -p
    zerostack -p "Explain this project"  
    
  • La dernière session peut être reprise avec -c
    zerostack -c  
    
  • Il est possible de préciser le fournisseur et le modèle
    zerostack --provider openrouter --model deepseek/deepseek-v4-flash  
    

Système de prompts

  • zerostack inclut un ensemble de prompts système intégrés qui modifient le comportement et le ton de l’agent
  • L’objectif est de créer une famille de prompts pouvant remplacer superpower ou les skills officiels de Claude
  • /prompt permet de lister les prompts enregistrés ou de basculer vers un autre prompt
  • Prompts intégrés

    • code est la valeur par défaut ; c’est un mode de codage utilisant l’accès complet aux fichiers et à Bash ainsi qu’un workflow TDD
    • plan est un mode dédié à la planification, qui explore avant de produire un plan sans écrire de code
    • review est un mode de revue de code examinant l’exactitude, la conception, les tests et l’impact
    • debug est un mode de débogage qui cherche la cause racine avant de proposer une correction
    • ask est un mode en lecture seule qui n’autorise que read, grep et glob, sans écriture ni Bash
    • brainstorm est un mode dédié à la conception qui explore des idées et propose une architecture sans écrire de code
    • frontend-design est un mode de design frontend pour des interfaces uniques et prêtes pour la production
    • review-security est un mode de revue sécurité qui recherche des vulnérabilités exploitables
    • simplify est un mode de simplification du code qui améliore la clarté sans changer le comportement
    • write-prompt est un mode de rédaction de prompts pour créer et optimiser des prompts d’agent
    • Des prompts personnalisés peuvent être créés en plaçant des fichiers Markdown dans $XDG_CONFIG_HOME/zerostack/prompts/ et en les référant par leur nom
    • Les fichiers AGENTS.md ou CLAUDE.md à la racine du projet ou dans un répertoire parent sont lus automatiquement et injectés dans le prompt système ; cela peut être désactivé avec -n ou --no-context-files

Système d’autorisations

  • zerostack propose 4 modes d’autorisation, du plus sûr au plus permissif
  • Modes d’autorisation

    • restrictive ou -R demande une approbation pour toute action d’outil qui n’est pas explicitement autorisée dans la configuration
    • standard est le mode par défaut ; il approuve automatiquement les commandes sûres comme ls, cd, git log ou cargo check, et demande une confirmation pour l’écriture et les opérations destructrices
    • accept-all ou --accept-all approuve automatiquement toutes les opérations dans le répertoire de travail et demande confirmation pour les chemins externes
    • yolo ou --yolo approuve automatiquement toutes les opérations sans prompt
    • Des patterns glob par outil peuvent être définis dans le fichier de configuration pour affiner les autorisations
    • Par exemple, il est possible d’autoriser automatiquement write **.rs tout en exigeant une confirmation pour l’écriture des autres fichiers
    • La liste blanche de session conserve les décisions approuvées pendant toute la session afin d’éviter de redemander la même validation
    • Si le même appel d’outil se répète 3 fois ou plus, la détection de doom loop affiche un prompt d’avertissement ou bloque l’action selon la configuration, afin d’empêcher l’agent de répéter des opérations destructrices

Commandes slash et gestion des sessions

  • Les principales commandes slash contrôlent le modèle, le niveau de réflexion, la conversation, les sessions, les boucles, les prompts et les modes d’autorisation
  • /model permet de changer de modèle, et /thinking de définir le niveau de réflexion
  • /clear efface la conversation, et /session permet de lister, sauvegarder et charger les sessions
  • /loop programme un prompt itératif, et /prompt permet de lister ou modifier le prompt de l’agent
  • /mode définit le mode du système d’autorisations, et l’ensemble des commandes est consultable avec /help
  • Les sessions sont enregistrées dans $XDG_DATA_HOME/zerostack/sessions/
  • -c reprend la session la plus récente, -r permet de parcourir et choisir une session, et --session <id> charge une session précise

Boucle itérative

  • zerostack inclut une boucle de codage itérative pour les tâches de longue durée
  • L’agent relit la tâche de manière répétée, choisit un élément du plan, exécute le travail, lance les tests, met à jour le plan, puis continue jusqu’à l’achèvement ou jusqu’à atteindre la limite d’itérations
  • Le système de boucle est une fonction expérimentale
  • Utilisation de la boucle

    • /loop Implement the user authentication system démarre une boucle avec le prompt indiqué
    • /loop stop arrête la boucle active
    • /loop status affiche l’état actuel de la boucle
    • Chaque itération inclut la tâche d’origine, le fichier LOOP_PLAN.md évolutif, le résumé des itérations précédentes et la sortie de validation
    • Tant que la boucle est active, les entrées qui ne sont pas des commandes slash sont bloquées
  • Boucle headless via CLI

    • La boucle headless peut être lancée avec la commande suivante
      zerostack --loop --loop-prompt "Refactor the API" --loop-max 10 --loop-run "cargo test"  
      
    • --loop active le mode boucle headless
    • --loop-prompt <text> définit le prompt à utiliser à chaque itération
    • --loop-plan <path> indique le chemin d’un fichier de plan personnalisé, dont la valeur par défaut est LOOP_PLAN.md
    • --loop-max <N> définit le nombre maximal d’itérations, avec aucune limite par défaut
    • --loop-run <cmd> définit la commande de validation à exécuter après chaque itération

Intégration des Git worktrees

  • zerostack propose un flux de travail par branche via les git worktrees
  • Depuis l’interface de chat, il est possible de créer un worktree, d’y travailler, de fusionner, puis d’en sortir
  • L’intégration des Git worktrees est une fonction expérimentale
  • Commandes worktree

    • /worktree <name> crée un git worktree sur la branche <name> et y bascule ; si elle existe déjà, la création est ignorée
    • /wt-merge [branch] fusionne la branche du worktree dans [branch], effectue un push, nettoie, puis revient au dépôt principal
    • /wt-exit revient au dépôt principal sans fusionner
  • Exemple de workflow

    • /worktree feature-x crée une nouvelle branche et un répertoire worktree, puis s’y déplace
    • Ensuite, l’utilisation de zerostack se fait normalement et les modifications restent sur la branche feature
    • /wt-merge permet à l’agent de fusionner la branche, faire le push, nettoyer, puis revenir au dépôt principal
    • /wt-exit permet de revenir immédiatement au dépôt principal sans fusion

Fournisseurs pris en charge et licence

  • Le fournisseur par défaut est OpenRouter
  • Les fournisseurs compatibles OpenAI incluent vLLM, LiteLLM, etc.
  • Anthropic, Gemini et Ollama sont pris en charge
  • Les fournisseurs personnalisés peuvent être configurés dans $XDG_CONFIG_HOME/zerostack/config.json avec une base URL arbitraire et une variable d’environnement pour la clé API
  • La licence est GPL-3.0-only

1 commentaires

 
GN⁺ 4 시간 전
Commentaires Hacker News
  • Je ne connais pas très bien ce genre d’outil, mais je me demande quels sont les avantages par rapport à des modèles/outils comme Claude Code.

  • J’étais en train de construire quelque chose de similaire sur mon temps libre, à la fois pour mieux comprendre les agents et pour apprendre Rust.
    Cela dit, je voulais conserver la configurabilité de pi. La capacité à se modifier soi-même et à créer de nouveaux outils est très utile, et je pense que ce type d’outil ne devrait pas avoir le droit d’exécuter du code arbitraire via bash.
    Bien sûr, si l’on a accès à edit et à cargo run, on peut quand même exécuter du code arbitraire, mais lorsqu’un agent sans bash a besoin de faire quelque chose, je préfère qu’il génère les outils au cas par cas.

    • J’ai réfléchi à cette question, mais Pi est basé sur TypeScript, donc il peut disposer d’un environnement proche du scripting, alors que Rust est un langage compilé, ce qui impose des contraintes.
      J’ai donc choisi d’autoriser la personnalisation autrement. La bibliothèque de prompts dans ~/.config/hypernova/prompts/ est une alternative simple aux Skills, et les prompts intégrés doivent remplacer superpowers et frontend-design de Claude.
      Les fonctionnalités susceptibles d’alourdir l’agent peuvent être désactivées à la compilation via des feature flags, et comme le code est court et facile à lire, on peut faire tourner zerostack sur le code source de zerostack lui-même pour créer un fork personnalisé si besoin.
      Concernant le modèle de permissions, après beaucoup de réflexion comme on peut le voir dans le README, j’ai créé 4 niveaux, allant de « Restrictive » sans commandes à « YOLO » où l’agent fait ce qu’il veut, avec aussi des regex autoriser/demander/refuser pour les appels bash. Dans ce cas, il suffit d’exécuter zerostack -R pour forcer tous les outils à demander une permission.
      Je travaille aussi sur des fonctionnalités d’agent programmable, mais ce n’est pas encore prêt à être annoncé.
    • Je suis en train de faire la même chose en Zig.
  • J’en ai aussi fait un récemment, à moitié pour rire, en moins de 200 lignes : https://github.com/pnegahdar/nano
    Il inclut un REPL, des sessions, une exécution non interactive, des validations, etc. Plus les modèles deviennent intelligents, plus l’importance du harnais diminue, en dehors de l’expérience développeur.
    Je le passerai peut-être un jour sur SWE-bench.

    • 200 lignes, enfin 190 en réalité, c’est vraiment impressionnant.
      J’en ai moi aussi bricolé un la semaine dernière pour m’amuser et apprendre, et il fonctionne même avec des intégrations vers des mcpServers configurés, comme la plupart des agents de code.
      J’ai documenté étape par étape ce qui est nécessaire et pourquoi : https://nb1t.sh/building-a-real-agent-step-by-step/
  • « RAM footprint: ~8MB on an empty session, ~12MB when working »
    J’aime beaucoup ce point. Claude Code consomme plusieurs Go, ce qui est assez pénible sur un portable modeste.

    • Je construis un framework d’agent en Go, et il est extrêmement léger.
      Le démarrage prend moins de 0,5 seconde et l’usage RAM est très faible. Il tourne très bien sans ralentir, même sur un portable vieux de 12 ans.
      Quelque chose qui est essentiellement proche d’un moteur de concaténation de chaînes ne devrait pas être lent sur quelque machine que ce soit, y compris du matériel ancien.
    • J’essaie de passer à Zed, et Agent Client Protocol a l’air plutôt solide. Je me demande dans quelle mesure la pression mémoire de Claude Code diminuerait en passant par cette approche.
      1: https://zed.dev/acp
    • Oui. Rien que ce fait suffira probablement à pousser beaucoup de gens à l’essayer.
    • L’usage mémoire est excellent, au point qu’on peut désormais faire tourner un agent de code sur de très petites instances comme le x1 de shellbox.dev.
    • Il faut vérifier qu’il n’y a pas aussi quelque chose comme un plugin LSP qui tourne en parallèle.
  • Je vais essayer ça en rentrant chez moi. Les outils légers et rapides changent vraiment l’expérience de programmation.
    Je me demande ce que vaut concrètement l’approche par prompts par rapport à la combinaison plus classique de skills et sous-agents. Personnellement, s’il y a un échec de build, je lance souvent un skill /fix-ci, puis je fais extraire par un sous-agent le message d’erreur, la stack trace et les logs pertinents pour résoudre le problème.
    Quand un test d’intégration révèle un problème de requête DB, l’agent peut aussi appeler un skill d’accès DB en lecture seule, soit de lui-même, soit avec un léger guidage de ma part. Quand il faut creuser longtemps et en profondeur, je dis des choses comme « utilise un sous-agent Sonnet et demande-lui de déboguer ce comportement avec le skill de requêtes DB ».
    Les skills ajoutent des capacités à la volée, et les sous-agents permettent l’isolation pour éviter l’explosion du contexte. Un agent qui se relancerait lui-même via bash avec d’autres prompts pourrait peut-être produire quelque chose de similaire, mais cela me semble un peu moins fluide ; il faudra que je teste.

    • Dans la plupart des cas, ça s’utilise comme des skills, mais il faut plutôt les voir comme un environnement que comme des « commandes ».
      Par exemple, l’un des prompts intégrés, /prompt debug, ouvre un agent orienté débogage, et depuis cet état on peut discuter comme avec un agent normal, puis revenir à l’agent de code standard avec /prompt code.
      Les sous-agents ne sont pas encore pris en charge, car actuellement l’ensemble de l’agent tourne dans un seul buffer de contexte et je veux que cela reste léger. Mais comme les tâches très exploratoires gonflent souvent la fenêtre de contexte, il est probable que des sous-agents soient ajoutés.
  • J’ai aussi demandé à Claude Code de m’en fabriquer un, et j’y ai ajouté le hachage de lignes de Dirac pour l’édition.
    Je l’ai fait en Rust, et j’avais aussi pensé à rendre l’auto-modification possible via des hooks en plugin, mais j’ai finalement opté pour une approche où il crée un fichier séparé avec des détails sur les améliorations, met à jour le code source, puis recompile.
    Comme l’emplacement du code source est fixe, l’agent peut se réécrire et se reconstruire lui-même. Je l’utilise avec DeepSeek 4 Flash sur 2x RTX 6000 Pro, et j’obtiens environ 138 tok/s.
    Honnêtement, c’est surtout un mélange repris de Pi, Dirac et OpenCode. Y a-t-il ici de nouvelles techniques intéressantes à reprendre ?

    • En dehors de sa légèreté, les fonctions intéressantes sont la bibliothèque de prompts, l’intégration Git worktree et l’intégration de la boucle Ralph Wiggum.
    • Je me demande si c’est publié sur GitHub.
  • Je viens de l’essayer rapidement et c’était effectivement assez rapide.
    Je me demande si vous cherchez des contributeurs, ou si c’est plutôt un outil personnel.
    En revanche, j’ai rencontré quelques problèmes en essayant d’utiliser d’autres modèles. Avec l’endpoint compatible OpenAI d’Azure, gpt-5.5 ne fonctionne pas parce que max_tokens devient max_completion_tokens.
    Je n’ai pas non plus trouvé de moyen de transmettre des en-têtes personnalisés, donc impossible de définir reasoning_effort pour les modèles DeepSeek.

    • J’accepte les PR.
      Ce que tu décris ressemble clairement à des bugs dans la base de code, donc si possible, ce serait bien d’ouvrir un ticket GitHub distinct pour chacun.
  • Claude Code et Opencode fonctionnent bien chez moi.
    C’est un peu drôle de voir que les agents de code tournent dans des datacenters avec plus de 1000 W de puissance et plus de 2 To de mémoire, alors que les gens se focalisent sur les derniers watts et quelques centaines de Mo de RAM de leur portable.
    Au final, ce sera de toute façon négligeable face au coût énergétique de la compilation du code, mais ce n’est pas une mauvaise chose de les rendre plus rapides et plus légers.

    • Les datacenters tournent sur des lignes électriques dédiées, mais mon portable tourne sur batterie.
      Quand j’utilise des agents de code maintenant, la batterie se vide assez vite, ce qui est surprenant étant donné que la plupart du travail n’a pas lieu sur mon ordinateur portable.
      Optimiser les agents de code côté client, ce n’est pas pour sauver le climat, c’est pour allonger mon temps de travail. En réalité, cela pourrait même être pire pour le climat.
    • Évidemment que les gens se concentrent sur les logiciels qui tournent sur leur propre machine.
      Ce qui tourne sur les ordinateurs des autres n’est pas mon problème. Je ne contrôle pas ce qui tourne sur les serveurs d’autrui, et même si je le pouvais, ce n’est pas moi qui paie le coût de cette RAM, donc cela m’importe peu.
      En revanche, la RAM de ma machine, c’est moi qui la paie. Si un TUI qui affiche moins de 1 Ko de texte occupe plusieurs Go de mémoire, au point de faire tomber d’autres applications en OOM sous Windows, ou de faire swapper Linux sur le HDD jusqu’à figer toute la machine, alors oui, je suis obligé de m’en préoccuper.
      Avec un prix de la RAM multiplié par 5 dans les faits, et celui des autres composants multiplié par 2 ou 3, il est particulièrement important d’éviter le gaspillage mémoire.
    • C’est excessivement simpliste.
      Oui, le modèle est énorme et consomme beaucoup de ressources, mais le harnais peut avoir une grande influence sur la quantité de travail réellement demandée au modèle.
      Par exemple, avec un ensemble d’outils puissant dans le harnais, le modèle peut travailler de manière bien plus efficace.
  • Comme la base de code est petite, je l’ai donnée à DeepSeek v4 Flash dans Pi pour qu’il repère d’éventuels points dangereux, et il n’a rien trouvé de particulièrement inquiétant. Beau travail.

    • Comme l’auteur disait qu’une grande partie du code avait été générée par DeepSeek V4 Flash, j’ai vérifié s’il y avait des dépendances obsolètes.
      Sur les projets Rust, si l’on n’indique pas explicitement au modèle de ne pas modifier Cargo.toml directement mais d’utiliser cargo add, j’ai souvent vu même Claude 4.7 Opus ajouter presque systématiquement des dépendances anciennes.
      J’ai vérifié manuellement les dépendances de ce projet et elles étaient toutes à jour, ce qui est appréciable. Cela ne veut évidemment pas dire qu’il n’y a pas de problèmes cachés dans les dépendances transitives.
      Faire relire du code par un LLM peut très vite devenir une affaire de préférences. Par exemple, en parcourant le code, je me suis dit à plusieurs reprises que certaines méthodes convertissant des chaînes en enum et inversement auraient peut-être pu se résumer à un simple #[derive] avec strum. Cela aurait rendu provider.rs bien plus concis, au prix d’une seule crate sans dépendances.
      Pour le plaisir, j’ai demandé à DeepSeek V4 Pro en mode Max thinking d’« auditer » la base de code, et il a dit n’avoir trouvé aucun signe évident de télémétrie cachée. En revanche, il a relevé que le projet configurait le gestionnaire de panic sur abort, et j’ai un avis tranché sur ce point.
      C’est sans doute pour éviter le lien avec libunwind et économiser quelques Ko sur la taille du binaire, mais cela donne un exécutable qui s’interrompt immédiatement en cas de crash sans fournir de stack trace à l’utilisateur. Je préfère un binaire environ 50 KiB plus gros si cela permet d’obtenir des informations de débogage utiles lors d’une panic.
      En plus, si une panic survient dans une tâche asynchrone, on ne peut pas la récupérer pour afficher un message d’erreur normal : tout le processus s’arrête immédiatement.
    • Une part assez importante du code a été écrite par DeepSeek v4 Flash, et j’ai écrit moi-même une partie de la logique TUI.
      DeepSeek échouait sans cesse sur une logique précise de déplacement du curseur. Pour l’optimisation mémoire, j’ai tout géré moi-même, en combinant comme je l’ai écrit ailleurs des optimisations du compilateur et l’utilisation de crates Rust fournissant des structures de données plus efficaces.
    • « Je l’ai donnée à DeepSeek v4 Flash dans Pi pour qu’il repère les parties dangereuses » : ce n’est pas une enquête assez fragile à cause de l’injection de prompt ?
  • C’est amusant que ça sorte justement aujourd’hui. J’étais justement sur le point d’en commencer un en Rust moi aussi.
    Quand on voit opencode fuir lentement en mémoire sur de gros projets jusqu’à atteindre 6 Go et devenir de plus en plus lent, c’est assez impressionnant.
    Je vais regarder ça. Ça a l’air chouette.

    • Oui. Ce projet est parti du moment où j’ai lancé Firefox et plus de deux instances d’opencode en même temps sur un vieux portable, ce qui a fini par déclencher l’OOM killer.