diff --git a/app/briefing.py b/app/briefing.py
index 6adafd5..27b04af 100644
--- a/app/briefing.py
+++ b/app/briefing.py
@@ -16,6 +16,43 @@ def ntfy_configured(settings: Settings) -> bool:
return bool(settings.ntfy_url and settings.ntfy_topic)
+def format_standup_text(data: dict) -> str:
+ """Automatic standup (issue #6): yesterday / today / blockers."""
+ lines = [f"🗣️ Standup — {data['today_label']}"]
+ closed = data["closed_yesterday"]
+ lines.append(
+ f"\n✅ Hier ({data['yesterday_label']}) : {len(closed)} fermée(s), "
+ f"{data['moved_yesterday']} déplacement(s)"
+ )
+ for item in closed[:8]:
+ lines.append(
+ f" • {item['repo']} #{item['number']} « {item['title']} »"
+ )
+ lines.append("\n📌 Aujourd'hui :")
+ if data["picks"]:
+ for pick in data["picks"]:
+ lines.append(
+ f" • {pick['repo']} #{pick['number']} « {pick['title']} »"
+ f" — {pick['column_label']}"
+ )
+ elif data["focus_titles"]:
+ for title in data["focus_titles"][:5]:
+ lines.append(f" • {title}")
+ lines.append(" (aucun focus épinglé — pense à /today)")
+ else:
+ lines.append(" • Rien en cours. Journée libre ou triage à faire !")
+ lines.append("\n🚧 Blocages :")
+ if data["blockers"]:
+ for card in data["blockers"][:6]:
+ lines.append(
+ f" • {card['repo']} #{card['number']} « {card['title']} »"
+ f" — {card['days']} j en {card['column_label']}"
+ )
+ else:
+ lines.append(" • Aucun blocage signalé. ✨")
+ return "\n".join(lines)
+
+
def format_briefing_text(data: dict) -> str:
"""Plain-text briefing (ntfy body, also shown on /briefing)."""
lines: list[str] = [f"📋 Kanbante — briefing du {data['date']}"]
@@ -67,6 +104,8 @@ def format_briefing_text(data: dict) -> str:
if data["focus_total"] == 0 and not data["aging"]:
lines.append("\n🎉 Rien d'urgent : aucun encours, aucune carte vieillissante.")
+ if data.get("standup"):
+ lines.append("\n" + data["standup"])
return "\n".join(lines)
diff --git a/app/config.py b/app/config.py
index 933c21a..719d56f 100644
--- a/app/config.py
+++ b/app/config.py
@@ -68,6 +68,16 @@ Environment variables:
KANBANTE_OBSIGATE_MCP_ARGS JSON argument template for the tool;
"{title}" and "{content}" placeholders
are substituted (JSON-escaped).
+ KANBANTE_BRIEFING_INCLUDE_STANDUP
+ "1" appends the automatic standup
+ (issue #6) to the morning briefing.
+ KANBANTE_RULES Automation rules (issue #8) as a JSON
+ array: [{"name": ..., "when":
+ {"column": "review", "min_age_days": 3},
+ "then": {"notify": true}}]. Conditions:
+ column, min_age_days, label, wip_over.
+ Actions: add_label, notify, move_top.
+ A rule can never close an issue.
"""
import os
@@ -76,7 +86,7 @@ from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
-APP_VERSION = "0.12.0"
+APP_VERSION = "0.13.0"
def _env_bool(name: str, default: bool) -> bool:
@@ -142,6 +152,8 @@ class Settings:
obsigate_mcp_token: str = ""
obsigate_mcp_tool: str = ""
obsigate_mcp_args: str = '{"title": "{title}", "content": "{content}"}'
+ briefing_include_standup: bool = False
+ rules_raw: str = ""
@property
def auth_enabled(self) -> bool:
@@ -184,4 +196,6 @@ def get_settings() -> Settings:
"KANBANTE_OBSIGATE_MCP_ARGS",
'{"title": "{title}", "content": "{content}"}',
),
+ briefing_include_standup=_env_bool("KANBANTE_BRIEFING_INCLUDE_STANDUP", False),
+ rules_raw=os.getenv("KANBANTE_RULES", ""),
)
diff --git a/app/templates/activity.html b/app/templates/activity.html
index 8b296ef..844ca5f 100644
--- a/app/templates/activity.html
+++ b/app/templates/activity.html
@@ -20,10 +20,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/briefing.html b/app/templates/briefing.html
index 76596c9..6d04274 100644
--- a/app/templates/briefing.html
+++ b/app/templates/briefing.html
@@ -24,6 +24,7 @@
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/capture.html b/app/templates/capture.html
index 2462122..ecb9f54 100644
--- a/app/templates/capture.html
+++ b/app/templates/capture.html
@@ -17,10 +17,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html
index 68f1162..fd8f73b 100644
--- a/app/templates/dashboard.html
+++ b/app/templates/dashboard.html
@@ -20,10 +20,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/digest.html b/app/templates/digest.html
index 618081f..c724c74 100644
--- a/app/templates/digest.html
+++ b/app/templates/digest.html
@@ -17,6 +17,7 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
diff --git a/app/templates/focus.html b/app/templates/focus.html
index 4aebec2..dd17d52 100644
--- a/app/templates/focus.html
+++ b/app/templates/focus.html
@@ -19,10 +19,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
{{ groups|map(attribute='cards')|map('length')|sum }} cartes en cours
diff --git a/app/templates/forecast.html b/app/templates/forecast.html
index 3d7b173..7545bc6 100644
--- a/app/templates/forecast.html
+++ b/app/templates/forecast.html
@@ -17,6 +17,7 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
diff --git a/app/templates/my.html b/app/templates/my.html
index c464672..346534c 100644
--- a/app/templates/my.html
+++ b/app/templates/my.html
@@ -23,6 +23,7 @@
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/search.html b/app/templates/search.html
index 9698b01..3796f4a 100644
--- a/app/templates/search.html
+++ b/app/templates/search.html
@@ -23,6 +23,7 @@
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/sprint.html b/app/templates/sprint.html
index 7e3332c..87d38bd 100644
--- a/app/templates/sprint.html
+++ b/app/templates/sprint.html
@@ -16,6 +16,7 @@
📋 Board
🌅 Aujourd'hui
🔮 Prévisions
+ ⚙️ Règles
diff --git a/app/templates/standup.html b/app/templates/standup.html
new file mode 100644
index 0000000..4725668
--- /dev/null
+++ b/app/templates/standup.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+ Standup — Kanbante
+
+
+
+
+
+
+
+ 🗣️ Standup automatique
+ Écrit par le journal, pas par la mémoire : fermé/déplacé hier, focus aujourd'hui, cartes qui vieillissent en QA/Révision en blocages.
+
+
+ {% if include_in_briefing %}
+ Inclus dans le briefing ntfy du matin ✔
+ {% else %}
+ Astuce : KANBANTE_BRIEFING_INCLUDE_STANDUP=1 l'ajoute au briefing ntfy du matin.
+ {% endif %}
+
+
+
+
+
+ {% include "_palette.html" %}
+
+
+
+
diff --git a/app/templates/today.html b/app/templates/today.html
index 08ee5ab..c304d01 100644
--- a/app/templates/today.html
+++ b/app/templates/today.html
@@ -17,10 +17,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/app/templates/triage.html b/app/templates/triage.html
index 54208e0..8182e32 100644
--- a/app/templates/triage.html
+++ b/app/templates/triage.html
@@ -17,10 +17,12 @@
👤 Mes issues
📰 Activité
📊 Briefing
+ 🗣️ Standup
🔍 Recherche
⚡ Capture
🧠 Digest
🔮 Prévisions
+ ⚙️ Règles
🖥️ Wallboard
diff --git a/static/js/palette.js b/static/js/palette.js
index cb7cc12..8370613 100644
--- a/static/js/palette.js
+++ b/static/js/palette.js
@@ -15,6 +15,8 @@
{ icon: '🎯', label: 'Focus — en cours, QA, révision', href: '/focus' },
{ icon: '🌅', label: "Focus du jour — les 3 cartes d'aujourd'hui", href: '/today' },
{ icon: '🔮', label: 'Prévisions — on finit quand ?', href: '/forecast' },
+ { icon: '🗣️', label: 'Standup automatique — hier, aujourd\'hui, blocages', href: '/standup' },
+ { icon: '⚙️', label: 'Règles d\'automatisation', href: '/rules' },
{ icon: '👤', label: 'Mes issues', href: '/my' },
{ icon: '📰', label: 'Activité — journal des événements', href: '/activity' },
{ icon: '📊', label: 'Briefing quotidien', href: '/briefing' },