Commit Graph
47 Commits
Author SHA1 Message Date
Spark ba47b1a9ac feat(projets): page Projet /project/{owner}/{repo} (#25)
Accueil du projet assemblé des briques existantes: jalons
ouverts (progression, échéances, ETA), santé en résumé, débit,
activité récente du journal, notes; actions board/capture/
triage/santé/wallboard/Gitea. Le titre des cartes y pointe.
2026-10-11 22:52:22 -04:00
Spark cf58bb9d0c feat(projets): épinglés par étoiles Gitea (#20)
list_starred/set_starred sur /user/starred (vérité dans la
forge), endpoint POST /api/projects/{o}/{r}/star (CSRF), section
Épinglés hors onglets, bouton étoile sur les cartes et bascule
sans rechargement; les épinglés sortent de leur grille d'onglet.
2026-10-11 22:52:22 -04:00
Spark b33b67fcb4 feat(dashboard): prochain jalon et pastille de santé sur les cartes (#17, #18)
Bloc jalon (progression Gitea, échéance FR, retard, ETA journal
avec signal après-échéance — mêmes définitions que le bandeau
du board) et point santé vert/orange/rouge dérivé de
_project_health, info-bulle et lien vers /health du projet.
2026-10-11 22:52:22 -04:00
Spark b4dc8f0d4f chore(release): Kanbante 0.16.1 — icône palette et accordéons du menu
CI / test (push) Successful in 1m50s
2026-10-11 21:12:09 -04:00
Spark 2290560627 feat(nav): palette en icône près du titre, sections accordéon (retour #16)
Le bouton Recherche & commandes devient une icône 🔍 seule à
droite du titre (sous le logo en rail replié). Les groupes
deviennent des accordéons: chevron animé, transition douce,
sections fermées mémorisées (appliquées avant le rendu), section
de la page courante toujours ouverte; rail replié = icônes.
2026-10-11 21:12:09 -04:00
Spark d4b3b324f5 chore(release): Kanbante 0.16.0 — layout barre latérale et wallboard verrouillé
CI / test (push) Successful in 1m46s
2026-10-11 20:48:46 -04:00
Spark ec3590d25f feat(wall): hauteur verrouillée 100dvh, pied toujours visible
La diapositive ne grandit plus au-delà de l'écran: plus de barre
de défilement de page, « Ouvertes »/« Fermées »/« EN DIRECT »
toujours affichés au-dessus de la navigation des diapos; cartes
tronquées en fondu + ligne « +N autres cartes en vol »; mode
compact sous 760px de hauteur (TV 720p).
2026-10-11 20:48:46 -04:00
Spark 16f03184bf feat(nav): refonte du layout — barre latérale repliable, topbar mince (issue #16)
Retour de Bruno sur la 0.15.0 (disposition pas conviviale, trop
de place, mobile inchangé): la barre horizontale disparaît.
Barre latérale groupée (Principal/Rituels/Pilotage/Outils),
repliable en rail d'icônes mémorisé sur desktop, tiroir
hors-canvas sur mobile; topbar de 52px (fil d'Ariane + actions).
2026-10-11 20:48:46 -04:00
Spark 6fdf39959c chore(release): Kanbante 0.15.0 — header unifié desktop/mobile
CI / test (push) Successful in 1m54s
2026-10-11 20:15:23 -04:00
Spark 58204e621e fix(forecast): semaines calées sur le référentiel UTC du journal
Les horodatages board_events sont en UTC (SQLite): une fermeture
en soirée locale tombait hors des semaines locales et faussait
le débit hebdomadaire.
2026-10-11 20:15:23 -04:00
Spark 2fde103e93 feat(nav): header unifié desktop/mobile (issue #16)
Partiel _header.html unique pour les 19 pages (fin des copies qui
dérivaient): desktop une ligne — primaires + menu Plus + Ctrl K,
page active déduite du gabarit dans render(); mobile ≤900px
burger + panneau ≥44px, Échap/clic extérieur; wallboard sans
header et triage sur le même partiel. nav.js partagé.
2026-10-11 20:15:23 -04:00
Spark 24a1ebb9a6 chore(release): Kanbante 0.14.0 — branche depuis la carte, santé du flux
CI / test (push) Successful in 1m49s
2026-10-11 14:49:38 -04:00
Spark 6453b53df4 feat(health): santé du flux — goulots et cartes zombies (issue #9)
app/flow.py: séjours par colonne reconstruits du journal,
médianes, colonne la plus lente; zombies = aucune activité
(journal/Gitea) depuis KANBANTE_ZOMBIE_DAYS (30). Pages /health
et /health/{o}/{r} + actions rapides (commenter/backlog/fermer).
2026-10-11 14:49:38 -04:00
Spark 1932d11457 feat(branch): créer la branche depuis la carte (issue #3)
slugify + branch_name_for (issue-<n>-<slug>, reconnu par #1/#2);
client create_branch; POST /api/issues/{o}/{r}/{n}/branch (nom
libre validé, idempotent si existante); la carte passe en En
cours, journalisée source branch, étiquette synchronisée;
formulaire dans la section Code lié du panneau détail.
2026-10-11 14:49:38 -04:00
Spark 5b41c5ea74 chore(release): Kanbante 0.13.0 — code lié, PR fusionnée, standup, règles
CI / test (push) Successful in 1m43s
2026-10-11 14:21:11 -04:00
Spark 7eef8bb604 feat(rules): règles d'automatisation déclaratives (issue #8)
KANBANTE_RULES (JSON validé): conditions colonne/âge/étiquette/
WIP -> add_label / notify (garde quotidienne) / move_top;
évaluation 15 min + POST /api/rules/run; actions journalisées
(événement rule); page /rules. Aucune fermeture possible.
2026-10-11 14:21:11 -04:00
Spark 0b48026752 feat(standup): standup automatique hier/aujourd'hui/blocages (issue #6)
format_standup_text + _standup_data (journal de la veille, focus
du jour, vieillissantes QA/Révision); page /standup copiable,
/api/standup; inclusion optionnelle au briefing ntfy
(KANBANTE_BRIEFING_INCLUDE_STANDUP).
2026-10-11 14:21:11 -04:00
Spark 675ce09083 feat(code): cartes liées au code — branches, PRs, commits (issue #1)
app/code_links.py: appariement pur (#n dans titres/corps/messages,
numéro en jeton de branche). Client: list_branches/list_pulls/
list_commits. Badge sur les cartes (board + fragments live),
section Code lié du panneau détail, /api/issues/{o}/{r}/{n}/code.
2026-10-11 14:21:11 -04:00
Spark 03fa1eb44e chore(release): Kanbante 0.12.0 — focus du jour, prévisions, récit de sprint
CI / test (push) Successful in 1m43s
2026-10-11 13:55:03 -04:00
Spark 4c5d1dee23 feat(sprint): récit de sprint généré par le journal (issue #4)
app/sprint.py + /sprint/{o}/{r} (rendu markdown, copier/télécharger)
+ /api/sprint en JSON: livré avec temps de cycle, plus lentes,
reporté, chiffres de période. Lien depuis le bandeau milestone.
Navigation: pilules Aujourd'hui/Prévisions et actions palette.
2026-10-11 13:55:03 -04:00
Spark cdabc77ccd feat(forecast): prévisions au débit réel du journal (issue #7)
app/forecast.py: fermetures hebdo (8 sem.), débit moy/min/max sur
4 semaines complètes, ETA en fourchette, silence sans historique.
Dashboard (épuisement du backlog), bandeau milestone (alerte
échéance), page /forecast (sparkline SVG, verdicts), /api/metrics
étendu (weekly_closures, throughput_4w).
2026-10-11 13:55:03 -04:00
Spark fbe58bbf16 feat(today): focus du jour — le rituel des 3 cartes (issue #5)
Table today_picks; POST /api/today/pin (max 3, idempotent) et
/unpin; page /today (picks en direct, candidates de l'encours,
reprises d'hier, récap du jour depuis le journal); bouton 📌 sur
les cartes (délégation capture dans today.js, fragments live
compris); sections dédiées dans le briefing du matin.
2026-10-11 13:55:03 -04:00
Spark 6b9ec1ff99 chore(release): Kanbante 0.11.0 — wallboard navigable
CI / test (push) Successful in 1m42s
2026-10-11 13:37:54 -04:00
Spark 715687da66 feat(wall): navigation manuelle (flèches, boutons, pastilles) + position mémorisée + fix SSE
←/→ et contrôles à l'écran changent de projet; navigation manuelle
= pause de rotation 90 s; Espace = pause franche avec badge. La
position survit aux rechargements via sessionStorage (le cycle de
12 projets x 30 s dépassait le refresh de sécurité de 5 min: le
mur semblait figé). Fix: l'écoute SSE utilisait onmessage, inerte
pour les événements nommés 'gitea' du hub.
2026-10-11 13:37:54 -04:00
Spark 2bc8ccaf4f chore(release): Kanbante 0.10.0 — mode Triage
CI / test (push) Successful in 1m43s
2026-10-11 13:17:21 -04:00
Spark 8a32d080b5 feat(triage): mode triage — vider le backlog au clavier (issue #11)
/triage (sélecteur par taille de backlog) + /triage/{o}/{r}
(session plein cadre, file embarquée): 1-5 colonnes, X fermer,
L étiquettes, A s'assigner (nouvel endpoint assign-self +
client.set_issue_assignees, idempotent), Entrée suivante, Z annuler.
Progression + résumé de session; décisions via /api/move et les
API existantes. Entrées: board + palette.
2026-10-11 13:17:21 -04:00
Spark 25040f974c chore(release): Kanbante 0.9.0 — board dynamique
CI / test (push) Successful in 1m42s
2026-10-11 12:59:54 -04:00
Spark 1088dd0b48 feat(live): board dynamique sans refresh (issue #15)
Diffusion SSE sur toutes les mutations (move, création, capture,
étiquettes) via _publish_board_changed; GET /api/board/{o}/{r}
(fragments _card.html rendus serveur, même pipeline que la page);
board-live.js: diff en place par colonne avec animation FLIP,
application différée pendant un drag, filtres/compteurs réappliqués,
repli par sondage 45 s sans webhooks. Carte extraite en partiel
_card.html partagé page/API.
2026-10-11 12:59:54 -04:00
Spark 6e71b87d09 feat(digest): digest hebdo vers ObsiGate via MCP, sur approbation (issue #13)
app/digest.py: format markdown (journal 7 j + focus), client MCP
(initialize/tools/list/tools/call, réponses JSON ou SSE), gabarit
d'arguments JSON configurable, webhook générique. Page /digest:
statut, sonde des outils, envoi en un clic. Planificateur: compose
+ notifie (kv digest_pending), ne livre JAMAIS seul.
2026-10-11 12:46:54 -04:00
Spark 0417d0593f feat(palette): palette de commandes Ctrl+K sur toutes les pages (issue #10)
GET /api/palette: projets (filtrage local) + recherche globale
d'issues annotées de leur colonne. Composant partagé _palette.html
+ palette.js (actions, projets, issues; ↑↓/Entrée/Échap; bouton
⌨️ dans la navigation). Aucune librairie ajoutée.
2026-10-11 12:46:54 -04:00
Spark 0c280b3c7e feat(capture): page /capture (formulaire, statut, exemples) + navigation 2026-10-11 12:40:32 -04:00
Spark 395ab6e14c feat(capture): capture éclair — API à jeton dédié + écoute ntfy (issue #12)
POST /api/capture (X-Capture-Token ou Bearer; 503 si non configuré;
exempté Basic Auth/CSRF car machine-à-machine), JSON ou texte libre
(1re ligne = titre), dépôt par défaut KANBANTE_CAPTURE_REPO.
Module app/capture.py: parsing partagé + abonné ntfy en tâche de
fond (reconnexion, curseur kv_store anti-rejeu, tag 'kanban'...
'kanbante' ignoré). _do_capture commun: issue créée, carte placée,
événement 'created' source 'capture'.
2026-10-11 12:40:31 -04:00
Spark 05b8c506e0 chore(release): Kanbante 0.6.0 — colonne QA, réconciliation par étiquettes, Wallboard
CI / test (push) Successful in 1m42s
2026-10-11 12:26:12 -04:00
Spark af59417d07 feat(wall): Wallboard plein écran /wall — issue #14 de la feuille de route
Rotation automatique entre projets actifs (30 s), compteurs des
six colonnes, cartes en vol avec âge, fermées du jour (journal),
horloge; rafraîchissement en direct par le flux SSE (rechargement,
aucune interaction à protéger) + filet de sécurité à 5 min.
?repo= fige un projet. Lien de navigation ajouté partout.
2026-10-11 12:26:12 -04:00
Spark a358c45d73 feat(colonnes): colonne QA entre En cours et Révision + réconciliation par étiquettes
- KANBAN_COLUMNS gagne 'qa' (🧪, #06b6d4, étiquette kanban:qa);
  Focus inclut QA; dashboard et board affichent les 6 colonnes.
- _adopt_label_columns: une étiquette kanban:* unique qui diverge
  de l'état local fait adopter sa colonne (board + focus), avec
  événement journalisé source 'gitea'. C'est ce qui permet de
  piloter le board depuis Gitea même.
2026-10-11 12:26:12 -04:00
Spark b7ddc10971 chore(release): Kanbante 0.5.2 — correctif indice de colonne vide
CI / test (push) Successful in 1m41s
2026-10-11 12:08:28 -04:00
Spark 52c41ead91 chore(release): Kanbante 0.5.1 — correctif boards vides contre vrai Gitea
CI / test (push) Successful in 1m41s
2026-10-11 11:42:23 -04:00
Spark 71881514c9 fix(board): les issues réelles Gitea n'étaient pas des PR — boards vides
Gitea 1.27.3 renvoie "pull_request": null sur les issues ordinaires:
_is_issue testait la présence de la clé et classait chaque vraie
issue comme un pull request. Board, Focus et briefing affichaient
zéro carte contre un vrai Gitea (le dashboard, basé sur les
compteurs de dépôts, semblait normal, d'où le signalement
« la nouvelle issue n'apparaît pas »). Le filtre teste maintenant
la valeur. Vérifié en réel: board bruno/flowdeck 0 -> 6 cartes.
2026-10-11 11:42:23 -04:00
Spark 6887d631ea feat(board): étiquettes gérables, notes repliable/redimensionnable/auto-save
- modale Étiquettes: liste, création (nom + couleur + palette),
  suppression via DELETE (CSRF par en-tête); panneau détail:
  bascules d'étiquettes par issue avec mise à jour immédiate des
  chips de la carte; _issue_payload expose les ids d'étiquettes
- API étiquettes dans main (routes repos + toggle issue)
- notes: bouton replier/déplier et largeur par glisser, persistés
  par projet (localStorage), sauvegarde automatique débouncée
  avec statut, formulaire repris par board.js (HTMX retiré du board)
- nouvelles pages search/my/briefing; navigation enrichie partout
  (Mes issues, Briefing, Recherche); CSS associé
2026-10-11 11:00:53 -04:00
Spark a788db7b1f feat(palier-3): recherche globale, mes issues, briefing ntfy, MCP lecture
- client: search_issues (/repos/issues/search, type=issues,
  assigned_by), delete_label + forget_label_cache; models: kv_store
- /search groupe par projet avec colonne Kanban; /my = issues
  ouvertes assignées à l'utilisateur du jeton (get_user)
- briefing: _briefing_data (focus, âgées, milestones <= 7 j,
  activité journal), page /briefing, /api/briefing, envoi ntfy
  manuel + planificateur lifespan à KANBANTE_BRIEFING_TIME
  (kv briefing_last_sent, pas de doublon); app/briefing.py =
  format texte + envoi ntfy (en-têtes ASCII)
- MCP: POST /mcp JSON-RPC (initialize, tools/list, tools/call,
  ping, notifications 202), 7 outils en lecture seule, GET /mcp
  de découverte; erreurs -32601/-32700, isError pour les outils
- focus refactoré en _collect_focus_groups réutilisé par le
  briefing et l'outil MCP get_focus
2026-10-11 11:00:53 -04:00
Spark dbda3bcf5a refonte(ui): design system moderne et intuitif sur les 5 pages
- en-tête vitré sticky, navigation en pastilles avec état actif,
  logo en tuile dégradée, fil d'Ariane projet
- dashboard: hero + tuiles de synthèse (actifs, fermées/déplacements
  30 j, cycle moyen), barre de progression par projet, états vides
  guidés, raccourci clavier /
- board: sélecteur de milestones + bandeau de progression, colonnes
  à défilement indépendant, placeholders de colonnes vides, hint
  sur le panneau de notes, toast et drawer animés
- live.js: recharge douce conditionnelle (visible, pas de drawer,
  pas de saisie, pas de drag) sinon pastille d'actualisation
- accessibilité: anneau de focus visible, prefers-reduced-motion,
  responsive retravaillé; board.js: drapeau de drag partagé avec
  live.js + raccourci / vers le filtre
2026-10-11 10:23:50 -04:00
Spark 23e63c7f6e feat(palier-2): webhooks Gitea signés, flux SSE, étiquettes, milestones
- POST /webhooks/gitea: HMAC-SHA256 si KANBANTE_WEBHOOK_SECRET,
  applique fermetures/réouvertures externes de façon idempotente
  (l'écho de nos propres appels est un no-op, journal source=webhook),
  invalide le cache, diffuse sur le hub SSE
- GET /api/stream (SSE) + LiveHub; générateur testable séparément
- synchro d'étiquettes kanban:* à chaque déplacement (ensure/add/
  remove granulaires, étiquettes utilisateur intactes, flag
  KANBANTE_SYNC_LABELS, échec rapporté label_sync sans casser le move)
- board ?milestone=<titre|id>: filtre, échéance, progression;
  client: get_milestones, labels, invalidate_cache public
- dashboard: métriques 30 j du journal exposées au template
2026-10-11 10:23:50 -04:00
Spark 9bf24da04e feat(frontend): panneau détail de carte, badges d'âge, limites WIP
- drawer de détail: corps markdown rendu (marked + DOMPurify
  vendorés), commentaires, formulaire de commentaire vers Gitea;
  clic distingué du drag par la distance du pointeur
- badges ⏳ N j au-delà du seuil d'âge (rouge au double)
- en-têtes de colonnes: n/limite, classe .over en rouge, toast
  d'avertissement au dépôt dans une colonne saturée
- page activity.html, liens Activité dans dashboard et board
2026-10-11 10:05:51 -04:00
Spark a6d2ed9eae feat(palier-1): journal d'événements, détail d'issue, vieillissement, WIP
- board_events append-only + log_event/get_events/column_entry_times/
  get_metrics (débit, temps de cycle); journalisation des moves,
  créations, fermetures/rouvertures (UI et réconciliation Gitea),
  commentaires; un reclassement intra-colonne ne journalise pas
- client Gitea: get_issue, get_issue_comments (paginés), create_comment
- API: GET /api/issues/{o}/{r}/{n} (404 propre), POST .../comments,
  GET /api/events, GET /api/metrics, page /activity
- config: KANBANTE_WIP_LIMITS (colonne:limite) et KANBANTE_AGING_DAYS;
  le board calcule le temps en colonne (journal, replis updated_at
  puis création de l'issue)
- reconcile_board_state retourne aussi les numéros fermés/purgés
2026-10-11 10:05:51 -04:00
Spark 9ae961f50f feat(frontend): filtres, création d'issues, vue Focus, CDN vendorés
- vendor: HTMX/Alpine/SortableJS servis depuis /static/vendor (M3)
- board.js: jeton CSRF, ordres source/destination envoyés, carte
  replacée + toast rouge en cas d'échec (M8), filtres texte/étiquette,
  formulaire de création d'issue
- dashboard: 3 onglets Actifs/Inactifs/Archivés, recherche via
  data-search échappé au lieu d'une interpolation JS (M9)
- board: cartes liées vers l'issue Gitea, méta CSRF, notes protégées
- nouvelles pages focus.html et error.html
- CSS: fond des badges en color-mix, l'ancien var(--accent)20 était
  invalide (M1); styles toolbar/focus/erreur/toast erreur
2026-10-11 09:31:48 -04:00
Spark d267df01fa fix(backend): consolidation 0.2.0 — config, DB_PATH, async, pagination, auth, synchro bidirectionnelle
- config.py: réglages centralisés par variables d'environnement
- models: KANBANTE_DB_PATH enfin honorée (C1), migrations idempotentes
  (position, notes.updated_at, nettoyage colonnes inconnues — I4),
  ordre des cartes persisté (M5), réconciliation avec Gitea
- gitea_client: httpx asynchrone, pagination complète (I2, plafond
  serveur de 50), uid résolu via /user, en-tête Authorization seulement
  si jeton, cache court, create_issue / set_issue_state, .env racine
- main: lifespan au lieu de on_event (M4), Basic Auth optionnelle +
  CSRF double-submit (C2), write-back done<->fermé (C3), classification
  par fenêtre glissante + drapeau archived (I1), erreurs Gitea en 502
  propre (I5), /api/readiness réel, PR exclues du board (M6),
  codes HTTP explicites et limite de taille des notes (M7)
2026-10-11 09:31:48 -04:00
bruno 3732b5cb45 feat: Kanbante v0.1.0 — Kanban Git-integrated PM tool
- Dashboard with all Gitea projects (active/archived)
- Kanban board per project (Backlog → À faire → En cours → Révision → Terminé)
- Drag & drop issues between columns (SortableJS)
- Project notes panel
- Gitea API integration (read issues, repos)
- SQLite local state for board positions
- Dark theme design system
- Docker-ready (Dockerfile + docker-compose.yml)
- FastAPI + Jinja2 + HTMX + Alpine.js stack
2026-07-07 23:24:15 -04:00