Skip to main content

middleware()

Creates a strictly typed middleware handler. Pass the vars and env schemas as generics for full type inference.

Signature

Parameters

handler
Handler<vars, env>
required
The middleware handler function that receives context and next function.

Return Type

Handler
Handler<vars, env>
Returns the same handler with proper type inference. This is an identity function that exists purely for type safety.

Examples

Basic Middleware

Typed Middleware

Use type parameters for full type inference with vars and env:

Handler Type

The middleware handler function type.

Type Signature

Parameters

context
Context<vars, env>
The middleware context object. See Context Type below.
next
() => Promise<void>
Function to call the next middleware in the chain or the command handler. Calling next() is optional - omitting it short-circuits the chain.

Context Type

The context object passed to middleware handlers. Contains CLI metadata, environment variables, and variable management.

Properties

agent
boolean
Whether the consumer is an agent (stdout is not a TTY).
command
string
The resolved command path (e.g. 'deploy' or 'pr create').
name
string
The CLI name.
env
InferEnv<env>
Parsed environment variables from the CLI-level env schema. Fully typed based on the schema.
var
InferVars<vars>
Variables set by upstream middleware. Read-only. Fully typed based on the vars schema.
version
string | undefined
The CLI version string, if provided.
set
<key extends keyof InferVars<vars>>(key: key, value: InferVars<vars>[key]) => void
Set a typed variable for downstream middleware and command handlers. Variables must be declared in the CLI’s vars schema.
error
(options: ErrorOptions) => never
Return an error result, short-circuiting the middleware chain. The command handler will not run.

next() Function

The next() function continues the middleware chain or invokes the command handler if this is the last middleware.

Behavior

  • Call await next() to continue execution
  • Omit await next() to short-circuit (useful for auth checks, caching, etc.)
  • Code before next() runs before the command
  • Code after next() runs after the command (cleanup, logging, etc.)

Examples

Before and After Hooks

Short-Circuit on Error

Middleware Patterns

Authentication

Check authentication before running commands:

Request Logging

Log all commands with timing:

Request ID Tracking

Add a unique ID to each request:

Rate Limiting

Implement rate limiting:

Scoped Middleware

Middleware on command groups only runs for that group’s commands:

Conditional Middleware

Skip middleware based on conditions:

Error Recovery

Handle errors in middleware:

Middleware Order

Middleware runs in the order it’s registered:

Middleware Chain Levels

Middleware runs in this order:
  1. CLI-level middleware — registered with cli.use()
  2. Group-level middleware — registered on mounted sub-CLIs
  3. Command-level middleware — defined in command definition
  4. Command handler — the run() function