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

> Discover how CLI-Anything's 7-phase pipeline analyzes software APIs and generates CLI commands. Transform GUIs into agent-native CLIs with static analysis and Python harnesses.

- Repository: [✨Data Intelligence Lab@HKU✨/CLI-Anything](https://github.com/HKUDS/CLI-Anything)
- Tags: how-to-guide
- Published: 2026-05-18

---

**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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/TEST.md) skeleton at `cli_anything/<software>/tests/TEST.md`. This document specifies:

- Unit-test inventory ([`test_core.py`](https://github.com/HKUDS/CLI-Anything/blob/main/test_core.py))
- E2E scenarios ([`test_full_e2e.py`](https://github.com/HKUDS/CLI-Anything/blob/main/test_full_e2e.py))
- Realistic workflow descriptions

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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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.

```python

# 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:

```bash
$ 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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/TEST.md) planning, pytest implementation, and documentation updates.
- **Phase 6.5** generates [`SKILL.md`](https://github.com/HKUDS/CLI-Anything/blob/main/SKILL.md) using [`skill_generator.py`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/cli-anything-plugin/HARNESS.md) and implemented in files like [`cli_anything/gimp/utils/gimp_backend.py`](https://github.com/HKUDS/CLI-Anything/blob/main/cli_anything/gimp/utils/gimp_backend.py).

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

The [`SKILL.md`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/skill_generator.py) using Jinja2 templates, this file is embedded in the package via [`setup.py`](https://github.com/HKUDS/CLI-Anything/blob/main/setup.py) configuration (`package_data={"cli_anything.<software>": ["skills/*.md"]}`) to enable automatic discovery by agent frameworks.