"""Tool: Project Registry – Projekt-Registrierung, Status-Tracking und Historien-Snapshots.""" import json from helpers.tool import Tool, Response from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError from usr.plugins.a0_software_orchestrator.helpers.db_state_store import ( list_projects, get_project_detail, register_project, update_project_state, create_project_snapshot, list_project_snapshots, remove_project, ) class ProjectRegistry(Tool): """Tool for managing software project entries in the plugin's project database.""" async def execute( self, action: str = "list", name: str = "", git_url: str = "", description: str = "", tech_stack: str = "", status: str = "", phase: str = "", plan_mode: str = "", total_tasks: int = 0, completed_tasks: int = 0, open_errors: int = 0, trigger: str = "", commit_hash: str = "", **kwargs ): try: if action == "list": projects = list_projects() return Response( message=json.dumps(projects, indent=2, ensure_ascii=False), break_loop=False ) elif action == "detail": if not name: return Response(message="Missing 'name' for detail action", break_loop=False) detail = get_project_detail(name) if not detail: return Response(message=f"Project '{name}' not found.", break_loop=False) return Response( message=json.dumps(detail, indent=2, ensure_ascii=False), break_loop=False ) elif action == "register": if not name: return Response(message="Missing 'name' for register action", break_loop=False) if not git_url: return Response(message="Missing 'git_url' for register action", break_loop=False) project_id = register_project( name=name, git_url=git_url, description=description, tech_stack=tech_stack or "{}", status=status or "active", phase=phase or "intake" ) return Response( message=f"Project '{name}' registered successfully (id={project_id}, git_url={git_url}).", break_loop=False ) elif action == "update": if not name: return Response(message="Missing 'name' for update action", break_loop=False) fields = {} for field in ["status", "phase", "plan_mode"]: val = kwargs.get(field, "") if val: fields[field] = val for field in ["total_tasks", "completed_tasks", "open_errors"]: val = kwargs.get(field) if val is not None: fields[field] = int(val) if "last_active_at" in kwargs: fields["last_active_at"] = kwargs["last_active_at"] if "completed_at" in kwargs: fields["completed_at"] = kwargs["completed_at"] if not fields: return Response(message="No fields to update.", break_loop=False) update_project_state(name, **fields) return Response( message=f"Project '{name}' updated.", break_loop=False ) elif action == "snapshot": if not name: return Response(message="Missing 'name' for snapshot action", break_loop=False) snapshot_id = create_project_snapshot( name=name, trigger=trigger or "manual", commit_hash=commit_hash or "" ) return Response( message=f"Snapshot saved for project '{name}' (trigger: {trigger or 'manual'}).", break_loop=False ) elif action == "history": if not name: return Response(message="Missing 'name' for history action", break_loop=False) snapshots = list_project_snapshots(name) return Response( message=json.dumps(snapshots, indent=2, ensure_ascii=False), break_loop=False ) elif action == "remove": if not name: return Response(message="Missing 'name' for remove action", break_loop=False) remove_project(name) return Response( message=f"Project '{name}' removed from registry (snapshots also deleted).", break_loop=False ) else: supported = ["list", "detail", "register", "update", "snapshot", "history", "remove"] return Response( message=f"Unknown action '{action}'. Supported: {', '.join(supported)}", break_loop=False ) except PluginDBError as e: return Response(message=f"Database error: {e}", break_loop=False) except ValueError as e: return Response(message=f"Error: {e}", break_loop=False)