Initial commit: a0_software_orchestrator v1.0

- Auto-Registration-Bug behoben (register_project/get_project_id/resolve_project Trennung)
- 25 Tests gruen (Pytest)
- block_compactor-Tool refactored (Option B: Soft-Check statt Hard-Block)
- 4 Restbaustellen gefixt
- DB-Schema: plugin_settings-Tabelle hinzugefuegt
- 3 Schattenprojekte aus DB geloescht
- Plan v3 + Refactor-Plan + Worklog dokumentiert
This commit is contained in:
Software Orchestrator
2026-06-16 22:13:06 +00:00
commit 5769c1cd22
236 changed files with 17825 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
"""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)