plantrack 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: plantrack
3
+ Version: 1.1.0
4
+ Summary: Contexte, plan et bugs persistants pour les longues sessions d'agent de code — journal JSONL append-only + hooks Claude Code
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
10
+
11
+ # PlanTrack — contexte, plan et bugs pour les longues sessions agent
12
+
13
+ Un seul fichier Python, stdlib uniquement, aucune dépendance, aucune base de données.
14
+ Objectif : ne perdre ni décision, ni bug, ni état de fil pendant une session longue,
15
+ malgré la compaction du contexte.
16
+
17
+ ## Installation (2 minutes)
18
+
19
+ Depuis la racine du projet cible :
20
+
21
+ ```bash
22
+ uvx --from git+https://github.com/mdjlabs/plantrack plantrack init
23
+ ./plantrack init --git-hook # optionnel : le garde-fou git pre-commit
24
+ ```
25
+
26
+ (Au jalon Publication, la commande deviendra simplement `uvx plantrack init`
27
+ via PyPI — décision 2026-08-29, PRD §16.)
28
+
29
+ `init` copie le cœur dans `.claude/hooks/pt.py` (auto-copie vendorée : le projet reste
30
+ autonome, les hooks marchent sur un simple clone), écrit `.claude/settings.json`
31
+ (4 hooks — jamais écrasé s'il existe : fusion à la main), le wrapper `./plantrack`, un
32
+ bloc d'instructions entre marqueurs `<!-- plantrack:start/end -->` dans `CLAUDE.md` ou
33
+ `AGENTS.md`, et exclut `.plantrack/transcripts/` du versionnage. Il est idempotent.
34
+
35
+ Le journal `.plantrack/events.jsonl` **se versionne** : une ligne par événement, diff
36
+ lisible en revue, merge trivial.
37
+
38
+ Redémarre Claude Code. Vérifie avec `/hooks` que les quatre hooks sont chargés, ou :
39
+
40
+ ```bash
41
+ ./plantrack doctor # hooks, journal, budget de contexte
42
+ ```
43
+
44
+ ## Utilisation
45
+
46
+ Tout se tape dans le prompt de l'agent. Les commandes commençant par `!` sont
47
+ **interceptées et rejetées avant d'atteindre le modèle** : l'agent ne les voit jamais,
48
+ son contexte reste propre, et tu ne le déconcentres pas de sa tâche.
49
+
50
+ | Commande | Effet |
51
+ |---|---|
52
+ | `!focus page inscription` | ouvre un fil de travail (ou reprend `!focus t1`) |
53
+ | `!bug page profil : l'avatar ne se rafraîchit pas` | enregistre un bug sans interrompre le fil en cours |
54
+ | `!decide on abandonne X — motif : Y` | acte une décision, rappelée à chaque session |
55
+ | `!park reste à faire… ne pas toucher à Z` | met le fil en pause **avec note de reprise obligatoire** |
56
+ | `!close` | ferme le fil actif |
57
+ | `!state` | affiche l'état persistant |
58
+ | `!n'importe quel texte` | capture libre dans l'inbox, à classer plus tard |
59
+
60
+ Un bug accepte une sévérité : `!bug le paiement échoue --blocker` (ou `--low`/`--high`).
61
+ Un bug `blocker` s'affiche en tête du bloc réinjecté à chaque session.
62
+
63
+ Côté humain, hors session :
64
+
65
+ ```bash
66
+ ./plantrack status # le bloc d'état, tel que l'agent le voit
67
+ ./plantrack bugs # bugs ouverts + tentatives + motifs de rejet
68
+ ./plantrack plan # arbre phases/tâches ; plan import <f.md> pour proposer
69
+ ./plantrack attempt b1 "hypothèse testée" # refusé si déjà tentée (similarité > 0.85)
70
+ ./plantrack attempts b1 # journal des tentatives et motifs de rejet
71
+ ./plantrack bug b1 wont_fix -m "cosmétique" # toi seule (motif obligatoire)
72
+ ./plantrack verify b1 # toi seule valides (bug en to_verify uniquement)
73
+ ./plantrack reject b1 -m "le cache n'était pas la cause, ne pas retenter"
74
+ ./plantrack file n1 bug # classe une note d'inbox en bug
75
+ ./plantrack stats # usage sur 14 jours — la mesure qui justifie l'outil
76
+ ```
77
+
78
+ ## Ce que font les quatre hooks
79
+
80
+ | Hook | Rôle |
81
+ |---|---|
82
+ | `UserPromptSubmit` | intercepte les `!`, écrit dans le journal, rejette le prompt (exit 2) |
83
+ | `PostToolUse` (Edit/Write) | journalise automatiquement chaque fichier écrit, rattaché au fil actif |
84
+ | `SessionStart` | injecte le bloc d'état — se redéclenche avec `source=compact`, donc **après chaque compaction** |
85
+ | `PreCompact` | archive le transcript dans `.plantrack/transcripts/` avant qu'il soit compacté |
86
+
87
+ Le bloc réinjecté fait environ 250 tokens sur un projet à deux fils. Plafond dur à
88
+ 3 000 caractères, avec troncature : s'il enflait, il se ferait compacter à son tour.
89
+
90
+ ## Garde-fous délibérés
91
+
92
+ - **Impossible de changer de fil sans parker.** `!focus` est refusé tant que le fil actif
93
+ n'a pas de note de reprise. C'est le seul moment où ton scénario perdait vraiment
94
+ quelque chose.
95
+ - **Note de reprise obligatoire.** `!park` sans texte échoue.
96
+ - **Motif de rejet obligatoire.** `plantrack reject` sans `-m` échoue.
97
+ - **Trois fils ouverts maximum.** Au-delà, le bloc réinjecté devient trop gros pour
98
+ survivre à une compaction.
99
+ - **Rien ne se supprime.** Journal append-only : l'état est reconstruit par rejeu.
100
+ - **Un commit ne touche pas un fil en pause.** `plantrack init --git-hook` installe un
101
+ `pre-commit` qui bloque tout commit d'un fichier appartenant à un fil parqué — le seul
102
+ garde-fou qui ne dépende d'aucun modèle. Contournement assumé : `git commit --no-verify`.
103
+
104
+ ## Vérifier que ça marche
105
+
106
+ ```bash
107
+ echo '{"prompt":"!focus test"}' | python3 .claude/hooks/pt.py hook-prompt
108
+ echo '{"prompt":"!bug ça casse ici"}' | python3 .claude/hooks/pt.py hook-prompt
109
+ echo '{"source":"compact"}' | python3 .claude/hooks/pt.py hook-context
110
+ ```
111
+
112
+ Le scénario complet — ouvrir un fil, éditer, remonter un bug ailleurs, acter une décision,
113
+ parker, ouvrir un autre fil, revenir — a été rejoué et passe.
114
+
115
+ ## Limites assumées
116
+
117
+ - Pas de MCP, pas de SQLite. Volontaire : un journal JSONL rejoué suffit à cette échelle.
118
+ - **Ce qui n'est jamais capturé reste perdu.** La nuance expliquée en prose et jamais
119
+ transformée en `!decide` disparaît à la compaction. Seul l'archivage du transcript
120
+ permet de la retrouver, à la main.
121
+ - Hooks Claude Code **et Codex CLI**. `plantrack init --agent codex` écrit
122
+ `.codex/hooks.json` (même protocole : `UserPromptSubmit` bloquant, `SessionStart`
123
+ — y compris `source: "compact"` —, `PostToolUse`, `PreCompact`) ; dans Codex,
124
+ lancer `/hooks` une fois pour approuver les hooks du projet. Le chemin des fichiers
125
+ édités est extrait du patch `apply_patch` ; la détection de rôle s'appuie sur
126
+ `CODEX_THREAD_ID`/`CODEX_SANDBOX` (posées par le shell de l'agent Codex — non
127
+ documentées, à confirmer sur un projet réel). Les autres agents retombent sur
128
+ la CLI + une consigne dans `AGENTS.md`, sans garantie.
129
+ - IDs séquentiels calculés par rejeu : à revoir en cas de travail multi-branches
130
+ simultané.
131
+
132
+ ## Mesure à tenir pendant deux semaines
133
+
134
+ Une seule ligne dans un fichier à part, à chaque fois que ça arrive :
135
+
136
+ - nombre de fois où tu as dû répéter une consigne déjà donnée ;
137
+ - nombre de bugs signalés deux fois ;
138
+ - nombre de reprises de fil où la note de reprise a suffi.
139
+
140
+ Sans ces trois chiffres, tu ne sauras pas dans six semaines si l'outil sert, et tu risques
141
+ de le maintenir par principe. C'est aussi le seul argument crédible le jour où tu publies.
142
+
143
+ ## La suite
144
+
145
+ Le PRD fait foi : voir `PRD-PlanTrack-v0.2.md` (jalons §16). Livré : couches 1 à 4
146
+ (capture, plan phases/tâches, bugs/tentatives, pre-commit) + `init`/`doctor`/`stats`
147
+ + le portage Codex (§13 — testé sur le contrat documenté ; PlanTrack n'installe jamais
148
+ d'agent, la validation en conditions réelles appartient à qui installe Codex).
149
+ Reste : la publication —
150
+ uniquement si les chiffres de `plantrack stats` la justifient. La greffe sur Beads a
151
+ été écartée par décision de conception (PRD §6 : un stockage binaire interdit le diff
152
+ et le merge git) — au mieux un pont d'export en extension. MCP en option, jamais en
153
+ socle.
154
+
155
+ Référence hooks : https://code.claude.com/docs/en/hooks
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ .claude/hooks/pt.py
5
+ .claude/hooks/plantrack.egg-info/PKG-INFO
6
+ .claude/hooks/plantrack.egg-info/SOURCES.txt
7
+ .claude/hooks/plantrack.egg-info/dependency_links.txt
8
+ .claude/hooks/plantrack.egg-info/entry_points.txt
9
+ .claude/hooks/plantrack.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ plantrack = pt:main