How the CLI-Anything Skill Generator Parses and Formats YAML Frontmatter for Agent Skill Discovery
The skill_generator.py script in HKUDS/CLI-Anything extracts CLI metadata and manually assembles a YAML frontmatter block using folded block scalars (>-), creating a discoverable SKILL.md file that agents parse to identify available skills by their name and description fields.
The HKUDS/CLI-Anything repository provides a framework for wrapping command-line interfaces into agent-compatible skills. At the heart of this system lies the skill generator, which transforms source code metadata into structured YAML frontmatter embedded in Markdown files, enabling automated discovery by AI agents scanning the repository.
Extracting CLI Metadata from Source Code
The skill generation process begins with deep inspection of the harness directory. The extract_cli_metadata function walks the project structure, extracting critical information needed for the frontmatter.
Directory Walking and AST Parsing
At lines 72-80 of zotero/agent-harness/skill_generator.py, the generator:
- Reads the README for introductory descriptions
- Pulls version strings from
setup.py - Discovers command groups and commands by parsing CLI source files using Python's
astmodule
The command extraction logic at lines 13-47 specifically hunts for @cli.group and @cli.command decorators within files like zotero/agent-harness/cli_anything/zotero/zotero_cli.py, building a complete map of the CLI's capabilities before formatting begins.
Constructing the YAML Frontmatter Block
Once metadata is collected, the generator formats it into a strict YAML structure that precedes the Markdown body content.
Manual Assembly with Folded Block Scalars
The generate_skill_md_simple function (lines 94-99) manually constructs the frontmatter using literal string concatenation:
---
name: >-
{skill_name}
description: >-
{skill_description}
---
The >- indicator is a YAML folded block scalar that strips newlines while preserving the content as a single logical line. This allows the source code to indent values for readability while ensuring agents receive compact, single-line strings for the name and description fields.
Required Frontmatter Fields
Every generated SKILL.md contains exactly two metadata keys:
name: A unique identifier (e.g.,cli-anything-zotero) that serves as the skill's canonical referencedescription: A brief, searchable summary of the CLI harness functionality
Template-Based Rendering with Jinja2 Fallback
While manual string assembly serves as the default, the generator supports sophisticated templating when available.
The generate_skill_md function (lines 44-50) attempts to load zotero/agent-harness/templates/SKILL.md.template and render the same frontmatter variables through Jinja2. If Jinja2 is not installed, the code gracefully falls back to generate_skill_md_simple (lines 45-48), ensuring the skill file is always produced regardless of optional dependencies.
Normalizing Markdown Output
After rendering, the _normalize_generated_markdown function (lines 37-41) performs final cleanup:
- Removes stray blank lines that could confuse YAML parsers
- Ensures the file terminates with a single newline character
- Guarantees the document conforms to strict Markdown/YAML hybrid formatting
This normalization step prevents parsing errors when agents read the file boundaries between the YAML frontmatter and the Markdown content body.
How Agents Discover Skills via Frontmatter
Agent frameworks implementing the CLI-Anything protocol scan repositories for Markdown files matching a specific header pattern. The discovery mechanism looks for files where the first three lines match:
---
name: ...
description: ...
---
Once identified, YAML parsers extract the name and description keys to register the skill for agent-native discovery. This convention allows any compatible agent to automatically inventory available CLI tools by parsing standardized metadata rather than executing arbitrary code.
Generating Skill Files
Command-Line Execution
Generate a skill file directly from the repository root:
python -m zotero.agent-harness.skill_generator /path/to/zotero/agent-harness \
-o ./skills/cli-anything-zotero/SKILL.md
The command outputs the path to the newly written SKILL.md containing the properly formatted frontmatter.
Programmatic API Usage
Import the generator functions directly in Python:
from zotero.agent_harness.skill_generator import generate_skill_file
skill_path = generate_skill_file(
harness_path="zotero/agent-harness",
output_path="skills/cli-anything-zotero/SKILL.md"
)
print(f"Skill file written to {skill_path}")
Verifying the YAML Structure
Inspect the generated frontmatter to confirm proper formatting:
from pathlib import Path
content = Path("skills/cli-anything-zotero/SKILL.md").read_text()
print(content.split("\n")[:5])
# Output:
# ['---',
# 'name: >-',
# ' cli-anything-zotero',
# 'description: >-',
# ' CLI harness for Zotero.']
Summary
- The
extract_cli_metadatafunction inskill_generator.pyuses AST parsing to extract CLI commands and metadata from harness source code. generate_skill_md_simplemanually assembles YAML frontmatter using the folded block scalar syntax (>-) to ensure single-line values with readable indentation.- The frontmatter requires exactly two fields:
namefor unique identification anddescriptionfor searchable summaries. - A Jinja2 template fallback at lines 44-50 provides extensibility while maintaining a hardcoded string fallback for environments without Jinja2.
_normalize_generated_markdownensures the output file ends with a newline and contains no stray blank lines, preserving YAML validity.- Agent discovery relies on parsing the specific
---\nname: ...\ndescription: ...\n---pattern found at the start ofSKILL.mdfiles throughout the repository.
Frequently Asked Questions
What YAML syntax does the skill generator use for multi-line strings?
The generator uses the folded block scalar indicator >- (lines 94-99). This YAML syntax strips literal newlines from the source while treating the indented content as a single logical line, allowing the Python code to format values across multiple lines for readability without breaking the YAML structure.
How does the skill generator handle missing Jinja2 dependencies?
If Jinja2 is not installed, the generate_skill_md function (lines 44-50) catches the import failure and falls back to generate_skill_md_simple, which constructs the frontmatter using basic string formatting. This ensures skill files are always generated regardless of optional templating libraries.
Where does the skill generator source the version information?
The extract_cli_metadata function extracts version strings by reading setup.py in the harness directory (lines 72-80), alongside documentation from the README and command structures parsed from CLI source files using the ast module.
What file pattern do agents use to discover CLI-Anything skills?
Agent frameworks scan for Markdown files containing a YAML frontmatter block where line 1 is ---, line 2 starts with name:, line 3 starts with description:, and line 4 is ---. This four-line header pattern allows automated parsers to identify SKILL.md files and extract the metadata needed to register CLI harnesses for agent-native discovery.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →