Une entrée user arrivée après la fin d'un tour de l'agent (dernière réponse du fil principal avec stop_reason autre que tool_use) ouvre une nouvelle plage, même écrite par Claude Code (isMeta) : message ou avis d'une autre session, commande slash, renommage. Une entrée isMeta écrite pendant un tour, ou après la fin d'un tour de sous-agent, ne coupe rien. Ajoute le fichier VERSION (1.0.1), vérifié égal à la constante de l'outil. Refs #2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KT2yBsd7nPivLnrEtcvuhX
108 lines
3.9 KiB
Markdown
108 lines
3.9 KiB
Markdown
# TKfA
|
|
|
|
Outils de *timekeeping* pour les agents : ils notent leur temps de travail
|
|
dans les tickets Gitea. Ce dépôt ne porte que l'outil : quand saisir, et sur
|
|
quel ticket, relève des consignes de chaque équipe.
|
|
|
|
## Récupérer l'outil
|
|
|
|
Le dépôt est public : un seul fichier, sans authentification. La dernière
|
|
version est sur `main` ; une version figée, sur son tag (`v1.0.0`…).
|
|
|
|
```
|
|
curl -fsSL -o temps-session.py \
|
|
https://gitea.raggaroth-factory.fr/public/TKfA/raw/branch/main/outils/temps-session.py
|
|
# version figée : …/raw/tag/v1.0.0/outils/temps-session.py
|
|
python3 -I temps-session.py --version
|
|
```
|
|
|
|
Les évolutions de chaque version sont dans `CHANGELOG.md`.
|
|
|
|
## `outils/temps-session.py`
|
|
|
|
Calcule le temps actif d'une session Claude Code sur un ticket, prêt à saisir
|
|
sur Gitea. Il lit le transcript de la session (`~/.claude/projects/*/<session>.jsonl`
|
|
et ses sous-agents) et ne compte que le temps où l'agent travaille : l'attente
|
|
d'une réponse de l'humain, ou d'un message d'une autre session, n'est jamais
|
|
comptée. Il retire ce qui est déjà saisi sur le ticket : le relancer ne
|
|
double rien.
|
|
|
|
Python 3.11 ou plus, sans dépendance. Il ne lit que le transcript et l'API
|
|
Gitea (GET). **Il n'écrit ni n'envoie rien** : il affiche une ligne JSON par
|
|
séance restant à saisir.
|
|
|
|
```
|
|
python3 -I outils/temps-session.py \
|
|
--depot <organisation>/<dépôt> --ticket <n> --depuis <heure> [--jusqua <heure>]
|
|
```
|
|
|
|
- `--depuis` : l'heure où l'on a commencé le ticket (`date -Iseconds`).
|
|
- `--jusqua` : l'heure où l'on est passé à un autre ticket sans saisir ; sans
|
|
elle, le travail fait sur l'autre serait compté sur celui-ci.
|
|
- L'instance Gitea et son jeton viennent de la configuration (voir
|
|
*Configuration*) : **sans elle, l'outil n'interroge rien.**
|
|
- La session est `CLAUDE_CODE_SESSION_ID`. Hors de Claude Code (un humain),
|
|
passer `--session <id>` : le nom du `.jsonl` de la session.
|
|
|
|
L'outil termine en affichant sur stderr l'adresse où saisir.
|
|
|
|
Options fines : `--pause` (trou non compté au sein d'un tour, 1800 s),
|
|
`--seance` (écart qui sépare deux séances, 3600 s). Voir `--help`.
|
|
|
|
## Configuration
|
|
|
|
Sans configuration, l'outil n'interroge aucune instance et s'arrête. Les
|
|
instances Gitea se décrivent dans un fichier TOML (modèle commenté :
|
|
`tkfa.exemple.toml`) :
|
|
|
|
```toml
|
|
defaut = "principale"
|
|
|
|
[instances.principale]
|
|
api = "https://gitea.example.org/api/v1"
|
|
jeton = "~/.config/tkfa/principale.jeton" # chemin du fichier, jamais le jeton
|
|
|
|
[instances.agents]
|
|
api = "https://gitea.example.com/api/v1"
|
|
jeton_env = "GITEA_TOKEN_FILE" # variable qui contient le chemin du fichier
|
|
```
|
|
|
|
- Le fichier : `--config <fichier>`, sinon `TKFA_CONFIG`, sinon
|
|
`~/.config/tkfa/config.toml` s'il existe (`XDG_CONFIG_HOME` respecté).
|
|
- L'instance : `--instance <nom>`, sinon la clé `defaut`.
|
|
- Le jeton : `--jeton <fichier>`, sinon la clé `jeton` de l'instance (un
|
|
chemin relatif se lit depuis le dossier du fichier), sinon le fichier que
|
|
nomme la variable de sa clé `jeton_env`. Une variable ne sert que
|
|
l'instance qui la nomme : le jeton d'une instance ne part pas vers une
|
|
autre. Préférer `jeton` ou `jeton_env` à `--jeton` : le chemin d'un jeton
|
|
en argument est refusé par certains garde-fous.
|
|
- L'`api` doit être en `https://`.
|
|
|
|
## Saisir
|
|
|
|
Chaque ligne affichée se saisit par un appel séparé, en-têtes passés par
|
|
stdin — **jamais le jeton dans la ligne de commande**, lisible par tous les
|
|
comptes de la machine (`/proc/<pid>/cmdline`) :
|
|
|
|
```
|
|
printf 'Authorization: token %s\nContent-Type: application/json\n' "$(cat <fichier du jeton>)" \
|
|
| curl -s -X POST -H @- -d '<ligne>' <adresse affichée par l'outil>
|
|
```
|
|
|
|
Le jeton est celui de l'instance que l'outil a interrogée.
|
|
|
|
Si l'outil échoue, on le signale : on ne saisit jamais une durée estimée à
|
|
la main.
|
|
|
|
## Tests
|
|
|
|
Hors ligne (transcript fabriqué, Gitea simulé, configurations jetables) :
|
|
|
|
```
|
|
python3 -I tests/test-temps-session.py
|
|
```
|
|
|
|
## Licence
|
|
|
|
GPL v3, voir `LICENSE`.
|