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).

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
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"
manifest: skills/data/frontrange-cli/SKILL.md
source content

FrontRange CLI Expert

Comprehensive guidance for using the FrontRange CLI (

fr
) to manage YAML front matter in text documents.

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:

  1. Wrap entire expression in SINGLE QUOTES
  2. 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.

CommandPurposeExample
get
Retrieve value
fr get --key title post.md
set
Set/update value
fr set --key draft --value false post.md
has
Check key exists
fr has --key author post.md
list
List all keys
fr list post.md
remove
Delete key
fr remove --key temp post.md
rename
Rename key
fr rename --old-key tag --new-key tags post.md
sort-keys
Alphabetize keys
fr sort-keys post.md
lines
Show line numbers
fr lines post.md
dump
Export front matter
fr dump post.md --format json
search
Query files (JMESPath)
fr search 'draft == \
true`' ./posts`
replace
Replace entire front matter
fr replace post.md --data '{}' --format json

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:

  • while read
    : Paths with spaces, 100+ files, multi-step operations
  • xargs
    : <100 files, no spaces, simple one-liners

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:

  1. Filter with search first:

    fr search 'tags' . | while read -r file; do
      fr get --key tags "$file"
    done
    
  2. Suppress expected errors:

    fr get --key tags posts/ -r 2>/dev/null
    
  3. 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
    /
    -r
    : Process subdirectories (default: false, except
    search
    which is always recursive)
  • --extensions
    /
    -e
    : File extensions to process (default:
    md,markdown,yml,yaml
    )
  • --format
    /
    -f
    : Output format (
    yaml
    ,
    json
    ,
    plainString
    )
  • --debug
    /
    -d
    : Enable debug output

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


Summary

Key Principles:

  1. Search is always recursive - no
    -r
    flag needed
  2. JMESPath requires backticks -
    'draft == \
    true`'
    not
    'draft == true'`
  3. Most commands need
    -r
    for subdirectories
    - except search
  4. 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.