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
+103
View File
@@ -0,0 +1,103 @@
"""Tool: manage next steps for a project (DB-backed, replaces .a0/next_steps.md)."""
from __future__ import annotations
import os
from helpers.tool import Tool, Response
from usr.plugins.a0_software_orchestrator.helpers.db_state_store import (
get_project_id,
add_next_step,
complete_next_step,
list_next_steps,
)
from usr.plugins.a0_software_orchestrator.helpers.exceptions import PluginDBError
def _resolve_name(project_name: str = "", project_root: str = "") -> str:
"""Ermittelt den Projektnamen: explizit → aus project_root → aus cwd."""
if project_name:
return project_name.strip()
if project_root:
return os.path.basename(project_root.rstrip("/"))
return os.path.basename(os.getcwd())
class NextStep(Tool):
"""Add, list, or complete next steps for a project.
Args (kwargs):
project_name (str): Projektname (bevorzugt).
project_root (str): Legacy wird zu basename() aufgelöst.
next_step (str): Inhalt des neuen Steps (bei action=add).
step_id (int): ID des Steps (bei action=complete).
action (str): "add" (default), "list", "complete".
"""
async def execute(
self,
project_name: str = "",
project_root: str = "",
next_step: str = "",
step_id: int = 0,
action: str = "",
**kwargs,
):
if not action:
return Response(message="ERROR: 'action' required. Supported: add, list, complete", break_loop=False)
name = _resolve_name(project_name, project_root)
try:
pid = get_project_id(name)
if pid is None:
raise LookupError(f"project '{name}' is not registered")
except (ValueError, LookupError) as e:
return Response(message=f"ERROR: {e}", break_loop=False)
except PluginDBError as e:
return Response(message=f"Database error: {e}", break_loop=False)
if action == "add":
if not next_step and kwargs.get("content"):
next_step = str(kwargs.get("content"))
if not next_step or not next_step.strip():
return Response(
message="ERROR: 'next_step' content required for action=add",
break_loop=False,
)
new_id = add_next_step(pid, next_step.strip())
return Response(
message=f"Next step added (id={new_id}, project={name}): {next_step.strip()}",
break_loop=False,
)
if action == "list":
steps = list_next_steps(pid, status="pending")
if not steps:
return Response(
message=f"No pending next steps for project '{name}'.",
break_loop=False,
)
lines = [f"Pending next steps for '{name}':"]
for s in steps:
lines.append(f" - [id={s['id']}] {s['content']}")
return Response(message="\n".join(lines), break_loop=False)
if action == "complete":
if not step_id:
return Response(
message="ERROR: 'step_id' required for action=complete",
break_loop=False,
)
ok = complete_next_step(int(step_id))
if ok:
return Response(
message=f"Next step id={step_id} marked as done.",
break_loop=False,
)
return Response(
message=f"No next step with id={step_id} found.",
break_loop=False,
)
return Response(
message=f"Unknown action {action!r}. Supported: add, list, complete",
break_loop=False,
)