### Quick Start: Create a Simple Greeting CLI Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates creating a basic CLI named 'greet' that takes a name argument and returns a greeting message. This example uses Zod for argument validation and the Cli.create function to define the CLI. ```ts import { Cli, z } from 'incur' const cli = Cli.create('greet', { description: 'A greeting CLI', args: z.object({ name: z.string().describe('Name to greet'), }), run({ args }) { return { message: `hello ${args.name}` } }, }) cli.serve() ``` -------------------------------- ### Full Incur CLI Example in TypeScript Source: https://github.com/wevm/incur/blob/main/SKILL.md A comprehensive example demonstrating the creation of a CLI application using Incur. It includes defining commands, arguments, options, aliases, output schemas, and examples, along with the necessary setup for Incur. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('npm', { version: '10.9.2', description: 'The package manager for JavaScript.', sync: { suggestions: ['install react as a dependency', 'check for outdated packages'], }, }) cli.command('install', { description: 'Install a package', args: z.object({ package: z.string().optional().describe('Package name to install'), }), options: z.object({ saveDev: z.boolean().optional().describe('Save as dev dependency'), global: z.boolean().optional().describe('Install globally'), }), alias: { saveDev: 'D', global: 'g' }, output: z.object({ added: z.number().describe('Number of packages added'), packages: z.number().describe('Total packages'), }), examples: [ { args: { package: 'express' }, description: 'Install a package' }, { args: { package: 'vitest' }, options: { saveDev: true }, description: 'Install as dev dependency', }, ], run({ args }) { if (!args.package) return { added: 120, packages: 450 } return { added: 1, packages: 451 } }, }) cli.command('outdated', { description: 'Check for outdated packages', options: z.object({ global: z.boolean().describe('Check global packages'), }), alias: { global: 'g' }, output: z.object({ packages: z.array( z.object({ name: z.string(), current: z.string(), wanted: z.string(), latest: z.string(), }), ), }), run() { return { packages: [{ name: 'express', current: '4.18.0', wanted: '4.21.2', latest: '4.21.2' }], } }, }) cli.serve() export default cli ``` -------------------------------- ### Install Incur CLI Framework Source: https://github.com/wevm/incur/blob/main/README.md Instructions for installing the Incur CLI framework using popular package managers like npm, pnpm, and bun. This is the first step to using Incur for building CLIs. ```bash npm i incur ``` ```bash pnpm i incur ``` ```bash bun i incur ``` -------------------------------- ### TOON Output Format Example Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates the TOON output format, which is designed to be human-readable and agent-parsable with reduced token usage compared to JSON. This example shows a CLI command and its TOON output. ```shell $ my-cli hikes --location Boulder --season spring_2025 # → context: # → task: Our favorite hikes together # → location: Boulder # → season: spring_2025 # → friends[3]: ana,luis,sam # → hikes[3]{id,name,distanceKm,elevationGain,companion,wasSunny}: # → 1,Blue Lake Trail,7.5,320,ana,true # → 2,Ridge Overlook,9.2,540,luis,false # → 3,Wildflower Loop,5.1,180,sam,true ``` -------------------------------- ### Incur CLI Help with Sub-commands Example (Shell) Source: https://github.com/wevm/incur/blob/main/README.md Displays the help output for a CLI created with Incur, showing the root command and its registered sub-command groups. ```sh $ tool --help # Usage: tool # # Commands: # run Run a task # db Database commands ``` -------------------------------- ### Conventional Commit Example Source: https://github.com/wevm/incur/blob/main/AGENTS.md Provides examples of conventional commit messages, demonstrating the use of prefixes like `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, and `chore:`, along with optional scopes. ```git feat: Add user authentication module Implements login and registration endpoints. feat(parser): Improve error handling for invalid input fix: Correct calculation error in reporting module ``` -------------------------------- ### JSON Output Format Example Source: https://github.com/wevm/incur/blob/main/README.md Illustrates how to switch to JSON format using the --format flag. This is useful for agents that require structured JSON data, though it may consume more tokens than TOON. ```shell $ my-cli status --format json # → { # → "context": { # → "task": "Our favorite hikes together", # → "location": "Boulder", # → "season": "spring_2025" # → }, # → "friends": ["ana", "luis", "sam"], # → "hikes": [ # → ... + 1000 more tokens # → ] # → } ``` -------------------------------- ### Incur CLI Call-to-Action Output Example (Shell) Source: https://github.com/wevm/incur/blob/main/README.md Shows the output of an Incur CLI command that includes call-to-actions. The output displays the command results and suggests relevant next steps for the agent. ```sh $ my-cli list # → items: # → - id: 1 # → title: Fix bug # Next: # my-cli get 1 – View item # my-cli list closed – View closed ``` -------------------------------- ### Shell: Starting CLI as an MCP stdio Server Source: https://github.com/wevm/incur/blob/main/SKILL.md This shell command starts the CLI as an MCP stdio server, exposing all commands as MCP tools over stdin/stdout. Command groups are flattened using underscores, and arguments/options are merged into a single flat input schema. ```shell my-cli --mcp ``` -------------------------------- ### Create a Multi-Command CLI with Incur Source: https://github.com/wevm/incur/blob/main/README.md Example of building a CLI with multiple subcommands using Incur. It shows how to chain `.command()` calls to register different commands, each with its own arguments, options, and run logic. ```typescript import { Cli, z } from 'incur' Cli.create('my-cli', { description: 'My CLI', }) .command('status', { description: 'Show repo status', run() { return { clean: true } }, }) .command('install', { description: 'Install a package', args: z.object({ package: z.string().optional().describe('Package name'), }), options: z.object({ saveDev: z.boolean().optional().describe('Save as dev dependency'), }), alias: { saveDev: 'D' }, run(c) { return { added: 1, packages: 451 } }, }) .serve() ``` -------------------------------- ### Serve CLI Commands with Options (TypeScript) Source: https://context7.com/wevm/incur/llms.txt Demonstrates how to create and serve CLI commands using the Incur library. It covers standard command execution and provides examples of testing with custom stdout and exit handlers, as well as environment variable injection. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('tool', { version: '1.0.0', description: 'A deployment tool', }) .command('deploy', { args: z.object({ env: z.enum(['staging', 'production']) }), run(c) { return { url: `https://${c.args.env}.example.com` } }, }) // Standard usage cli.serve() // Testing usage with custom stdout/exit async function testServe() { let output = '' let exitCode: number | undefined await cli.serve(['deploy', 'staging'], { stdout(s) { output += s }, exit(code) { exitCode = code }, env: { API_TOKEN: 'test-token' }, }) console.log(output) // "url: https://staging.example.com\n" console.log(exitCode) // undefined (success) } ``` -------------------------------- ### Per-Command Middleware with Error Handling in TypeScript Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how to apply middleware to specific commands and handle errors using `c.error()` or by throwing exceptions. This example includes authentication and admin role checks. ```typescript import { Cli, middleware, z } from 'incur'; type User = { id: string; name: string; admin?: boolean }; const cli = Cli.create('my-cli', { description: 'My CLI', vars: z.object({ user: z.custom() }), }); const requireAuth = middleware((c, next) => { if (!c.var.user) return c.error({ code: 'AUTH', message: 'must be logged in' }); return next(); }); const requireAdmin = middleware((c, next) => { if (!c.var.user?.admin) throw new Error('admin required'); return next(); }); cli.command('deploy', { middleware: [requireAuth], run() { return { deployed: true }; }, }); // Example usage: // $ my-cli deploy // Error (AUTH): must be logged in // $ my-cli other-cmd // per-command middleware does not run ``` -------------------------------- ### Create a Single-Command CLI with Incur Source: https://github.com/wevm/incur/blob/main/README.md Example of creating a basic single-command CLI using Incur. It demonstrates defining arguments with Zod schemas and a simple run function that returns a JSON object. The CLI is then served using `.serve()`. ```typescript import { Cli, z } from 'incur' 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() ``` -------------------------------- ### Incur CLI Light API Surface Example (TypeScript) Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates the Incur CLI's light API surface using TypeScript. It shows how to create a root CLI, define sub-command groups, register commands, and serve the CLI with minimal boilerplate code. ```ts import { Cli, z } from 'incur' // Define sub-command groups const db = Cli.create('db', { description: 'Database commands' }).command('migrate', { description: 'Run migrations', run: () => ({ migrated: true }), }) // Create the root CLI Cli.create('tool', { description: 'A tool' }) // Register commands .command('run', { description: 'Run a task', run: () => ({ ok: true }) }) // Mount sub-command groups .command(db) // Serve the CLI .serve() ``` -------------------------------- ### Register a Command with Arguments, Options, and Aliases Source: https://github.com/wevm/incur/blob/main/SKILL.md Shows how to register a command with detailed configurations including arguments, options, aliases, output schema, and examples. Zod is used for defining schemas. ```ts cli.command('install', { description: 'Install a package', args: z.object({ package: z.string().optional().describe('Package name'), }), options: z.object({ saveDev: z.boolean().optional().describe('Save as dev dependency'), global: z.boolean().optional().describe('Install globally'), }), alias: { saveDev: 'D', global: 'g' }, output: z.object({ added: z.number(), packages: z.number(), }), examples: [ { args: { package: 'express' }, description: 'Install a package' }, { args: { package: 'vitest' }, options: { saveDev: true }, description: 'Install as dev dependency', }, ], run({ args, options }) { return { added: 1, packages: 451 } }, }) ``` -------------------------------- ### Shell: Generating and Installing Agent Skill Files Source: https://github.com/wevm/incur/blob/main/SKILL.md This shell command automatically generates and installs agent skill files from the CLI's command definitions. This enables agents to discover and utilize the CLI's functionality without explicit configuration. ```shell my-cli skills add ``` -------------------------------- ### Incur Agent Discovery Mechanisms Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how to use Incur CLI for agent discovery. It includes commands to auto-generate and install agent skill files, register as an MCP server, and output a machine-readable manifest for LLMs. ```sh # Auto-generate and install agent skill files (recommended – lighter on tokens) my-cli skills add # Register as an MCP server for your agents my-cli mcp add # Output machine-readable manifest my-cli --llms ``` -------------------------------- ### Implement Root-Level Middleware (TypeScript) Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates how to register middleware using `cli.use()` to execute logic before or after command execution. This example logs the execution time of commands. ```typescript const cli = Cli.create('deploy-cli', { description: 'Deploy tools' }) .use(async (c, next) => { const start = Date.now() await next() console.log(`took ${Date.now() - start}ms`) }) .command('deploy', { run() { return { deployed: true } }, }) ``` -------------------------------- ### Customizing CLI Usage Patterns Source: https://github.com/wevm/incur/blob/main/SKILL.md Illustrates how to define alternative usage patterns for a CLI command to be displayed in the `--help` output. This allows for more descriptive and varied command-line examples, including prefixes and suffixes. ```typescript Cli.create('curl.md', { args: z.object({ url: z.string() }), options: z.object({ objective: z.string().optional() }), usage: [ { args: { url: true } }, { args: { url: true }, options: { objective: true } }, { prefix: 'cat file.txt |', suffix: '| head' }, ], run({ args }) { return { content: '...' } }, }) ``` -------------------------------- ### Vitest Type Test Example Source: https://github.com/wevm/incur/blob/main/AGENTS.md Illustrates how to write type-checking tests using Vitest's `expectTypeOf` in colocated `.test-d.ts` files. This ensures that generic type inference works as expected. ```typescript // my-module.test-d.ts import { expectTypeOf } from 'vitest'; import { processSchema } from './my-module'; import { z } from 'zod'; const schema = z.object({ id: z.number() }); processSchema(schema, (data) => { expectTypeOf(data).toEqualTypeOf<{ id: number }>(); }); ``` -------------------------------- ### Incur CLI Call-to-Action Example (TypeScript) Source: https://github.com/wevm/incur/blob/main/README.md Illustrates how to implement call-to-actions (CTAs) in an Incur CLI command using TypeScript. The `run` function returns CTAs to suggest next steps to the agent, including command names, arguments, and descriptions. ```ts cli.command('list', { args: z.object({ state: z.enum(['open', 'closed']).default('open') }), run(c) { const items = [{ id: 1, title: 'Fix bug' }] return c.ok( { items }, { cta: { commands: [ { command: 'get 1', description: 'View item' }, { command: 'list', args: { state: 'closed' }, description: 'View closed' }, ], }, }, ) }, }) ``` -------------------------------- ### Define Commands with Typed Arguments and Options (TypeScript) Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates how to define a CLI command named 'deploy' with typed arguments and options using Zod for validation. It includes example usage for deploying to different environments and forcing a deployment. ```typescript cli.command('deploy', { args: z.object({ env: z.enum(['staging', 'production']) }), options: z.object({ force: z.boolean().optional() }), examples: [ { args: { env: 'staging' }, description: 'Deploy to staging' }, { args: { env: 'production' }, options: { force: true }, description: 'Force deploy to prod' }, ], run({ args }) { return { deployed: args.env } }, }) ``` -------------------------------- ### Inferred Types for CLI Arguments and Outputs Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates type safety in incur by showing how argument and option types are inferred and checked. The example highlights how the `run` callback, output, and CTA commands benefit from zero-manual annotations due to flowing generics. ```typescript cli.command('greet', { args: z.object({ name: z.string() }), options: z.object({ loud: z.boolean().default(false) }), output: z.object({ message: z.string() }), run(c) { c.args.name // ^? (property) name: string c.options.loud // ^? (property) loud: boolean return c.ok( { message: `hello ${c.args.name}` }, //^? (property) message: string { cta: { commands: ['greet world'] }, // ^? 'greet' | 'other-cmd' }, ) }, }) ``` -------------------------------- ### Arbitrarily Nested Subcommand Groups Source: https://github.com/wevm/incur/blob/main/SKILL.md Shows how subcommand groups can be nested to any depth, creating complex CLI structures. This example demonstrates a three-level nesting for GitHub CLI commands. ```ts const cli = Cli.create('gh', { description: 'GitHub CLI' }) const pr = Cli.create('pr', { description: 'Pull requests' }) const review = Cli.create('review', { description: 'Review commands' }) review.command('approve', { run: () => ({ approved: true }) }) pr.command(review) cli.command(pr) // → gh pr review approve ``` -------------------------------- ### TypeScript: Displaying CTAs for Agent Guidance Source: https://github.com/wevm/incur/blob/main/SKILL.md This TypeScript code snippet demonstrates how to provide Call to Actions (CTAs) to guide agents on success or error scenarios. It includes suggested commands for successful operations and error-handling commands for self-correction. ```typescript run(c) { const result = { id: 42, name: c.args.name } return c.ok(result, { cta: { description: 'Suggested commands:', commands: [ { command: 'get', args: { id: 42 }, description: 'View the item' }, 'list', ], }, }) } ``` ```typescript run(c) { const token = process.env.GH_TOKEN if (!token) return c.error({ code: 'NOT_AUTHENTICATED', message: 'GitHub token not found', retryable: true, cta: { description: 'To authenticate:', commands: [ { command: 'auth login', description: 'Log in to GitHub' }, { command: 'config set', options: { token: true }, description: 'Set token manually' }, ], }, }) // ... } ``` -------------------------------- ### TypeScript: Configuring Agent Skill Generation Source: https://github.com/wevm/incur/blob/main/SKILL.md This TypeScript code snippet shows how to configure the `skills add` command for generating agent skill files. It allows customization of grouping depth, inclusion of additional skill files, and provides example prompts for user guidance. ```typescript const cli = Cli.create('my-cli', { sync: { depth: 1, include: ['_root'], suggestions: ['install react as a dependency', 'check for outdated packages'], }, }) ``` -------------------------------- ### Return Structured Results with Context Helpers (TypeScript) Source: https://context7.com/wevm/incur/llms.txt Illustrates the use of `ok()` and `error()` context helpers in Incur CLI command handlers. These functions allow returning structured success data or error information, including optional call-to-actions (CTAs) for guiding user interaction. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('todo', { description: 'Todo manager' }) cli.command('create', { args: z.object({ title: z.string() }), output: z.object({ id: z.number(), title: z.string() }), run(c) { const item = { id: 42, title: c.args.title } return c.ok(item, { cta: { description: 'Next steps:', commands: [ { command: 'get 42', description: 'View the item' }, { command: 'list', description: 'See all items' }, 'delete 42', // String shorthand ], }, }) }, }) cli.command('get', { args: z.object({ id: z.string() }), run(c) { const id = parseInt(c.args.id) if (isNaN(id)) { return c.error({ code: 'INVALID_ID', message: 'ID must be a number', retryable: true, cta: { commands: [{ command: 'list', description: 'See valid IDs' }], }, }) } return { id, title: 'Buy milk', done: false } }, }) cli.serve() // Output with CTA: // id: 42 // title: My task // // Next steps: // todo get 42 # View the item // todo list # See all items ``` -------------------------------- ### Implement Sub-CLI Middleware (TypeScript) Source: https://github.com/wevm/incur/blob/main/SKILL.md Shows how middleware attached to a sub-CLI only affects commands within that sub-CLI. This example restricts access to 'admin' commands. ```typescript const admin = Cli.create('admin', { description: 'Admin commands' }) .use(async (c, next) => { if (!isAdmin()) throw new Error('forbidden') await next() }) .command('reset', { run: () => ({ reset: true }) }) cli.command(admin) ``` -------------------------------- ### TypeScript Generic with Const Modifier Source: https://github.com/wevm/incur/blob/main/AGENTS.md Example of using the `const` generic modifier in TypeScript to preserve literal types for full inference, particularly useful when passing types to functions. ```typescript function process(value: T): void { /* ... */ } ``` -------------------------------- ### Create and Serve CLI as MCP Server with Incur Cli Source: https://context7.com/wevm/incur/llms.txt Demonstrates how to create a command-line interface (CLI) application using the Incur Cli module and expose it as an MCP stdio server. This allows agents to invoke CLI commands as tools, with support for streaming handlers and progress notifications. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('deploy-tool', { version: '1.0.0', description: 'Deployment automation', }) cli.command('deploy', { description: 'Deploy to environment', args: z.object({ env: z.enum(['staging', 'production']).describe('Target environment'), }), options: z.object({ force: z.boolean().default(false).describe('Skip confirmations'), }), output: z.object({ id: z.string(), url: z.string(), duration: z.string(), }), run(c) { return { id: 'deploy-abc123', url: `https://${c.args.env}.example.com`, duration: '45s', } }, }) cli.serve() // Start as MCP server: // $ deploy-tool --mcp // (stdio server running, accepts JSON-RPC requests) // Or register with agents: // $ deploy-tool mcp add // ✓ Registered deploy-tool as MCP server // Tool schema exposed to agents: // { // "name": "deploy", // "description": "Deploy to environment", // "inputSchema": { // "type": "object", // "properties": { // "env": { "type": "string", "enum": ["staging", "production"] }, // "force": { "type": "boolean", "default": false } // }, // "required": ["env"] // } // } ``` -------------------------------- ### Incur CLI Help and Commands Source: https://github.com/wevm/incur/blob/main/README.md Displays the help information for the Incur CLI, outlining its usage, available commands (pr, mcp, skills), and global options like format, help, llms, mcp, verbose, and version. ```sh $ my-cli --help # my-cli – My CLI # # Usage: my-cli # # Commands: # pr Pull request commands # # Built-in Commands: # mcp add Register as an MCP server # skills add Sync skill files to your agent # # Global Options: # --format Output format # --help Show help # --llms Print LLM-readable manifest # --mcp Start as MCP stdio server # --verbose Show full output envelope # --version Show version ``` -------------------------------- ### Serve CLI Application (TypeScript) Source: https://github.com/wevm/incur/blob/main/SKILL.md Shows the basic usage of `cli.serve()` to parse command-line arguments and execute the CLI application. It also demonstrates how to override `stdout` and `exit` handlers for testing purposes. ```typescript cli.serve() ``` ```typescript let output = '' await cli.serve(['install', 'express', '--json'], { stdout(s) { output += s }, exit() {}, }) ``` -------------------------------- ### Create a Single-Command CLI Application Source: https://context7.com/wevm/incur/llms.txt Creates a new CLI application instance with a run handler for a single command. It accepts a name, description, version, and Zod schemas for arguments, options, environment variables, and output. The `run` function defines the CLI's core logic. ```typescript import { Cli, z } from 'incur' // Single-command CLI with run handler const greet = Cli.create('greet', { description: 'A greeting CLI', version: '1.0.0', args: z.object({ name: z.string().describe('Name to greet'), }), options: z.object({ loud: z.boolean().default(false).describe('Shout the greeting'), }), output: z.object({ message: z.string(), }), run(c) { const msg = c.options.loud ? `HELLO ${c.args.name}!` : `hello ${c.args.name}` return { message: msg } }, }) greet.serve() // Router CLI without run handler (registers subcommands) const cli = Cli.create('my-cli', { description: 'My CLI application', version: '2.0.0', }) ``` -------------------------------- ### Inheriting Output Policy Across CLI Groups Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how the `outputPolicy` can be set on a parent CLI group to be inherited by its child commands. This example shows a group set to 'agent-only' with one child command overriding it to 'all'. ```typescript const internal = Cli.create('internal', { description: 'Internal commands', outputPolicy: 'agent-only', }) internal.command('sync', { run: () => ({ synced: true }) }) // inherits agent-only internal.command('status', { outputPolicy: 'all', // overrides to show output run: () => ({ ok: true }), }) ``` -------------------------------- ### Registering Middleware in TypeScript Source: https://github.com/wevm/incur/blob/main/README.md Illustrates how to register middleware functions using `cli.use()` to execute code before or after command handlers. Middleware runs in registration order and uses `await next()` to pass control. ```typescript import { Cli, z } from 'incur'; const cli = Cli.create('deploy-cli', { description: 'Deploy tools' }); cli.use(async (c, next) => { const start = Date.now(); await next(); console.log(`took ${Date.now() - start}ms`); }); cli.command('deploy', { run() { return { deployed: true }; }, }); // Example usage: // $ deploy-cli deploy // → deployed: true // took 12ms ``` -------------------------------- ### Create a Router CLI with Subcommands Source: https://github.com/wevm/incur/blob/main/SKILL.md Sets up a CLI that acts as a router for subcommands. The `run` function is omitted from `Cli.create`, and subcommands are added using the `.command()` method. ```ts const cli = Cli.create('gh', { version: '1.0.0', description: 'GitHub CLI', }) cli.command('status', { description: 'Show repo status', run() { return { clean: true } }, }) cli.serve() ``` -------------------------------- ### Zod Generic Schema Passing with Const Modifier Source: https://github.com/wevm/incur/blob/main/AGENTS.md Example of a factory function in TypeScript that accepts Zod schemas and uses `const` generic parameters to preserve the literal types of the schema object. This is crucial for accurate type inference downstream. ```typescript import { z } from 'zod'; function createHandler>(schema: T) { type OutputType = z.output; return (data: OutputType) => { // ... handler logic }; } ``` -------------------------------- ### Using CLI Name in Command Logic Source: https://github.com/wevm/incur/blob/main/README.md Shows how the CLI name, provided during `Cli.create()`, is available in the `run` context. This name can be used to construct dynamic help text, error messages, or user-facing strings. ```typescript const cli = Cli.create('deploy-cli', { description: 'Deploy tools' }) cli.command('check', { output: z.string(), run(c) { if (!authenticated()) return `Not logged in. Run `${c.name} auth login` to log in.` return 'OK' }, }) ``` -------------------------------- ### Agent Discovery with Incur CLI (TypeScript) Source: https://context7.com/wevm/incur/llms.txt Demonstrates using 'skills add' for skill file generation and 'mcp add' for MCP server registration. The '--llms' flag provides a machine-readable command manifest. Configures skills sync depth and target agents for MCP. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('my-tool', { version: '1.0.0', description: 'A helpful tool', // Configure skills sync sync: { depth: 1, // Group skills by first command segment suggestions: [ 'install react as a dependency', 'check for outdated packages', ], }, // Configure MCP registration mcp: { agents: ['claude-code', 'cursor'], // Target agents command: 'npx my-tool --mcp', // Override auto-detected command }, }) cli.command('install', { description: 'Install a package', args: z.object({ package: z.string() }), run(c) { return { installed: c.args.package } }, }) cli.serve() // Built-in commands: // $ my-tool skills add // Syncing... // ✓ my-tool Install a package // 1 skill synced // // $ my-tool mcp add // ✓ Registered my-tool as MCP server // Agents: claude-code, cursor // // $ my-tool --llms // # my-tool install // Install a package // ## Arguments // | Name | Type | Required | Description | // |------|------|----------|-------------| // | `package` | `string` | yes | | // // $ my-tool --llms --format json // {"version":"incur.v1","commands":[{"name":"install","description":"Install a package","schema":{"args":{"type":"object","properties":{"package":{"type":"string"}},"required":["package"]}}}]} ``` -------------------------------- ### Streaming Output with CTAs and Return Value Source: https://github.com/wevm/incur/blob/main/README.md Illustrates streaming output that includes status updates and a final return value signaling success with associated actions (CTAs). The `ok()` function is used to return a success status and define callable commands. ```typescript async *run(c) { yield { step: 1 } yield { step: 2 } return c.ok(undefined, { cta: { commands: ['status'] } }) } ``` -------------------------------- ### Create a Single-Command CLI Source: https://github.com/wevm/incur/blob/main/SKILL.md Defines a CLI that performs a single action. The `run` function is provided directly to `Cli.create` to handle the command's logic. ```ts const cli = Cli.create('tool', { description: 'Does one thing', args: z.object({ file: z.string() }), run({ args, options }) { return { processed: args.file } }, }) ``` -------------------------------- ### Using `ok()` and `error()` Helpers for Results Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates the use of `c.ok()` and `error()` helper functions within the `run` context for explicitly returning successful results or structured error objects. This provides clear control over command outcomes. ```typescript run(c) { const item = await db.find(c.args.id) if (!item) return error({ code: 'NOT_FOUND', message: `Item ${c.args.id} not found`, retryable: false, }) return c.ok(item) } ``` -------------------------------- ### Configuring Output Formats in Incur CLI (TypeScript) Source: https://context7.com/wevm/incur/llms.txt Shows how to configure different output formats for CLI commands using the '--format' flag or '--json' shorthand. Supports TOON, JSON, YAML, Markdown, and JSONL. The '--verbose' flag includes metadata. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('api', { description: 'API client' }) cli.command('users', { description: 'List users', output: z.object({ users: z.array(z.object({ id: z.number(), name: z.string(), role: z.string(), })), }), run() { return { users: [ { id: 1, name: 'Alice', role: 'admin' }, { id: 2, name: 'Bob', role: 'user' }, ], } }, }) cli.serve() // Default TOON format: // $ api users // users[2]{id,name,role}: // 1,Alice,admin // 2,Bob,user // JSON format: // $ api users --json // { // "users": [ // {"id": 1, "name": "Alice", "role": "admin"}, // {"id": 2, "name": "Bob", "role": "user"} // ] // } // Verbose envelope: // $ api users --verbose // ok: true // data: // users[2]{id,name,role}: // 1,Alice,admin // 2,Bob,user // meta: // command: users // duration: 5ms // YAML format: // $ api users --format yaml // users: // - id: 1 // name: Alice // role: admin // - id: 2 // name: Bob // role: user ``` -------------------------------- ### Streaming Text Output from CLI Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how to stream text output incrementally from a CLI command using an async generator function. Each yielded string is outputted as a separate line. ```typescript cli.command('logs', { description: 'Tail logs', async *run() { yield 'connecting...' yield 'streaming logs' yield 'done' }, }) ``` -------------------------------- ### Create and Mount Subcommand Groups Source: https://github.com/wevm/incur/blob/main/SKILL.md Illustrates creating nested CLIs (subcommand groups) and mounting them onto a parent CLI. This allows for organizing commands hierarchically. ```ts const cli = Cli.create('gh', { description: 'GitHub CLI' }) const pr = Cli.create('pr', { description: 'Pull request commands' }) pr.command('list', { description: 'List pull requests', options: z.object({ state: z.enum(['open', 'closed', 'all']).default('open'), }), run({ options }) { return { prs: [], state: options.state } }, }) pr.command('view', { description: 'View a pull request', args: z.object({ number: z.number() }), run({ args }) { return { number: args.number, title: 'Fix bug' } }, }) // Mount onto the parent CLI cli.command(pr) cli.serve() ``` -------------------------------- ### Parse Arguments and Environment Variables with Incur Parser Source: https://context7.com/wevm/incur/llms.txt Demonstrates how to use the Incur Parser module to parse command-line arguments and environment variables against Zod schemas. It supports various argument types, aliases, and type coercion for robust input handling. ```typescript import { Parser, z } from 'incur' // Parse arguments and options const argsSchema = z.object({ name: z.string(), version: z.string().optional(), }) const optionsSchema = z.object({ verbose: z.boolean().default(false), count: z.number().default(1), tags: z.array(z.string()).optional(), }) const result = Parser.parse( ['my-package', '1.0.0', '--verbose', '--count', '5', '--tags', 'latest', '--tags', 'beta'], { args: argsSchema, options: optionsSchema, alias: { verbose: 'v', count: 'n' }, } ) console.log(result.args) // { name: 'my-package', version: '1.0.0' } console.log(result.options) // { verbose: true, count: 5, tags: ['latest', 'beta'] } // Parse environment variables const envSchema = z.object({ API_TOKEN: z.string(), DEBUG: z.boolean().default(false), PORT: z.number().default(3000), }) const env = Parser.parseEnv(envSchema, { API_TOKEN: 'secret-123', DEBUG: 'true', PORT: '8080', }) console.log(env) // { API_TOKEN: 'secret-123', DEBUG: true, PORT: 8080 } ``` -------------------------------- ### Marking Options as Deprecated in TypeScript Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how to mark command-line options as deprecated using the `.meta({ deprecated: true })` configuration in TypeScript. Deprecated flags will display a warning in help messages and when used in TTY mode. ```typescript import { Cli, z } from 'incur'; const cli = new Cli(); cli.command('deploy', { options: z.object({ zone: z.string().optional().describe('Availability zone').meta({ deprecated: true }), region: z.string().optional().describe('Target region'), }), run(c) { return { region: c.options.region }; }, }); // Example usage: // $ my-cli deploy --zone us-east-1 // Warning: --zone is deprecated ``` -------------------------------- ### Chain Command Registrations Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates chaining multiple `.command()` calls to register several subcommands on a CLI instance. This allows for a concise way to add multiple commands. ```ts cli .command('ping', { run: () => ({ pong: true }) }) .command('version', { run: () => ({ version: '1.0.0' }) }) ``` -------------------------------- ### JSON: LLM Command Manifest in JSON Format Source: https://github.com/wevm/incur/blob/main/SKILL.md This JSON output represents a machine-readable manifest of CLI commands, generated using the `--llms --format json` flags. It details command names, descriptions, and their corresponding argument and option schemas. ```json { "version": "incur.v1", "commands": [ { "name": "install", "description": "Install a package", "schema": { "args": { "type": "object", "properties": { "package": { "type": "string" } } }, "options": { "type": "object", "properties": { "saveDev": { "type": "boolean" } } }, "output": { "type": "object", "properties": { "added": { "type": "number" } } } } } ] } ``` -------------------------------- ### Snapshot Test for Deterministic Output Source: https://github.com/wevm/incur/blob/main/AGENTS.md Shows the use of `toMatchInlineSnapshot()` for snapshot testing of deterministic string outputs like TOML or JSON. It also covers handling mostly deterministic output with dynamic properties. ```javascript describe('generateConfig', () => { it('should produce correct TOML output', () => { const config = { server: { port: 8080 }, database: { type: 'postgres' } }; const output = toml.stringify(config); expect(output).toMatchInlineSnapshot(` "[server]\nport = 8080\n\n[database]\ntype = \"postgres\"\n" `); }); }); ``` -------------------------------- ### Implement Middleware for CLI Commands (TypeScript) Source: https://context7.com/wevm/incur/llms.txt Shows how to register middleware functions with the Incur CLI to execute logic before or after command handlers. It illustrates root middleware, typed middleware using generic context and environment variables, and per-command middleware for access control. ```typescript import { Cli, middleware, z } from 'incur' type User = { id: string; name: string; admin: boolean } const cli = Cli.create('deploy-cli', { description: 'Deploy tools', env: z.object({ API_TOKEN: z.string().describe('Auth token'), }), vars: z.object({ user: z.custom(), requestId: z.string(), }), }) // Root middleware - runs for all commands cli.use(async (c, next) => { const start = Date.now() c.set('requestId', crypto.randomUUID()) await next() console.log(`Request ${c.var.requestId} took ${Date.now() - start}ms`) }) // Auth middleware with typed vars const requireAuth = middleware(async (c, next) => { // Access CLI-level env const token = c.env.API_TOKEN // Simulate auth lookup const user = { id: 'u_123', name: 'Alice', admin: true } c.set('user', user) await next() }) cli.use(requireAuth) // Per-command middleware const requireAdmin = middleware((c, next) => { if (!c.var.user?.admin) { return c.error({ code: 'FORBIDDEN', message: 'Admin required' }) } return next() }) cli.command('deploy', { middleware: [requireAdmin], run(c) { return { deployed: true, by: c.var.user.name, requestId: c.var.requestId } }, }) cli.serve() ``` -------------------------------- ### Shell: Outputting LLM Command Manifest Source: https://github.com/wevm/incur/blob/main/SKILL.md This shell command utilizes the `--llms` flag to output a machine-readable manifest of all available commands. By default, it outputs Markdown skill documentation, but can be configured to output JSON, YAML, or TOON formats. ```shell tool --llms ``` -------------------------------- ### Implement Per-Command Middleware (TypeScript) Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates how to apply middleware to a specific command. This middleware runs after root and group middleware and only for the designated command. It includes type safety for middleware context. ```typescript import { Cli, middleware, z } from 'incur' const cli = Cli.create('my-cli', { description: 'My CLI', vars: z.object({ user: z.custom<{ id: string }>() }), }) const requireAuth = middleware((c, next) => { if (!c.var.user) throw new Error('must be logged in') return next() }) cli.command('deploy', { middleware: [requireAuth], run() { return { deployed: true } }, }) ``` -------------------------------- ### Create Nested Command Groups Source: https://context7.com/wevm/incur/llms.txt Organizes related commands into nested groups by creating separate CLI instances and mounting them using `.command(cli)`. This allows for hierarchical command structures, such as `cli pr list` or `cli pr create`. ```typescript import { Cli, z } from 'incur' const cli = Cli.create('gh', { description: 'GitHub CLI' }) // Create a command group const pr = Cli.create('pr', { description: 'Pull request commands' }) .command('list', { description: 'List pull requests', options: z.object({ state: z.enum(['open', 'closed', 'all']).default('open'), }), run(c) { return { prs: [], state: c.options.state } }, }) .command('create', { description: 'Create a pull request', args: z.object({ title: z.string().describe('PR title'), }), run(c) { return { id: 42, title: c.args.title } }, }) // Nested groups const review = Cli.create('review', { description: 'Review commands' }) .command('approve', { description: 'Approve a review', run: () => ({ approved: true }), }) pr.command(review) cli.command(pr) cli.serve() // Usage: // gh pr list --state closed // gh pr create "My feature" // gh pr review approve ``` -------------------------------- ### Define CLI Options using Zod Source: https://github.com/wevm/incur/blob/main/SKILL.md Illustrates defining named options for a CLI using Zod schemas. Supports various types, defaults, optionality, and array inputs. ```ts options: z.object({ state: z.enum(['open', 'closed']).default('open').describe('Filter by state'), limit: z.number().default(30).describe('Max results'), label: z.array(z.string()).optional().describe('Filter by labels'), verbose: z.boolean().optional().describe('Show details'), }) ``` -------------------------------- ### Create a Nested Sub-command CLI with Incur Source: https://github.com/wevm/incur/blob/main/README.md Demonstrates how to create nested command groups in an Incur CLI. A separate `Cli` instance is created for a subcommand group ('pr') and then mounted into the main CLI using `.command(cli)`. ```typescript const cli = Cli.create('my-cli', { description: 'My CLI' }) // Create a `pr` group. const pr = Cli.create('pr', { description: 'Pull request commands' }).command('list', { description: 'List pull requests', options: z.object({ state: z.enum(['open', 'closed', 'all']).default('open'), }), run(c) { return { prs: [], state: c.options.state } }, }) cli .command(pr) // Link the `pr` group. .serve() ``` -------------------------------- ### Stream Output in TypeScript Source: https://github.com/wevm/incur/blob/main/SKILL.md Demonstrates how to stream output incrementally using `async *run`. Yields can be strings for text or objects for structured data. Each yielded value is formatted based on the output mode (human/TOON or JSONL). ```typescript cli.command('logs', { description: 'Tail logs', async *run() { yield 'connecting...' yield 'streaming logs' yield 'done' }, }) ``` ```typescript async *run() { yield { progress: 50 } yield { progress: 100 } } ``` ```typescript async *run({ ok }) { yield { step: 1 } yield { step: 2 } return ok(undefined, { cta: { commands: ['status'] } }) } ```