104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
|
|
"""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,
|
|||
|
|
)
|