Claude-skill-registry frontrange-cli
Expert guidance for using the FrontRange CLI (fr command) to manage YAML front matter in text documents. Use when working with front-mattered files, YAML metadata, blog posts, markdown with front matter, or when the user mentions 'fr' commands. Supports reading/writing front matter keys, JMESPath-based searching, bulk operations via piping, directory recursion, and multiple format output (JSON/YAML/plist/CSV).
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/frontrange-cli" ~/.claude/skills/majiayu000-claude-skill-registry-frontrange-cli && rm -rf "$T"
skills/data/frontrange-cli/SKILL.mdFrontRange CLI Expert
Comprehensive guidance for using the FrontRange CLI (
) to manage YAML front matter in text documents.fr
Core Concepts
What is Front Matter?
Front matter is YAML metadata at the beginning of a text file, enclosed by
--- delimiters:
--- title: My Blog Post draft: true tags: ["swift", "tutorial"] date: 2025-01-15 --- # Blog Post Content This is the body of the document...
How to Invoke the CLI
Recommended (installed globally):
fr <command>
During development (from FrontRange project directory):
swift run fr <command>
DO NOT USE
swift run fr unless developing or testing FrontRange itself.
Quick Start: Essential Commands
Read a Value
# Single file fr get --key title post.md # All files in directory recursively fr get --key title posts/ -r
Write a Value
# Single file fr set --key draft --value false post.md # All files recursively fr set --key published --value true posts/ -r
Search for Files
# Find all drafts (ALWAYS recursive) fr search 'draft == `true`' ./posts # Complex query fr search 'draft == `false` && contains(tags, `"swift"`)' ./posts
Bulk Operations (Piping)
# Update all matching files fr search 'draft == `true`' ./posts | while read -r file; do fr set "$file" --key draft --value false fr set "$file" --key publishDate --value "$(date +%Y-%m-%d)" done
Critical Non-Obvious Behaviors
1. Search is ALWAYS Recursive
Unlike other commands,
search always searches recursively - no -r flag needed:
# Other commands: explicit recursive flag required fr get --key title posts/ # Only direct children fr get --key title posts/ -r # Includes subdirectories ✓ # Search: ALWAYS recursive automatically fr search 'draft == `true`' posts/ # Searches ALL subdirectories ✓
2. JMESPath Literal Syntax - THE ONE TRUE WAY
ALWAYS use this exact syntax for search queries:
- Wrap entire expression in SINGLE QUOTES
- Use BACKTICKS around ALL literals
# CORRECT ✓ fr search 'draft == `true`' . fr search 'status == `"published"`' . fr search 'count > `100`' . fr search 'contains(tags, `"swift"`)' . # WRONG ✗ fr search draft == `true` . # Missing quotes fr search "draft == `true`" . # Wrong quotes (shell interprets backticks) fr search 'draft == true' . # Missing backticks around literal
Common JMESPath patterns:
# Equality 'draft == `true`' 'status == `"published"`' # Arrays 'contains(tags, `"tutorial"`)' # Boolean logic 'draft == `false` && featured == `true`' 'status == `"draft"` || status == `"review"`' # Comparisons 'views > `1000`' 'rating >= `4.5`'
3. Directory Processing Modes
Default: Most commands only process files in the specified directory (non-recursive).
Recursive: Use
--recursive / -r flag to include subdirectories.
Exception:
search is ALWAYS recursive.
# Process only posts/ directory (direct children) fr get --key title posts/ # Process posts/ and all subdirectories fr get --key title posts/ --recursive # Short form fr get --key title posts/ -r
4. Extension Filtering
Default extensions:
md, markdown, yml, yaml
Override with
/ --extensions
:-e
# Only markdown files fr get --key title docs/ -r --extensions md # Multiple extensions fr list content/ --extensions txt,md,rst # All files (empty string) fr search 'title' . --extensions ""
Common Commands Overview
For complete command reference, see references/commands.md.
| Command | Purpose | Example |
|---|---|---|
| Retrieve value | |
| Set/update value | |
| Check key exists | |
| List all keys | |
| Delete key | |
| Rename key | |
| Alphabetize keys | |
| Show line numbers | |
| Export front matter | |
| Query files (JMESPath) | true`' ./posts` |
| Replace entire front matter | |
Bulk Operations
The
search command outputs file paths (one per line), enabling powerful piping:
Using while loops (Recommended)
Handles spaces, special characters, and large file sets:
# Publish and date-stamp matching posts fr search 'draft == `true`' ./posts | while read -r file; do fr set "$file" --key published --value true fr set "$file" --key date --value "$(date +%Y-%m-%d)" done
Using xargs (Simple cases only)
Works for small file sets without spaces in paths:
# Simple bulk update fr search 'draft == `true`' ./posts | xargs fr set --key draft --value false # With spaces: use -I flag fr search 'tags' . | xargs -I {} fr get --key tags "{}"
When to use each:
: Paths with spaces, 100+ files, multi-step operationswhile read
: <100 files, no spaces, simple one-linersxargs
For detailed piping patterns, see references/examples.md.
Output Formats
Most commands support
--format / -f for output formatting:
# YAML (default for most commands) fr get --key tags post.md --format yaml # JSON fr get --key tags post.md --format json # Plain string (no formatting) fr get --key title post.md --format plainString # Dump supports additional formats fr dump post.md --format plist # Apple PropertyList XML fr dump post.md --format yaml --include-delimiters
Handling Missing Keys
Not all files have all keys. Commands error when keys are missing:
$ fr get --key tags post.md Error: Key 'tags' not found in frontmatter.
Strategies:
-
Filter with search first:
fr search 'tags' . | while read -r file; do fr get --key tags "$file" done -
Suppress expected errors:
fr get --key tags posts/ -r 2>/dev/null -
Check for errors in scripts:
if fr has --key tags "$file" 2>/dev/null; then fr get --key tags "$file" fi
Common Workflows
Publishing Workflow
# Find drafts ready to publish fr search 'draft == `true` && ready == `true`' ./posts # Publish them fr search 'draft == `true` && ready == `true`' ./posts | while read -r file; do fr set "$file" --key draft --value false fr set "$file" --key published --value true fr set "$file" --key publishDate --value "$(date +%Y-%m-%d)" done
Content Auditing
# Get all authors fr get --key author content/ -r --format json # Count by status fr search 'status == `"draft"`' posts | wc -l fr search 'status == `"published"`' posts | wc -l # List unique tags fr get --key tags posts/ -r --format json | jq -r '.[]' | sort -u
Batch Updates
# Add key to all files fr set --key version --value "2.0" content/ -r # Rename keys across project fr rename --old-key category --new-key categories . -r # Remove deprecated keys fr search 'oldField' . | xargs fr remove --key oldField
For more patterns and recipes, see references/examples.md.
Global Options
Available across most commands:
- Path arguments: File(s) and/or directory(ies) to process
/--recursive
: Process subdirectories (default: false, except-r
which is always recursive)search
/--extensions
: File extensions to process (default:-e
)md,markdown,yml,yaml
/--format
: Output format (-f
,yaml
,json
)plainString
/--debug
: Enable debug output-d
Quick Reference: When to Use Each Approach
Single File Operations
fr get --key title post.md fr set --key draft --value false post.md
Directory Operations (Non-Recursive)
fr get --key title posts/ # Only direct children fr set --key reviewed --value true posts/
Directory Operations (Recursive)
fr get --key title posts/ -r # All subdirectories fr set --key category --value "blog" content/ -r
Query-Based Operations
# Search (always recursive) + pipe to other commands fr search 'draft == `true`' . | xargs fr set --key draft --value false # With while loop for safety fr search 'ready == `true`' . | while read -r file; do fr set "$file" --key published --value true done
Additional Documentation
- references/commands.md - Complete command reference with all options and flags
- references/examples.md - Detailed patterns, recipes, and workflows
- references/troubleshooting.md - Troubleshooting guide and advanced usage
Summary
Key Principles:
- Search is always recursive - no
flag needed-r - JMESPath requires backticks -
true`''draft == \
'draft == true'`not - Most commands need
for subdirectories - except search-r - Pipe search results for bulk operations -
fr search ... | xargs fr set ...
The FrontRange CLI provides a complete toolkit for managing YAML front matter with powerful directory processing, flexible querying, and seamless bulk operations.