Supyagent
CLI Reference

supypowers CLI

Complete reference for the supypowers CLI -- tool execution, documentation, testing, and skill generation.

supypowers CLI Reference

The supypowers CLI is the tool execution engine that powers supyagent's tool system. It runs self-contained Python scripts as callable, schema-documented functions with automatic dependency resolution via uv.

supypowers COMMAND [OPTIONS] [ARGS]

All commands assume a powers/ directory exists in the project root (or the directory specified by --root).


supypowers init

Initialize a powers/ folder with starter templates.

supypowers init
supypowers init --root /path/to/project
supypowers init --force    # Overwrite existing files

Creates powers/hello.py and powers/hello.md as starter templates demonstrating the supypower contract.

FlagDescriptionDefault
--rootRoot directory (creates powers/ inside it). (current directory)
--forceOverwrite existing powers/hello.py and powers/hello.mdfalse

supypowers new

Create a new supypower script from template.

supypowers new my_tool
supypowers new my_tool --root /path/to/project
supypowers new my_tool --force

Creates powers/my_tool.py with a Pydantic-based function template following the supypower contract.

FlagDescriptionDefault
--rootRoot directory containing the powers/ folder.
--forceOverwrite if file already existsfalse

supypowers run

Run a function in a script via uv run. This is the core execution command used by supyagent's tool system.

supypowers run script:function '{"key": "value"}'
supypowers run exponents:compute_sqrt '{"x": 9}'
supypowers run --examples exponents:compute_sqrt '{"x": 9}'
supypowers run web:fetch_url '{"url": "https://example.com"}' --secrets API_KEY=xxx
supypowers run web:fetch_url '{"url": "https://example.com"}' --secrets .env
ArgumentDescription
targetScript and function in script:function format (script may omit .py)
input_dataInput data as JSON string
FlagDescriptionDefault
--rootRoot directory containing the powers/ folder.
--examplesRun from bundled examples instead of local powers/false
--secretsSecrets as .env path or inline KEY=VAL (repeatable)None

Execution Flow

  1. Resolves the script path in the powers/ folder
  2. Extracts dependencies from the # /// script metadata block
  3. Runs the function via uv run --with <deps> python -c <code>
  4. Passes the input JSON via stdin
  5. Validates input against the Pydantic model
  6. Returns JSON output: {"ok": true, "data": ...} or {"ok": false, "error": "..."}

Output Format

Successful execution:

{
  "ok": true,
  "data": {
    "result": 3.0
  }
}

Failed execution:

{
  "ok": false,
  "error": "ValueError: x must be non-negative"
}

supypowers docs

Generate documentation for all discovered functions in JSON or Markdown format.

supypowers docs
supypowers docs --format md
supypowers docs --format json --output docs.json
supypowers docs --recursive
supypowers docs --examples
supypowers docs --require-marker
FlagDescriptionDefault
--rootRoot directory containing the powers/ folder.
--examplesDocument bundled examplesfalse
--recursiveRecurse into subfoldersfalse
--formatOutput format: json, mdjson
--outputWrite output to a file instead of stdoutNone (stdout)
--require-markerOnly include functions explicitly marked with @superpower decoratorfalse
--secretsSecrets as .env path or inline KEY=VAL (repeatable)None

JSON Output Structure

The JSON output is an array of script entries:

[
  {
    "script": "powers/web.py",
    "functions": [
      {
        "name": "fetch_url",
        "description": "Fetch a URL and return the response body.",
        "parameters": {
          "type": "object",
          "properties": {
            "url": {
              "type": "string",
              "description": "URL to fetch"
            }
          },
          "required": ["url"]
        }
      }
    ]
  }
]

This is the format consumed by supyagent's discover_tools() function to build OpenAI-compatible tool definitions.


supypowers test

Test a function with auto-generated example input or a fixture file.

supypowers test my_tool:my_function
supypowers test --examples exponents:compute_sqrt
supypowers test my_tool:process --fixture test_input.json
supypowers test my_tool:call_api --secrets API_KEY=xxx
ArgumentDescription
targetScript and function in script:function format
FlagDescriptionDefault
--rootRoot directory containing the powers/ folder.
--examplesTest from bundled examplesfalse
--fixturePath to a JSON file containing test inputNone (auto-generated)
--secretsSecrets as .env path or inline KEY=VAL (repeatable)None

When no fixture is provided, supypowers attempts to generate example input based on the function's Pydantic model schema (using default values and type-appropriate placeholders).


supypowers skills

Generate skill files for AI agents (one per script in powers/). These files follow Claude's Agent Skills format with YAML frontmatter.

supypowers skills
supypowers skills --output .claude/skills/
supypowers skills --stdout
supypowers skills --secrets .env
FlagDescriptionDefault
--rootRoot directory containing the powers/ folder.
--outputOutput directory for skill files.claude/skills/
--stdoutPrint all skill content to stdout instead of writing filesfalse
--secretsSecrets as .env path or inline KEY=VAL (repeatable)None

Each generated skill file contains:

  • YAML frontmatter with the skill name and description
  • Function signatures and descriptions
  • Input/output schema documentation
  • Example usage with supypowers run commands

The Supypower Contract

Every supypowers script must follow these rules:

  1. One parameter named input -- Each function takes exactly one parameter named input, typed as a Pydantic BaseModel
  2. Pydantic models -- Both input and output must be Pydantic models with descriptions
  3. No print() -- Printing breaks JSON output
  4. No input() -- No interactive terminal is available
  5. Declare dependencies -- All packages go in the # /// script metadata block
  6. Return errors, do not raise -- Use the {"ok": bool, "data": ..., "error": ...} pattern

Script Template

powers/my_tool.py
# /// script
# dependencies = ["pydantic", "httpx"]
# ///
from pydantic import BaseModel, Field


class MyToolInput(BaseModel):
    """Input for my_tool function."""
    url: str = Field(..., description="URL to process")
    timeout: int = Field(default=30, description="Request timeout in seconds")


class MyToolOutput(BaseModel):
    """Output for my_tool function."""
    ok: bool
    data: str | None = None
    error: str | None = None


def my_tool(input: MyToolInput) -> MyToolOutput:
    """
    Process a URL and return the result.

    Examples:
        >>> my_tool({"url": "https://example.com"})
    """
    try:
        import httpx
        response = httpx.get(input.url, timeout=input.timeout)
        return MyToolOutput(ok=True, data=response.text[:1000])
    except Exception as e:
        return MyToolOutput(ok=False, error=str(e))

Dependency Declaration

Dependencies are declared in the # /// script block at the top of the file:

# /// script
# dependencies = ["pydantic", "httpx", "beautifulsoup4"]
# ///

These are parsed by uv_script_metadata.py and passed to uv run --with <deps> at execution time. Each script runs in its own isolated environment.