feat(dev_session): Add agent-driven Notion status reporting
Implements the functionality in , allowing the Gemini agent to non-interactively update a Notion task with a detailed progress summary. The agent can now be prompted to: - Collect the new task status and any open to-dos. - Generate a summary of Git changes () and commit messages. - Post a formatted report as a comment to the Notion task. - Update the task's status property. The has been updated to document this new agent-centric workflow, detailing how to start a session, work within it, and use the agent to report progress and push changes seamlessly.
This commit is contained in:
150
dev_session.py
150
dev_session.py
@@ -412,9 +412,152 @@ def select_task(token: str, project_id: str, tasks_db_id: str) -> Optional[Dict]
|
||||
print("Ungültige Eingabe. Bitte eine Zahl eingeben.")
|
||||
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
# --- Git Summary Generation ---
|
||||
|
||||
def generate_git_summary() -> Tuple[str, str]:
|
||||
"""Generiert eine Zusammenfassung der Git-Änderungen und Commit-Nachrichten seit dem letzten Push zum Main-Branch."""
|
||||
try:
|
||||
# Finde den aktuellen Main-Branch Namen (master oder main)
|
||||
try:
|
||||
main_branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode("utf-8").strip()
|
||||
if main_branch not in ["main", "master"]:
|
||||
# Versuche, den Remote-Tracking-Branch für main/master zu finden
|
||||
result = subprocess.run(["git", "branch", "-r"], capture_output=True, text=True)
|
||||
if "origin/main" in result.stdout:
|
||||
main_branch = "origin/main"
|
||||
elif "origin/master" in result.stdout:
|
||||
main_branch = "origin/master"
|
||||
else:
|
||||
print("Warnung: Konnte keinen 'main' oder 'master' Branch finden. Git-Zusammenfassung wird möglicherweise unvollständig sein.")
|
||||
main_branch = "HEAD~1" # Fallback zum letzten Commit, falls kein Main-Branch gefunden wird
|
||||
except subprocess.CalledProcessError:
|
||||
main_branch = "HEAD~1" # Fallback, falls gar kein Branch gefunden wird
|
||||
|
||||
# Git diff --stat
|
||||
diff_stat_cmd = ["git", "diff", "--stat", f"{main_branch}...HEAD"]
|
||||
diff_stat = subprocess.check_output(diff_stat_cmd).decode("utf-8").strip()
|
||||
|
||||
# Git log --pretty
|
||||
commit_log_cmd = ["git", "log", "--pretty=format:- %s", f"{main_branch}...HEAD"]
|
||||
commit_messages = subprocess.check_output(commit_log_cmd).decode("utf-8").strip()
|
||||
|
||||
return diff_stat, commit_messages
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ FEHLER beim Generieren der Git-Zusammenfassung: {e}")
|
||||
return "", ""
|
||||
|
||||
# --- Report Status to Notion ---
|
||||
|
||||
def report_status_to_notion(
|
||||
status_override: Optional[str],
|
||||
todos_override: Optional[str],
|
||||
git_changes_override: Optional[str],
|
||||
commit_messages_override: Optional[str]
|
||||
) -> None:
|
||||
"""
|
||||
Erstellt einen Statusbericht für den Notion-Task, entweder interaktiv oder mit überschriebenen Werten.
|
||||
"""
|
||||
if not os.path.exists(SESSION_FILE_PATH):
|
||||
print("❌ FEHLER: Keine aktive Session gefunden. Kann keinen Statusbericht erstellen.")
|
||||
return
|
||||
|
||||
try:
|
||||
with open(SESSION_FILE_PATH, "r") as f:
|
||||
session_data = json.load(f)
|
||||
task_id = session_data.get("task_id")
|
||||
token = session_data.get("token")
|
||||
|
||||
if not (task_id and token):
|
||||
print("❌ FEHLER: Session-Daten unvollständig. Kann keinen Statusbericht erstellen.")
|
||||
return
|
||||
|
||||
print(f"--- Erstelle Statusbericht für Task {task_id} ---")
|
||||
|
||||
# Git-Zusammenfassung generieren (immer, wenn nicht explizit überschrieben)
|
||||
actual_git_changes = git_changes_override
|
||||
actual_commit_messages = commit_messages_override
|
||||
if not git_changes_override or not commit_messages_override:
|
||||
print("Generiere Git-Zusammenfassung...")
|
||||
diff_stat, commit_log = generate_git_summary()
|
||||
if not git_changes_override:
|
||||
actual_git_changes = diff_stat
|
||||
if not commit_messages_override:
|
||||
actual_commit_messages = commit_log
|
||||
|
||||
# Status abfragen oder übernehmen
|
||||
actual_status = status_override
|
||||
if not actual_status:
|
||||
tasks_db_id = find_database_by_title(token, "Tasks [UT]")
|
||||
if tasks_db_id:
|
||||
status_options = get_database_status_options(token, tasks_db_id)
|
||||
if status_options:
|
||||
print("\nBitte wähle den neuen Status des Tasks:")
|
||||
for i, option in enumerate(status_options):
|
||||
print(f"[{i+1}] {option}")
|
||||
while True:
|
||||
try:
|
||||
choice = int(input("Wähle eine Nummer: "))
|
||||
if 1 <= choice <= len(status_options):
|
||||
actual_status = status_options[choice - 1]
|
||||
break
|
||||
else:
|
||||
print("Ungültige Auswahl.")
|
||||
except ValueError:
|
||||
print("Ungültige Eingabe. Bitte eine Zahl eingeben.")
|
||||
else:
|
||||
print("Warnung: Konnte Status-Optionen nicht abrufen. Bitte Status manuell eingeben.")
|
||||
actual_status = input("Bitte gib den neuen Status manuell ein: ")
|
||||
|
||||
if not actual_status:
|
||||
print("❌ FEHLER: Kein Status festgelegt. Abbruch des Berichts.")
|
||||
return
|
||||
|
||||
# To-Dos abfragen oder übernehmen
|
||||
actual_todos = todos_override
|
||||
if not actual_todos:
|
||||
user_todos = input("\nGibt es offene To-Dos oder nächste Schritte? (Leer lassen zum Überspringen): ")
|
||||
actual_todos = user_todos.strip()
|
||||
|
||||
# Kommentar zusammenstellen
|
||||
report_lines = []
|
||||
report_lines.append(f"**Status Update ({datetime.now().strftime('%Y-%m-%d %H:%M')})**")
|
||||
report_lines.append(f"**Neuer Status:** `{actual_status}`")
|
||||
|
||||
if actual_git_changes or actual_commit_messages:
|
||||
report_lines.append("\n**Zusammenfassung der Änderungen:**")
|
||||
if actual_git_changes:
|
||||
report_lines.append("```diff")
|
||||
report_lines.append(actual_git_changes)
|
||||
report_lines.append("```")
|
||||
if actual_commit_messages:
|
||||
report_lines.append("\n**Commit Nachrichten:**")
|
||||
report_lines.append("```")
|
||||
report_lines.append(actual_commit_messages)
|
||||
report_lines.append("```")
|
||||
|
||||
if actual_todos:
|
||||
report_lines.append("\n**Offene To-Dos / Nächste Schritte:**")
|
||||
# Sicherstellen, dass To-Dos als Liste oder einzelne Zeilen formatiert sind
|
||||
for todo_item in actual_todos.split('\n'):
|
||||
report_lines.append(f"- {todo_item.strip()}")
|
||||
|
||||
notion_comment = "\n".join(report_lines)
|
||||
|
||||
# Notion aktualisieren
|
||||
add_comment_to_notion_task(token, task_id, notion_comment)
|
||||
update_notion_task_status(token, task_id, actual_status)
|
||||
|
||||
except (FileNotFoundError, json.JSONDecodeError) as e:
|
||||
print(f"❌ FEHLER beim Lesen der Session-Informationen für Statusbericht: {e}")
|
||||
except Exception as e:
|
||||
print(f"❌ Unerwarteter Fehler beim Erstellen des Statusberichts: {e}")
|
||||
|
||||
|
||||
# --- Context Generation ---
|
||||
|
||||
|
||||
def generate_cli_context(project_title: str, task_title: str, task_id: str, readme_path: Optional[str], task_description: Optional[str]) -> str:
|
||||
"""Erstellt den reinen Kontext-String für die Gemini CLI."""
|
||||
|
||||
@@ -613,6 +756,11 @@ def main():
|
||||
parser = argparse.ArgumentParser(description="Interaktiver Session-Manager für die Gemini-Entwicklung mit Notion-Integration.")
|
||||
parser.add_argument("--done", action="store_true", help="Schließt die aktuelle Entwicklungs-Session ab.")
|
||||
parser.add_argument("--add-comment", type=str, help="Fügt einen Kommentar zum aktuellen Notion-Task hinzu.")
|
||||
parser.add_argument("--report-status", action="store_true", help="Erstellt einen Statusbericht für den Notion-Task.")
|
||||
parser.add_argument("--status", type=str, help="Status, der im Notion-Task gesetzt werden soll (z.B. 'In Bearbeitung', 'Bereit für Review').")
|
||||
parser.add_argument("--todos", type=str, help="Eine durch '\n' getrennte Liste offener To-Dos.")
|
||||
parser.add_argument("--git-changes", type=str, help="Zusammenfassung der Git-Änderungen (git diff --stat).")
|
||||
parser.add_argument("--commit-messages", type=str, help="Eine durch '\n' getrennte Liste der Commit-Nachrichten.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -634,6 +782,8 @@ def main():
|
||||
print("❌ FEHLER: Session-Daten unvollständig. Kann keinen Kommentar hinzufügen.")
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
print("❌ FEHLER: Fehler beim Lesen der Session-Informationen. Kann keinen Kommentar hinzufügen.")
|
||||
elif args.report_status:
|
||||
report_status_to_notion(args.status, args.todos, args.git_changes, args.commit_messages)
|
||||
else:
|
||||
start_interactive_session()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user