macos-programmer
macOS-specific development patterns, platform APIs, and decision frameworks. Use when developing Mac apps, macOS applications, Cocoa/AppKit code, or making…
Fish shell scripting judgment frameworks and critical idioms. Use when writing Fish scripts or shell automation. Focuses on when to use Fish vs bash, macOS/Fedora compatibility requirements, and Fish-specific patterns that prevent bugs (universal variable anti-patterns, wrapper
$ npx -y skills add Pyroxin/opinionated-claude-skills --skill fish-shell-scripting --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/fish-shell-scriptingContext preview
The summary Claude sees to decide when to auto-load this skill.
Fish shell scripting judgment frameworks and critical idioms. Use when writing Fish scripts or shell automation. Focuses on when to use Fish vs bash, macOS/Fedora compatibility requirements, and Fish-specific patterns that prevent bugs (universal variable anti-patterns, wrapper
name: fish-shell-scripting description: Fish shell scripting judgment frameworks and critical idioms. Use when writing Fish scripts or shell automation. Focuses on when to use Fish vs bash, macOS/Fedora compatibility requirements, and Fish-specific patterns that prevent bugs (universal variable anti-patterns, wrapper functions, interactive guards).
**Related skills:**
<core_philosophy> **Fish is a user-friendly shell that prioritizes correctness over POSIX compatibility.** Its lists-not-strings semantics eliminates entire classes of bugs common in bash/zsh. The limitation is portability, not capability.
**Key insight**: Fish handles sophisticated automation well. Choose Fish when you control the environment; choose bash when you don't. </core_philosophy>
<platform_requirements> **Compatibility**: All Fish scripts MUST work on both macOS and Fedora Linux. Handle platform differences via `uname` detection.
**Quote paths with spaces**: Always quote file paths even though Fish has no word splitting. Fish doesn't need quotes technically (no word splitting), but quoting anyway: (1) makes intent explicit for readability, (2) builds consistent habits when switching between shells, (3) ensures compatibility when passing to external commands that may interpret spaces.
**Shebang**: Use `#!/usr/bin/env fish` for portability across installation locations. </platform_requirements>
<fish_vs_alternatives> **Use Fish for:**
**Use bash for:**
**Use a programming language for:**
</fish_vs_alternatives>
<posix_differences> **No word splitting**: Variables don't split on spaces. `set name "foo bar"; echo $name` is one argument. This eliminates a major source of bugs in bash/zsh.
**All variables are lists**: A "string" is a one-element list. Indexing is 1-based: `$PATH[1]`, `$PATH[-1]`.
**No `VAR=value` syntax**: Use `set` command. `set -gx VAR value` (global exported), `set -lx VAR value` (local exported).
**Command substitution splits on newlines only**: `set lines (cat file)` creates one element per line. For space-splitting: `string split " "`. </posix_differences>
<scoping_decision> **Choosing a scope:**
| Need | Scope | Example Use Case | |------|-------|------------------| | Temporary within function/block | `-l` | Loop variables, intermediate results | | Shared across session | `-g` | Current project settings, temporary overrides | | Available to child processes | `-gx` or `-lx` | PATH, EDITOR, build flags | | Persist across sessions (Fish UI only) | `-U` | fish_color_*, key bindings, prompt config |
**Flag combinations:**
**Example**: `set -gx EDITOR vim` (global + exported), `set -lx DEBUG 1` (local + exported to children).
**CRITICAL**: Environment variables (PATH, EDITOR, etc.) should NEVER be universal. Universal scope is for Fish UI config only. </scoping_decision>
<universal_variable_antipattern> **NEVER use universal variables for PATH or environment variables**. Universal scope is for Fish UI config only (colors, key bindings, prompt).
**Why this matters**: Universal variables persist to disk and are shared across all Fish sessions. If you append to PATH in config.fish using universal variables, it grows indefinitely on every shell start because: 1. config.fish runs on every session 2. Universal variable already contains previous value 3. Append adds duplicate entries 4. This compounds across reboots
# WRONG: Grows PATH indefinitely on every shell start set -U fish_user_paths ~/bin $fish_user_paths # RIGHT: Session-scoped (recalculated fresh each session) set -gx PATH ~/bin $PATH # RIGHT: Use fish_add_path once interactively (idempotent, uses universal internally) fish_add_path ~/bin
**Safe universal variable uses**: `fish_color_*`, `fish_key_bindings`, `fish_prompt`, `fish_greeting`. </universal_variable_antipattern>
<cross_platform> **OS detection**: `switch (uname); case Darwin; ...; case Linux; ...; end`
**Conditional PATH**: `test -d ~/.cargo/bin; and fish_add_path ~/.cargo/bin`
**Platform-specific utilities to watch for**:
</cross_platform>
<critical_idioms> **Wrapper functions require `--wraps` and `$argv`**:
function ls --wraps=ls --description "ls with color"
command ls --color=auto $argv
end**Argument parsing**: Use `argparse` + `fish_opt` for complex CLI tools. Check flags with `set -q _flag_name`.
**Guard interactive code**: Non-in
This project descends from the personal prompts I'd been keeping for Claude Code prior to the release of skills and plugins. Over time it's also evolved into a sandbox where I figure out what makes Claude reliably good at a task, and find prompts that work.
macOS-specific development patterns, platform APIs, and decision frameworks. Use when developing Mac apps, macOS applications, Cocoa/AppKit code, or making…
Swift-specific idioms, tooling, and philosophy for both application development and command-line scripting. Use when working with Swift code, including Swift…
Java-specific tooling, documentation standards, testing practices, and modern idioms. Use when working with Java code or Java-based projects on the JVM.
Clojure-specific philosophy, idioms, and judgment frameworks. Use when working with Clojure code. Emphasizes data-oriented design, runtime validation with…
Racket-specific tooling, libraries, idioms, and language-oriented programming philosophy. Use when working with Racket code. Emphasizes LOP, contracts, macros,…
SWI-Prolog-specific tooling, standards, and idioms. Use when working with SWI-Prolog code. Emphasizes relational thinking, steadfastness, DCGs, constraints,…