run handler directly to Cli.create().
When to Use Single-Command Pattern
Use this pattern when your CLI:- Performs a single, focused task
- Doesn’t need subcommands or command groups
- Has a simple input/output flow
greet, convert, validate, ping
Basic Single-Command CLI
1
Import incur
2
Start by importing
Cli and z from incur:3
import { Cli, z } from 'incur'
4
Define the CLI with run
5
Pass the
run handler directly to Cli.create():6
Cli.create('greet', {
description: 'A greeting CLI',
args: z.object({
name: z.string().describe('Name to greet'),
}),
run(c) {
return { message: `hello ${c.args.name}` }
},
}).serve()
7
Run the CLI
8
greet world
# → message: hello world
Adding Arguments
Define positional arguments using a Zod schema. Arguments are parsed in the order they appear in the schema:Arguments are always required unless marked with
.optional(). Use z.coerce.number() or z.coerce.boolean() to parse string input from the command line.Adding Options
Options are named flags that users pass with--flag syntax:
Option Aliases
Create short aliases for options:Output Handling
The return value fromrun is automatically formatted and displayed to the user.
Default Output (TOON)
By default, incur uses TOON format - a compact, token-efficient format:Async Handlers
Handlers can be async:Error Handling
Usec.error() for structured errors:
IncurError:
Context Properties
Therun handler receives a context object with:
c.args- Parsed positional argumentsc.options- Parsed option flagsc.name- The CLI name (useful for help messages)c.agent-trueif called by an agent (stdout is not a TTY)c.env- Parsed environment variables (ifenvschema is defined)c.var- Variables set by middlewarec.ok(data, meta?)- Return success with optional CTAsc.error(options)- Return an error

