suivi-taches-automatique
Pour chaque demande utilisateur, créer une entrée dans le Google Sheet de suivi avec statuts (planifiée, en cours, terminée, abandonnée) et code couleur
Quand l'utiliser (Trigger)
Déclenchement standard selon le contexte de l'écosystème Hermès.
Mode d'emploi (Usage)
Mode d'emploi standard via l'agent Hermès. Suivi Automatique des Tâches
À charge pour chaque nouvelle demande utilisateur.
Prérequis
- Google Sheet maître :
1ApgDSz7ZjlMj_1WeRt7EFkLf_fVSxgsWRGBUTEF2dRw - Sheet nommé ”📋 Tableau de Bord — Suivi des Tâches & Projets”
- Onglets : Tâches, Projets, Stats
- Raccourci GAPI :
GAPI="python ~/.hermes/skills/productivity/google-workspace/scripts/google_api.py"
Workflow Obligatoire
Pour CHAQUE nouvelle tâche que l’utilisateur donne :
1. Créer l’entrée dans le Google Sheet
Lire d’abord l’onglet Tâches pour déterminer le prochain numéro et la liste existante :
# Lecture des tâches existantes (import google_api, build_service)
data = service.spreadsheets().values().get(
spreadsheetId=SHEET_ID, range="Tâches!A:J"
).execute()
rows = data.get('values', [])
next_num = len(rows) # après le header
existing_titles = {r[1].strip() for r in rows if len(r) >= 2}
Ajouter une ligne avec append API si le titre n’existe pas déjà.
Colonnes de l’onglet Tâches :
| Col | Champ | Valeur |
|---|---|---|
| A | # | Prochain numéro auto |
| B | Tâche | Nom de la tâche |
| C | Projet | Catégorie (DevOps, Emploi, Workflow, etc.) |
| D | Statut | Planifiée / En cours / Terminée / Abandonnée |
| E | Priorité | Haute / Moyenne / Basse |
| F | Date création | Aujourd’hui (YYYY-MM-DD) |
| G | Dernière MAJ | Aujourd’hui |
| H | Lien Vikunja | (facultatif — projet 19, buckets: Planifiée=55, En cours=56, Terminée=57, Abandonnée=62) |
| I | Tags | mots-clés séparés par virgule |
| J | Notes | Description ou contexte |
1b. Optionnel: Ajouter l’entrée dans Vikunja
Si Vikunja est accessible (https://vikunja.iatuto.com), synchroniser aussi la tâche dans le projet “Suivi des Tâches” (ID:19). Utiliser le JWT depuis le login API (curl, pas Python urllib — Cloudflare bloque SSL Python).
Méthode (via curl en subprocess):
import json, subprocess
# Login
r = subprocess.run(["curl","-sk",
"https://vikunja.iatuto.com/api/v1/login","-X","POST",
"-H","Content-Type: application/json",
"-d",'{"username":"hermes-agent","password":"DwzBo77RmVlf02Cg"}'],
capture_output=True, text=True, timeout=15)
token = json.loads(r.stdout)["token"]
# Create task - use PUT not POST, labels as objects not bare IDs
# IMPORTANT: avoid braces in f-strings for the auth header
# use %s or concat to prevent template interpretation
AUTH_HDR = "Authorization: Bearer %s" % token
cmd = ["curl","-sk",
"https://vikunja.iatuto.com/api/v1/projects/19/tasks","-X","PUT",
"-H","Content-Type: application/json",
"-H", AUTH_HDR,
"-d", json.dumps({
"title": task_title,
"description": desc,
"priority": priority,
"labels": [{"id": label_id}], # objects, not bare ints
"bucket_id": bucket_id # 55=Planifiee, 56=En cours, 57=Terminee
})]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
Config sauvegardée dans ~/.hermes/vikunja_config.json.
2. Appliquer le code couleur via batchUpdate
Obligatoire après chaque ajout ou modification de statut. Utiliser l’API
batchUpdate de Sheets (pas via google_api.py — il faut un appel direct) :
colors = {
"Terminée": {"red": 0.78, "green": 0.92, "blue": 0.78}, # vert pâle
"En cours": {"red": 0.85, "green": 0.91, "blue": 0.98}, # bleu pâle
"Planifiée": {"red": 1.0, "green": 0.96, "blue": 0.78}, # jaune pâle
"Abandonnée": {"red": 0.92, "green": 0.92, "blue": 0.92}, # gris pâle
}
# 1) Trouver l'ID de l'onglet "Tâches"
meta = service.spreadsheets().get(spreadsheetId=SHEET_ID).execute()
tasks_sheet_id = None
for s in meta['sheets']:
if s['properties']['title'] == 'Tâches':
tasks_sheet_id = s['properties']['sheetId']
# 2) Colorer la cellule de statut (colonne D, gras)
requests.append({
"repeatCell": {
"range": {"sheetId": tasks_sheet_id, "startRowIndex": row_idx,
"endRowIndex": row_idx + 1, "startColumnIndex": 3, "endColumnIndex": 4},
"cell": {"userEnteredFormat": {"backgroundColor": bg, "textFormat": {"bold": True}}},
"fields": "userEnteredFormat.backgroundColor,userEnteredFormat.textFormat.bold"
}
})
# 3) Colorer la ligne entière en version plus claire (optionnel mais recommandé)
light_bg = {k: v * 0.95 + 0.05 for k, v in bg.items()}
requests.append({
"repeatCell": {
"range": {"sheetId": tasks_sheet_id, "startRowIndex": row_idx,
"endRowIndex": row_idx + 1, "startColumnIndex": 0, "endColumnIndex": 10},
"cell": {"userEnteredFormat": {"backgroundColor": light_bg}},
"fields": "userEnteredFormat.backgroundColor"
}
})
# Envoyer par batch de 100 max
BATCH_SIZE = 100
for start in range(0, len(requests), BATCH_SIZE):
service.spreadsheets().batchUpdate(
spreadsheetId=SHEET_ID,
body={"requests": requests[start:start + BATCH_SIZE]}
).execute()
3. Mettre à jour les Stats
Toujours recalculer après chaque modification. Lire toutes les tâches et compter :
data = service.spreadsheets().values().get(
spreadsheetId=SHEET_ID, range="Tâches!D:D").execute()
rows = data.get('values', [])
by_status = {}
for r in rows[1:]:
s = r[0].strip() if r else '?'
by_status[s] = by_status.get(s, 0) + 1
stats = [
['Tâches totales', str(len(rows) - 1), today, ''],
['En cours', str(by_status.get('En cours', 0)), today, ''],
['Planifiées', str(by_status.get('Planifiée', 0)), today, ''],
['Terminées', str(by_status.get('Terminée', 0)), today, ''],
['Abandonnées', str(by_status.get('Abandonnée', 0)), today, ''],
['Projets actifs', '3', today, ''],
]
service.spreadsheets().values().update(
spreadsheetId=SHEET_ID, range="Stats!A2:D7",
valueInputOption='USER_ENTERED',
body={'values': stats}).execute()
4. Audit rétrospectif (import de tâches historiques)
Quand l’utilisateur demande un état des lieux complet, NE PAS se limiter aux tâches de la session en cours. Chercher dans l’historique des sessions avec session_search() pour identifier TOUTES les tâches passées, puis les ajouter au Sheet si absentes avec leur statut réel (En cours / Terminée / Abandonnée). Ne pas deviner — vérifier chaque statut en fonction du contexte réel.
5. Mettre à jour le Todo interne (Hermes)
Utiliser le tool todo() pour suivre l’avancement en temps réel dans la session.
Codes Statut & Couleurs
| Statut | Couleur | Emoji | Signification |
|---|---|---|---|
| Planifiée | 🟡 Jaune | 📋 | Identifiée, pas démarrée |
| En cours | 🔵 Bleu | 🔧 | Travail actif |
| Terminée | 🟢 Vert | ✅ | Complétée |
| Abandonnée | ⚪ Gris | 🗑️ | Annulée ou remplacée |
Pitfalls
- Ne pas ajouter deux fois la même tâche — lire existing_titles avant append.
- Ne pas oublier les stats — toujours recalculer après ajout/suppression.
- Code couleur post-ajout — l’append seul ne colore pas. Faire batchUpdate après.
- Vikunja via curl, pas Python urllib — Vikunja derrière Cloudflare, Python SSL
handshake timeoute. Toujours utiliser
subprocess.run(["curl",...])depuis Python. - batchUpdate limit 100 — diviser les requêtes par batch de 100 max.
- Vikunja labels = objets pas entiers —
{"labels": [{"id": 15}]}pas[15]. - Vikunja PUT pas POST — création tâche via
-X PUTpas-X POST. - Jamais {token} ou {jwt} dans les strings Python — les write_file les interprète comme templates. Utiliser
AUTH_HDR=*** Bearer %s" % tokou concat simple.
Références
references/color-coding-sheet.md— API calls complètes pour batchUpdate (repeatCell, backgroundColor)references/vikunja-token-format.md— Structure des tokens hashés Vikunja + limitations API- Voir skill
google-workspacepour l’API Google Sheets générique - Voir skill
claude-codesection “Usage as Fallback for Failed Hermes Tasks” pour utiliser Claude Code en fallback quand les outils Hermes échouent
Absorbed: Personal Organizer
references/personal-organizer.md — Monstre Organisateur: personal task management for users mentioning tasks, ideas, planning, overwhelm, procrastination, reminders, or daily priorities. Previously a standalone skill (personal-organizer).