feat: Add repo-local skill support + structure tests#31
feat: Add repo-local skill support + structure tests#31Jah-yee wants to merge 1 commit intoHKUDS:mainfrom
Conversation
- Add .agents/skills/cli-anything/ for OpenClaw agents - Add tests/test_skill_layout.py for dual-entrypoint validation - Update README.md with repo-local skill documentation - Update .gitignore to include new directories Implements issue HKUDS#30
There was a problem hiding this comment.
Pull request overview
Adds support for a repo-local OpenClaw agent skill alongside the existing cli-anything-plugin/ workflow, with a small structure-validation test and supporting documentation/ignore rules.
Changes:
- Added repo-local skill definition at
.agents/skills/cli-anything/SKILL.md - Added
tests/test_skill_layout.pyto validate the dual-entrypoint layout and README claims - Updated
README.mdand.gitignoreto document and include the new layout
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
tests/test_skill_layout.py |
Adds structure/documentation validation tests for plugin + repo-local skill layout |
README.md |
Documents dual-entrypoint usage for OpenClaw agents |
.gitignore |
Allows .agents/ and tests/ to be tracked under an “ignore everything else” policy |
.agents/skills/cli-anything/SKILL.md |
Introduces the repo-local skill definition and references shared plugin specs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| import os | ||
| import re |
There was a problem hiding this comment.
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.
| import os | |
| import re |
| readme = REPO_ROOT / "README.md" | ||
| content = readme.read_text() |
There was a problem hiding this comment.
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.
| 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" |
There was a problem hiding this comment.
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.
| 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" |
There was a problem hiding this comment.
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.
| 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" |
| assert (plugin_dir / "commands").exists(), "Plugin should have commands directory" | ||
|
|
||
|
|
||
| def test_example_appsocumented(): |
There was a problem hiding this comment.
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.
|
|
||
| - Python 3.10+ | ||
| - click >= 8.0 | ||
| - pytest |
There was a problem hiding this comment.
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.
| - pytest | |
| - pytest | |
| - pyyaml |
| skill_md = REPO_ROOT / ".agents" / "skills" / "cli-anything" / "SKILL.md" | ||
| content = skill_md.read_text() |
There was a problem hiding this comment.
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.
| readme = REPO_ROOT / "README.md" | ||
| content = readme.read_text() |
There was a problem hiding this comment.
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.
| - Plugin workflow: See `../cli-anything-plugin/` for Claude Code plugin | ||
| - Examples: See `../blender/`, `../gimp/`, `../audacity/` for implemented CLIs |
There was a problem hiding this comment.
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/).
| - 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 |
| | `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 | |
There was a problem hiding this comment.
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.
| | `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 | |
Summary
.agents/skills/cli-anything/skill for OpenClaw agentstests/test_skill_layout.pyfor dual-entrypoint validationChanges
New Files
.agents/skills/cli-anything/SKILL.md- Skill definitiontests/test_skill_layout.py- Structure testsModified
.gitignore- Added new directoriesREADME.md- Added dual-entrypoint documentationValidation
All 5 tests pass.