How CLI-Anything's 7-Phase Pipeline Analyzes Software APIs and Generates CLI Commands

CLI-Anything transforms GUI-centric open-source applications into agent-native command-line interfaces through a systematic 7-phase pipeline that discovers APIs via static analysis, designs Click-based architectures, implements Python harnesses, and publishes installable packages with SKILL.md files for AI agents.

CLI-Anything is an open-source framework that converts any GUI application into a programmable CLI tool. By implementing CLI-Anything's 7-phase pipeline, the system analyzes source code to extract API capabilities, maps GUI actions to command-line operations, and generates a complete Python harness with REPL support. This methodology is documented in the repository's cli-anything-plugin/HARNESS.md, which serves as the canonical specification for the transformation process.

Phase 1: Codebase Analysis

The pipeline begins with static source-code inspection to discover the application's underlying API surface. According to the cli-anything-plugin/HARNESS.md methodology, this phase produces a metadata JSON consumed by subsequent stages.

Identify the backend engine – The system scans src/ directories and requirements.txt files to detect core libraries (e.g., ImageMagick for GIMP, MLT for Shotcut).

Map GUI actions to API calls – The parser extracts UI definitions from Qt .ui files, GTK builder XML, and menu scripts to create a command-action map. This mapping correlates each widget with its underlying function or CLI invocation.

Identify the data model – The pipeline detects file formats (XML, JSON, ODF) by examining parsers and serializers in the source tree.

Find existing CLI tools – The system locates external binaries (ffmpeg, libreoffice, blender) referenced via subprocess.run or shutil.which calls.

Catalog the command/undo system – When the app implements a command pattern (Command, UndoStack), each command class is recorded as a potential CLI operation.

Phase 2: CLI Architecture Design

Using the action map from Phase 1, the pipeline designs the CLI structure in four steps:

  1. Interaction model selection – Determines whether the CLI needs a stateful REPL, pure sub-commands, or both, based on the presence of a persistent project model discovered in Phase 1.
  2. Command-group definition – Creates logical groups (project, import, export, settings, session) that mirror the original menu hierarchy.
  3. State model specification – Defines what internal state must persist between commands (e.g., currently opened project path) and stores this in a JSON session file.
  4. Output format planning – Ensures all commands support a --json flag for machine-readable payloads while maintaining human-readable output.

The result is a CLI spec JSON that catalogs command groups, individual commands, expected arguments, and output modes.

Phase 3: Implementation

This phase generates the actual Python code under cli_anything/<software>/, implementing the architecture as a PEP 420 namespace package.

Data Layer

The pipeline generates helpers that read/write the discovered project format. In cli_anything/gimp/utils/gimp_backend.py, functions like write_xcf() handle format-specific operations.

Command Implementation

Probe / info commands – Generated in files like cli_anything/gimp/core/inspect.py, these provide project info and layer list commands that let agents query state before mutation.

Mutation commands – Each GUI action becomes a Click sub-command in cli_anything/gimp/commands/layer.py, calling the appropriate backend function.

Backend wrapper – Wraps the real software executable (found via shutil.which) and provides clear install hints when binaries are missing. The cli-anything-plugin/HARNESS.md defines this pattern for error handling and CLI invocation.

Session management – Implements _locked_save_json() to manage a lock-protected JSON file storing REPL state between commands.

REPL skin – Copies repl_skin.py into the harness and wires it as the default entry point using invoke_without_command=True. The REPL class is instantiated in the cli() group, providing unified banner, progress, and table formatting across all generated tools.

Phase 4: Test Planning

Before writing implementation code, the pipeline generates a TEST.md skeleton at cli_anything/<software>/tests/TEST.md. This document specifies:

This test-driven approach ensures every generated command has defined coverage criteria before implementation begins.

Phase 5: Test Implementation

The pipeline generates three test categories under cli_anything/<software>/tests/:

  • Unit tests – Verify core functions using synthetic data
  • E2E tests with intermediate files – Validate that generated project files meet syntax requirements (XML schema, valid ZIP for ODF)
  • E2E tests with true backend – Launch the real application (e.g., gimp -i -b …) and verify exported artifacts via magic-bytes and file size

CLI subprocess tests – Use a _resolve_cli() helper to run the installed entry point (cli-anything-gimp) from any working directory, ensuring proper package installation.

Phase 6: Test Documentation

After the test suite passes, the pipeline appends pytest output, summary statistics, and coverage notes to TEST.md. This updated file becomes part of the final harness for human reviewers and CI pipelines.

Phase 6.5: SKILL.md Generation

The pipeline auto-generates a SKILL.md file from the Click command tree using skill_generator.py and the Jinja2 template at templates/SKILL.md.template. This skill file contains:

  • YAML front-matter for AI agent discovery (name: cli-anything-<software>)
  • Markdown body describing command groups, --json usage, and realistic examples

The canonical skill resides in skills/cli-anything-<software>/SKILL.md and is copied into the installed package at cli_anything/<software>/skills/SKILL.md.

Phase 7: Publishing

Finally, the harness is packaged as a PEP 420 namespace package (cli_anything.<software>) and uploaded to PyPI. The setup.py includes package_data={"cli_anything.<software>": ["skills/*.md"]} to ensure the SKILL file ships with the distribution, making the CLI immediately discoverable by AI agents upon installation.

From GUI Action to CLI Command: A Complete Example

The following excerpt demonstrates how a GUI "Export PNG" button becomes a Python CLI command through the pipeline.


# utils/gimp_backend.py (auto-generated)

def export_png(project_path: str, output_path: str) -> dict:
    """Wrap the real GIMP CLI call."""
    gimp = shutil.which("gimp")
    if not gimp:
        raise RuntimeError(
            "GIMP executable not found. Install it and ensure it's in $PATH."
        )
    subprocess.run(
        [gimp, "-i", "-b", f"(gimp-file-export \"{project_path}\" \"{output_path}\" PNG)", "-b", "(gimp-quit 0)"],
        check=True,
    )
    return {"output": output_path, "format": "png", "method": "gimp-cli"}

# commands/export.py (auto-generated)

@click.command("png")
@click.argument("project")
@click.argument("output")
@click.pass_context
def export_png_cmd(ctx, project, output):
    """Export the current GIMP project as PNG."""
    try:
        result = ctx.obj["backend"].export_png(project, output)
        ctx.obj["skin"].success(f"Exported → {result['output']}")
    except Exception as e:
        ctx.obj["skin"].error(str(e))
        ctx.exit(1)

# cli entry point (auto-generated)

@click.group()
@click.pass_context
def cli(ctx):
    ctx.obj = {
        "backend": import_module("cli_anything.gimp.utils.gimp_backend"),
        "skin": ReplSkin("gimp", version="1.0.0"),
    }

cli.add_command(export_png_cmd, name="export")

Running the generated CLI produces structured JSON output:

$ cli-anything-gimp export png myproj.xcf out.png --json
{
  "output": "out.png",
  "format": "png",
  "method": "gimp-cli"
}

The --json flag is automatically added by the generated invoke_cli() wrapper defined in repl_skin.py, ensuring all commands support both human and machine-readable output modes.

Summary

  • CLI-Anything's 7-phase pipeline systematically transforms GUI applications into agent-native CLIs through static analysis, architecture design, implementation, testing, and publishing.
  • Phase 1 extracts API capabilities by scanning source code for UI definitions, data models, and existing CLI tools, storing results in a metadata JSON.
  • Phase 2 designs the CLI structure as Click command groups with REPL support and --json output flags.
  • Phase 3 generates the Python harness under cli_anything/<software>/, including backend wrappers, mutation commands, and session management via _locked_save_json().
  • Phases 4-6 implement test-driven development with TEST.md planning, pytest implementation, and documentation updates.
  • Phase 6.5 generates SKILL.md using skill_generator.py for AI agent discovery.
  • Phase 7 packages the result as a PEP 420 namespace package with embedded skill files for PyPI distribution.

Frequently Asked Questions

How does CLI-Anything discover API capabilities in Phase 1?

The pipeline uses regular-expression greps over the entire repository to locate UI definitions, subprocess.run calls, and command pattern implementations. It scans src/ directories and requirements.txt to identify backend engines like ImageMagick or MLT, then maps GUI widgets to their underlying API calls to create a command-action map stored in metadata JSON.

What determines whether the generated CLI uses a REPL or sub-commands?

The interaction model selection in Phase 2 depends on the presence of a persistent project model discovered during codebase analysis. If the application maintains project state between operations, the pipeline generates both a stateful REPL (set as default via invoke_without_command=True) and traditional sub-commands. Stateless tools receive only the sub-command interface.

How does the pipeline ensure the generated CLI handles missing dependencies gracefully?

During Phase 3 implementation, the backend wrapper uses shutil.which() to locate the target executable (e.g., gimp, blender). If the binary is not found in $PATH, the wrapper raises a RuntimeError with specific installation instructions. This pattern is defined in cli-anything-plugin/HARNESS.md and implemented in files like cli_anything/gimp/utils/gimp_backend.py.

What is the purpose of the SKILL.md file generated in Phase 6.5?

The SKILL.md file serves as machine-readable documentation for AI agents, containing YAML front-matter with the package name and markdown descriptions of all commands, arguments, and --json usage patterns. Generated by skill_generator.py using Jinja2 templates, this file is embedded in the package via setup.py configuration (package_data={"cli_anything.<software>": ["skills/*.md"]}) to enable automatic discovery by agent frameworks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →