Skip to content
Back to skills

Frontrange Cli

ASecurity

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

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
documentationgoswiftshellbashexpresstestingdocumentation

Works with

  • cli

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill frontrange-cli --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frontrange Cli?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Frontrange Cli
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-frontrange-cli/badge)](https://www.skillsdirectory.com/skills/majiayu000-frontrange-cli)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: frontrange-cli
description: 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).
---

# 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:

```markdown
---
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):**
```bash
fr <command>
```

**During development (from FrontRange project directory):**
```bash
swift run fr <command>
```

DO NOT USE `swift run fr` unless developing or testing FrontRange itself.

---

## Quick Start: Essential Commands

### Read a Value
```bash
# Single file
fr get --key title post.md

# All files in directory recursively
fr get --key title posts/ -r
```

### Write a Value
```bash
# Single file
fr set --key draft --value false post.md

# All files recursively
fr set --key published --value true posts/ -r
```

### Search for Files
```bash
# Find all drafts (ALWAYS recursive)
fr search 'draft == `true`' ./posts

# Complex query
fr search 'draft == `false` && contains(tags, `"swift"`)' ./posts
```

### Bulk Operations (Piping)
```bash
# 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:

```bash
# 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**

```bash
# 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:**
```bash
# 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.

```bash
# 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`:**

```bash
# 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](references/commands.md).

| Command | Purpose | Example |
|---------|---------|---------|
| `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:

```bash
# 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:

```bash
# 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](references/examples.md).

---

## Output Formats

Most commands support `--format` / `-f` for output formatting:

```bash
# 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:

```bash
$ fr get --key tags post.md
Error: Key 'tags' not found in frontmatter.
```

**Strategies:**

1. **Filter with search first:**
   ```bash
   fr search 'tags' . | while read -r file; do
     fr get --key tags "$file"
   done
   ```

2. **Suppress expected errors:**
   ```bash
   fr get --key tags posts/ -r 2>/dev/null
   ```

3. **Check for errors in scripts:**
   ```bash
   if fr has --key tags "$file" 2>/dev/null; then
     fr get --key tags "$file"
   fi
   ```

---

## Common Workflows

### Publishing Workflow

```bash
# 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

```bash
# 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

```bash
# 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](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
```bash
fr get --key title post.md
fr set --key draft --value false post.md
```

### Directory Operations (Non-Recursive)
```bash
fr get --key title posts/              # Only direct children
fr set --key reviewed --value true posts/
```

### Directory Operations (Recursive)
```bash
fr get --key title posts/ -r           # All subdirectories
fr set --key category --value "blog" content/ -r
```

### Query-Based Operations
```bash
# 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](references/commands.md)** - Complete command reference with all options and flags
- **[references/examples.md](references/examples.md)** - Detailed patterns, recipes, and workflows
- **[references/troubleshooting.md](references/troubleshooting.md)** - Troubleshooting guide and advanced usage

---

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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.