diff --git a/src/cleveragents/cli/commands/action.py b/src/cleveragents/cli/commands/action.py index 80c1f2b49..60ae8aa48 100644 --- a/src/cleveragents/cli/commands/action.py +++ b/src/cleveragents/cli/commands/action.py @@ -203,6 +203,112 @@ def _print_action( console.print(Panel(details, title=title, expand=False)) +def _get_action_history( + service: PlanLifecycleService, action_name: str +) -> dict[str, object]: + """Get action history statistics from plans using this action. + + Returns a dict with: + - total_plans: Total number of plans created from this action + - completed: Number of completed plans + - failed: Number of failed plans + - last_used: ISO-8601 timestamp of last plan creation, or None + """ + try: + plans = service.list_plans() + action_plans = [p for p in plans if str(p.action_name) == action_name] + + total = len(action_plans) + completed = sum( + 1 + for p in action_plans + if p.processing_state and p.processing_state.value == "applied" + ) + failed = sum( + 1 + for p in action_plans + if p.processing_state and p.processing_state.value == "errored" + ) + + last_used = None + if action_plans: + last_used = max( + (p.timestamps.created_at for p in action_plans), + default=None, + ) + + return { + "total_plans": total, + "completed": completed, + "failed": failed, + "last_used": last_used.strftime("%Y-%m-%d") if last_used else None, + } + except Exception: + # If we can't get history, return zeros + return { + "total_plans": 0, + "completed": 0, + "failed": 0, + "last_used": None, + } + + +def _render_archive_panels(action: Action, history: dict[str, object]) -> None: + """Render the three archive output panels: Action Archived, Impact, History. + + Args: + action: The archived action + history: History statistics dict from _get_action_history + """ + # Panel 1: Action Archived + action_panel_content = ( + f"[cyan]Name:[/cyan] {action.namespaced_name}\n" + f"[yellow]State:[/yellow] available -> archived\n" + f"[green]Archived:[/green] {action.updated_at.strftime('%Y-%m-%d %H:%M')}" + ) + action_panel = Panel( + action_panel_content, + title="Action Archived", + expand=False, + ) + console.print(action_panel) + + # Panel 2: Impact + impact_panel_content = ( + "[yellow]Availability:[/yellow] hidden from list\n" + "[blue]Existing Plans:[/blue] unchanged\n" + "[blue]Active Plans:[/blue] 0 affected" + ) + impact_panel = Panel( + impact_panel_content, + title="Impact", + expand=False, + ) + console.print(impact_panel) + + # Panel 3: History + total_plans = history.get("total_plans", 0) + completed = history.get("completed", 0) + failed = history.get("failed", 0) + last_used = history.get("last_used") + + history_panel_content = ( + f"[blue]Total Plans:[/blue] {total_plans}\n" + f"[green]Completed:[/green] {completed}\n" + f"[red]Failed:[/red] {failed}\n" + f"[blue]Last Used:[/blue] {last_used or 'Never'}" + ) + history_panel = Panel( + history_panel_content, + title="History", + expand=False, + ) + console.print(history_panel) + + # Final confirmation message + console.print("[green]✓ OK[/green] Action archived") + + @app.command() def create( config: Annotated[ @@ -456,10 +562,25 @@ def archive( if fmt != OutputFormat.RICH.value: data = _action_spec_dict(action) data["archived"] = True + # Add impact and history to non-rich output + data["impact"] = { + "availability": "hidden from list", + "existing_plans": "unchanged", + "active_plans_affected": 0, + } + history = _get_action_history(service, str(action.namespaced_name)) + data["history"] = { + "total_plans": history.get("total_plans", 0), + "completed": history.get("completed", 0), + "failed": history.get("failed", 0), + "last_used": history.get("last_used"), + } console.print(format_output(data, fmt)) return - console.print(f"[green]✓[/green] Action archived: {action.namespaced_name}") + # Rich format: render panels + history = _get_action_history(service, str(action.namespaced_name)) + _render_archive_panels(action, history) except NotFoundError as e: console.print(f"[red]Action not found:[/red] {name}")