À propos du projet
Vole est un moniteur local d'utilisation, de coût et d'anomalies pour les agents de codage IA. Il s'adresse aux situations où plusieurs agents fonctionnent côte à côte, consommant chacun des tokens indépendamment sans signaler les dysfonctionnements — comme un blocage dans une boucle d'outils, des tentatives répétées contre une API défectueuse ou la relecture constante d'un contexte volumineux. Là où d'autres outils répondent à la question « combien ai-je dépensé ? », Vole demande « est-ce que quelque chose se passe mal en ce moment ? » et rapporte les dépenses comme effet secondaire.
Gestion des données
Vole lit les fichiers journaux que les outils écrivent déjà sur le disque — par exemple ~/.claude/projects/**/*.jsonl pour Claude Code, ~/.local/share/opencode/opencode.db pour OpenCode, ~/.codex/sessions/**/rollout-*.jsonl pour Codex CLI, ~/.grok/logs/unified.jsonl pour Grok CLI, ainsi que les stockages locaux pour Cursor, Devin et Antigravity — et les normalise dans un schéma unique. Tout s'exécute localement : pas de scraping, pas d'API cloud, pas de connexion, et aucun contenu de prompt ou d'outil n'est stocké. La seule permission optionnelle demandée concerne les notifications, pour les alertes lors d'incidents critiques.
Outils supportés et politique de fidélité
La couverture varie selon l'outil : Claude Code et OpenCode fournissent les tokens et le coût exacts ; Codex CLI et Grok CLI fournissent les tokens exacts mais n'ont pas de tarif publié ; Cursor, Devin et Antigravity n'enregistrent aucun token localement et sont donc couverts uniquement en tant qu'activité. Le projet stipule qu'il n'y a pas de niveau « estimé » par politique — un nombre de tokens est soit lu textuellement dans les logs de l'outil, soit réellement absent, et les lignes sans tokens comptent toujours comme des appels mais sont exclues des agrégats de tokens et de coûts. L'estimation des tokens Cursor à partir des lignes de code a été envisagée et explicitement rejetée.
L'application
Un élément de la barre de menus affiche les tokens en direct, le coût ou simplement l'icône, colorée lorsqu'un incident est ouvert. Un clic ouvre un panneau avec des chiffres clés, une sparkline et des barres par outil ; un tableau de bord fournit la vue complète. Son élément signature est une chronologie annotée d'incidents qui empile les tokens par outil et nomme le groupe, ses tokens et tout incident déclenché au survol. L'application intègre son propre collecteur, le démarre elle-même et se met à jour sur place : une version publiant une archive avec somme de contrôle offre une installation en un clic qui vérifie le SHA-256 publié avant de remplacer le bundle, et une version sans somme de contrôle ne s'installe jamais silencieusement.
Ligne de commande et MCP
Parallèlement à l'application, Vole expose des commandes terminal sur les mêmes données : pnpm top (sessions en direct, contexte versus fenêtre, tokens par minute, compte à rebours du cache), pnpm digest (un résumé d'utilisation d'agent en markdown avec options de plage et JSON), pnpm pr (utilisation sur la branche actuelle pour une description de PR), pnpm statusline, et pnpm mcp, un serveur MCP stdio. Le serveur MCP expose vole_summary, vole_live_sessions, vole_session, vole_incidents, vole_breakdown, vole_whatif et vole_digest, permettant ainsi à un agent de demander le coût de sa propre session ou si Vole l'a signalé. Le serveur lit la base de données locale et répond sur stdout.
Règles d'anomalie
Cinq règles sont intégrées : billable_burn_spike (une fenêtre de 10 minutes coûtant plus de 3x la fenêtre typique de cette session), repeat_call_loop (45+ appels en 5 minutes alors que la sortie reste stable), error_storm (taux d'erreur supérieur à 20 % sur 15 minutes avec au moins 5 erreurs), rate_limit_pressure (Codex rapporte plus de 80 % du quota consommé) et context_pressure (un appel a transporté au moins 80 % de la fenêtre de contexte du modèle). Les lignes de base sont de type « leave-one-out », comparant une fenêtre à la médiane de toutes les autres fenêtres, et la détection de boucle nécessite deux signaux pour qu'une salve productive d'appels ne soit pas confondue avec une boucle.
Modèle de coût
Le coût correspond à la valeur API équivalente au prix catalogue — ce que l'utilisation aurait coûté via l'API — et l'interface précise que les plans d'abonnement ne sont pas facturés par token. Les tarifs se trouvent dans packages/core/src/data/pricing.json, versionnés avec effective_from, et un fichier ~/.vole/pricing.json par installation fusionne par-dessus pour permettre l'ajout d'un modèle sans nouvelle version ; les lignes stockées avant qu'un modèle n'ait un tarif sont repriciées rétroactivement. Les modèles inconnus retournent NULL, jamais 0.
Vérification et tests
Le projet propose pnpm test pour les tests unitaires des règles, des requêtes, du regroupement et des invariants de confiance, et pnpm verify, qui réconcilie chaque ligne stockée avec son enregistrement source en utilisant une formule de coût réimplémentée indépendamment. La vérification compare par enregistrement plutôt que par total et échoue sur un store vide pour éviter un succès vacuus. Une commande pnpm seed écrit 30 jours d'historique synthétique tagués source='seed', tracés séparément des données réelles.
Construction et limitations
La compilation à partir des sources nécessite Node 22+, pnpm et Xcode 26, testé sur macOS 26 arm64 ; pnpm app:bundle construit et ouvre l'application, ou le collecteur et l'application peuvent être exécutés séparément. Les limitations documentées incluent une couverture superficielle pour les outils n'enregistrant pas de tokens locaux, is_error couvrant uniquement les erreurs API (ce qui peut sous-compter error_storm), les vitesses de génération étant des bornes inférieures pour certains outils, les fenêtres de contexte ne se résolvant que pour les identifiants de modèles propriétaires, et un timing approximatif pour Antigravity basé sur les mtimes des fichiers. Le projet est sous licence MIT et accueille les contributions, avec deux règles de revue : ne jamais inventer un nombre, et chaque collecteur doit être idempotent.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.