--- name: shell-tooling description: "Use when: running terminal commands, writing or debugging shell/PowerShell scripts, choosing or installing CLI tools, or diagnosing command failures, quoting/escaping errors, or garbled output. Do not use for project build, test, or CI configuration covered by other skills." --- # Shell and Tooling Terminal rules for this repository's supported platforms (Windows, Linux, macOS). Prefer modern high-performance CLI tools over traditional Unix tools whenever they are installed. ## Shell selection - On Windows use PowerShell 7+ (`pwsh.exe`). Never use the legacy Windows PowerShell 5.1 (`powershell.exe`): it lacks `&&`/`||`, passes native arguments differently, and defaults to legacy encodings. - Launch independent PowerShell processes as `pwsh.exe -NoLogo -NoProfile` so user profiles cannot inject extra commands or configuration; add `-NonInteractive` for unattended runs. - Do not nest `cmd.exe`, Git Bash, WSL, or other shells unless the task explicitly requires it. When a command fails, check the command name, path, quoting, and exit code first; do not switch shells to make an error disappear. - On Linux/macOS use the harness's default POSIX shell. ## Tool selection - Probe before use (`Get-Command ` on Windows, `command -v ` on POSIX). Prefer an installed modern tool; otherwise fall back to a PowerShell cmdlet or the traditional tool. Do not install tools unless asked. - Highest-value tools: `rg` (grep), `fd` (find), `sd` (sed), `bat` (cat), `jq`/`yq` (JSON/YAML), `eza` (ls/tree). - PowerShell-native fallbacks: `Select-String` (grep), `Get-ChildItem -Recurse -Filter` (find), `Get-Content` (cat), `ConvertFrom-Json`/`ConvertTo-Json` (JSON). - Full inventory, per-platform install commands, and static-binary channels: [references/modern-cli-tools.md](references/modern-cli-tools.md). Read it before installing tools. ## Agent practices - Output is parsed, not viewed: modern tools detect pipes and disable color/pagers automatically; when a PTY is allocated, force clean output (`NO_COLOR=1`, `--color=never`, `--paging=never`, `git --no-pager`). - Prefer structured output (`rg --json`, `doggo --json`, `jq -r ...`) over parsing human-oriented layouts. - Never wait for interaction: use non-interactive flags (`fzf --filter`, package-manager `-y`/`--accept-*` switches); on POSIX redirect stdin from `/dev/null` for commands that may read input. - Cap output before it floods context: `rg --max-count 50`, `fd --max-results 100`, `Select-Object -First 200`, `head -n 200`. - Exit-code semantics differ per tool family; do not assume one rule. Grep family (`rg`/`grep`/`ugrep`): 0 = match found, 1 = no match (not an error), >= 2 = real error. `fd` and `sd`: 0 on success whether or not anything matched, so the simple "nonzero = failed" rule is safe for them (invalid regex or missing path exits 1) — but not with `fd --quiet`, where 1 means no match or error alike. In PowerShell check `$LASTEXITCODE` after native commands; `$ErrorActionPreference` and `try/catch` do not apply to them. ## PowerShell authoring rules Quoting and text: - Single quotes for literals; double quotes only when expansion is needed. Write `${name}` when adjacent characters make the boundary ambiguous. Inside double quotes escape with backtick (`` `" ``, `` `$ ``), never backslash. - Multiline text uses here-strings (`@' ... '@` / `@" ... "@`); the opening delimiter must end its line and the closing delimiter must start at column 0. Never use Bash heredocs (`<`, `Out-File`) writes UTF-8 without BOM by default. Paths, comparisons, output: - Use `-LiteralPath` when a path contains `[`, `]`, `*`, or `?`; build paths with `Join-Path`, not string concatenation. - Comparison operators are case-insensitive by default; use the `-c` variants (`-ceq`, `-clike`) when case matters. - Emit objects instead of `Write-Host` when output is consumed downstream; never use `Read-Host` in automation.