---
phase: 03-registry-compatibility
plan: 04
type: execute
wave: 2
depends_on: [03-01]
files_modified:
  - src/clawrium/cli/registry.py
  - src/clawrium/cli/main.py
  - tests/test_cli_registry.py
autonomous: true
requirements: [REG-02]

must_haves:
  truths:
    - "User runs clm registry list and sees available claws with versions"
    - "User runs clm registry show <claw> and sees full manifest details"
    - "CLI output uses Rich tables consistent with existing commands"
  artifacts:
    - path: "src/clawrium/cli/registry.py"
      provides: "Registry CLI commands"
      exports: ["registry_app"]
    - path: "src/clawrium/cli/main.py"
      provides: "Registry app registered"
      contains: "registry_app"
    - path: "tests/test_cli_registry.py"
      provides: "CLI tests for registry commands"
      min_tests: 4
  key_links:
    - from: "src/clawrium/cli/registry.py"
      to: "src/clawrium/core/registry.py"
      via: "import list_claws, get_claw_info, load_manifest"
      pattern: "from clawrium.core.registry import"
    - from: "src/clawrium/cli/main.py"
      to: "src/clawrium/cli/registry.py"
      via: "app.add_typer(registry_app)"
      pattern: "add_typer.*registry"
---

<objective>
Implement CLI commands for browsing the claw registry.

Purpose: Users need to discover available claw types before installation. The registry list command shows a summary of all claws, and registry show provides detailed manifest information for a specific claw.

Output: CLI module with list and show commands, integrated into main app.
</objective>

<execution_context>
@/home/devashish/workspace/ric03uec/clawrium/.claude/get-shit-done/workflows/execute-plan.md
@/home/devashish/workspace/ric03uec/clawrium/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/03-registry-compatibility/03-CONTEXT.md

<interfaces>
<!-- From 03-01: Registry functions -->

```python
def list_claws() -> list[str]:
    """List all available claw names."""
    ...

def get_claw_info(claw_name: str) -> dict:
    """Get summary info: name, description, latest_version, supported_platforms."""
    ...

def load_manifest(claw_name: str) -> ClawManifest:
    """Load full manifest for a claw."""
    ...

class ManifestNotFoundError(Exception):
    """Raised when claw manifest doesn't exist."""
    ...
```

<!-- From cli/host.py: CLI patterns to follow -->

```python
from rich.console import Console
from rich.table import Table
import typer

console = Console()

host_app = typer.Typer(
    name="host",
    help="Manage hosts in your fleet",
    no_args_is_help=True,
)

@host_app.command(name="list")
def list_hosts() -> None:
    """List all registered hosts."""
    table = Table(title="Registered Hosts")
    table.add_column("Alias", style="cyan")
    ...
    console.print(table)
```

<!-- From cli/main.py: Registration pattern -->

```python
from clawrium.cli.host import host_app
app.add_typer(host_app, name="host")
```
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Implement registry list command</name>
  <files>
    src/clawrium/cli/registry.py
    src/clawrium/cli/main.py
    tests/test_cli_registry.py
  </files>
  <read_first>
    - /home/devashish/workspace/ric03uec/clawrium/src/clawrium/cli/host.py (CLI patterns, Rich table usage)
    - /home/devashish/workspace/ric03uec/clawrium/src/clawrium/cli/main.py (app registration pattern)
    - /home/devashish/workspace/ric03uec/clawrium/tests/test_cli_host.py (CLI test patterns)
    - /home/devashish/workspace/ric03uec/clawrium/.planning/phases/03-registry-compatibility/03-CONTEXT.md (D-14 through D-16)
  </read_first>
  <action>
    1. Create src/clawrium/cli/registry.py:
       ```python
       """Registry commands for browsing available claws."""

       import typer
       from rich.console import Console
       from rich.table import Table

       from clawrium.core.registry import (
           list_claws,
           get_claw_info,
           ManifestNotFoundError,
       )

       __all__ = ["registry_app"]

       console = Console()

       registry_app = typer.Typer(
           name="registry",
           help="Browse available claw types",
           no_args_is_help=True,
       )


       @registry_app.command(name="list")
       def list_registry() -> None:
           """List available claw types in the registry."""
           claws = list_claws()

           if not claws:
               console.print("No claws available in registry.")
               return

           table = Table(title="Available Claws")
           table.add_column("Name", style="cyan")
           table.add_column("Latest Version", style="green")
           table.add_column("Description")

           for claw_name in claws:
               try:
                   info = get_claw_info(claw_name)
                   table.add_row(
                       info["name"],
                       info["latest_version"],
                       info["description"],
                   )
               except ManifestNotFoundError:
                   table.add_row(claw_name, "?", "Error loading manifest")

           console.print(table)
       ```

    2. Update src/clawrium/cli/main.py to register registry_app:
       ```python
       from clawrium.cli.registry import registry_app
       # ...
       app.add_typer(registry_app, name="registry")
       ```

    3. Create tests/test_cli_registry.py with initial tests:
       ```python
       """Tests for registry CLI commands."""

       from typer.testing import CliRunner
       from clawrium.cli.main import app

       runner = CliRunner()


       def test_registry_list_shows_table():
           """Test that registry list shows available claws."""
           result = runner.invoke(app, ["registry", "list"])
           assert result.exit_code == 0
           assert "openclaw" in result.output.lower()
           assert "Available Claws" in result.output


       def test_registry_list_shows_version():
           """Test that registry list includes version."""
           result = runner.invoke(app, ["registry", "list"])
           assert result.exit_code == 0
           # Should show version from manifest
           assert "0.1.0" in result.output
       ```
  </action>
  <verify>
    <automated>uv run pytest tests/test_cli_registry.py::test_registry_list_shows_table tests/test_cli_registry.py::test_registry_list_shows_version -v</automated>
  </verify>
  <acceptance_criteria>
    - src/clawrium/cli/registry.py exists
    - src/clawrium/cli/registry.py contains "registry_app = typer.Typer"
    - src/clawrium/cli/registry.py contains "def list_registry"
    - src/clawrium/cli/main.py contains "from clawrium.cli.registry import registry_app"
    - src/clawrium/cli/main.py contains "add_typer(registry_app"
    - clm registry list shows "Available Claws" table with openclaw entry
    - tests/test_cli_registry.py contains "test_registry_list_shows_table"
    - uv run pytest tests/test_cli_registry.py -v -k list exits 0
  </acceptance_criteria>
  <done>
    - registry_app Typer created with list command
    - clm registry list shows table with Name, Latest Version, Description
    - openclaw appears in registry list output
    - Registry app registered in main.py
    - List tests pass
  </done>
</task>

<task type="auto">
  <name>Task 2: Implement registry show command</name>
  <files>
    src/clawrium/cli/registry.py
    tests/test_cli_registry.py
  </files>
  <read_first>
    - /home/devashish/workspace/ric03uec/clawrium/src/clawrium/cli/registry.py (registry module from Task 1)
    - /home/devashish/workspace/ric03uec/clawrium/src/clawrium/cli/host.py (status command shows detailed table)
    - /home/devashish/workspace/ric03uec/clawrium/.planning/phases/03-registry-compatibility/03-CONTEXT.md (D-15)
  </read_first>
  <action>
    1. Add show command to registry.py:
       ```python
       from clawrium.core.registry import load_manifest

       @registry_app.command()
       def show(
           claw_name: str = typer.Argument(..., help="Name of the claw to show"),
       ) -> None:
           """Show detailed information about a claw type."""
           try:
               manifest = load_manifest(claw_name)
           except ManifestNotFoundError:
               console.print(f"[red]Error:[/red] Claw '{claw_name}' not found in registry")
               raise typer.Exit(code=1)

           # Header info
           console.print(f"\n[bold cyan]{manifest['name']}[/bold cyan]")
           console.print(f"{manifest['description']}\n")

           # Supported platforms table
           table = Table(title="Supported Platforms")
           table.add_column("Version", style="green")
           table.add_column("OS")
           table.add_column("Architecture")
           table.add_column("Min Memory")
           table.add_column("GPU Required")

           for entry in manifest["entries"]:
               reqs = entry["requirements"]
               table.add_row(
                   entry["version"],
                   f"{entry['os']} {entry['os_version']}",
                   entry["arch"],
                   f"{reqs['min_memory_mb']}MB",
                   "Yes" if reqs["gpu_required"] else "No",
               )

           console.print(table)

           # Dependencies section (if any entry has dependencies)
           all_deps = set()
           for entry in manifest["entries"]:
               for dep, version in entry["requirements"].get("dependencies", {}).items():
                   all_deps.add(f"{dep} {version}")

           if all_deps:
               console.print("\n[bold]Dependencies:[/bold]")
               for dep in sorted(all_deps):
                   console.print(f"  - {dep}")
       ```

    2. Add tests for show command:
       ```python
       def test_registry_show_openclaw():
           """Test registry show displays claw details."""
           result = runner.invoke(app, ["registry", "show", "openclaw"])
           assert result.exit_code == 0
           assert "openclaw" in result.output.lower()
           assert "Supported Platforms" in result.output
           assert "ubuntu" in result.output.lower()


       def test_registry_show_not_found():
           """Test registry show with unknown claw shows error."""
           result = runner.invoke(app, ["registry", "show", "nonexistent"])
           assert result.exit_code == 1
           assert "not found" in result.output.lower()
       ```
  </action>
  <verify>
    <automated>uv run pytest tests/test_cli_registry.py -v</automated>
  </verify>
  <acceptance_criteria>
    - src/clawrium/cli/registry.py contains "def show("
    - src/clawrium/cli/registry.py contains "load_manifest"
    - clm registry show openclaw displays claw name, description, and platforms table
    - clm registry show nonexistent exits 1 with "not found" error
    - tests/test_cli_registry.py contains "test_registry_show_openclaw"
    - tests/test_cli_registry.py contains "test_registry_show_not_found"
    - uv run pytest tests/test_cli_registry.py -v exits 0
  </acceptance_criteria>
  <done>
    - registry show command displays full manifest details
    - Supported Platforms table shows version, OS, arch, memory, GPU
    - Dependencies listed if present
    - Unknown claw returns error with exit code 1
    - All registry CLI tests pass
  </done>
</task>

</tasks>

<verification>
```bash
# Verify registry module exists with commands
grep -n "def list_registry" src/clawrium/cli/registry.py
grep -n "def show" src/clawrium/cli/registry.py

# Verify main.py registration
grep -n "registry_app" src/clawrium/cli/main.py

# Test CLI commands work
uv run clm registry --help
uv run clm registry list
uv run clm registry show openclaw

# Run all tests
uv run pytest tests/test_cli_registry.py -v
```
</verification>

<success_criteria>
- clm registry list shows table with Name, Latest Version, Description
- clm registry show <claw> shows full manifest with platforms and requirements
- clm registry show <unknown> exits 1 with clear error
- Rich tables consistent with existing CLI style
- All CLI tests pass
</success_criteria>

<output>
After completion, create `.planning/phases/03-registry-compatibility/03-04-SUMMARY.md`
</output>
