Skip to main content

PlanTrack — contexte, plan et bugs pour les longues sessions agent

Un seul fichier Python, stdlib uniquement, aucune dépendance, aucune base de données. Objectif : ne perdre ni décision, ni bug, ni état de fil pendant une session longue, malgré la compaction du contexte.

Installation (2 minutes)

Depuis la racine du projet cible :

uvx plantrack init               # ou : pipx run plantrack init
./plantrack init --git-hook      # optionnel : le garde-fou git pre-commit

Pour mettre à jour une installation existante :

uvx plantrack@latest update

update remplace la copie vendorée par la dernière version puis rejoue init : toutes les étapes savent se mettre à niveau (fusion des hooks, blocs entre marqueurs, skill), et rien de ce que tu as écrit n'est touché — le journal .plantrack/ encore moins.

(Paquet publié sur PyPI — licence MIT. Depuis un clone du repo : uvx --from git+https://github.com/mdjlabs/plantrack plantrack init marche aussi.)

init copie le cœur dans .claude/hooks/pt.py (auto-copie vendorée : le projet reste autonome, les hooks marchent sur un simple clone), écrit les hooks de tous les agents supportés — .claude/settings.json (Claude Code) et .codex/hooks.json (Codex) ; si le fichier existe déjà (un settings.json existe dans presque tout projet réel), les hooks PlanTrack y sont fusionnés sans toucher au reste —, le wrapper ./plantrack, le bloc d'instructions complet dans AGENTS.md (la source unique, le standard lu par la plupart des agents) plus une ligne d'import @AGENTS.md entre marqueurs dans CLAUDE.md et GEMINI.md, une skill .deepcode/skills/plantrack/SKILL.md qui renvoie vers AGENTS.md (Deep Code), et exclut .plantrack/transcripts/ du versionnage. Il est idempotent — un fichier de config est inerte tant que l'agent n'est pas là : celui que tu installeras après trouvera PlanTrack déjà en place, sans option à connaître, même s'ils sont plusieurs.

Le journal .plantrack/events.jsonl se versionne : une ligne par événement, diff lisible en revue, merge trivial.

Redémarre Claude Code. Vérifie avec /hooks que les quatre hooks sont chargés, ou :

./plantrack doctor               # hooks, journal, budget de contexte

Comment ça marche, tout simplement

Un agent de codage oublie : quand la conversation devient trop longue, elle est compressée et des détails disparaissent — un bug signalé au passage, une décision prise il y a deux heures. PlanTrack tient un carnet de bord dans le projet, et tout ce qui y est noté est définitif : à chaque nouvelle session, et après chaque compression, l'agent reçoit automatiquement le résumé de ce carnet. Il repart toujours de ce qui a été décidé, pas de ce dont il « se souvient ».

Au quotidien :

  • Tu vois un bug en plein milieu d'une tâche ? Tape !bug l'avatar ne se rafraîchit pas. Le bug est noté et l'agent ne voit même pas passer le message : il n'est pas déconcentré de sa tâche. Le bug ressortira à chaque session tant qu'il n'est pas réglé — impossible de l'oublier.
  • Vous prenez une décision ? !decide on abandonne X — motif : Y. Elle est rappelée à l'agent à chaque session, avec interdiction de la réimplémenter.
  • Tu changes d'avis plus tard ? Tu actes une nouvelle décision. Rien ne s'efface jamais : l'ancienne reste dans l'historique — on sait pourquoi on avait choisi autrement — et la nouvelle fait foi.
  • Tu pars sur un autre sujet ? !park reste à faire : Z. La note de reprise est obligatoire — c'est elle qui permet de reprendre le fil dans trois jours sans rien reperdre.
  • L'agent dit qu'un bug est corrigé ? Il n'a pas le droit de le déclarer réglé : le bug passe « à vérifier » et c'est toi qui valides ou rejettes, avec un motif conservé — l'agent ne retentera pas deux fois la même correction.
  • Une nouvelle session démarre ? Rien à faire : l'état complet (fils en cours, décisions, bugs ouverts) est réinjecté automatiquement.

Le carnet (.plantrack/events.jsonl) ne fait que s'allonger, ligne par ligne : rien ne s'y supprime, l'état courant est recalculé en le relisant. Changer d'avis, revenir en arrière, reprendre après une pause : tout reste cohérent parce que tout est écrit.

Utilisation

Tout se tape dans le prompt de l'agent. Les commandes commençant par ! sont interceptées et rejetées avant d'atteindre le modèle : l'agent ne les voit jamais, son contexte reste propre, et tu ne le déconcentres pas de sa tâche.

Commande Effet
!focus page inscription ouvre un fil de travail (ou reprend !focus t1)
!bug page profil : l'avatar ne se rafraîchit pas enregistre un bug sans interrompre le fil en cours
!decide on abandonne X — motif : Y acte une décision, rappelée à chaque session
!park reste à faire… ne pas toucher à Z met le fil en pause avec note de reprise obligatoire
!close ferme le fil actif
!state affiche l'état persistant
!n'importe quel texte capture libre dans l'inbox, à classer plus tard

Un bug accepte une sévérité : !bug le paiement échoue --blocker (ou --low/--high). Un bug blocker s'affiche en tête du bloc réinjecté à chaque session.

Côté humain, hors session :

./plantrack status              # le bloc d'état, tel que l'agent le voit
./plantrack bugs                # bugs ouverts + tentatives + motifs de rejet
./plantrack plan                # arbre phases/tâches ; plan import <f.md> pour proposer
./plantrack attempt b1 "hypothèse testée"   # refusé si déjà tentée (similarité > 0.85)
./plantrack attempts b1         # journal des tentatives et motifs de rejet
./plantrack bug b1 wont_fix -m "cosmétique"  # toi seule (motif obligatoire)
./plantrack verify b1           # toi seule valides (bug en to_verify uniquement)
./plantrack reject b1 -m "le cache n'était pas la cause, ne pas retenter"
./plantrack file n1 bug         # classe une note d'inbox en bug
./plantrack stats               # usage sur 14 jours — la mesure qui justifie l'outil

Ce que font les quatre hooks

Hook Rôle
UserPromptSubmit intercepte les !, écrit dans le journal, rejette le prompt (exit 2)
PostToolUse (Edit/Write) journalise automatiquement chaque fichier écrit, rattaché au fil actif
SessionStart injecte le bloc d'état — se redéclenche avec source=compact, donc après chaque compaction
PreCompact archive le transcript dans .plantrack/transcripts/ avant qu'il soit compacté

Le bloc réinjecté fait environ 250 tokens sur un projet à deux fils. Plafond dur à 3 000 caractères, avec troncature : s'il enflait, il se ferait compacter à son tour.

Garde-fous délibérés

  • Impossible de changer de fil sans parker. !focus est refusé tant que le fil actif n'a pas de note de reprise. C'est le seul moment où ton scénario perdait vraiment quelque chose.
  • Note de reprise obligatoire. !park sans texte échoue.
  • Motif de rejet obligatoire. plantrack reject sans -m échoue.
  • Trois fils ouverts maximum. Au-delà, le bloc réinjecté devient trop gros pour survivre à une compaction.
  • Rien ne se supprime. Journal append-only : l'état est reconstruit par rejeu.
  • Un commit ne touche pas un fil en pause. plantrack init --git-hook installe un pre-commit qui bloque tout commit d'un fichier appartenant à un fil parqué — le seul garde-fou qui ne dépende d'aucun modèle. Contournement assumé : git commit --no-verify.

Vérifier que ça marche

echo '{"prompt":"!focus test"}'        | python3 .claude/hooks/pt.py hook-prompt
echo '{"prompt":"!bug ça casse ici"}'  | python3 .claude/hooks/pt.py hook-prompt
echo '{"source":"compact"}'            | python3 .claude/hooks/pt.py hook-context

Le scénario complet — ouvrir un fil, éditer, remonter un bug ailleurs, acter une décision, parker, ouvrir un autre fil, revenir — a été rejoué et passe.

Limites assumées

  • Pas de MCP, pas de SQLite. Volontaire : un journal JSONL rejoué suffit à cette échelle.
  • Ce qui n'est jamais capturé reste perdu. La nuance expliquée en prose et jamais transformée en !decide disparaît à la compaction. Seul l'archivage du transcript permet de la retrouver, à la main.
  • Hooks Claude Code et Codex CLI, écrits d'office par init (même protocole : UserPromptSubmit bloquant, SessionStart — y compris source: "compact" —, PostToolUse, PreCompact) ; dans Codex, lancer /hooks une fois pour approuver les hooks du projet. Le chemin des fichiers édités est extrait du patch apply_patch ; la détection de rôle s'appuie sur CODEX_THREAD_ID/CODEX_SANDBOX (posées par le shell de l'agent Codex — non documentées, à confirmer sur un projet réel). Les autres agents n'ont pas de hooks : ils lisent AGENTS.md et utilisent la CLI, sans réinjection automatique. Lisent AGENTS.md nativement (vérifié sur leur doc, 2026-08) : ZCode (Z.ai/GLM), Grok Build (xAI), Kimi Code CLI (Moonshot), Mistral Vibe ; Gemini CLI passe par la ligne d'import de GEMINI.md. Aucun de ces agents ne supporte l'import @fichier — d'où le bloc complet dans AGENTS.md, jamais une simple référence. DeepSeek n'a pas de CLI officiel à ce jour : init écrit une skill pour Deep Code (outil tiers lessweb/deepcode-cli, listé par la doc DeepSeek ; format SKILL.md compatible Claude Code) qui renvoie vers AGENTS.md et rappelle ./plantrack status faute de hooks.
  • Surcouches d'orchestration (BMAD, task-master, claude-flow, spec-kit…) : déjà couvertes — leurs sous-agents reçoivent le CLAUDE.md du projet, donc la ligne @AGENTS.md ; BMAD et task-master écrivent d'ailleurs eux-mêmes dans AGENTS.md, chacun entre ses propres marqueurs, sans conflit. Exception : GSD génère son propre CLAUDE.md et peut écraser la ligne d'import — plantrack doctor le détecte, plantrack init la repose.
  • IDs séquentiels calculés par rejeu : à revoir en cas de travail multi-branches simultané.

Mesure à tenir pendant deux semaines

Une seule ligne dans un fichier à part, à chaque fois que ça arrive :

  • nombre de fois où tu as dû répéter une consigne déjà donnée ;
  • nombre de bugs signalés deux fois ;
  • nombre de reprises de fil où la note de reprise a suffi.

Sans ces trois chiffres, tu ne sauras pas dans six semaines si l'outil sert, et tu risques de le maintenir par principe. C'est aussi le seul argument crédible le jour où tu publies.

La suite

Le PRD fait foi : voir PRD-PlanTrack-v0.2.md (jalons §16). Livré : couches 1 à 4 (capture, plan phases/tâches, bugs/tentatives, pre-commit) + init/doctor/stats

  • le portage Codex (§13 — testé sur le contrat documenté ; PlanTrack n'installe jamais d'agent, la validation en conditions réelles appartient à qui installe Codex). Reste : la publication — uniquement si les chiffres de plantrack stats la justifient. La greffe sur Beads a été écartée par décision de conception (PRD §6 : un stockage binaire interdit le diff et le merge git) — au mieux un pont d'export en extension. MCP en option, jamais en socle.

Référence hooks : https://code.claude.com/docs/en/hooks

Metadata

Release files for plantrack 1.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plantrack 1.4.2
File Size Uploaded Provenance
plantrack-1.4.2.tar.gz 26.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for plantrack 1.4.2
File Interpreter ABI Platform
plantrack-1.4.2-py3-none-any.whl Python 3 none any Details

Total release size: 49.2 kB

Release files / plantrack-1.4.2.tar.gz

Download URL plantrack-1.4.2.tar.gz
Size 26.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d2dfbd8cd1f7f8125365bbe96996e51299bc2521f9674f770240ffd9c8fc3174
BLAKE2b-256 checksum
How to use checksums
837391a727622596652f94fab0543d43a7d6fc11c36b7a37e1ac1c74e44c6d4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release files / plantrack-1.4.2-py3-none-any.whl

Download URL plantrack-1.4.2-py3-none-any.whl
Size 22.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
459a9ccc2db9268433d83ffeb7e9b2e7c329b88d62dc198455ac68a6cbfc674b
BLAKE2b-256 checksum
How to use checksums
5d7a934f06d7a4f020596bfa522587ba54c84a8cc2d171e3f304e7c007a98360
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Security for plantrack 1.4.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for plantrack-1.4.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.4.2 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page