rtb generate¶
Scaffold something from the embedded templates. Five kinds:
project, command, flag, setting, docs.
Every kind except project requires an existing scaffolded tree — they
read .rtb/manifest.yaml and fail without it.
rtb generate project [PATH]¶
Render a preset into a new directory.
| Argument | Type | Default | Notes |
|---|---|---|---|
PATH (positional) |
path | ./<name> |
Destination directory. Must not already exist. |
-n, --name <NAME> |
string | — | Tool name. Must match ^[a-z][a-z0-9-]{0,63}$ and not be a reserved name. Required under --non-interactive; otherwise the wizard asks. |
-d, --description <TEXT> |
string | empty | One-line description written into the generated Cargo.toml and the tool's clap about. At most 500 bytes after NFC normalisation, no control characters except tab, and no {{ or }}. |
--preset <NAME> |
string | minimal |
Which bundled preset to render. See presets. |
--non-interactive |
flag | off | Never prompt. Every required field must arrive as a flag. |
--no-git |
flag | off | Skip git init and the initial commit. |
What it writes¶
Six files, plus a git repository unless --no-git is given:
$ rtb generate project --name greeter --description "A greeting tool" --non-interactive
Created `greeter` (6 files written to greeter)
greeter/
├── .git/
├── .gitignore
├── .rtb/manifest.yaml
├── Cargo.toml
├── README.md
└── src/
├── commands/mod.rs
└── main.rs
When it fails¶
- The destination exists.
generatenever overwrites; it errors and suggests removing the directory or choosing another destination. This is what keeps the verb safe to re-run. --non-interactivewith a missing required field. One diagnostic lists every missing field at once, rather than failing on the first.- The name or description fails validation. See validation rules.
- The preset is not bundled. Unknown preset names are a hard error;
there is no silent fallback to
minimal.
rtb generate command <COMMAND_PATH>¶
Add a subcommand to a scaffolded tool. Writes
src/commands/<name>.rs and registers it between the
// rtb:commands-begin / -end markers in src/commands/mod.rs.
| Argument | Type | Default | Notes |
|---|---|---|---|
COMMAND_PATH (positional) |
string | — | Command name. Required unless a protect / unprotect sub-verb is used. |
--about <ABOUT> |
string | Scaffolded subcommand |
Short help text for the command. |
--short <CHAR> |
char | — | One-character alias. Recorded in the manifest. |
--aliases <A,B,C> |
comma list | — | Alternative command names. Deduplicated; each validated as a command name. |
--long <TEXT> |
string | falls back to --about |
Long help shown in the command's own --help. |
--args <name:type,…> |
comma list | — | Scaffold arguments alongside the command. Equivalent to one generate flag per entry; the type defaults to string. |
--provider <PROVIDER> |
string | anthropic |
AI provider for --prompt / --script. See environment variables. |
--model <MODEL> |
string | provider default | Model id override. |
--prompt <TEXT-OR-PATH> |
string | — | Natural-language description of the behaviour, or a path to a file holding one. |
--script <PATH> |
path | — | A bash / python / js script to port into the command body. |
--agentless |
flag | off | One-shot generation; skip the verify-and-repair loop. |
--max-repair-iterations <N> |
u32 | 5 |
Cap on repair attempts. |
Sub-verbs¶
rtb generate command protect <COMMAND_PATH>— add the command's file to the manifest'sprotected:list.regenerate projectthen always skips it, andremoverefuses it without--force.rtb generate command unprotect <COMMAND_PATH>— reverse that.
When it fails¶
- The name contains
/. Nested command paths are rejected with "nested command paths are not yet supported", even thoughvalidate_command_pathaccepts up to four segments. - The command already exists in the manifest, or the target file exists on disk.
--promptor--scripton theclipreset. AI codegen targets theminimalpreset only; oncliit errors before touching disk.
The AI call, when requested, happens before anything is written, so a provider failure leaves no half-scaffolded command behind and the command can simply be re-run.
rtb generate flag <FLAG_NAME>¶
Add a clap argument to an already-scaffolded command.
| Argument | Type | Default | Notes |
|---|---|---|---|
FLAG_NAME (positional) |
string | — | Long name without the leading --. Passing --name rather than name is rejected with a message saying so. |
-c, --command <COMMAND_PATH> |
string | — | Required. Target command, matching the file basename under src/commands/. |
--type <TY> |
enum | string |
string, bool, int, float, string_slice. Aliases below. |
-d, --description <TEXT> |
string | empty | Rendered as .help("…"). |
-s, --shorthand <CHAR> |
char | — | One-character short flag. |
--required |
flag | off | Renders clap::Arg::required(true). |
--persistent |
flag | off | Renders clap::Arg::global(true). |
--default <VALUE> |
string | — | Default value as a string literal. Ignored when --type bool. |
--default-is-code |
flag | off | Not implemented — setting it is an error. |
--provider <PROVIDER> / --model <MODEL> |
string | — | Draft the help text with an AI when --description is omitted. |
Accepted --type values¶
| Canonical | Also accepted | Renders |
|---|---|---|
string |
str |
plain value argument |
bool |
boolean, flag |
.action(clap::ArgAction::SetTrue) |
int |
i64, integer |
.value_parser(clap::value_parser!(i64)) |
float |
f64, number |
.value_parser(clap::value_parser!(f64)) |
string_slice |
stringslice, strings |
.action(clap::ArgAction::Append) |
Anything else is rejected and the message lists the five canonical names.
rtb generate setting <FIELD_NAME>¶
Add a persistent setting — a field on the tool's AppConfig struct in
src/main.rs, inserted between the // rtb:settings-begin / -end
markers.
| Argument | Type | Default | Notes |
|---|---|---|---|
FIELD_NAME (positional) |
string | — | See the naming constraint below. |
--type <TY> |
enum | string |
Same names as generate flag; rendered as String, bool, i64, f64, Vec<String>. |
--default <VALUE> |
string | — | Written as a // default: <value> comment above the field. It does not change the runtime value. |
-p, --path <PATH> |
path | cwd | Project root. |
The name must be a single lowercase word¶
The help text calls FIELD_NAME a "snake_case Rust identifier", but
the value is checked with the flag-name validator, which requires
^[a-z][a-z0-9-]{0,63}$. In practice:
greeting— accepted, renderspub greeting: String,.default_name— rejected:invalid setting name: flag_name: must match ^[a-z][a-z0-9-]{0,63}$.default-name— accepted by the validator, but renderspub default-name: String,, which is not valid Rust and will not compile.
Until that is fixed, keep setting names to one lowercase word. See what RTB does not do.
--default is documentation only¶
The value is rendered as a comment; the field still takes its type's
Default at runtime:
rtb generate docs¶
Write one Markdown page per scaffolded command, plus an index.
| Argument | Type | Default | Notes |
|---|---|---|---|
-p, --path <PATH> |
path | cwd | Project root. |
--provider <PROVIDER> |
string | — | Run the AI prose pass over each page. Omit for the mechanical extraction only. |
--model <MODEL> |
string | provider default | Model id override. |
--page-by-page |
flag | off | Accepted but not implemented — it changes nothing. |
Where the pages land¶
Into docs/components/ in the target project, hardcoded. The path is
not configurable, and it does not match the Diátaxis layout this project
now uses (reference/cli/ for command pages). Generated pages are
recorded in the manifest's generated: map so regenerate manifest
keeps them in sync.
The two passes¶
- Extraction (always). Reads each scaffolded command file, pulls the
string literals out of
fn name,fn aboutand the flag long names, and writes a structural page. - AI prose (only with
--provider). Sends each extracted page to the provider and replaces it with the returned prose. The index page is deliberately skipped — its content is mechanical.
The AI pass rewrites pages in place with no diff and no confirmation step, so run it on a clean working tree.
Related¶
rtb remove— the inverse of each kind.rtb regenerate— reconcile a tree with its manifest.- Flags vs settings —
why
flagandsettingare separate verbs.