From 72834167b6679465a4f3ff85ae7313282aa2cbd3 Mon Sep 17 00:00:00 2001 From: Bluscream Date: Fri, 18 Sep 2026 12:40:55 +0200 Subject: [PATCH] feat(cli-tooling): add generic CLI, tooling and script-placement rules Extracted from the per-agent profile files and the private ai-agents skill, where they were duplicated and environment-coupled: - discovery over guessing: walk the help tree, never invent flags, never hand-roll a script when a dedicated CLI exists - non-interactive invocation: explicit targets, the tool's own --wait - machine-readable output flags (json/compact/csv) vs. never filtering diagnostics - orient before starting: project instructions, git log, prior work records, and verifying TODOs against the code - script placement: dedicated version-controlled dir, symlinked into PATH - destructive/outward-facing command care; environment drift verification coding-dev.md and code-languages/bash.md now cross-reference it instead of carrying their own one-line versions. Co-Authored-By: Claude Opus 5 --- README.md | 1 + cli-tooling.md | 189 +++++++++++++++++++++++++++++++++++++++++ code-languages/bash.md | 9 +- coding-dev.md | 4 + 4 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 cli-tooling.md diff --git a/README.md b/README.md index 8930364..497598e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A collection of public, reusable agent skills, cheatsheets, and operational work | Skill File | Scope / Topics Covered | | :--- | :--- | | **[`coding-dev.md`](./coding-dev.md)** | Standing rules for all code work: maximum linter/compiler strictness, never filtering build output, reuse-before-reinvent dependency ordering, file/function size limits, test & regression discipline, verification gates, scope control, commit hygiene, and honest reporting. | +| **[`cli-tooling.md`](./cli-tooling.md)** | Using command-line tools correctly: reading the help tree instead of guessing flags, preferring an existing CLI over an ad-hoc script, non-interactive invocation, machine-readable output formats, orienting on prior work before starting, script placement & symlinking, and care around destructive commands. | ### ๐Ÿ”ค Per-Language Rules ([`code-languages/`](./code-languages/)) diff --git a/cli-tooling.md b/cli-tooling.md new file mode 100644 index 0000000..cd84506 --- /dev/null +++ b/cli-tooling.md @@ -0,0 +1,189 @@ +--- +name: cli-tooling +description: >- + Use this skill whenever invoking a command-line tool, choosing between a CLI and an ad-hoc + script, writing a standalone utility script, or orienting on unfamiliar work before starting. + Covers discovering a CLI's real interface instead of guessing flags, non-interactive and + machine-readable invocation, script placement and symlinking, and care around destructive + or outward-facing commands. +--- + +# CLI & Tooling โ€” Discovery, Invocation, and Script Placement + +How to use command-line tools correctly, and where utility scripts belong. +Companion to [`coding-dev.md`](./coding-dev.md), which covers writing the code itself. + +--- + +## 1. Discovery Over Guessing + +> [!IMPORTANT] +> **Read the tool's own help before using it. Never guess subcommands or flags.** +> ```bash +> --help +> --help +> ``` + +A tool's built-in help is authoritative and current; memory and training data are neither. +Flags get renamed, subcommands get restructured, and a confidently-invented flag either +errors out or โ€” far worse โ€” silently means something else. + +**This applies to listing capabilities, too.** When asked what a tool can do, run its help +and report what it actually says. Do not produce a speculative command list; a plausible- +looking invented flag is indistinguishable from a real one to whoever reads it next. + +### Walk the whole help tree + +Multi-level CLIs hide most of their surface one level down. ` --help` shows the +subcommand list; the flags that matter usually live in ` --help`. + +### Don't reinvent a tool that exists + +**When a dedicated CLI already provides the functionality, use it** rather than writing an +ad-hoc script, a one-off `curl` pipeline, or a bespoke API client. The CLI already handles +authentication, retries, pagination, error formatting, and the edge cases you have not +thought of yet. + +Before writing a script to do something, check whether: +- a dedicated CLI for that system is already installed, +- the tool you are already using has a subcommand for it, +- the project's own `scripts/` directory already contains it. + +--- + +## 2. Non-Interactive Invocation + +Anything run from a script, a CI job, or an agent must not depend on a human being present. + +- **Pass required targets explicitly.** A CLI that manages multiple objects will, when no + target is given, either prompt interactively or fail โ€” both of which break automation. + Always pass `--server `, `--profile `, `--target ` rather than relying on a + default or a prompt. +- **Use the tool's own blocking flag** (`--wait`, `--follow`, `--no-detach`) when you need an + operation to finish before the next step. Do not build a polling loop around a command that + already knows how to wait โ€” and never write a shell `until`/`while` wait loop + (see [`code-languages/bash.md`](./code-languages/bash.md)). +- **Prefer a `--dry-run` rehearsal** for anything that deploys, releases, or deletes, when the + tool offers one. +- Set `--yes` / `--non-interactive` deliberately and only where the action is genuinely safe โ€” + not as a reflex to stop a tool from asking. + +--- + +## 3. Machine-Readable Output + +When output feeds another program โ€” or an agent's context โ€” ask the tool for a structured +format rather than parsing its human-facing table. + +```bash +tool list -o json # full fidelity +tool list -o compact # minimal tokens, good for agent context +tool list -o csv # structured columns for a spreadsheet or script +``` + +- **Never scrape a table meant for humans.** Column widths, truncation, colour codes, and + alignment all change without notice; a structured format is a contract. +- Strip colour explicitly (`--color never`, `NO_COLOR=1`) when capturing output, or escape + sequences end up in your parsed values. +- Keep in mind that a "compact" or summary format is the right default for feeding an agent, + while `json` is right for a script that needs every field. + +> [!WARNING] +> **Never pipe build, lint, or test output through a filter to make it shorter.** That is a +> different situation and the rule there is the opposite โ€” see +> [`coding-dev.md` ยง2](./coding-dev.md). Structured output flags are for data; `grep` on +> diagnostics hides warnings. + +--- + +## 4. Orient Before Starting + +Before beginning work in an unfamiliar project or one you have not touched recently, spend a +moment establishing what has already happened. Cheap, and it prevents the most expensive +failure mode: rebuilding something that already exists. + +In rough order of value: +1. **The project's own instructions** โ€” `AGENTS.md`, `CLAUDE.md`, `.rules`, `CONTRIBUTING.md`, + `README.md`. Read them before touching code. +2. **Recent history** โ€” `git log --oneline -20`, and `git status --short` to see what is + already in flight so you do not clobber it. +3. **Prior work records** โ€” session/conversation history tooling, issue trackers, or notes + files, scoped to the project directory. +4. **The code itself** โ€” `grep` for the symbol before trusting any document that says it is + missing. + +> [!CAUTION] +> **Task documents are leads, not facts.** A `TODO.md` entry can be stale, duplicated, or +> simply wrong โ€” including when it sounds confident and especially when it sounds familiar. +> Verify against the code before acting on one. A single `grep` is cheaper than rediscovering +> that the work shipped last week. + +--- + +## 5. Where Scripts Live + +> [!IMPORTANT] +> **Never write a standalone script directly into a `PATH` directory** (`~/.local/bin`, +> `/usr/local/bin`, or similar). Write it into a **dedicated scripts directory** that is +> version-controlled, then **symlink** it into `PATH`. + +```bash +# write the script to its real home +$EDITOR /path/to/scripts/my-tool.sh +chmod +x /path/to/scripts/my-tool.sh + +# then expose it +ln -s /path/to/scripts/my-tool.sh ~/.local/bin/my-tool +``` + +**Why:** one versioned source of truth. A script living directly in `PATH` is invisible to +version control, easy to clobber on a reinstall, impossible to diff, and indistinguishable +from a package-manager-owned binary sitting beside it. The symlink makes the provenance +obvious โ€” `ls -l` shows exactly where the real file is. + +The same applies within a project: scripts belong in `scripts/`, referenced by the build +system, not scattered at the repository root. + +--- + +## 6. Destructive and Outward-Facing Commands + +- **Look at the target before deleting or overwriting it.** Inspect it first โ€” the cost of a + wrong `rm` or a wrong overwrite is unbounded and the check is one command. +- **Read-only first.** When exploring an unfamiliar tool, use its inspection subcommands + (`status`, `list`, `show`, `get`) before any mutating one. +- **Mutating commands that rewrite shared configuration** โ€” syncing settings across machines, + purging caches or state, patching installed applications โ€” should be confirmed before + running, even when they are reversible in principle. +- **Never use real data as scratch space.** Real accounts, real configuration directories, + live services, and the user's actual files are not disposable test fixtures. Use temporary + directories and disposable targets. +- Anything that sends, publishes, deploys, or purchases is outward-facing: confirm first, and + treat approval as applying to that one action rather than the category. + +--- + +## 7. Environment Constraints + +- **Entering a container or changing shells resets the working directory.** Chain `cd` inside + the same command string rather than relying on it persisting: + ```bash + container-run -- bash -c "cd /path/to/project && make" + ``` +- **Verify what actually exists rather than assuming from documentation.** Container names, + tool versions, and installed toolchains drift. A one-command check (` list`, + ` --version`, `command -v `) costs nothing and prevents a confident invocation + of something that was removed months ago. +- **Check for an optional dependency before the step that needs it**, and fail loudly if it + is missing. A packaging step that silently skips when its tool is absent ships an + incomplete release. +- **Don't saturate the machine.** A full build consuming every core makes the workstation + unusable. When something latency-sensitive is running, reduce the job count and `nice` the + work โ€” and say that you did. + +--- + +## 8. Related Skills +- [`coding-dev.md`](./coding-dev.md) โ€” writing the code these tools build and test. +- [`code-languages/bash.md`](./code-languages/bash.md) โ€” writing the scripts themselves: + strict mode, quoting, build-gate structure, destructive-command guards. diff --git a/code-languages/bash.md b/code-languages/bash.md index 06faedf..2330165 100644 --- a/code-languages/bash.md +++ b/code-languages/bash.md @@ -161,12 +161,15 @@ mistakes before a human does. ## 9. Script Placement -Standalone utility scripts belong in a **dedicated scripts directory**, symlinked into `PATH` -rather than copied there. Never write a loose script directly into `~/.local/bin` or another -`PATH` directory โ€” the source of truth should be one versioned location. +Standalone utility scripts belong in a **dedicated, version-controlled scripts directory**, +symlinked into `PATH` rather than copied there. Never write a loose script directly into +`~/.local/bin` or another `PATH` directory โ€” the source of truth should be one versioned +location. See [`../cli-tooling.md` ยง5](../cli-tooling.md) for the reasoning and the pattern. --- ## 10. Related - [`../coding-dev.md`](../coding-dev.md) โ€” the general rules this extends. +- [`../cli-tooling.md`](../cli-tooling.md) โ€” invoking other tools *from* these scripts: + discovery, non-interactive flags, structured output. - [`python.md`](./python.md) โ€” where a shell script should have become a Python script. diff --git a/coding-dev.md b/coding-dev.md index 9579e65..68fb8d0 100644 --- a/coding-dev.md +++ b/coding-dev.md @@ -294,8 +294,12 @@ Run the **whole** gate, not the convenient part of it. A typical full gate: ## 13. Environment & Tooling +Full version in [`cli-tooling.md`](./cli-tooling.md); the essentials: + - **Read ` --help` before using a CLI.** Do not guess flags, and do not write an ad-hoc script when an existing tool already does the job. +- **Standalone scripts live in a dedicated, version-controlled scripts directory**, symlinked + into `PATH` โ€” never written directly into `~/.local/bin` or another `PATH` directory. - **Build inside the project's designated environment** (container, venv, toolchain manager) rather than the host, when the project specifies one. Note that entering a container typically resets the working directory โ€” chain `cd` inside the same command string.