SLOPSHOPPER

bilan

Commande /bilan : coût, durée, remplissage du fil et quotas, lus sur le moteur

guardcommand
v0.1.0no licenseupdated 2026-10-17graphixxgeek-boop/CCM-claude-code-mods/bilan
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · bilan
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /bilan ⎿ bilan: Bilan de la session (chiffres lus sur le moteur, pas estimés) ⎿ bilan: - Durée : 30 min ⎿ bilan: - Fil rempli à 49 % (97400 sur 200000 tokens) ⎿ bilan: - Appels d'outils depuis le chargement : 9 ⎿ bilan: - Coût : 0.42 $ ⎿ bilan: - quota 5 h : 31 %, remis à zéro le 1760003600000 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

CCM-claude-code-mods

Cinq mods pour Claude Code, utilisables dans n'importe quel projet. Un mod est un petit ajout qui change ce que Claude Code affiche ou ce qu'il accepte de faire.

ModCe qu'il fait
jaugeUne barre au-dessus de la zone de saisie : remplissage du fil (en %) et quota sur 5 heures. Prévient à 85 %. Dans un projet Claude (application Projets), ajoute aussi une petite ligne « 📊 Jauge » en bas de chaque message des fils (remplissage, quotas 5 h et 7 jours, durée et actions du tour, durée de la session), puisque la barre n'y est pas visible.
chronoDans la ligne d'état : durée réelle du dernier tour et nombre d'appels d'outils, lus sur l'horloge.
sonnetteUne notification quand Claude a fini un travail de plus d'une minute.
garde-fouRefuse les commandes qu'on ne peut pas défaire (changer l'adresse distante git, pousser en force ou sur main, supprimer en masse, effacer des changements non sauvegardés) et dit pourquoi.
bilanLa commande /bilan : coût, durée, remplissage du fil et quotas de la session.

Tous les chiffres sont lus sur Claude Code lui-même, jamais estimés.

Installer

Dans Claude Code, à l'invite, une ligne par mod voulu :

/plugin install jauge --marketplace graphixxgeek-boop/CCM-claude-code-mods
/plugin install chrono --marketplace graphixxgeek-boop/CCM-claude-code-mods
/plugin install sonnette --marketplace graphixxgeek-boop/CCM-claude-code-mods
/plugin install garde-fou --marketplace graphixxgeek-boop/CCM-claude-code-mods
/plugin install bilan --marketplace graphixxgeek-boop/CCM-claude-code-mods

Répondre y pour ajouter la source, puis choisir la portée.

Depuis un terminal : claude plugin install <mod> --marketplace graphixxgeek-boop/CCM-claude-code-mods.

Dans l'application de bureau : cliquer sur + à côté de la zone de saisie, puis Plugins, Add marketplace avec graphixxgeek-boop/CCM-claude-code-mods, puis Add plugin.

Le dépôt est privé : pour installer, GitHub doit être configuré sur l'ordinateur.

/plugin liste les mods chargés et permet de les éteindre.

Limite connue du garde-fou

Il lit le texte entier de la commande. Une commande qui contient seulement le texte d'une commande interdite (par exemple dans un fichier qu'on écrit) est refusée aussi. C'est voulu : mieux vaut un refus de trop qu'une commande irréversible qui passe.

Vérifier

claude plugin validate <dossier du mod>
claude plugin test garde-fou
Source 1 files
hooks/register.ts 32 lines
1import type { Register } from 'claude-code'
2
3const NOMS: Record<string, string> = { five_hour: 'quota 5 h', seven_day: 'quota 7 jours', spend_limit: 'plafond de dépense' }
4
5export const register: Register = on => {
6  let outils = 0
7
8  on('session.start', async ($, e, next) => {
9    await $.command.register({ name: 'bilan', description: 'Coût, durée, remplissage du fil et quotas de cette session' })
10    return next(e)
11  })
12
13  on('tool.call', ($, e, next) => {
14    outils += 1
15    return next(e)
16  }).catch(($, e, next) => next(e))
17
18  on('command.run', { command: 'bilan' }, async $ => {
19    const { startedAt, context, rateLimits, cost } = await $.session.usage()
20    const minutes = Math.round(((await $.clock.now()) - startedAt) / 60_000)
21    const lignes = [
22      `Bilan de la session (chiffres lus sur le moteur, pas estimés)`,
23      `- Durée : ${minutes} min`,
24      `- Fil rempli à ${context.percent ?? '?'} % (${context.tokens ?? '?'} sur ${context.window} tokens)`,
25      `- Appels d'outils depuis le chargement : ${outils}`,
26      ...(cost ? [`- Coût : ${cost.usd.toFixed(2)} $`] : []),
27      ...rateLimits.map(r => `- ${NOMS[r.kind] ?? r.kind} : ${r.percentUsed} %${r.resetsAt ? `, remis à zéro le ${r.resetsAt}` : ''}`),
28    ]
29    return { text: lignes.join('\n') }
30  })
31}
32