{"id":30876160,"url":"https://github.com/robingenz/zli","last_synced_at":"2025-09-08T02:07:04.715Z","repository":{"id":310544436,"uuid":"1040292692","full_name":"robingenz/zli","owner":"robingenz","description":"📟 A powerful CLI parser built with TypeScript and Zod for type-safe command-line interfaces.","archived":false,"fork":false,"pushed_at":"2025-09-01T20:09:42.000Z","size":420,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-02T14:04:26.427Z","etag":null,"topics":["cli","parser","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robingenz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"polar":"robingenz"}},"created_at":"2025-08-18T18:46:45.000Z","updated_at":"2025-09-01T20:09:46.000Z","dependencies_parsed_at":"2025-08-18T20:28:05.001Z","dependency_job_id":"cc44daa7-576b-4651-8d9c-3f1366e58776","html_url":"https://github.com/robingenz/zli","commit_stats":null,"previous_names":["robingenz/zli"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/robingenz/zli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robingenz%2Fzli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robingenz%2Fzli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robingenz%2Fzli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robingenz%2Fzli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robingenz","download_url":"https://codeload.github.com/robingenz/zli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robingenz%2Fzli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274121957,"owners_count":25225801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","parser","zod"],"created_at":"2025-09-08T02:06:58.850Z","updated_at":"2025-09-08T02:07:04.704Z","avatar_url":"https://github.com/robingenz.png","language":"TypeScript","funding_links":["https://polar.sh/robingenz"],"categories":[],"sub_categories":[],"readme":"# @robingenz/zli\n\n[![npm version](https://img.shields.io/npm/v/@robingenz/zli)](https://www.npmjs.com/package/@robingenz/zli)\n[![npm downloads](https://img.shields.io/npm/dm/@robingenz/zli)](https://www.npmjs.com/package/@robingenz/zli)\n[![license](https://img.shields.io/npm/l/@robingenz/zli)](https://github.com/robingenz/zli/blob/main/LICENSE)\n\nA powerful CLI parser built with TypeScript and Zod for type-safe command-line interfaces.\n\n## Features\n\n- 🛡️ **Type-safe**: Built with TypeScript and Zod for runtime validation.\n- 📋 **Declarative**: Define commands, options, and arguments with simple schemas.\n- 🔄 **Flexible parsing**: Support for long flags, short flags, and flag clustering.\n- 🔀 **Smart conversion**: Automatic kebab-case to camelCase conversion.\n- 🏷️ **Alias support**: Define short aliases for any option.\n- 📦 **Array handling**: Automatic normalization of single values to arrays.\n- 🎯 **Default commands**: Set a default command to run when no command is specified.\n- ❓ **Help message**: Automatic help generation for commands and options.\n- ⚠️ **Error handling**: Clear, actionable error messages.\n- 🚀 **Zero dependencies**: Only requires Zod as a peer dependency.\n- 📦 **ESM support**: Modern ES modules with full TypeScript support.\n\n## Installation\n\n```bash\nnpm install @robingenz/zli zod\n```\n\n## Usage\n\n### Basic Example\n\n```javascript\nimport { z } from 'zod';\nimport { defineConfig, defineCommand, defineOptions, processConfig } from '@robingenz/zli';\n\n// Define a simple command\nconst greetCommand = defineCommand({\n  description: 'Greet someone',\n  options: defineOptions(\n    z.object({\n      name: z.string().describe('Name to greet'),\n      loud: z.boolean().default(false).describe('Use uppercase'),\n    }),\n    { n: 'name', l: 'loud' } // Short aliases\n  ),\n  action: async (options) =\u003e {\n    const greeting = `Hello, ${options.name}!`;\n    console.log(options.loud ? greeting.toUpperCase() : greeting);\n  },\n});\n\n// Configure the CLI\nconst config = defineConfig({\n  meta: {\n    name: 'my-cli',\n    version: '1.0.0',\n    description: 'A simple CLI example',\n  },\n  commands: {\n    greet: greetCommand,\n  },\n  defaultCommand: greetCommand,\n});\n\n// Process command line arguments\ntry {\n  const result = processConfig(config, process.argv.slice(2));\n  await result.command.action(result.options, result.args);\n} catch (error) {\n  console.error('Error:', error.message);\n  process.exit(1);\n}\n```\n\n### Command Usage\n\n```bash\n# Show help\nmy-cli --help\nmy-cli greet --help\n\n# Run commands\nmy-cli greet --name Alice\nmy-cli greet -n Bob --loud\n\n# Run default command\nmy-cli --name Alice\nmy-cli greet --name Alice\n```\n\n### Advanced Features\n\n#### Default Commands\n\nYou can specify a default command that will be executed when no command is provided:\n\n```javascript\nconst config = defineConfig({\n  meta: {\n    name: 'my-app',\n    version: '1.0.0',\n  },\n  commands: {\n    start: startCommand,\n    build: buildCommand,\n  },\n  defaultCommand: startCommand,\n});\n```\n\nWith this configuration:\n- `my-app` will run the `startCommand`\n- `my-app --help` will still show the help message\n- `my-app build` will run the `build` command\n\n#### Commands with Arguments\n\n```javascript\nconst copyCommand = defineCommand({\n  description: 'Copy a file',\n  args: z.tuple([\n    z.string().describe('Source file'),\n    z.string().describe('Destination file'),\n  ]),\n  options: defineOptions(\n    z.object({\n      verbose: z.boolean().default(false).describe('Verbose output'),\n    }),\n    { v: 'verbose' }\n  ),\n  action: async (options, args) =\u003e {\n    const [source, dest] = args;\n    console.log(`Copying ${source} to ${dest}`);\n  },\n});\n```\n\n#### Array Options\n\n```javascript\nconst options = defineOptions(\n  z.object({\n    files: z.array(z.string()).describe('Input files'),\n    tags: z.array(z.string()).optional().describe('Tags to apply'),\n  })\n);\n\n// Usage: --files file1.txt --files file2.txt\n// Single values are automatically converted to arrays\n```\n\n#### Type Transformations\n\n```javascript\nconst options = defineOptions(\n  z.object({\n    port: z.coerce.number().min(1).max(65535).describe('Port number'),\n    count: z.coerce.number().min(1).describe('Count'),\n  })\n);\n```\n\n### Flag Parsing\n\n`@robingenz/zli` supports various flag formats:\n\n```bash\n# Long flags\n--verbose --name=value --port 3000\n\n# Short flags  \n-v -n value -p 3000\n\n# Flag clustering\n-abc  # equivalent to -a -b -c\n\n# Kebab-case conversion\n--my-option  # becomes myOption in your code\n\n# Multiple values\n--file a.txt --file b.txt  # becomes ['a.txt', 'b.txt']\n```\n\n### API Reference\n\n#### `defineOptions(schema, aliases?)`\n\nDefine options for a command with optional aliases.\n\n- `schema`: Zod object schema defining the options\n- `aliases`: Optional object mapping short aliases to option names\n\n#### `defineCommand(config)`\n\nDefine a command with options, arguments, and action.\n\n- `description`: Command description for help\n- `options`: Options definition (optional)\n- `args`: Zod schema for arguments (optional)  \n- `action`: Function to execute when command is run\n\n#### `defineConfig(config)`\n\nDefine the CLI configuration.\n\n- `meta`: CLI metadata (name, version, description)\n- `commands`: Object mapping command names to definitions\n- `defaultCommand`: Optional default command definition to run when no command is specified\n\n#### `processConfig(config, args)`\n\nProcess command line arguments and return the result.\n\n- `config`: CLI configuration\n- `args`: Command line arguments (typically `process.argv.slice(2)`)\n\nReturns an object with:\n- `command`: The matched command definition\n- `options`: Parsed and validated options\n- `args`: Parsed and validated arguments\n\n## Changelog\n\nSee [CHANGELOG.md](./CHANGELOG.md).\n\n## License\n\nSee [LICENSE](./LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobingenz%2Fzli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobingenz%2Fzli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobingenz%2Fzli/lists"}