> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/wevm/incur/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

> Command definition and registration API

## CommandDefinition

Defines a command's schema, behavior, and documentation. Commands are registered with `cli.command()`.

### Type Signature

```typescript theme={null}
type CommandDefinition<
  args extends z.ZodObject<any> | undefined = undefined,
  env extends z.ZodObject<any> | undefined = undefined,
  options extends z.ZodObject<any> | undefined = undefined,
  output extends z.ZodType | undefined = undefined,
  parentVars extends z.ZodObject<any> | undefined = undefined,
  parentEnv extends z.ZodObject<any> | undefined = undefined,
> = {
  args?: args
  description?: string
  env?: env
  options?: options
  output?: output
  alias?: Record<string, string>
  examples?: Example[]
  format?: 'toon' | 'json' | 'yaml' | 'md'
  outputPolicy?: 'all' | 'agent-only'
  usage?: Usage[]
  middleware?: MiddlewareHandler[]
  run: (context: Context) => InferReturn<output> | Promise<InferReturn<output>> | AsyncGenerator
}
```

### Properties

<ParamField path="args" type="z.ZodObject<any>">
  Zod schema for positional arguments. Arguments are parsed in the order they are defined in the schema.

  ```typescript theme={null}
  args: z.object({
    name: z.string(),
    age: z.number()
  })
  // Usage: my-cli greet John 25
  ```
</ParamField>

<ParamField path="description" type="string">
  A short description of what the command does. Shown in help text, agent discovery, and skill manifests.
</ParamField>

<ParamField path="env" type="z.ZodObject<any>">
  Zod schema for command-specific environment variables. Merged with CLI-level env schema. Keys are the variable names (e.g. `DEPLOY_TOKEN`).
</ParamField>

<ParamField path="options" type="z.ZodObject<any>">
  Zod schema for named options/flags. Options are passed as `--key value` or `--flag` for booleans.

  ```typescript theme={null}
  options: z.object({
    verbose: z.boolean().default(false),
    output: z.string().optional()
  })
  // Usage: my-cli deploy --verbose --output ./dist
  ```
</ParamField>

<ParamField path="output" type="z.ZodType">
  Zod schema for the return value. Used for output validation and type inference in the command registry.
</ParamField>

<ParamField path="alias" type="Record<string, string>">
  Map of option names to single-char aliases.

  ```typescript theme={null}
  options: z.object({ verbose: z.boolean() }),
  alias: { verbose: 'v' }
  // Usage: my-cli deploy -v
  ```
</ParamField>

<ParamField path="examples" type="Example[]">
  Usage examples for this command. Shown in help output with `--help`.
</ParamField>

<ParamField path="format" type="'toon' | 'json' | 'yaml' | 'md'" default="'toon'">
  Default output format for this command. Overrides CLI-level format. Can still be overridden by `--format` or `--json` flags.
</ParamField>

<ParamField path="outputPolicy" type="'all' | 'agent-only'" default="'all'">
  Controls when output data is displayed:

  * `'all'` — displays to both humans and agents
  * `'agent-only'` — suppresses data output in human/TTY mode while still returning it to agents
</ParamField>

<ParamField path="usage" type="Usage[]">
  Alternative usage patterns shown in help output. Useful for documenting multiple invocation styles.
</ParamField>

<ParamField path="middleware" type="MiddlewareHandler[]">
  Command-specific middleware that runs only for this command. Runs after CLI-level and group-level middleware.
</ParamField>

<ParamField path="run" type="(context: Context) => InferReturn<output>" required>
  The command handler function. Receives a context object with parsed arguments, options, environment variables, and utility functions.

  Can return:

  * A plain value (synchronous)
  * A Promise (asynchronous)
  * An AsyncGenerator (streaming)

  See [Context Type](#context-type) below for details.
</ParamField>

## Context Type

The context object passed to the `run` handler. Contains parsed inputs, CLI metadata, and control flow functions.

### Properties

<ResponseField name="agent" type="boolean">
  Whether the consumer is an agent (stdout is not a TTY). Use this to customize output for different audiences.

  ```typescript theme={null}
  run(c) {
    if (c.agent) {
      return { structured: 'data' }
    }
    console.log('Human-friendly message')
    return {}
  }
  ```
</ResponseField>

<ResponseField name="args" type="InferOutput<args>">
  Positional arguments parsed according to the args schema. Fully typed based on the Zod schema.

  ```typescript theme={null}
  args: z.object({ name: z.string() }),
  run(c) {
    c.args.name // string (typed!)
  }
  ```
</ResponseField>

<ResponseField name="name" type="string">
  The CLI name (not the command name).
</ResponseField>

<ResponseField name="env" type="InferOutput<env>">
  Parsed environment variables according to the env schema. Includes both CLI-level and command-level env vars.
</ResponseField>

<ResponseField name="options" type="InferOutput<options>">
  Named options/flags parsed according to the options schema. Fully typed based on the Zod schema.

  ```typescript theme={null}
  options: z.object({ verbose: z.boolean().default(false) }),
  run(c) {
    c.options.verbose // boolean (typed!)
  }
  ```
</ResponseField>

<ResponseField name="var" type="InferVars<vars>">
  Variables set by middleware. Typed according to the CLI's vars schema.

  ```typescript theme={null}
  vars: z.object({ user: z.string() }),
  // In middleware: c.set('user', 'alice')
  run(c) {
    c.var.user // string (typed!)
  }
  ```
</ResponseField>

<ResponseField name="ok" type="(data: InferReturn<output>, meta?: { cta?: CtaBlock }) => never">
  Return a success result with optional metadata. Calling this function short-circuits execution and immediately returns.

  ```typescript theme={null}
  run(c) {
    return c.ok({ success: true }, {
      cta: {
        description: 'Next steps:',
        commands: ['my-cli deploy']
      }
    })
  }
  ```
</ResponseField>

<ResponseField name="error" type="(options: ErrorOptions) => never">
  Return an error result with optional CTAs. Calling this function short-circuits execution, exits with code 1, and displays the error.

  ```typescript theme={null}
  run(c) {
    if (!isValid) {
      return c.error({
        code: 'INVALID_INPUT',
        message: 'Invalid configuration',
        retryable: true,
        cta: {
          description: 'Try:',
          commands: ['my-cli validate']
        }
      })
    }
  }
  ```

  <Expandable title="ErrorOptions">
    <ParamField path="code" type="string" required>
      Error code (e.g. `'INVALID_INPUT'`, `'NOT_FOUND'`).
    </ParamField>

    <ParamField path="message" type="string" required>
      Human-readable error message.
    </ParamField>

    <ParamField path="retryable" type="boolean">
      Whether the operation can be retried. Helps agents decide if they should retry.
    </ParamField>

    <ParamField path="cta" type="CtaBlock">
      Call-to-action suggestions for the user.
    </ParamField>
  </Expandable>
</ResponseField>

<ResponseField name="version" type="string | undefined">
  The CLI version string, if provided.
</ResponseField>

## Command Registration Patterns

### Basic Command

Register a simple command with args and options:

```typescript theme={null}
import { Cli, z } from 'incur'

const cli = Cli.create('my-cli')

cli.command('greet', {
  description: 'Greet a person',
  args: z.object({
    name: z.string()
  }),
  options: z.object({
    loud: z.boolean().default(false)
  }),
  run(c) {
    const greeting = `Hello ${c.args.name}!`
    return { 
      message: c.options.loud ? greeting.toUpperCase() : greeting 
    }
  }
})
```

### Async Command

Commands can be async and use await:

```typescript theme={null}
cli.command('fetch', {
  args: z.object({ url: z.string() }),
  async run(c) {
    const response = await fetch(c.args.url)
    const data = await response.json()
    return { data }
  }
})
```

### Streaming Command

Return an AsyncGenerator to stream results:

```typescript theme={null}
cli.command('watch', {
  description: 'Watch for changes',
  async *run(c) {
    for (let i = 0; i < 5; i++) {
      await new Promise(r => setTimeout(r, 1000))
      yield { count: i, timestamp: Date.now() }
    }
  }
})
```

### Command with Environment Variables

Access typed environment variables:

```typescript theme={null}
cli.command('deploy', {
  description: 'Deploy to production',
  env: z.object({
    DEPLOY_TOKEN: z.string(),
    DEPLOY_URL: z.string().default('https://api.example.com')
  }),
  async run(c) {
    const response = await fetch(c.env.DEPLOY_URL, {
      headers: { Authorization: `Bearer ${c.env.DEPLOY_TOKEN}` }
    })
    return { status: response.status }
  }
})
```

### Command with Aliases

Provide short aliases for options:

```typescript theme={null}
cli.command('build', {
  options: z.object({
    output: z.string(),
    verbose: z.boolean().default(false)
  }),
  alias: {
    output: 'o',
    verbose: 'v'
  },
  run(c) {
    // Can be called with: build -o ./dist -v
    return { output: c.options.output }
  }
})
```

### Command Groups

Mount sub-CLIs as command groups:

```typescript theme={null}
// Create a command group
const pr = Cli.create('pr', { 
  description: 'Pull request management' 
})

pr.command('list', {
  description: 'List pull requests',
  run() {
    return { items: [] }
  }
})

pr.command('create', {
  description: 'Create a pull request',
  args: z.object({ title: z.string() }),
  run(c) {
    return { title: c.args.title }
  }
})

// Mount the group
cli.command(pr)

// Now available as:
// my-cli pr list
// my-cli pr create "My PR"
```

### Error Handling

Use context methods for structured error handling:

```typescript theme={null}
cli.command('validate', {
  args: z.object({ file: z.string() }),
  run(c) {
    if (!existsSync(c.args.file)) {
      return c.error({
        code: 'FILE_NOT_FOUND',
        message: `File not found: ${c.args.file}`,
        retryable: false,
        cta: {
          description: 'Available files:',
          commands: ['my-cli list']
        }
      })
    }
    return { valid: true }
  }
})
```

### Using Middleware Variables

Access variables set by middleware:

```typescript theme={null}
const cli = Cli.create('api', {
  vars: z.object({
    userId: z.string().default('anonymous')
  })
})

cli.use(async (c, next) => {
  // Authenticate and set user
  c.set('userId', 'user-123')
  await next()
})

cli.command('profile', {
  run(c) {
    // Access the userId set by middleware
    return { userId: c.var.userId }
  }
})
```
