docs/skills/cli-tools/SKILL.md
Modern CLI tool usage (fd, rg) for fast file and content searching. Critical for Nix store searches and large codebases. Use when searching files or content, especially in /nix/store.
npx skillsauth add megalithic/dotfiles cli-toolsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CRITICAL: Always use modern, fast CLI tools instead of legacy UNIX commands. This is especially important when searching the Nix store (/nix/store), which contains millions of files.
| Legacy | Modern | Speedup | When Legacy Will Fail |
|--------|--------|---------|----------------------|
| find | fd | 10-100x faster | Timeout on /nix/store |
| grep | rg | 10-100x faster | Timeout on large dirs |
Both fd and rg respect .gitignore by default and are optimized for large directory trees.
Need to find files?
│
├─▶ Know the filename/pattern?
│ └─▶ fd "pattern"
│ └─▶ fd -e lua (by extension)
│ └─▶ fd -g "*.nix" (glob pattern)
│
├─▶ Know it's in a specific directory?
│ └─▶ fd "pattern" /path/to/dir
│
├─▶ Need to include hidden/gitignored?
│ └─▶ fd -H (hidden) / fd -I (ignored) / fd -HI (both)
│
├─▶ Searching in /nix/store?
│ └─▶ fd "pattern" /nix/store
│ └─▶ CRITICAL: Never use find here!
│
└─▶ Need to run command on results?
└─▶ fd -x cmd {} (one at a time)
└─▶ fd -X cmd {} (all at once)
Need to search contents?
│
├─▶ Simple pattern search?
│ └─▶ rg "pattern"
│
├─▶ Need specific file types?
│ └─▶ rg "pattern" -t lua
│ └─▶ rg "pattern" -g "*.nix"
│
├─▶ Need context around matches?
│ └─▶ rg "pattern" -C 3 (3 lines before/after)
│ └─▶ rg "pattern" -A 5 (5 lines after)
│ └─▶ rg "pattern" -B 2 (2 lines before)
│
├─▶ Just need filenames?
│ └─▶ rg -l "pattern"
│
├─▶ Need case-insensitive?
│ └─▶ rg -i "pattern"
│
├─▶ Searching in /nix/store?
│ └─▶ rg "pattern" /nix/store
│ └─▶ CRITICAL: Never use grep here!
│
└─▶ Need to replace text?
└─▶ rg "old" -r "new" --passthru (preview)
└─▶ Use sed/Edit tool for actual replacement
What are you trying to do?
│
├─▶ Find files by name/pattern?
│ └─▶ fd
│
├─▶ Search file contents?
│ └─▶ rg
│
├─▶ Find files AND search contents?
│ └─▶ fd -e lua -x rg "pattern"
│ └─▶ fd + rg piped together
│
├─▶ Count/list matches only?
│ └─▶ rg -c (count per file)
│ └─▶ rg -l (list files only)
│
└─▶ Using Claude Code's built-in tools?
└─▶ Glob tool = like fd (for finding files)
└─▶ Grep tool = like rg (for searching content)
└─▶ Prefer built-in tools when available
fd "pattern" # Find files/dirs matching pattern
fd -e lua # Find by extension
fd -t f config # Files only (-t d for directories)
fd -t x # Executables only
fd -g "*.nix" # Glob pattern
fd -H # Include hidden files
fd -I # Include gitignored files
fd -d 3 # Max depth 3
fd -E "*.log" # Exclude pattern
| Flag | Long Form | Description |
|------|-----------|-------------|
| -H | --hidden | Include hidden files/directories |
| -I | --no-ignore | Don't respect .gitignore |
| -s | --case-sensitive | Case-sensitive search |
| -i | --ignore-case | Case-insensitive search |
| -g | --glob | Glob-based search |
| -F | --fixed-strings | Literal string match |
| -a | --absolute-path | Show absolute paths |
| -l | --list-details | Show file details (like ls -l) |
| -L | --follow | Follow symbolic links |
| -p | --full-path | Match against full path |
| -d | --max-depth | Maximum search depth |
| -t | --type | Filter by type (f/d/l/x/e/s/p) |
| -e | --extension | Filter by extension |
| -E | --exclude | Exclude patterns |
| -x | --exec | Execute command per result |
| -X | --exec-batch | Execute command with all results |
| -0 | --print0 | Null-separated output |
| | --changed-within | Modified within timeframe |
| | --changed-before | Modified before timeframe |
| | --size | Filter by size (+100k, -1m) |
| | --owner | Filter by owner |
| Type | Description |
|------|-------------|
| f | Regular files |
| d | Directories |
| l | Symbolic links |
| x | Executable files |
| e | Empty files/directories |
| s | Sockets |
| p | Named pipes (FIFO) |
# Find by name
fd "config" # Contains "config"
fd "^config" # Starts with "config"
fd "\.lua$" # Ends with .lua (regex)
fd -e lua # Same, extension flag
# Find in specific directory
fd -e nix modules/ # .nix files in modules/
fd pattern /path/to/dir # Search specific directory
# Include hidden/ignored
fd -H "\.env" # Include hidden files
fd -I node_modules # Include gitignored files
fd -HI "secret" # Include both
# Filter by type
fd -t f config # Files only
fd -t d src # Directories only
fd -t x # Executables only
fd -t l # Symlinks only
# Limit depth
fd -d 1 # Current directory only
fd -d 3 pattern # Max 3 levels deep
# Filter by time
fd --changed-within 1d # Modified in last day
fd --changed-within 1h # Modified in last hour
fd --changed-before 1w # Modified more than a week ago
# Filter by size
fd --size +1m # Larger than 1MB
fd --size -100k # Smaller than 100KB
# Exclude patterns
fd -E "*.log" # Exclude log files
fd -E ".git" -E "node_modules" # Exclude multiple
# Execute per file (-x)
fd -e lua -x wc -l # Count lines in each lua file
fd -e jpg -x convert {} {.}.png # Convert jpg to png
# Execute batch (-X, all at once)
fd -e ts -X prettier -w # Format all TypeScript files
fd -e lua -X wc -l # Total line count
# Placeholders
# {} - Full path
# {/} - Basename
# {//} - Parent directory
# {.} - Path without extension
# {/.} - Basename without extension
rg "pattern" # Search current dir recursively
rg -i "error" # Case-insensitive
rg -w "app" # Whole word only
rg -F "exact.string" # Fixed string (no regex)
rg -t lua "require" # Search only Lua files
rg -l "TODO" # List files with matches only
rg -c "TODO" # Count matches per file
| Flag | Long Form | Description |
|------|-----------|-------------|
| -i | --ignore-case | Case-insensitive search |
| -s | --case-sensitive | Case-sensitive search |
| -S | --smart-case | Smart case (insensitive if all lowercase) |
| -w | --word-regexp | Match whole words only |
| -F | --fixed-strings | Literal string match |
| -x | --line-regexp | Match entire lines |
| -v | --invert-match | Invert match |
| -l | --files-with-matches | Only print file names |
| -L | --files-without-match | Files without matches |
| -c | --count | Count matches per file |
| -o | --only-matching | Print only matching part |
| -n | --line-number | Show line numbers (default) |
| -N | --no-line-number | Hide line numbers |
| -H | --with-filename | Show filenames (default) |
| -I | --no-filename | Hide filenames |
| -A | --after-context | Lines after match |
| -B | --before-context | Lines before match |
| -C | --context | Lines before and after |
| -t | --type | Search specific file type |
| -T | --type-not | Exclude file type |
| -g | --glob | Include/exclude globs |
| -r | --replace | Replace matches |
| -U | --multiline | Enable multiline mode |
| | --hidden | Search hidden files |
| | --no-ignore | Don't respect .gitignore |
| | --max-depth | Maximum directory depth |
| | --max-count | Stop after N matches |
| | --json | Output as JSON |
| | --stats | Show search statistics |
# Built-in types
rg --type-list # Show all known types
rg -t lua "pattern" # Lua files
rg -t nix "pattern" # Nix files
rg -t py "pattern" # Python files
rg -t js "pattern" # JavaScript files
rg -t ts "pattern" # TypeScript files
rg -t md "pattern" # Markdown files
rg -t sh "pattern" # Shell scripts
# Glob patterns
rg "pattern" -g "*.lua" # Include only .lua
rg "pattern" -g "!*.md" # Exclude .md files
rg "pattern" -g "!vendor/" # Exclude vendor directory
rg "pattern" -g "src/**/*.ts" # TypeScript in src/
rg "function" -A 3 # 3 lines after match
rg "function" -B 2 # 2 lines before match
rg "function" -C 2 # 2 lines before and after
rg "error" -C 5 # More context for errors
# Default: show matches with context
rg "pattern"
# Files only
rg -l "pattern" # Files with matches
rg -L "pattern" # Files without matches
# Count
rg -c "pattern" # Count per file
rg -c "pattern" | awk -F: '{sum+=$2} END {print sum}' # Total
# Only matching text
rg -o "pattern" # Just the match
rg -oI "pattern" # Match only, no filenames
# JSON output
rg --json "pattern" # For programmatic parsing
# Multiline matching
rg -U "start.*\nend" # Match across lines
rg -U "function.*\{[^}]*\}" # Function bodies
# Regex features
rg "\bword\b" # Word boundary
rg "foo|bar" # Alternation
rg "a{2,4}" # Quantifiers
rg "(?i)case" # Inline case insensitive
rg "(?:non-capturing)" # Non-capturing group
rg "look(?=ahead)" # Lookahead
rg "(?<=look)behind" # Lookbehind
# Replace (preview)
rg "old" -r "new" --passthru # Show what would change
# Statistics
rg --stats "pattern" # Search statistics
| Scenario | Use Built-in | Use fd/rg | |----------|-------------|-----------| | Finding files in codebase | Glob tool | Complex patterns | | Searching file contents | Grep tool | /nix/store, complex regex | | Need execution on results | - | fd -x / fd -X | | Need JSON output | - | rg --json | | Multiple operations | - | Piping fd | rg |
# Claude Code's Glob tool
# Good for: simple file finding in codebase
# Equivalent patterns:
# Glob: "**/*.lua" ≈ fd -e lua
# Glob: "src/**/*.ts" ≈ fd -e ts src/
# Claude Code's Grep tool
# Good for: searching content with context
# Equivalent patterns:
# Grep with -C 3 ≈ rg "pattern" -C 3
# Grep output_mode: files_with_matches ≈ rg -l
# Find files then search contents
fd -e lua -x rg "require"
# Search specific file types in specific dirs
fd -e nix modules/ -x rg "enable = true"
# Find and process
fd -e json -X jq '.version'
CRITICAL: The Nix store contains millions of files. Legacy tools will timeout.
# Find where a binary comes from
fd -t x "nvim" /nix/store --max-depth 3
# Find all packages with a specific file
fd "libcurl.so" /nix/store -x dirname | sort -u
# Search derivation files
fd -e drv /nix/store | head -100 | xargs rg "python"
# Find config files
fd "config" /nix/store -t f -d 4 | head -50
# Find package by name pattern
fd "ghostty" /nix/store -d 1 -t d
# Find all TODO/FIXME comments
rg "TODO|FIXME" -t lua -t nix
# Find function definitions
rg "^function |^local function " -t lua
# Find all imports/requires
rg "^import |^from |require\("
# Find unused exports
rg "^export " -l | xargs -I {} sh -c 'rg -l "from.*{}" || echo "Unused: {}"'
# Find large files
fd -t f -S +1m
# Find recently modified config
fd -e nix --changed-within 1d
fd -d 3 or rg --max-depth 3-t lua, -g "*.nix"-E node_modules -E .git-X instead of -x when possible# BAD: Will timeout on /nix/store
find /nix/store -name "*.so"
grep -r "pattern" /nix/store
ls -R /nix/store | grep pattern
# GOOD: Fast even with millions of files
fd -e so /nix/store
rg "pattern" /nix/store
fd "pattern" /nix/store
# fd help
fd --help
fd --help | grep -i "flag-name"
man fd
# rg help
rg --help
rg --help | grep -i "flag-name"
man rg
# List file types
rg --type-list
rg --type-list | grep lua
# Test fd pattern (dry run)
fd "pattern" --max-results 5
# Test rg pattern (limited)
rg "pattern" --max-count 5
# Count results before processing
fd "pattern" | wc -l
rg -c "pattern" | awk -F: '{sum+=$2} END {print sum}'
# Check installed version
fd --version
rg --version
# Check available features
rg --pcre2-version # PCRE2 support
# Check if pattern is correct
fd "exact" -F # Try fixed string
rg "exact" -F # Try fixed string
# Include hidden/ignored
fd -HI "pattern"
rg --hidden --no-ignore "pattern"
# Check file types
rg --type-list | grep yourtype
# Limit depth
fd -d 2 "pattern"
rg --max-depth 2 "pattern"
# Limit count
fd --max-results 10
rg --max-count 10
# More specific pattern
fd "^exact$" # Exact match
rg "\bexact\b" # Word boundary
# Check if searching /nix/store with wrong tool
# Use fd/rg, NEVER find/grep
# Exclude large directories
fd -E node_modules -E .git
rg -g '!node_modules' -g '!.git'
# Limit depth
fd -d 3
rg --max-depth 3
fd PATTERN Find files matching pattern
fd -e EXT Find by extension
fd -t f/d/x Type: file/dir/executable
fd -H/-I Hidden/ignored files
fd -d N Max depth
fd -E PAT Exclude pattern
fd -x CMD Execute per result
fd -X CMD Execute batch
rg PATTERN Search contents
rg -i Case insensitive
rg -w Whole word
rg -F Fixed string
rg -t TYPE File type
rg -g GLOB Glob filter
rg -l Files only
rg -c Count matches
rg -A/B/C N Context lines
testing
Apply Strunk's timeless writing rules to ANY prose humans will read - documentation, commit messages, error messages, explanations, reports, or UI text. Makes your writing clearer, stronger, and more professional.
tools
Web search using DuckDuckGo (free, unlimited). Falls back to pi-web-access extension for content extraction.
tools
Interact with web pages using agent-browser CLI. MUST run 'browser connect 9222' FIRST to use existing browser with authenticated sessions.
tools
Remote control tmux sessions for interactive CLIs (python, gdb, etc.) by sending keystrokes and scraping pane output.