Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .agents/skills/cli-anything/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# cli-anything Skill

Build powerful, stateful CLI interfaces for any GUI application using the cli-anything harness methodology.

## Overview

This skill enables AI agents to transform any software application into an agent-controllable CLI. It follows the proven cli-anything methodology that has successfully generated CLIs for GIMP, Blender, Inkscape, Audacity, LibreOffice, OBS Studio, and Kdenlive.

## Usage

```bash
# Build CLI for local source
cli-anything /path/to/software

# Build CLI from GitHub
cli-anything https://github.com/org/repo
```

## Prerequisites

- Python 3.10+
- click >= 8.0
- pytest
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prerequisites list omits pyyaml, but the install command below includes it (pip install ... pyyaml). Please make these consistent by either listing pyyaml as a prerequisite or removing it from the install command.

Suggested change
- pytest
- pytest
- pyyaml

Copilot uses AI. Check for mistakes.

Install dependencies:
```bash
pip install click pytest pyyaml
```

## Methodology

This skill follows the 7-phase cli-anything methodology:

### Phase 0: Source Acquisition
- Clone GitHub repos or validate local paths
- Verify source code structure

### Phase 1: Codebase Analysis
- Analyze application architecture
- Map GUI actions to API calls
- Identify existing CLI tools

### Phase 2: CLI Architecture Design
- Design command groups matching app domains
- Plan state model and output formats
- Create software-specific SOP documents

### Phase 3: Implementation
- Create directory structure: `agent-harness/cli_anything/<software>/`
- Implement core modules with Click
- Add REPL support with JSON output mode

### Phase 4: Test Planning
- Design unit and E2E test coverage
- Plan validation scenarios

### Phase 5: Test Implementation
- Write comprehensive tests
- Ensure 100% pass rate

### Phase 6: Documentation & Publishing
- Document commands and usage
- Prepare for PyPI publishing

## Key Files

| File | Purpose |
|------|---------|
| `HARNESS.md` | Complete methodology specification |
| `commands/cli-anything.md` | Main build command |
| `commands/validate.md` | Validation command |
| `commands/test.md` | Testing command |
| `commands/refine.md` | Refinement command |
Comment on lines +69 to +73
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this context, HARNESS.md and commands/... look like they’re relative to the skill directory, but those files actually live under cli-anything-plugin/. Consider spelling the full repo paths (e.g., cli-anything-plugin/HARNESS.md, cli-anything-plugin/commands/...) or explicitly stating the base directory to avoid confusion.

Suggested change
| `HARNESS.md` | Complete methodology specification |
| `commands/cli-anything.md` | Main build command |
| `commands/validate.md` | Validation command |
| `commands/test.md` | Testing command |
| `commands/refine.md` | Refinement command |
| `cli-anything-plugin/HARNESS.md` | Complete methodology specification |
| `cli-anything-plugin/commands/cli-anything.md` | Main build command |
| `cli-anything-plugin/commands/validate.md` | Validation command |
| `cli-anything-plugin/commands/test.md` | Testing command |
| `cli-anything-plugin/commands/refine.md` | Refinement command |

Copilot uses AI. Check for mistakes.

## Output

- Stateful CLI with REPL mode
- JSON output for agent consumption
- Undo/redo support
- Full test coverage

## Related

- Plugin workflow: See `../cli-anything-plugin/` for Claude Code plugin
- Examples: See `../blender/`, `../gimp/`, `../audacity/` for implemented CLIs
Comment on lines +84 to +85
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relative paths in this section don’t resolve from .agents/skills/cli-anything/ (e.g., ../cli-anything-plugin/ points to .agents/skills/cli-anything-plugin). Use repo-root-relative paths (like cli-anything-plugin/, blender/, etc.) or correct the relative traversal (e.g., ../../../cli-anything-plugin/).

Suggested change
- Plugin workflow: See `../cli-anything-plugin/` for Claude Code plugin
- Examples: See `../blender/`, `../gimp/`, `../audacity/` for implemented CLIs
- Plugin workflow: See `cli-anything-plugin/` for Claude Code plugin
- Examples: See `blender/`, `gimp/`, `audacity/` for implemented CLIs

Copilot uses AI. Check for mistakes.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
# Step 3: Allow cli-anything-plugin entirely
!/cli-anything-plugin/

# Step 3.5: Allow .agents for repo-local skills
!/.agents/

# Step 3.6: Allow tests directory
!/tests/

# Step 4: Allow each software dir (top level only)
!/gimp/
!/blender/
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,19 @@ The playbook distills key insights from successfully building all 8 diverse, pro
/cli-anything <software-name>
```

### For Repo-Local Usage (OpenClaw Agents)

This project supports dual-entrypoint design:

1. **Plugin workflow** (see above): Use `cli-anything-plugin/` as a Claude Code plugin
2. **Repo-local skill**: Use `.agents/skills/cli-anything/` for OpenClaw agents

```bash
# The repo-local skill at .agents/skills/cli-anything/
# reuses HARNESS.md and command specs from cli-anything-plugin/
# No additional installation needed for OpenClaw agents
```

### For Generated CLIs

```bash
Expand Down
87 changes: 87 additions & 0 deletions tests/test_skill_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
Test suite for CLI-Anything repo structure validation.

This test ensures the dual-entrypoint design (plugin + repo-local skill)
is properly documented and aligned with README claims.
"""

import os
import re
Comment on lines +8 to +9
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os and re are imported but never used in this test module. Please remove the unused imports to avoid dead code and keep the test file minimal.

Suggested change
import os
import re

Copilot uses AI. Check for mistakes.
from pathlib import Path

REPO_ROOT = Path(__file__).parent.parent


def test_readme_mentions_plugin_and_skill():
"""README should mention both plugin and repo-local skill paths."""
readme = REPO_ROOT / "README.md"
content = readme.read_text()
Comment on lines +17 to +18
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.read_text() is called without an explicit encoding. To avoid platform-dependent decoding issues (especially on Windows), pass encoding="utf-8" (and optionally errors="strict") when reading README.md.

Copilot uses AI. Check for mistakes.

# Check plugin path is documented
assert "cli-anything-plugin" in content, "README should mention cli-anything-plugin"

# Check skill path is documented (dual-entrypoint)
assert ".agents/skills" in content or "repo-local" in content.lower(), \
"README should mention repo-local skill path"


def test_skill_directory_exists():
"""Repo-local skill directory should exist."""
skill_dir = REPO_ROOT / ".agents" / "skills" / "cli-anything"
assert skill_dir.exists(), f"Skill directory should exist at {skill_dir}"
assert (skill_dir / "SKILL.md").exists(), "Skill should have SKILL.md"
Comment on lines +30 to +32
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks use .exists(), which would also pass if a file exists at this path. Since this test is validating repo structure, prefer .is_dir() for directories (and .is_file() for SKILL.md) so the assertions fail on the wrong filesystem type.

Copilot uses AI. Check for mistakes.


def test_skill_reuses_harness():
"""Skill should reference the existing HARNESS.md."""
skill_md = REPO_ROOT / ".agents" / "skills" / "cli-anything" / "SKILL.md"
content = skill_md.read_text()
Comment on lines +37 to +38
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.read_text() is called without an explicit encoding. Consider using encoding="utf-8" here as well to make the test consistent and avoid locale-dependent failures.

Copilot uses AI. Check for mistakes.

assert "HARNESS.md" in content, "Skill should reference HARNESS.md"
assert "cli-anything-plugin" in content, "Skill should mention plugin for shared specs"


def test_plugin_directory_exists():
"""Plugin directory should exist for dual-entrypoint design."""
plugin_dir = REPO_ROOT / "cli-anything-plugin"
assert plugin_dir.exists(), "cli-anything-plugin directory should exist"
assert (plugin_dir / "HARNESS.md").exists(), "Plugin should have HARNESS.md"
assert (plugin_dir / "commands").exists(), "Plugin should have commands directory"
Comment on lines +47 to +49
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, consider using .is_dir() for cli-anything-plugin/ and commands/ (and .is_file() for HARNESS.md) so the structure test catches incorrect file-vs-directory cases.

Suggested change
assert plugin_dir.exists(), "cli-anything-plugin directory should exist"
assert (plugin_dir / "HARNESS.md").exists(), "Plugin should have HARNESS.md"
assert (plugin_dir / "commands").exists(), "Plugin should have commands directory"
assert plugin_dir.is_dir(), "cli-anything-plugin directory should exist and be a directory"
assert (plugin_dir / "HARNESS.md").is_file(), "Plugin should have HARNESS.md as a file"
assert (plugin_dir / "commands").is_dir(), "Plugin should have commands directory"

Copilot uses AI. Check for mistakes.


def test_example_appsocumented():
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test function name has a typo: test_example_appsocumented reads like it’s missing a word (e.g., apps_documented). Renaming will make failures/searching clearer.

Copilot uses AI. Check for mistakes.
"""README should list example applications."""
readme = REPO_ROOT / "README.md"
content = readme.read_text()
Comment on lines +54 to +55
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.read_text() is called without an explicit encoding. Please specify encoding="utf-8" when reading README.md to prevent failures on systems where the default encoding isn't UTF-8.

Copilot uses AI. Check for mistakes.

examples = ["GIMP", "Blender", "Inkscape", "Audacity"]
for example in examples:
assert example in content, f"README should mention {example} as example"


if __name__ == "__main__":
import sys

tests = [
test_readme_mentions_plugin_and_skill,
test_skill_directory_exists,
test_skill_reuses_harness,
test_plugin_directory_exists,
test_example_appsocumented,
]

failed = []
for test in tests:
try:
test()
print(f"✓ {test.__name__}")
except AssertionError as e:
print(f"✗ {test.__name__}: {e}")
failed.append(test.__name__)

if failed:
print(f"\n{len(failed)} test(s) failed")
sys.exit(1)
else:
print(f"\nAll {len(tests)} tests passed!")
sys.exit(0)
Loading