5.9 KiB
5.9 KiB
| tags | name | description | version | author | updated | |
|---|---|---|---|---|---|---|
|
agent-cli-builder | Building agent-native CLIs — wrap HTTP APIs or GUI apps into structured, stateful CLIs with REPL mode, JSON output, and SKILL.md for AI agent discoverability. Based on CLI-Anything methodology adapted for Hermes. | 1.0 | 小唯 A06 | 2026-07-01 |
Agent CLI Builder
Build agent-native command-line interfaces for any software, service, or HTTP API. A CLI built this way lets AI agents (or humans) operate the software through deterministic commands instead of GUI clicks.
When to Use
- An HTTP API exists but has no CLI (e.g., ZhiYi, KOCR, gaokao API)
- A GUI app has a backend CLI but no structured agent interface (e.g., Blender, LibreOffice)
- You want any AI agent to discover and use a tool via SKILL.md
Methodology (CLI-Anything 7-Phase SOP, Adapted)
Phase 1: API/Codebase Analysis
Identify the target:
- HTTP API → catalog all endpoints, request/response shapes, auth
- GUI app → find backend engine, native CLI, data model
- Existing CLI → identify gaps for --json output, REPL mode
Map operations to command groups
Design state model (session, project, undo/redo)
Phase 2: CLI Architecture
Interaction model (pick at least 2):
- Stateful REPL (default — `invoke_without_command=True`)
- One-shot subcommands (for scripting)
- Both ✓
Command groups matching logical domains:
- Health/status
- Core operations (search, navigate, create)
- Stats/metrics
- Configuration/settings
Output format:
- Human-readable (tables, icons) for interactive use
- `--json` flag for machine-readable (EVERY command)
Phase 3: Implementation
Standard project layout:
<project>/
├── setup.py ← PyPI installable (pip install -e .)
├── cli_anything/ ← PEP 420 namespace (NO __init__.py)
│ └── <service>/ ← Sub-package
│ ├── __init__.py
│ ├── __main__.py ← python3 -m entry
│ ├── README.md
│ ├── <service>_cli.py ← Click CLI (main entry point)
│ ├── core/
│ │ ├── __init__.py
│ │ └── client.py ← API client wrapper
│ ├── utils/
│ │ ├── __init__.py
│ │ └── repl_skin.py ← (optional) prompt_toolkit REPL
│ ├── skills/
│ │ └── SKILL.md ← Agent-discoverable skill definition
│ └── tests/
│ ├── TEST.md
│ ├── __init__.py
│ └── test_core.py
Core patterns:
# client.py — API wrapper
class ServiceClient:
def _get(self, path): ...
def _post(self, path, data): ...
def search(self, query, **kwargs): ...
def health(self): ...
# <service>_cli.py — Click CLI
@click.group(invoke_without_command=True)
@click.option("--json", is_flag=True)
def cli(ctx, json_flag):
"""Description."""
global _json_output; _json_output = json_flag
if ctx.invoked_subcommand is None:
ctx.invoke(repl)
# Every command MUST support --json + human-readable dual output
def output(data, message=""):
if _json_output:
click.echo(json.dumps(data, indent=2, ensure_ascii=False, default=str))
else:
if message: click.echo(message)
# Format nicely for humans
Iron rules:
- Use
cli_anythingas PEP 420 namespace package (no__init__.py) invoke_without_command=True→ REPL as default- Every command
--jsonflag - CLI = Click +
entry_points.console_scripts - API key via environment variable with sensible defaults
Phase 4: Test Plan (TEST.md)
Write BEFORE test code:
- Test inventory (files + estimated count)
- Client unit tests (each method)
- CLI subprocess tests (install, run, verify output)
- E2E tests (real API calls)
Phase 5: Test Implementation
# test_core.py
def test_health():
c = Client()
r = c.health()
assert r.get("status") == "ok"
def test_search():
c = Client()
r = c.search("query")
assert len(r.get("results", [])) > 0
Phase 6: SKILL.md Generation
Generate a skills/SKILL.md so AI agents can auto-discover the CLI:
---
name: cli-anything-<service>
description: One-line description of what the CLI does
---
Include: install command, all commands with options, JSON output examples, environment variables.
Phase 7: Install & Verify
cd <project> && pip install -e .
which cli-anything-<service>
cli-anything-<service> --help
cli-anything-<service> health
cli-anything-<service> search "test" --json
python3 tests/test_core.py
Verification Checklist
pip install -e .succeeds- CLI entry point registered (
which cli-anything-<name>) --helpshows all command groupshealthcommand returns 200- Core operations work
--jsonproduces valid JSON- Default mode enters REPL
- Tests pass (9+ tests)
- SKILL.md exists in
skills/ - Environment vars documented in README
Examples
| Project | Service | API Base | Key | Location |
|---|---|---|---|---|
| cli-anything-zhiyi | ZhiYi MemoryWeave | localhost:7821 |
zhiyi-dev-key-2026 |
~/bin/cli-anything-zhiyi/ |
For detailed examples from a real implementation, see references/cli-anything-zhiyi.md.
Pitfalls
- Namespace package:
cli_anything/directory must NOT have__init__.py. Each sub-package does. - Global state: Use module-level globals for
_json_outputand_client— they're per-CLI-instance and reset with each CLI call. - REPL vs one-shot: REPL as default via
invoke_without_command=True. Make sure /quit works gracefully. - Auth: API keys in env vars with sensible defaults. Never hardcode in source.
- Timeout: API calls need generous timeouts (10s for reads, 30s for search).