Help us improve
Share bugs, ideas, or general feedback.
From hatch3r
Category-indexed reference for selecting among 29 specialist CLI tools (HTTP clients, AI/LLM, structural search, data ops, containers, browser automation, etc.) beyond the five always-on tools (ripgrep, jq, gh, fd, fzf).
npx claudepluginhub hatch3r/hatch3rHow this skill is triggered — by the user, by Claude, or both
Slash command
/hatch3r:hatch3r-cli-toolboxThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Compact decision reference for 29 specialist CLI tools agents may reach for in addition to the five always-on skills (`hatch3r-cli-ripgrep`, `hatch3r-cli-jq`, `hatch3r-cli-gh`, `hatch3r-cli-fd`, `hatch3r-cli-fzf`).
Provides shell scripting expertise for bash, zsh, POSIX; CLI tools like jq, yq, fd, rg for JSON/YAML processing, file search, automation, error handling, and cross-platform best practices. Useful for CLI commands, pipes, script development.
Covers fundamental CLI tools and utilities for software development: shells, Git, system package managers, Docker, SSH, curl, jq, regex, and build runners like Make.
Writes and reviews defensive Bash scripts for production automation, CI/CD, and system utilities. Enforces strict error handling, safe argument parsing, and portable patterns.
Share bugs, ideas, or general feedback.
Compact decision reference for 29 specialist CLI tools agents may reach for in addition to the five always-on skills (hatch3r-cli-ripgrep, hatch3r-cli-jq, hatch3r-cli-gh, hatch3r-cli-fd, hatch3r-cli-fzf).
Each entry below states a single discriminator ("When to use"), one representative recipe, and the better alternative ("Wrong choice when"). Tools are installed via npx hatch3r cli-tools; this skill governs selection, not installation.
Before invoking any tool below, resolve these via agents/shared/user-question-protocol.md (default behavior, not exception-driven):
sd … <file>, comby -i, yq -i, taplo writes, glab mr/az repos pr, and any docker run/podman run with a writable host mount. Confirm intent before running these; in-place and remote mutations are not safe to assume. Honor each tool's own caveat (e.g. rtk proxy for piped output, container hardening flags for untrusted images).ast-grep vs comby vs sd for a rename), pick per the discriminators below or ask which one.Tier 1 reference card — no fan-out. This skill is a category-indexed selection reference an agent consults inline; it spawns no sub-agents. Fan-out is owned by the calling workflow per its own Fan-out Discipline block. Source: .claude/rules/fan-out-discipline.md (P8 B2).
| Category | Tools |
|---|---|
| HTTP clients | curl, httpie, xh |
| AI / LLM | aichat, llm, mods, rtk |
| Structural search & rewrite | ast-grep, comby |
| Sed-style literal edits | sd |
| Format converters / queriers | yq, taplo, dasel |
| Data ops (CSV / Parquet / JSON-Lines) | csvkit, duckdb, miller, qsv |
| Containers | docker, podman, container-use |
| Git TUI / diff viewers | lazygit, delta, difftastic, bat |
| Visualisation / view | bat, overview |
| Forges (non-GitHub) | glab (GitLab), az-devops (Azure DevOps) |
| Browser automation | playwright, stagehand |
| Compression | zstd |
| React state | rtk (caveat — see below) |
(Some tools appear in two cells when their best use spans categories.)
CLI tools return structured stdout that fits in <1 KB for typical queries; equivalent MCP calls regularly exceed 10 KB. Reference: Anthropic engineering (Nov 4 2025) — code-execution-over-MCP yields 98.7% token reduction. Apply this same discipline across every tool below: prefer --json/--output json, scope with flags, cap with --max-count / LIMIT, project with jq -r.
--upload-file), header injection (-H), cookie sessions (-b/-c), OAuth flows, custom write-out templates (-w). Tier-1 default-on.curl -sS -H "Authorization: Bearer $TOKEN" https://api.example.com/v1/runs | jq '.runs[] | {id, status}'httpie; HTTP/2 / HTTP/3 throughput-sensitive bulk transfers — use xh. Version floor: >=8.20.0 — 8.18.0–8.19.0 carry CVE-2026-7168/7009/6429/6253/6276/3805/3783 (credential-leak and connection-reuse cluster patched in 8.20.0, 2026-04-29).http --session=staging POST api.example.com/v1/auth username=admin password=$PW Content-Type:application/jsoncurl; HTTP/2 + HTTP/3 throughput — use xh. Note: latest release 3.2.4 (2024-11-01) — project under maintenance but on a stable-cadence release tempo.--http3, JSON output (--json), resume-on-416 download recovery.xh --http3 GET api.example.com/v1/runs Authorization:"Bearer $TOKEN" | jq '.runs[] | {id, status}'brew install xh; linux cargo install xh --locked; Windows winget install ducaale.xh (signed first-party channel) with cargo install xh --locked as the fallback when winget is unavailable — Windows users are not forced onto a Rust-toolchain-only path.httpie workflows that depend on a Python plugin — keep httpie; environments without a Rust toolchain (or no Homebrew/winget) — use curl. Version floor: >=0.25.3 (2025-12-16) — earlier 0.24.x builds miss recent --http3 and resume fixes.aichat --rag mydocs 'how do we configure auth?' — query a pre-built local RAG index.mods; plugin-rich CI workflows — use llm.llm -t code-review -m claude-3-5-sonnet < patch.diffsd/comby/ast-grep; multi-turn TTY chat — use aichat.git diff | mods 'write a conventional-commits message for this diff'llm; multi-turn session — use aichat.rtk proxy <cmd> — proxy is a documented raw-passthrough subcommand. Track: https://github.com/rtk-ai/rtk/issues/1282rtk run pytest -xjq/grep/awk without rtk proxy — use plain shell + tee; safety-critical CI — run the test directly.sg (the ast-grep package installs the binary as sg — run command -v sg to detect it, not command -v ast-grep).sg run -p 'await $FN()' -r 'await ($FN()).catch(e => log(e))' --update-all src/hatch3r-cli-ripgrep; multi-language SAST rule packs — use semgrep.:[hole] pattern match-and-rewrite spanning mixed-language repositories — single template, 30+ grammars.comby 'console.log(:[arg])' 'logger.info(:[arg])' -i src/ast-grep; plain text — use sd.-s switches to literal mode.rg --files-with-matches 'oldName' -tts | xargs sd 'oldName' 'newName'ast-grep; multi-step transforms — use sed -e.-P.yq -i '.version = "1.7.5"' .hatch3r/hatch.jsonhatch3r-cli-jq; TOML — use taplo.pyproject.toml, Cargo.toml); bundled schemas for both.taplo get -f Cargo.toml package.versionyq/jq; cross-format conversion — use dasel (pin >=3.11.0).dasel -r yaml -w json -f config.yaml '.services.app.env'yq (YAML) or taplo (TOML); stream-friendly JSON filtering — use jq with its richer filter language. Version floor: >=3.11.0 — earlier builds carry CVE-2026-46377 / CVE-2026-46378 / CVE-2026-33320 (selector-lexer DoS, index-out-of-range panic, YAML alias DoS — all fixed in 3.11.0, 2026-05-19).csvlook, csvsql, csvjoin, csvstat — best for ad-hoc EDA and SQL-over-CSV.csvsql --query 'SELECT name FROM data WHERE active = 1' data.csvduckdb; single-column slice — use qsv.duckdb -c "SELECT count(*) FROM 'data/*.parquet'"qsv; transactional writes — use SQLite/Postgres.awk-like record processing across CSV/TSV/JSON-Lines streams with the put/filter DSL.mlr --icsv --ojson put '$tax = $amount * 0.07' transactions.csvduckdb; trivial slicing — use qsv.xsv successor (BurntSushi/xsv archived 2025-04-24, jqnatividad/qsv is the active fork).qsv search -s email '@example\.com$' users.csvduckdb; per-record DSL transforms — use miller.docker run --rm -v "$PWD":/app -w /app node:22 npm test:ro sub-tree bind.podman; Kubernetes deploy — use kubectl/helm.The default recipe above bind-mounts the entire repo root read-write, which exposes .env*, .git/, .aws/, .npmrc, .docker/config.json, ~/.kube/config, .hatch3r/learnings/, and node_modules to a compromised post-install script inside the container (D15-M15). On Linux, a process running as root inside a non-rootless container can write back through that mount with host-root semantics. F15.7-H5 (Cycle 10 D15-SA15.7) + D15-M15 hardening — copy the relevant flags into your runs when the workload comes from untrusted sources (third-party image, agent-generated docker run command, public Dockerfile):
--read-only --tmpfs /tmp keeps the container from writing back to the host even via /app.--user "$(id -u):$(id -g)" or rely on the image's non-root USER directive. Without it, a process inside the container runs as host root on Linux when Docker Desktop's user remapping is disabled.--security-opt no-new-privileges:true neutralises setuid binaries inside the image.-v "$PWD/src:/app/src:ro" instead of the full repo root. Never bind-mount ~, /, or /var/run/docker.sock to an untrusted container — the socket grants host root.Hardened equivalent of the recipe above:
docker run --rm --read-only --tmpfs /tmp \
--user "$(id -u):$(id -g)" \
--security-opt no-new-privileges:true \
--cap-drop ALL \
-v "$PWD/src:/app/src:ro" -w /app node:22 npm test
podman run --rm -v "$PWD:/app:Z" -w /app node:22 npm test (:Z triggers SELinux relabel on Fedora/RHEL).docker; tools that hard-code /var/run/docker.sock (unless podman system service is running).SECURITY.md is published. Adopt only if you accept undefined CVE disclosure paths. Track: https://github.com/dagger/container-use/releases.container-use env create --git-ref refs/heads/main --image node:22 --workdir /repo then cu exec npm test.docker or podman; stable D15 sandbox-escape boundary required — use podman rootless + selinux relabel.git.lazygit -p path/to/repo (TTY required; hangs in non-TTY).git status/add/commit for parseable stdout.git config --global core.pager delta then git config --global interactive.diffFilter 'delta --color-only'.difftastic.git -c diff.external=difft diff HEAD~1 HEADdiff -u; quick unified-diff pager — use delta.bat --plain --line-range 50:100 src/adapters/cursor.tsxxd | bat --language=hex); strict POSIX pipelines (use cat); two-file compare (use delta).hatch3r-cli-toolbox skill replaces it. Retained as a category cell for back-references in user content; if you see hatch3r-cli-overview mentioned anywhere (un-backticked here to keep the cross-reference scanner clean), treat it as a synonym for this toolbox.glab mr list --assignee=@me --output json | jq '.[] | {iid, title, web_url}'hatch3r-cli-gh; Azure Repos — use az-devops.az CLI extension.az repos pr list --status active --query '[].pullRequestId' --output tsvhatch3r-cli-gh; GitLab — use glab.npx playwright test --grep '@smoke' --workers=1 --reporter=linecurl + jq; agent-driven natural-language browsing — use stagehand.Playwright launches real Chrome / Firefox / WebKit processes that inherit the host user's environment (HOME, ~/.aws, browser profiles under ~/.config/google-chrome/). Visiting an attacker-controlled URL with the host user's credential store is the equivalent of granting that URL read access to every site you are logged into. F15.7-H5 (Cycle 10 D15-SA15.7) hardening — apply when navigating to URLs the agent has not vetted:
userDataDir: tmp.dirSync().name (or --user-data-dir=$(mktemp -d)) so the browser sees no saved sessions, no autofill, no cookies from the host profile.mcr.microsoft.com/playwright:v1.49.0-jammy (pin the exact tag). The image preinstalls every browser binary and isolates filesystem + network from the host. Reference: https://playwright.dev/docs/docker (Microsoft's official Playwright image is the maintained surface; pin to the immutable digest).args: ['--disable-gpu', '--no-sandbox'] is acceptable inside a hardened container, never on the host.await context.close(); context = await browser.newContext(); between unvetted URLs so cookie state does not leak across hops.playwright codegen <url> against an authed site. npx playwright codegen opens a browser session the user logs into, then writes the captured locators and credentials into a test file on disk. Running codegen against a host browser profile bakes the live session cookie / Authorization header into the emitted test, exposing the credential in any artefact the test is checked into. Mitigation: always pass --save-storage=storageState.json to capture state into a single named file you can scrub or .gitignore (instead of writing inline credentials), pass --user-data-dir=$(mktemp -d) so codegen does not start from the host's logged-in profile, and review the emitted test for any literal token, bearer string, or cookie: header before committing. Reference: https://playwright.dev/docs/codegen#preserve-authenticated-state (preserve auth via the storage-state file rather than inline credentials).Hardened equivalent of the recipe above (inside Microsoft's pinned image):
docker run --rm --network none -v "$PWD:/work:ro" -w /work \
mcr.microsoft.com/playwright:v1.49.0-jammy \
npx playwright test --grep '@smoke' --workers=1 --reporter=line
playwright-core, puppeteer-core, patchright-core) are peer deps — install only the one you need.npx create-browser-app scaffolds a v3 project; runtime: stagehand.act("click the login button").playwright-core (Microsoft) as the default driver. puppeteer-core (Google) is also vendor-maintained; patchright-core is a less-vetted community detection-bypass fork with a different supply-chain trust profile. Pin whichever driver you install.tar --zstd -cf bundle.tar.zst dist/ docs/xz -9e; legacy Windows recipients — use zip; already-compressed payloads — skip compression.Verify each tool with command -v <bin>. Install commands.
Each install command below resolves to one of four trust postures. Read the posture before running any install command on an end-user machine — cargo install and bash <(curl … | sh) channels lack vendor-signed artefacts and require additional vetting.
| Posture | Channels | What it means | Mitigation when posture is "unsigned" |
|---|---|---|---|
| Signed | brew (homebrew/cask), apt (signed repo + Signed-By), snap, npm with --provenance / npm audit signatures, Microsoft Store, Mac App Store | Channel verifies a vendor signature against a pinned key before installing | (none) |
| Vendor-pinned | pipx, pip (lockfile + --require-hashes), go install against proxy.golang.org + GOSUMDB=on | Channel checksums or transparency log verifies that the resolved tarball matches the version's pinned hash | Verify lockfile committed, GOSUMDB=sum.golang.org not set to off |
| Unsigned | cargo install <crate> (crates.io publishes tarballs without per-release Sigstore signatures), pipx install directly from PyPI without --require-hashes | Channel ships the resolved tarball but does not verify it against a vendor signature; integrity is per-channel checksum only | Pin the version, verify SHA-256 against the project's published release, prefer --locked (cargo) or --require-hashes (pip); avoid running on a credential-bearing machine |
| Curl-piped-shell | bash <(curl … get.comby.dev), curl -fsSL … install.sh | bash | No checksum, no signature, attacker who controls the URL gets shell on your machine. Vendor maintained but unsigned at the channel level | Download the script first (curl -fsSL <url> -o install.sh), inspect it, optionally pin to a committed SHA via git show <ref>:install.sh | bash, never | bash straight from an untrusted network |
Install commands:
| Tool | mac (brew) | linux (apt / pip / other) |
|---|---|---|
aichat | brew install aichat | cargo install aichat |
ast-grep | brew install ast-grep | cargo install ast-grep --locked |
az-devops | brew install azure-cli && az extension add --name azure-devops | apt install azure-cli && az extension add --name azure-devops |
bat | brew install bat | apt install bat (binary may be batcat) |
comby | brew install comby | bash <(curl -sL get.comby.dev) |
container-use | brew install dagger/tap/container-use | curl -fsSL https://raw.githubusercontent.com/dagger/container-use/main/install.sh | bash |
csvkit | pipx install csvkit | pipx install csvkit |
curl | brew install curl (pin >=8.20.0) | apt install curl (verify >=8.20.0) |
dasel | brew install dasel (pin >=3.11.0) | go install github.com/tomwright/dasel/v3/cmd/dasel@latest |
delta | brew install git-delta | apt install git-delta (or download release) |
difftastic | brew install difftastic | cargo install difftastic |
docker | brew install --cask docker | apt install docker.io |
duckdb | brew install duckdb | download from https://duckdb.org/ |
glab | brew install glab | apt install glab (or GitLab release) |
httpie | brew install httpie | snap install httpie (or pipx install httpie) |
lazygit | brew install lazygit | apt install lazygit |
llm | brew install llm | pipx install llm |
miller | brew install miller | apt install miller |
mods | brew install charmbracelet/tap/mods | apt install mods (Charm repo) |
playwright | npm install -D @playwright/test && npx playwright install | same |
podman | brew install podman | apt install podman |
qsv | brew install qsv | cargo install qsv |
rtk | brew install rtk-ai/tap/rtk | check upstream release |
sd | brew install sd | cargo install sd |
stagehand | npm install -g @browserbasehq/stagehand | same |
taplo | brew install taplo | cargo install taplo-cli --locked |
xh | brew install xh (pin >=0.25.3) | cargo install xh --locked |
yq | brew install yq | apt install yq (verify mikefarah Go build, not python wrapper) |
zstd | brew install zstd | apt install zstd |
This skill synthesizes 25 pre-existing in-repo per-tool skills (collapsed in v1.9.0 per the Decision #14 toolbox criterion in .claude/rules/content-authoring.md). The original source files (now removed) lived at the following paths (IDs intentionally un-backticked here so the cross-reference scanner does not treat removed standalone skills as broken canonical IDs):
Per hatch3r's artifact-inventory and redundancy analysis, the rejected merge alternative (keep every tool as a standalone skill) was rejected because the 25 collapsed entries averaged 75 lines each (1.9k lines total) with >70% structural duplication of the same "When to Use / Token Cost / Recipes / Wrong Choice / Alternatives / Install" frame — collapse into a single category-indexed reference cuts the surface to ~250 lines while preserving the discriminator that picks one tool over another.