Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/add-cli-command/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Paths are relative to `crates/clickhousectl/`.
1. Follow the procedure for the kind of command:
- Local (`local ...`, runs on this machine): [references/local.md](references/local.md)
- Cloud (`cloud ...`, calls the Cloud API): [references/cloud.md](references/cloud.md)
2. Write help text to "Writing help text" in the root `AGENTS.md`.
2. Write help text with the `cli-help-text` skill (`.agents/skills/cli-help-text/SKILL.md`).
3. Finish with the steps below.

## Finish
Expand All @@ -26,7 +26,7 @@ Copy this checklist and tick it off as you go:

```
- [ ] Procedure steps (local.md or cloud.md)
- [ ] Help text follows the root AGENTS.md rules
- [ ] Help text follows the cli-help-text skill
- [ ] try_parse_from tests for new flags
- [ ] Both classifiers map new files
- [ ] README example
Expand Down
110 changes: 110 additions & 0 deletions .agents/skills/cli-help-text/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
name: cli-help-text
description: Writes and reviews `clickhousectl` `--help` text — command `about` lines, flag help, option order, and the `CONTEXT FOR AGENTS:` block — so people and coding agents can learn the CLI from help alone. Use when adding or changing a command or flag, editing clap `about`/`after_help`/arg doc comments, reviewing help in a PR, or fixing a help-structure test failure.
---

# CLI help text

Help is how people and coding agents learn the CLI. An agent reads `--help` the way it reads a tool description,
so every line should help it pick the right command, pass the right inputs, and avoid a surprise. Anything else
is noise that costs the reader time and tokens.

## Where help lives

- `#[command(about = ..., after_help = ...)]` and arg doc comments in `src/cli.rs`, `src/local/cli.rs`,
`src/cloud/cli.rs` and `src/cloud/<domain>.rs` (all under `crates/clickhousectl/`).
- `const INSTALL_AFTER_HELP` in `src/local/cli.rs`.
- `src/cloud/permissions.rs` appends API-key permission lines to every executable Cloud command, built from each
domain's declarations. Don't write those lines by hand.

## Screen shape

A help screen has only these parts, in this order:

1. A one-line `about`.
2. clap's `Usage:`, `Arguments:`/`Options:` and `Commands:` sections, with the standard headings.
3. Optionally, a trailing `CONTEXT FOR AGENTS:` block set with `after_help`.

No `long_about`, `before_help`, `after_long_help`, or any other `after_help` header.

## `about`

- An imperative verb phrase, up to about 60 characters, no trailing period.
- Say what the command does, not how it does it.
- Keep siblings parallel: "List X", "Get X details", "Create X", "Delete X".
- Mark beta commands with `(Beta)`.

## Flags and arguments

- One line, up to about 70 characters. Include units or format: "Interval in seconds", "RFC 3339 timestamp".
- Don't restate what clap renders: `[default: …]` and `[possible values: …]`.
- Put a cross-flag constraint on the flag it limits: "Only with `--replication-mode cdc_only`".
- Add a second doc-comment paragraph (up to about 3 lines) only for a constraint the flag's name and type
can't convey.
- Use enums (`value_enum`) rather than describing valid strings in prose, so clap lists and checks them.
- Shared flags (`--org-id`, `--org-name`, `--api-key`, `--api-secret`, `--url`, `--json`, `--debug`) read the same
everywhere. Copy the wording from an existing declaration.
- Resource names stay positional, under `Arguments`. Compatibility flags stay hidden.

## Option order

- Command-specific flags first, with display ranks below 900.
- Then the shared block, in this order: `--org-id`, `--org-name` (where it exists), `--api-key`, `--api-secret`,
`--url`, `--json`, `--debug`. Use the `help_order` ranks in `src/cli.rs` (900–906). clap adds `--help` at 999.
- Set the rank at every declaration, including local `--json` and auth flags, so inherited flags keep the block
together.
- Both local clients order common arguments as name, host, port, version, query, queries-file.
- Keep release-only URL hiding as it is.

## `CONTEXT FOR AGENTS:`

At most 8 content lines, ideally 3 to 6. Write densely: the block is for agents, not people, so pack related
facts onto one line. Permission lines added by `permissions.rs` don't count toward the 8.

Include only what changes what the agent does next:

- An auth requirement or precondition ("must be stopped first"). If meeting it takes a command or flag, name
it: "stop first (`cloud service stop`)". The agent shouldn't have to guess or read more help to find it.
- Runtime behaviour the flags don't show, when it affects how the command is used: timeouts, stdin handling,
irreversibility, long waits, retry safety.
- An output note, only if it changes what the agent does with the output.
- A `Typical flow:` line describing likely follow-on commands.
- Rarely, a docs URL: only when help can't cover something the agent needs. Never more than one.

NEVER include implementation details, crate or file names, HTTP and API mechanics, storage paths, history or
compatibility notes, reassurance, or anything already in the `about` line, the flag list or `[default:]`.

Put shared context (auth model, typical flow) on the parent command, such as `cloud service` or
`local server`. A leaf gets a block only for its own gotcha. A plain `get` or `list` usually needs none.

Write it plainly. State the fact and, where it isn't obvious, the reason. Don't use capitals or "MUST" for
emphasis: current models follow plain instructions closely, and emphasis makes them over-apply a rule.

Before (states mechanics, not consequences):

```
CONTEXT FOR AGENTS:
Calls DELETE /v1/organizations/{id}/services/{id} via clickhouse-cloud-api.
IMPORTANT: you MUST stop the service first!!
```

After:

```
CONTEXT FOR AGENTS:
Irreversible. Running service must be stopped first (--force or `cloud service stop`).
```

## Tests

NEVER add tests that pin help or README wording, such as `help.contains("some sentence")` or whole-screen
equality.

## Checklist

1. Edit the clap definitions.
2. Build, then read each changed screen as an agent would see it:
`cargo run -q -p clickhousectl -- <command path> --help`. Check the parent's screen too.
3. Check each line against the rules above. For each `CONTEXT FOR AGENTS:` line, ask whether an agent would act
differently without it. If not, delete it.
4. Run `cargo test -p clickhousectl` to catch structure failures, then the gates in the root `AGENTS.md`.
2 changes: 1 addition & 1 deletion .agents/skills/openapi-drift-remediation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ An API PR may touch CLI code only to keep it compiling after a breaking library
surface and an unchanged wire request (pin it with a test). A CLI PR never changes the library.

Read `crates/clickhouse-cloud-api/AGENTS.md` (model policy, analyzer configuration) and the root `AGENTS.md`
(help text, tests, gates) before editing. This skill is the workflow; those files are the rules.
(tests, gates) before editing. This skill is the workflow; those files are the rules.

## 1. Reproduce and inventory

Expand Down
1 change: 1 addition & 0 deletions .claude/skills/cli-help-text
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
/.agents/skills/*
!/.agents/skills/openapi-drift-remediation/
!/.agents/skills/add-cli-command/
!/.agents/skills/cli-help-text/
/.claude/*
!/.claude/skills/
/.claude/skills/*
!/.claude/skills/openapi-drift-remediation
!/.claude/skills/add-cli-command
!/.claude/skills/cli-help-text
/.codex/
/.cursor/
/.opencode/
Expand Down
39 changes: 3 additions & 36 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,41 +75,8 @@ domain keeps its definitions, handlers and tests together in `src/cloud/<domain>

## Writing help text

- Help lives in `#[command(about/after_help)]` and arg doc comments in `src/cli.rs`, `src/local/cli.rs`,
`src/cloud/cli.rs`, and `src/cloud/<domain>.rs`; one block is `const INSTALL_AFTER_HELP` in `src/local/cli.rs`.
`src/cloud/permissions.rs` adds permission context from domain declarations and API-library metadata.
- A help screen has only: one-line `about`, clap's `Usage:`, `Arguments:`/`Options:`, `Commands:`, and an optional
trailing `CONTEXT FOR AGENTS:` block via `after_help`. No `long_about`; no other `after_help` header.
- `about`: imperative verb phrase, ≤ ~60 chars, no trailing period, no implementation detail; keep siblings parallel
("List X", "Get X details", "Create X", "Delete X"). Flag help: one line, ≤ ~70 chars, include units/format
("Interval in seconds"), and never repeat clap's `[default: …]` or `[possible values: …]` in prose.
- Use `(Beta)` for beta markers; keep `(limited preview)` distinct.
- State cross-flag constraints on the flag itself ("only with `--replication-mode cdc_only`"). Add a second
doc-comment paragraph (≤ ~3 lines) only for a constraint the flag's name and type cannot convey.
- Shared flags (`--api-key`, `--api-secret`, `--url`, `--org-id`, `--org-name`, `--json`, `--debug`) read identically everywhere.
- Help options: command-specific flags first (display ranks below 900), then the contiguous shared block
`--org-id`, `--org-name` (when available), `--api-key`, `--api-secret`, `--url`, `--json`, `--debug`, `--help`.
Use `src/cli.rs`'s `help_order` ranks 900–906; `--org-name` uses 901, and clap supplies help at 999.
Apply ranks at every declaration, including local JSON and auth flags; inheritance must preserve the block.
Both local clients order common arguments as name, host, port, version, query, queries-file. Names stay in
Arguments; compatibility flags stay hidden. Keep standard headings and release-only URL hiding.
- `CONTEXT FOR AGENTS:` — hard cap 8 content lines, target 3-6, one fact per line. May hold: an auth requirement or
precondition; credential precedence without storage paths; where to get required inputs
("Service ID: `cloud service list`"); non-obvious runtime behaviour
(timeouts, stdin handling, irreversibility, "must be stopped first"); an output note only when it changes what the
agent does; a `Typical flow:` line; at most one docs URL.
It must NOT hold implementation details, crates/files, HTTP or API mechanics, storage paths, history or
compatibility notes, reassurance, or anything already in the flag list, `[default:]`, or the `about` line.
- Put shared context (auth model, how to find IDs, typical flow) on the parent (`cloud service`, `local server`).
The permission helper adds API-key requirements to every executable Cloud command; pure grouping commands
stay unchanged. Keep other leaf context specific to a gotcha. Permission lines count toward the 8-line cap;
move longer operational guidance to the README when necessary.
- Do not write tests that pin help or README wording (`help.contains("some sentence")`, `include_str!` on
`README.md`, whole-screen equality). They protect phrasing, not facts, and turn every rewording into a test edit.
Test structure instead: `try_parse_from` outcomes, `ErrorKind`, defaults and value names clap renders, hidden
flags staying hidden, every subcommand having an `about`, block size, and a flag reading identically everywhere.
A fact that must not disappear from help is guarded by review against this section, not by a substring.
- Content users still need but help must not carry goes to `README.md` as a short example or ≤ 3-line note.
Use the `cli-help-text` skill (`.agents/skills/cli-help-text/SKILL.md`) whenever you add or change a command, a
flag, or any help text. It holds the help standard and its test rule.

## Tests

Expand All @@ -128,7 +95,7 @@ Test coverage is non-negotiable.
`telemetry_test.rs`. Add a new file rather than growing `cli_request_shape_test.rs`, which is Cloud-only.
- **Pure logic** — inline `mod tests` blocks across `src/` for version resolution, auth precedence, output
formatting, platform detection, and other module-local helpers.
- **Help and README text** — structural assertions only (see Writing help text). No wording pins.
- **Help and README text** — structural assertions only (see the `cli-help-text` skill). No wording pins.

## CI gates

Expand Down
Loading