chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
# cli-anything Command
|
||||
|
||||
Build a complete, stateful CLI harness for any GUI application.
|
||||
|
||||
## CRITICAL: Read HARNESS.md First
|
||||
|
||||
**Before doing anything else, you MUST read `./HARNESS.md`.** It defines the complete methodology, architecture standards, and implementation patterns. Every phase below follows HARNESS.md. Do not improvise — follow the harness specification.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/cli-anything <software-path-or-repo>
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- `<software-path-or-repo>` - **Required.** Either:
|
||||
- A **local path** to the software source code (e.g., `/home/user/gimp`, `./blender`)
|
||||
- A **GitHub repository URL** (e.g., `https://github.com/GNOME/gimp`, `github.com/blender/blender`)
|
||||
|
||||
If a GitHub URL is provided, the agent clones the repo locally first, then works on the local copy.
|
||||
|
||||
**Note:** Software names alone (e.g., "gimp") are NOT accepted. You must provide the actual source code path or repository URL so the agent can analyze the codebase.
|
||||
|
||||
## What This Command Does
|
||||
|
||||
This command implements the complete cli-anything methodology to build a production-ready CLI harness for any GUI application. **All phases follow the standards defined in HARNESS.md.**
|
||||
|
||||
### Phase 0: Source Acquisition
|
||||
- If `<software-path-or-repo>` is a GitHub URL, clone it to a local working directory
|
||||
- Verify the local path exists and contains source code
|
||||
- Derive the software name from the directory name (e.g., `/home/user/gimp` -> `gimp`)
|
||||
|
||||
### Phase 1: Codebase Analysis
|
||||
- Analyzes the local source code
|
||||
- Analyzes the backend engine and data model
|
||||
- Maps GUI actions to API calls
|
||||
- Identifies existing CLI tools
|
||||
- Documents the architecture
|
||||
|
||||
### Phase 2: CLI Architecture Design
|
||||
- Designs command groups matching the app's domains
|
||||
- Plans the state model and output formats
|
||||
- Creates the software-specific SOP document (e.g., GIMP.md)
|
||||
|
||||
### Phase 3: Implementation
|
||||
- Creates the directory structure: `agent-harness/cli_anything/<software>/core`, `utils`, `tests`
|
||||
- Implements core modules (project, session, export, etc.)
|
||||
- Builds the Click-based CLI with REPL support
|
||||
- Implements `--json` output mode for agent consumption
|
||||
- All imports use `cli_anything.<software>.*` namespace
|
||||
|
||||
### Phase 4: Test Planning
|
||||
- Creates `TEST.md` with comprehensive test plan
|
||||
- Plans unit tests for all core modules
|
||||
- Plans E2E tests with real files
|
||||
- Designs realistic workflow scenarios
|
||||
|
||||
### Phase 5: Test Implementation
|
||||
- Writes unit tests (`test_core.py`) - synthetic data, no external deps
|
||||
- Writes E2E tests (`test_full_e2e.py`) - real files, full pipeline
|
||||
- Implements workflow tests simulating real-world usage
|
||||
- Adds output verification (pixel analysis, format validation, etc.)
|
||||
- Adds `TestCLISubprocess` class with `_resolve_cli("cli-anything-<software>")`
|
||||
that tests the installed command via subprocess (no hardcoded paths or CWD)
|
||||
|
||||
### Phase 6: Test Documentation
|
||||
- Runs all tests with `pytest -v --tb=no`
|
||||
- Appends full test results to `TEST.md`
|
||||
- Documents test coverage and any gaps
|
||||
|
||||
### Phase 6.5: SKILL.md Generation
|
||||
- Extracts CLI metadata using `skill_generator.py`
|
||||
- Generates SKILL.md with YAML frontmatter and Markdown body
|
||||
- Includes command groups, examples, and agent-specific guidance
|
||||
- Outputs the canonical skill to `skills/cli-anything-<software>/SKILL.md` and refreshes the packaged compatibility copy at `cli_anything/<software>/skills/SKILL.md`
|
||||
- Makes the CLI discoverable and usable by AI agents
|
||||
|
||||
### Phase 7: PyPI Publishing and Installation
|
||||
- Creates `setup.py` with `find_namespace_packages(include=["cli_anything.*"])`
|
||||
- Package name: `cli-anything-<software>`, namespace: `cli_anything.<software>`
|
||||
- `cli_anything/` has NO `__init__.py` (PEP 420 namespace package)
|
||||
- Configures console_scripts entry point for PATH installation
|
||||
- Tests local installation with `pip install -e .`
|
||||
- Verifies CLI is available in PATH: `which cli-anything-<software>`
|
||||
|
||||
## Output Structure
|
||||
|
||||
```
|
||||
<software-name>/
|
||||
└── agent-harness/
|
||||
├── <SOFTWARE>.md # Software-specific SOP
|
||||
├── setup.py # PyPI package config (find_namespace_packages)
|
||||
└── cli_anything/ # Namespace package (NO __init__.py)
|
||||
└── <software>/ # Sub-package (HAS __init__.py)
|
||||
├── README.md # Installation and usage guide
|
||||
├── <software>_cli.py # Main CLI entry point
|
||||
├── core/ # Core modules
|
||||
│ ├── project.py
|
||||
│ ├── session.py
|
||||
│ ├── export.py
|
||||
│ └── ...
|
||||
├── utils/ # Utilities
|
||||
└── tests/
|
||||
├── TEST.md # Test plan and results
|
||||
├── test_core.py # Unit tests
|
||||
└── test_full_e2e.py # E2E tests
|
||||
```
|
||||
|
||||
Canonical repo-root skill output:
|
||||
|
||||
```
|
||||
skills/
|
||||
└── cli-anything-<software>/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
# Build a CLI for GIMP from local source
|
||||
/cli-anything /home/user/gimp
|
||||
|
||||
# Build from a GitHub repo
|
||||
/cli-anything https://github.com/blender/blender
|
||||
```
|
||||
|
||||
## Auto-Save + --dry-run (Required for Session-Based CLIs)
|
||||
|
||||
**Session-based CLIs must auto-save after one-shot mutations.** Without this, one-shot commands silently lose changes because `save_session()` is never called before the process exits. A `--dry-run` flag must also be provided to suppress the save.
|
||||
|
||||
See [`guides/auto-save-dry-run.md`](../guides/auto-save-dry-run.md) for the full pattern, code examples, and when it applies.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
The command succeeds when:
|
||||
1. All core modules are implemented and functional
|
||||
2. CLI supports both one-shot commands and REPL mode
|
||||
3. `--json` output mode works for all commands
|
||||
4. All tests pass (100% pass rate)
|
||||
5. Subprocess tests use `_resolve_cli()` and pass with `CLI_ANYTHING_FORCE_INSTALLED=1`
|
||||
6. TEST.md contains both plan and results
|
||||
7. README.md documents installation and usage
|
||||
8. SKILL.md is generated with proper YAML frontmatter and command documentation
|
||||
9. setup.py is created and local installation works
|
||||
10. CLI is available in PATH as `cli-anything-<software>`
|
||||
11. **Session-based CLIs implement auto-save + `--dry-run`** (see [guide](../guides/auto-save-dry-run.md))
|
||||
@@ -0,0 +1,237 @@
|
||||
# cli-anything:list Command
|
||||
|
||||
List all available CLI-Anything tools (installed and generated).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/cli-anything:list [--path <directory>] [--depth <n>] [--json]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- `--path <directory>` - Directory to search for generated CLIs (default: current directory)
|
||||
- `--depth <n>` - Maximum recursion depth for scanning (default: unlimited). Use `0` for current directory only, `1` for one level deep, etc.
|
||||
- `--json` - Output in JSON format for machine parsing
|
||||
|
||||
## What This Command Does
|
||||
|
||||
Displays all CLI-Anything tools available in the system:
|
||||
|
||||
### 1. Installed CLIs
|
||||
|
||||
Uses `importlib.metadata` to find installed `cli-anything-*` packages:
|
||||
- Pattern: package name starts with `cli-anything-`
|
||||
- Extracts: software name, version, entry point
|
||||
|
||||
```python
|
||||
from importlib.metadata import distributions
|
||||
|
||||
installed = {}
|
||||
for dist in distributions():
|
||||
name = dist.metadata.get("Name", "")
|
||||
if name.startswith("cli-anything-"):
|
||||
software = name.replace("cli-anything-", "")
|
||||
version = dist.version
|
||||
# Find executable via entry points or shutil.which
|
||||
executable = shutil.which(f"cli-anything-{software}")
|
||||
installed[software] = {
|
||||
"status": "installed",
|
||||
"version": version,
|
||||
"executable": executable
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Generated CLIs
|
||||
|
||||
Uses `glob` to find local CLI directories:
|
||||
- Pattern: `**/agent-harness/cli_anything/*/__init__.py` (or depth-limited variant)
|
||||
- Extracts: software name, version (from setup.py), source path
|
||||
- Status: `generated`
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
import glob
|
||||
import re
|
||||
|
||||
search_path = args.get("path", ".")
|
||||
max_depth = args.get("depth", None) # None means unlimited
|
||||
generated = {}
|
||||
|
||||
def extract_version_from_setup(setup_path):
|
||||
"""Extract version from setup.py using regex."""
|
||||
try:
|
||||
content = Path(setup_path).read_text()
|
||||
match = re.search(r'version\s*=\s*["\']([^"\']+)["\']', content)
|
||||
return match.group(1) if match else None
|
||||
except:
|
||||
return None
|
||||
|
||||
def build_glob_patterns(base_path, depth):
|
||||
"""Build list of glob patterns for depths 0 through max_depth.
|
||||
|
||||
Returns multiple patterns so that --depth 2 finds tools at depth 0, 1, AND 2.
|
||||
"""
|
||||
base = Path(base_path)
|
||||
suffix = "agent-harness/cli_anything/*/__init__.py"
|
||||
|
||||
if depth is None:
|
||||
# Unlimited depth: use **
|
||||
return [str(base / "**" / suffix)]
|
||||
|
||||
# Generate patterns for all depths from 0 to max_depth
|
||||
patterns = []
|
||||
for d in range(depth + 1):
|
||||
if d == 0:
|
||||
# depth 0: look in current directory
|
||||
patterns.append(str(base / suffix))
|
||||
else:
|
||||
# depth N: look N levels deep
|
||||
prefix = "/".join(["*"] * d)
|
||||
patterns.append(str(base / prefix / suffix))
|
||||
return patterns
|
||||
|
||||
patterns = build_glob_patterns(search_path, max_depth)
|
||||
for pattern in patterns:
|
||||
for init_file in glob.glob(pattern, recursive=True):
|
||||
parts = Path(init_file).parts
|
||||
# Find cli_anything/<software> pattern
|
||||
for i, p in enumerate(parts):
|
||||
if p == "cli_anything" and i + 1 < len(parts):
|
||||
software = parts[i + 1]
|
||||
# Get agent-harness directory as source
|
||||
agent_harness_idx = parts.index("agent-harness") if "agent-harness" in parts else i - 1
|
||||
source = str(Path(*parts[:agent_harness_idx + 2])) # up to agent-harness
|
||||
# Extract version from setup.py (setup.py is in agent-harness/, not cli_anything/)
|
||||
setup_path = Path(*parts[:agent_harness_idx + 1]) / "setup.py"
|
||||
version = extract_version_from_setup(setup_path)
|
||||
generated[software] = {
|
||||
"status": "generated",
|
||||
"version": version,
|
||||
"executable": None,
|
||||
"source": source
|
||||
}
|
||||
break
|
||||
```
|
||||
|
||||
### 3. Merge Results
|
||||
|
||||
- Deduplicate by software name
|
||||
- If both installed and generated: show `installed` status with both paths
|
||||
- The `source` field shows where the generated code is (even for installed)
|
||||
|
||||
## Output Formats
|
||||
|
||||
### Table Format (default)
|
||||
|
||||
```
|
||||
CLI-Anything Tools (found 5)
|
||||
|
||||
Name Status Version Source
|
||||
──────────────────────────────────────────────────────────────
|
||||
gimp installed 1.0.0 ./gimp/agent-harness
|
||||
blender installed 1.0.0 ./blender/agent-harness
|
||||
inkscape generated 1.0.0 ./inkscape/agent-harness
|
||||
audacity generated 1.0.0 ./audacity/agent-harness
|
||||
libreoffice generated 1.0.0 ./libreoffice/agent-harness
|
||||
```
|
||||
|
||||
### JSON Format (--json)
|
||||
|
||||
```json
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"name": "gimp",
|
||||
"status": "installed",
|
||||
"version": "1.0.0",
|
||||
"executable": "/usr/local/bin/cli-anything-gimp",
|
||||
"source": "./gimp/agent-harness"
|
||||
},
|
||||
{
|
||||
"name": "inkscape",
|
||||
"status": "generated",
|
||||
"version": "1.0.0",
|
||||
"executable": null,
|
||||
"source": "./inkscape/agent-harness"
|
||||
}
|
||||
],
|
||||
"total": 2,
|
||||
"installed": 1,
|
||||
"generated_only": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Scenario | Action |
|
||||
|----------|--------|
|
||||
| No CLIs found | Show "No CLI-Anything tools found" message |
|
||||
| Invalid --path | Show error: "Path not found: <path>" |
|
||||
| Permission denied | Skip directory, continue scanning, show warning |
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
When this command is invoked, the agent should:
|
||||
|
||||
1. **Parse arguments**
|
||||
- Extract `--path` value (default: `.`)
|
||||
- Extract `--depth` value (default: `None` for unlimited recursion)
|
||||
- Extract `--json` flag (default: false)
|
||||
|
||||
2. **Validate path exists**
|
||||
- If `--path` specified and doesn't exist, show error and exit
|
||||
|
||||
3. **Scan installed CLIs**
|
||||
- Use `importlib.metadata.distributions()` to find all packages
|
||||
- Filter for packages starting with `cli-anything-`
|
||||
- Extract name, version, find executable path
|
||||
|
||||
4. **Scan generated CLIs**
|
||||
- Build glob pattern based on depth parameter
|
||||
- Use `glob.glob(pattern, recursive=True)`
|
||||
- Parse directory structure to extract software name
|
||||
- Calculate relative path from current directory
|
||||
|
||||
5. **Merge results**
|
||||
- Create dict keyed by software name
|
||||
- Prefer installed data when both exist
|
||||
- Keep source path from generated if available
|
||||
|
||||
6. **Format output**
|
||||
- If `--json`: output JSON to stdout
|
||||
- Otherwise: format as table with proper alignment
|
||||
|
||||
7. **Print results**
|
||||
- Show summary line with count
|
||||
- Show table or JSON
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# List all tools in current directory (unlimited depth)
|
||||
/cli-anything:list
|
||||
|
||||
# List tools with depth limit (only scan 2 levels deep)
|
||||
/cli-anything:list --depth 2
|
||||
|
||||
# List tools in current directory only (no recursion)
|
||||
/cli-anything:list --depth 0
|
||||
|
||||
# List tools with JSON output
|
||||
/cli-anything:list --json
|
||||
|
||||
# Search a specific directory with depth limit
|
||||
/cli-anything:list --path /projects/my-tools --depth 3
|
||||
|
||||
# Combined
|
||||
/cli-anything:list --path ./output --depth 2 --json
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `--depth` controls how many directory levels to descend from the search path
|
||||
- Default depth is unlimited (`**` glob pattern)
|
||||
- CLI-Anything tools typically need at least 3-4 levels to find `agent-harness/cli_anything/software/__init__.py`
|
||||
- Relative paths are preferred for readability
|
||||
- The command should work without any external dependencies beyond Python stdlib
|
||||
@@ -0,0 +1,104 @@
|
||||
# cli-anything:refine Command
|
||||
|
||||
Refine an existing CLI harness to improve coverage of the software's functions and usage patterns.
|
||||
|
||||
## CRITICAL: Read HARNESS.md First
|
||||
|
||||
**Before refining, read `./HARNESS.md`.** All new commands and tests must follow the same standards as the original build. HARNESS.md is the single source of truth for architecture, patterns, and quality requirements.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/cli-anything:refine <software-path> [focus]
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- `<software-path>` - **Required.** Local path to the software source code (e.g., `/home/user/gimp`, `./blender`). Must be the same source tree used during the original build.
|
||||
|
||||
**Note:** Only local paths are accepted. If you need to work from a GitHub repo, clone it first with `/cli-anything`, then refine.
|
||||
|
||||
- `[focus]` - **Optional.** A natural-language description of the functionality area to focus on. When provided, the agent skips broad gap analysis and instead targets the specified capability area.
|
||||
|
||||
Examples:
|
||||
- `/cli-anything:refine /home/user/shotcut "vid-in-vid and picture-in-picture features"`
|
||||
- `/cli-anything:refine /home/user/gimp "all batch processing and scripting filters"`
|
||||
- `/cli-anything:refine /home/user/blender "particle systems and physics simulation"`
|
||||
- `/cli-anything:refine /home/user/inkscape "path boolean operations and clipping"`
|
||||
|
||||
When `[focus]` is provided:
|
||||
- Step 2 (Analyze Software Capabilities) narrows to only the specified area
|
||||
- Step 3 (Gap Analysis) compares only the focused capabilities against current coverage
|
||||
- The agent should still present findings before implementing, but scoped to the focus area
|
||||
|
||||
## What This Command Does
|
||||
|
||||
This command is used **after** a CLI harness has already been built with `/cli-anything`. It analyzes gaps between the software's full capabilities and what the current CLI covers, then iteratively expands coverage. If a `[focus]` is given, the agent narrows its analysis and implementation to that specific functionality area.
|
||||
|
||||
### Step 1: Inventory Current Coverage
|
||||
- Read the existing CLI entry point (`<software>_cli.py`) and all core modules
|
||||
- List every command, subcommand, and option currently implemented
|
||||
- Read the existing test suite to understand what's tested
|
||||
- Build a coverage map: `{ function_name: covered | not_covered }`
|
||||
|
||||
### Step 2: Analyze Software Capabilities
|
||||
- Re-scan the software source at `<software-path>`
|
||||
- Identify all public APIs, CLI tools, scripting interfaces, and batch-mode operations
|
||||
- Focus on functions that produce observable output (renders, exports, transforms, conversions)
|
||||
- Categorize by domain (e.g., for GIMP: filters, color adjustments, layer ops, selection tools)
|
||||
|
||||
### Step 3: Gap Analysis
|
||||
- Compare current CLI coverage against the software's full capability set
|
||||
- Prioritize gaps by:
|
||||
1. **High impact** — commonly used functions missing from the CLI
|
||||
2. **Easy wins** — functions with simple APIs that can be wrapped quickly
|
||||
3. **Composability** — functions that unlock new workflows when combined with existing commands
|
||||
- Present the gap report to the user and confirm which gaps to address
|
||||
|
||||
### Step 4: Implement New Commands
|
||||
- Add new commands/subcommands to the CLI for the selected gaps
|
||||
- Follow the same patterns as existing commands (as defined in HARNESS.md):
|
||||
- Click command groups
|
||||
- `--json` output support
|
||||
- Session state integration
|
||||
- Error handling with `handle_error`
|
||||
- Add corresponding core module functions in `core/` or `utils/`
|
||||
|
||||
### Step 5: Expand Tests
|
||||
- Add unit tests for every new function in `test_core.py`
|
||||
- Add E2E tests for new commands in `test_full_e2e.py`
|
||||
- Add workflow tests that combine new commands with existing ones
|
||||
- Run all tests (old + new) to ensure no regressions
|
||||
|
||||
### Step 6: Update Documentation
|
||||
- Update `README.md` with new commands and usage examples
|
||||
- Update `TEST.md` with new test results
|
||||
- Update the SOP document (`<SOFTWARE>.md`) with new coverage notes
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
# Broad refinement — agent finds gaps across all capabilities
|
||||
/cli-anything:refine /home/user/gimp
|
||||
|
||||
# Focused refinement — agent targets a specific functionality area
|
||||
/cli-anything:refine /home/user/shotcut "vid-in-vid and picture-in-picture compositing"
|
||||
/cli-anything:refine /home/user/gimp "batch processing and Script-Fu filters"
|
||||
/cli-anything:refine /home/user/blender "particle systems and physics simulation"
|
||||
/cli-anything:refine /home/user/inkscape "path boolean operations and clipping masks"
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- All existing tests still pass (no regressions)
|
||||
- New commands follow the same architectural patterns (per HARNESS.md)
|
||||
- New tests achieve 100% pass rate
|
||||
- Coverage meaningfully improved (new functions exposed via CLI)
|
||||
- Documentation updated to reflect changes
|
||||
|
||||
## Notes
|
||||
|
||||
- Refine is incremental — run it multiple times to steadily expand coverage
|
||||
- Each run should focus on a coherent set of related functions rather than trying to cover everything at once
|
||||
- The agent should present the gap analysis before implementing, so the user can steer priorities
|
||||
- Refine never removes existing commands — it only adds or enhances
|
||||
@@ -0,0 +1,73 @@
|
||||
# cli-anything:test Command
|
||||
|
||||
Run tests for a CLI harness and update TEST.md with results.
|
||||
|
||||
## CRITICAL: Read HARNESS.md First
|
||||
|
||||
**Before running tests, read `./HARNESS.md`.** It defines the test standards, expected structure, and what constitutes a passing test suite.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/cli-anything:test <software-path-or-repo>
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- `<software-path-or-repo>` - **Required.** Either:
|
||||
- A **local path** to the software source code (e.g., `/home/user/gimp`, `./blender`)
|
||||
- A **GitHub repository URL** (e.g., `https://github.com/GNOME/gimp`, `github.com/blender/blender`)
|
||||
|
||||
If a GitHub URL is provided, the agent clones the repo locally first, then works on the local copy.
|
||||
|
||||
The software name is derived from the directory name. The agent locates the CLI harness at `/root/cli-anything/<software-name>/agent-harness/`.
|
||||
|
||||
## What This Command Does
|
||||
|
||||
1. **Locates the CLI** - Finds the CLI harness based on the software path
|
||||
2. **Runs pytest** - Executes tests with `-v -s --tb=short`
|
||||
3. **Captures output** - Saves full test results
|
||||
4. **Verifies subprocess backend** - Confirms `[_resolve_cli] Using installed command:` appears in output
|
||||
5. **Updates TEST.md** - Appends results to the Test Results section
|
||||
6. **Reports status** - Shows pass/fail summary
|
||||
|
||||
## Test Output Format
|
||||
|
||||
The command appends to TEST.md:
|
||||
|
||||
```markdown
|
||||
## Test Results
|
||||
|
||||
Last run: 2024-03-05 14:30:00
|
||||
|
||||
```
|
||||
[full pytest -v --tb=no output]
|
||||
```
|
||||
|
||||
**Summary**: 103 passed in 3.05s
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
# Run all tests for GIMP CLI
|
||||
/cli-anything:test /home/user/gimp
|
||||
|
||||
# Run tests for Blender from GitHub
|
||||
/cli-anything:test https://github.com/blender/blender
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- All tests pass (100% pass rate)
|
||||
- TEST.md is updated with full results
|
||||
- No test failures or errors
|
||||
- `[_resolve_cli]` output confirms installed command path
|
||||
|
||||
## Failure Handling
|
||||
|
||||
If tests fail:
|
||||
1. Shows which tests failed
|
||||
2. Does NOT update TEST.md (keeps previous passing results)
|
||||
3. Suggests fixes based on error messages
|
||||
4. Offers to re-run after fixes
|
||||
@@ -0,0 +1,123 @@
|
||||
# cli-anything:validate Command
|
||||
|
||||
Validate a CLI harness against HARNESS.md standards and best practices.
|
||||
|
||||
## CRITICAL: Read HARNESS.md First
|
||||
|
||||
**Before validating, read `./HARNESS.md`.** It is the single source of truth for all validation checks below. Every check in this command maps to a requirement in HARNESS.md.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
/cli-anything:validate <software-path-or-repo>
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- `<software-path-or-repo>` - **Required.** Either:
|
||||
- A **local path** to the software source code (e.g., `/home/user/gimp`, `./blender`)
|
||||
- A **GitHub repository URL** (e.g., `https://github.com/GNOME/gimp`, `github.com/blender/blender`)
|
||||
|
||||
If a GitHub URL is provided, the agent clones the repo locally first, then works on the local copy.
|
||||
|
||||
The software name is derived from the directory name. The agent locates the CLI harness at `/root/cli-anything/<software-name>/agent-harness/`.
|
||||
|
||||
## What This Command Validates
|
||||
|
||||
### 1. Directory Structure
|
||||
- `agent-harness/cli_anything/<software>/` exists (namespace sub-package)
|
||||
- `cli_anything/` has NO `__init__.py` (PEP 420 namespace package)
|
||||
- `<software>/` HAS `__init__.py` (regular sub-package)
|
||||
- `core/`, `utils/`, `tests/` subdirectories present
|
||||
- `setup.py` in agent-harness/ uses `find_namespace_packages`
|
||||
|
||||
### 2. Required Files
|
||||
- `README.md` - Installation and usage guide
|
||||
- `<software>_cli.py` - Main CLI entry point
|
||||
- `core/project.py` - Project management
|
||||
- `core/session.py` - Undo/redo
|
||||
- `core/export.py` - Rendering/export
|
||||
- `tests/TEST.md` - Test plan and results
|
||||
- `tests/test_core.py` - Unit tests
|
||||
- `tests/test_full_e2e.py` - E2E tests
|
||||
- `../<SOFTWARE>.md` - Software-specific SOP
|
||||
|
||||
### 3. CLI Implementation Standards
|
||||
- Uses Click framework
|
||||
- Has command groups (not flat commands)
|
||||
- Implements `--json` flag for machine-readable output
|
||||
- Implements `--project` flag for project file
|
||||
- Has `handle_error` decorator for consistent error handling
|
||||
- Has REPL mode
|
||||
- Has global session state
|
||||
|
||||
### 4. Core Module Standards
|
||||
- `project.py` has: create, open, save, info, list_profiles
|
||||
- `session.py` has: Session class with undo/redo/snapshot
|
||||
- `export.py` has: render function and EXPORT_PRESETS
|
||||
- All modules have proper docstrings
|
||||
- All functions have type hints
|
||||
|
||||
### 5. Test Standards
|
||||
- `TEST.md` has both plan (Part 1) and results (Part 2)
|
||||
- Unit tests use synthetic data only
|
||||
- E2E tests use real files
|
||||
- Workflow tests simulate real-world scenarios
|
||||
- `test_full_e2e.py` has a `TestCLISubprocess` class
|
||||
- `TestCLISubprocess` uses `_resolve_cli("cli-anything-<software>")` (no hardcoded paths)
|
||||
- `_resolve_cli` prints which backend is used and supports `CLI_ANYTHING_FORCE_INSTALLED`
|
||||
- Subprocess `_run` does NOT set `cwd` (installed commands work from any directory)
|
||||
- All tests pass (100% pass rate)
|
||||
|
||||
### 6. Documentation Standards
|
||||
- `README.md` has: installation, usage, command reference, examples
|
||||
- `<SOFTWARE>.md` has: architecture analysis, command map, rendering gap assessment
|
||||
- No duplicate `HARNESS.md` (should reference plugin's HARNESS.md)
|
||||
- All commands documented with examples
|
||||
|
||||
### 7. PyPI Packaging Standards
|
||||
- `setup.py` uses `find_namespace_packages(include=["cli_anything.*"])`
|
||||
- Package name follows `cli-anything-<software>` convention
|
||||
- Entry point: `cli-anything-<software>=cli_anything.<software>.<software>_cli:main`
|
||||
- `cli_anything/` has NO `__init__.py` (namespace package rule)
|
||||
- All imports use `cli_anything.<software>.*` prefix
|
||||
- Dependencies listed in install_requires
|
||||
- Python version requirement specified (>=3.10)
|
||||
|
||||
### 8. Code Quality
|
||||
- No syntax errors
|
||||
- No import errors
|
||||
- Follows PEP 8 style
|
||||
- No hardcoded paths (uses relative paths or config)
|
||||
- Proper error handling (no bare `except:`)
|
||||
|
||||
## Validation Report
|
||||
|
||||
The command generates a detailed report:
|
||||
|
||||
```
|
||||
CLI Harness Validation Report
|
||||
Software: gimp
|
||||
Path: /root/cli-anything/gimp/agent-harness/cli_anything/gimp
|
||||
|
||||
Directory Structure (5/5 checks passed)
|
||||
Required Files (9/9 files present)
|
||||
CLI Implementation (7/7 standards met)
|
||||
Core Modules (5/5 standards met)
|
||||
Test Standards (10/10 standards met)
|
||||
Documentation (4/4 standards met)
|
||||
PyPI Packaging (7/7 standards met)
|
||||
Code Quality (5/5 checks passed)
|
||||
|
||||
Overall: PASS (52/52 checks)
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
# Validate GIMP CLI
|
||||
/cli-anything:validate /home/user/gimp
|
||||
|
||||
# Validate from GitHub repo
|
||||
/cli-anything:validate https://github.com/blender/blender
|
||||
```
|
||||
Reference in New Issue
Block a user