"""Skill management CLI commands""" import os from typing import Optional import typer from rich import print as rprint from rich.table import Table skill_app = typer.Typer(name="skill", help="Skill management commands", no_args_is_help=True) @skill_app.command("list") def list_skills( server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"), ): """List registered skills""" if server_url: # Remote mode: call API import httpx try: with httpx.Client(timeout=10.0) as client: response = client.get(f"{server_url}/api/v1/skills") response.raise_for_status() skills = response.json() except Exception as e: rprint(f"[red]Error connecting to server: {e}[/red]") raise typer.Exit(code=1) else: # Local mode: use SkillRegistry directly, loading from default configs/skills/ from agentkit.skills.loader import SkillLoader from agentkit.skills.registry import SkillRegistry from agentkit.tools.registry import ToolRegistry registry = SkillRegistry() # Load skills from the default configs/skills/ directory if it exists default_skills_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "configs", "skills") if os.path.isdir(default_skills_dir): loader = SkillLoader(registry, ToolRegistry()) loader.load_from_directory(default_skills_dir) skills = [ { "name": s.name, "agent_type": s.config.agent_type, "version": s.config.version, "description": s.config.description, } for s in registry.list_skills() ] if not skills: rprint("[dim]No skills registered[/dim]") return table = Table(title="Skills") table.add_column("Name", style="cyan") table.add_column("Type") table.add_column("Description") for s in skills: table.add_row( s.get("name", ""), s.get("agent_type", ""), s.get("description", ""), ) rprint(table) @skill_app.command("load") def load_skill( path: str = typer.Argument(help="Path to skill YAML file"), ): """Load a skill from YAML file""" if not os.path.exists(path): rprint(f"[red]Error: File not found: {path}[/red]") raise typer.Exit(code=1) try: from agentkit.skills.loader import SkillLoader from agentkit.skills.registry import SkillRegistry from agentkit.tools.registry import ToolRegistry registry = SkillRegistry() loader = SkillLoader(registry, ToolRegistry()) skill = loader.load_from_file(path) rprint(f"[green]Skill loaded:[/green] {skill.name}") rprint(f" Description: {skill.config.description}") rprint(f" Mode: {skill.config.task_mode}") except Exception as e: rprint(f"[red]Error loading skill: {e}[/red]") raise typer.Exit(code=1) @skill_app.command("create") def skill_create( name: str = typer.Argument(..., help="Skill name"), output_dir: Optional[str] = typer.Option(".", "--output-dir", "-o", help="Output directory"), ): """Create a new SKILL.md template""" template = f'''--- name: {name} description: "Description of {name}" agent_type: {name} execution_mode: react intent: keywords: ["{name}"] description: "Tasks related to {name}" quality_gate: required_fields: [] min_word_count: 0 --- # Trigger - When to use this skill # Steps 1. Step one 2. Step two 3. Step three # Pitfalls - Common mistakes to avoid # Verification - How to verify the output ''' output_path = os.path.join(output_dir, f"{name}.md") os.makedirs(output_dir, exist_ok=True) with open(output_path, "w", encoding="utf-8") as f: f.write(template) rprint(f"[green]Created SKILL.md template:[/green] {output_path}") @skill_app.command("info") def skill_info( name: str = typer.Argument(help="Skill name"), server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"), ): """Show skill details""" if server_url: import httpx try: with httpx.Client(timeout=10.0) as client: response = client.get(f"{server_url}/api/v1/skills/{name}") response.raise_for_status() info = response.json() except Exception as e: rprint(f"[red]Error: {e}[/red]") raise typer.Exit(code=1) else: from agentkit.skills.registry import SkillRegistry registry = SkillRegistry() try: skill = registry.get(name) info = { "name": skill.name, "agent_type": skill.config.agent_type, "version": skill.config.version, "description": skill.config.description, "task_mode": skill.config.task_mode, "execution_mode": skill.config.execution_mode, } except Exception as e: rprint(f"[red]Skill '{name}' not found: {e}[/red]") raise typer.Exit(code=1) table = Table(title=f"Skill: {name}") table.add_column("Field", style="cyan") table.add_column("Value") for key, value in info.items(): table.add_row(key, str(value)) rprint(table)