{"_id":"@bioleyl/zargv","_rev":"4-6430624ec9697e7ddccbce8b3a90c45f","name":"@bioleyl/zargv","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@bioleyl/zargv","version":"0.1.0","_id":"@bioleyl/zargv@0.1.0","maintainers":[{"name":"bioleyl","email":"lb@syware.ch"}],"homepage":"https://github.com/bioleyl/zargv#readme","bugs":{"url":"https://github.com/bioleyl/zargv/issues"},"dist":{"shasum":"7322869e7b1ef4c409fff4cf51f44b147f73ec16","tarball":"https://registry.npmjs.org/@bioleyl/zargv/-/zargv-0.1.0.tgz","fileCount":13,"integrity":"sha512-zE2IaM2TMdrRVjN6ZkYPkaFipUepIRyxQBKBPoAOp6uQQkq80YeUVmUP7yXSuyKCnoftmkGKCGva+elFBTMbqA==","signatures":[{"sig":"MEUCICn3UJClRMyfVwWtSOJ0QJh6SxJYKVWUS2UlFvuff5Q4AiEAqYw9uxDspVOlAFiKJTxiAMkV9f42+Fd8qTad14zR5nY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":193048},"main":"./dist/cjs/index.cjs","type":"module","types":"./dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/cjs/index.cjs"}}},"gitHead":"931c61ef7f7ebebe9fb9929055e7a5578f2a554d","scripts":{"dev":"rollup -c rollup.config.mjs -w","demo":"tsx examples/demo.ts","test":"vitest run","build":"npm run clean && rollup -c rollup.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationDir dist/types --outDir dist/types","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest","publish:guard":"node -e \"if (process.env.GITHUB_ACTIONS !== 'true') { console.error('Publishing is restricted to the manual GitHub Actions workflow (workflow_dispatch).'); process.exit(1); }\"","release:check":"npm run test && npm run build && npm pack --dry-run","prepublishOnly":"npm run publish:guard && npm run build"},"_npmUser":{"name":"bioleyl","email":"lb@syware.ch"},"repository":{"url":"git+https://github.com/bioleyl/zargv.git","type":"git"},"_npmVersion":"11.6.1","description":"A Zod-first CLI framework where Zod schemas remain the single source of truth.","directories":{},"_nodeVersion":"24.11.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.9","zod":"^3.24.0","rollup":"^4.40.0","vitest":"^3.1.0","@swc/core":"^1.15.47","typescript":"^7.0.2","@types/node":"^22.15.0","@rollup/plugin-swc":"^0.4.1"},"peerDependencies":{"zod":"^3.24.0 || ^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/zargv_0.1.0_1786107612247_0.33789194073754336","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bioleyl/zargv","version":"0.1.1","_id":"@bioleyl/zargv@0.1.1","maintainers":[{"name":"bioleyl","email":"lb@syware.ch"}],"homepage":"https://github.com/bioleyl/zargv#readme","bugs":{"url":"https://github.com/bioleyl/zargv/issues"},"dist":{"shasum":"1d2078530e10fbb0a7360e8d94a0e7b98953c642","tarball":"https://registry.npmjs.org/@bioleyl/zargv/-/zargv-0.1.1.tgz","fileCount":13,"integrity":"sha512-3Hbirt6YpqHpHOzWDKz0wPW5s1NZxMTMuIybsqMYpS4xVmqnoN8oxM6rBaPIB3e+PQpXTB91RxNR1VJk9ahi+w==","signatures":[{"sig":"MEUCICCskwwav+CCLEfraytsavfqBboDEGi7i3GQCXJZTOHvAiEAxvJcAyXZ2/ZGieYXYUPAz0pIe3iis3vtn62xM5e7p7U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bioleyl%2fzargv@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":193208},"main":"./dist/cjs/index.cjs","type":"module","types":"./dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/cjs/index.cjs"}}},"gitHead":"79cca1474a6d5fcf0ba163678ef1893296f5d6d5","scripts":{"dev":"rollup -c rollup.config.mjs -w","demo":"tsx examples/demo.ts","test":"vitest run","build":"npm run clean && rollup -c rollup.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationDir dist/types --outDir dist/types","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest","publish:guard":"node -e \"if (process.env.GITHUB_ACTIONS !== 'true') { console.error('Publishing is restricted to the manual GitHub Actions workflow (workflow_dispatch).'); process.exit(1); }\"","release:check":"npm run test && npm run build && npm pack --dry-run","prepublishOnly":"npm run publish:guard && npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e8e8c6a-58fc-4e8d-9966-b5b4c81d4d70"}},"repository":{"url":"git+https://github.com/bioleyl/zargv.git","type":"git"},"_npmVersion":"11.16.0","description":"A Zod-first CLI framework where Zod schemas remain the single source of truth.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.9","zod":"^3.24.0","rollup":"^4.40.0","vitest":"^3.1.0","@swc/core":"^1.15.47","typescript":"^7.0.2","@types/node":"^22.15.0","@rollup/plugin-swc":"^0.4.1"},"peerDependencies":{"zod":"^3.24.0 || ^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/zargv_0.1.1_1786108319499_0.9923607702903203","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bioleyl/zargv","version":"0.1.2","_id":"@bioleyl/zargv@0.1.2","maintainers":[{"name":"bioleyl","email":"lb@syware.ch"}],"homepage":"https://github.com/bioleyl/zargv#readme","bugs":{"url":"https://github.com/bioleyl/zargv/issues"},"dist":{"shasum":"822d391a520311e861fc5a2ff52ac750cd4e67ca","tarball":"https://registry.npmjs.org/@bioleyl/zargv/-/zargv-0.1.2.tgz","fileCount":13,"integrity":"sha512-8mwTbrO9S0NZB+Ft366oH0HMyXnRwEfuyrmrdE+MdWfdMaDgKkZ4DoaPqEYnu8BhDhHTO01751ovVGN3P1hXYw==","signatures":[{"sig":"MEQCIEoVduAp1QeJqOyfqLwKbagvLP/sImCFzYvB94PDGWEQAiAm7gA+8JhQFsDeZHyQjyb5UXLip8PP1FWXL8zBPA0woA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bioleyl%2fzargv@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":208449},"main":"./dist/cjs/index.cjs","type":"module","types":"./dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/cjs/index.cjs"}}},"gitHead":"7b5a470a3e66f84af7bd5fe2cb73ccbddfeb28e5","scripts":{"dev":"rollup -c rollup.config.mjs -w","demo":"tsx examples/demo.ts","lint":"biome check .","test":"vitest run","build":"npm run clean && rollup -c rollup.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationDir dist/types --outDir dist/types","clean":"rm -rf dist","lint:fix":"biome check . --fix","typecheck":"tsc --noEmit","test:watch":"vitest","publish:guard":"node -e \"if (process.env.GITHUB_ACTIONS !== 'true') { console.error('Publishing is restricted to the manual GitHub Actions workflow (workflow_dispatch).'); process.exit(1); }\"","release:check":"npm run test && npm run build && npm pack --dry-run","prepublishOnly":"npm run publish:guard && npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e8e8c6a-58fc-4e8d-9966-b5b4c81d4d70"}},"repository":{"url":"git+https://github.com/bioleyl/zargv.git","type":"git"},"_npmVersion":"11.16.0","description":"A Zod-first CLI framework where Zod schemas remain the single source of truth.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.9","zod":"^3.24.0","rollup":"^4.40.0","vitest":"^3.1.0","@swc/core":"^1.15.47","typescript":"^7.0.2","@types/node":"^22.15.0","@biomejs/biome":"^2.5.7","@rollup/plugin-swc":"^0.4.1"},"peerDependencies":{"zod":"^3.24.0 || ^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/zargv_0.1.2_1786305899591_0.9220695965247026","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bioleyl/zargv","version":"0.2.0","description":"A Zod-first CLI framework where Zod schemas remain the single source of truth.","type":"module","main":"./dist/cjs/index.cjs","types":"./dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/cjs/index.cjs"}}},"scripts":{"clean":"rm -rf dist","build":"npm run clean && rollup -c rollup.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationDir dist/types --outDir dist/types","dev":"rollup -c rollup.config.mjs -w","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","release:check":"npm run test && npm run build && npm pack --dry-run","publish:guard":"node -e \"if (process.env.GITHUB_ACTIONS !== 'true') { console.error('Publishing is restricted to the manual GitHub Actions workflow (workflow_dispatch).'); process.exit(1); }\"","prepublishOnly":"npm run publish:guard && npm run build","demo":"tsx examples/demo.ts","lint":"biome check .","lint:fix":"biome check . --fix"},"publishConfig":{"access":"public","provenance":true},"repository":{"type":"git","url":"git+https://github.com/bioleyl/zargv.git"},"peerDependencies":{"zod":"^4.0.0"},"devDependencies":{"@biomejs/biome":"^2.5.7","@rollup/plugin-swc":"^0.4.1","@swc/core":"^1.15.47","@types/node":"^22.15.0","rollup":"^4.40.0","tsx":"^4.23.9","typescript":"^7.0.2","vitest":"^3.1.0","zod":"^4.0.0"},"gitHead":"484fc61bfad84c844a28c4871822e5c7b4754578","_id":"@bioleyl/zargv@0.2.0","bugs":{"url":"https://github.com/bioleyl/zargv/issues"},"homepage":"https://github.com/bioleyl/zargv#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-Ta1K8nNT5YA7UxsMGigWNf/0AQYjOIUd4DFCxzSBrQRE2F8+cmkhjvCtl4ozrlBWNTadiRdqCx6elR+mI8X5kg==","shasum":"0b85b17dec5750348ffed9cb34bb3c824485bc39","tarball":"https://registry.npmjs.org/@bioleyl/zargv/-/zargv-0.2.0.tgz","fileCount":13,"unpackedSize":196636,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bioleyl%2fzargv@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDSWqaVILddMMVBVXz7iHlQDmfF+2wUqQm4mMq0qQgZhQIgRs1cODsmnMHw2KE4zmS0NH1Zbrrpq8ePnBiiLPnfLMY="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e8e8c6a-58fc-4e8d-9966-b5b4c81d4d70"}},"directories":{},"maintainers":[{"name":"bioleyl","email":"lb@syware.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zargv_0.2.0_1786606254136_0.9787614443856483"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T13:00:12.128Z","modified":"2026-08-13T07:30:54.748Z","0.1.0":"2026-08-07T13:00:12.397Z","0.1.1":"2026-08-07T13:11:59.672Z","0.1.2":"2026-08-09T20:04:59.732Z","0.2.0":"2026-08-13T07:30:54.288Z"},"bugs":{"url":"https://github.com/bioleyl/zargv/issues"},"homepage":"https://github.com/bioleyl/zargv#readme","repository":{"type":"git","url":"git+https://github.com/bioleyl/zargv.git"},"description":"A Zod-first CLI framework where Zod schemas remain the single source of truth.","maintainers":[{"name":"bioleyl","email":"lb@syware.ch"}],"readme":"# zargv\n\nA **type-safe CLI framework** powered by [Zod](https://zod.dev). Define your command tree once, validate everything through schemas you already trust, and keep handler types inferred end-to-end.\n\n## Table of Contents\n\n1. [Installation](#installation)\n2. [First Example: A Command Without Arguments](#first-example-a-command-without-arguments)\n3. [Adding Options with `--flag <value>`](#adding-options-with---flag-value)\n4. [Boolean Flags (`--verbose`)](#boolean-flags----verbose)\n5. [Default Values](#default-values)\n6. [Positional Arguments: A Single Operand](#positional-arguments-a-single-operand)\n7. [Positional Arguments: Multiple Operands](#positional-arguments-multiple-operands)\n8. [Composing a Command Tree](#composing-a-command-tree)\n9. [External Handlers with `HandlerCtx`](#external-handlers-with-handlerctx)\n10. [API Reference](#api-reference)\n\n---\n\n## Installation\n\n```bash\nnpm install @bioleyl/zargv zod@^4\n```\n\n---\n\n## First Example: A Command Without Arguments\n\nThe simplest form — a command that does something, without any arguments:\n\n```ts\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Print a greeting\",\n\n  async handler() {\n    console.log(\"Hello!\");\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli greet\nHello!\n```\n\n---\n\n## Adding Options with `--flag <value>`\n\nTo accept named arguments, use `zargv.from()` which converts a Zod schema into an options definition:\n\n```ts\nimport { z } from \"zod\";\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Greet a user by name\",\n\n  args: zargv.from(\n    z.object({\n      name: z.string().describe(\"User to greet\"),\n    }),\n  ),\n\n  async handler({ args }) {\n    // TypeScript knows: args.name is string\n    console.log(`Hello, ${args.name}!`);\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli greet --name Alice\nHello, Alice!\n```\n\nShort aliases are optional:\n\n```ts\nzargv.from(\n  z.object({ name: z.string() }),\n  { aliases: { name: \"n\" } }, // now both -n and --name work\n);\n```\n\n---\n\n## Boolean Flags (`--verbose`)\n\nBooleans act as flags: the presence of the flag activates the value, its absence deactivates it.\n\n```ts\nimport { z } from \"zod\";\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Run a build\",\n\n  args: zargv.from(\n    z.object({\n      verbose: z.boolean().describe(\"Enable verbose output\"),\n    }),\n  ),\n\n  async handler({ args }) {\n    if (args.verbose) {\n      console.log(\"[verbose] Starting build...\");\n    } else {\n      console.log(\"Building...\");\n    }\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli build          # → Building...\n$ mycli build --verbose # → [verbose] Starting build...\n```\n\n---\n\n## Default Values\n\nWhen an option has a default value, it becomes optional — the flag does not appear in the usage signature.\n\n```ts\nimport { z } from \"zod\";\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Create a user\",\n\n  args: zargv.from(\n    z.object({\n      name:   z.string().describe(\"User display name\"),\n      admin:  z.boolean().default(false).describe(\"Grant administrator privileges\"),\n    }),\n  ),\n\n  async handler({ args }) {\n    console.log(`Creating user ${args.name} (admin=${args.admin})`);\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli users create --name Bob          # → Creating user Bob (admin=false)\n$ mycli users create -n Alice --admin    # → Creating user Alice (admin=true)\n```\n\n---\n\n## Positional Arguments: A Single Operand\n\nFor commands that accept exactly **one** positional argument, use `zargv.positionals.single()`:\n\n```ts\nimport { z } from \"zod\";\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Stage a destination\",\n\n  positionals: zargv.positionals.single([\n    \"destination\",\n    z.string(),\n  ]),\n\n  async handler({ positionals }) {\n    // TypeScript knows: positionals.destination is string\n    console.log(`Staging to ${positionals.destination}`);\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli stage dist/       # → Staging to dist/\n$ mycli stage             # → Error: exactly one operand required\n$ mycli stage a b         # → Error: too many operands\n```\n\n---\n\n## Positional Arguments: Multiple Operands\n\nFor commands with **multiple** positional arguments, use `zargv.positionals.splitLast()` — it splits all operands except the last into a group, and keeps the last one separate. This is the classic pattern of `cp SOURCE... DEST` or `mv SOURCE... DIR`:\n\n```ts\nimport { z } from \"zod\";\nimport { zargv } from \"zargv\";\n\nexport default zargv.command({\n  description: \"Move files\",\n\n  args: zargv.from(\n    z.object({ force: z.boolean().default(false) }),\n    { aliases: { force: \"f\" } },\n  ),\n\n  positionals: zargv.positionals.splitLast([\n    [\"sources\",   z.array(z.string()).min(1)],\n    [\"directory\", z.string()],\n  ]),\n\n  async handler({ args, positionals }) {\n    // args.force: boolean\n    // positionals.sources: string[]\n    // positionals.directory: string\n    console.log(args.force, positionals.sources, positionals.directory);\n  },\n});\n```\n\nUsage :\n\n```bash\n$ mycli mv file1.txt dir/\n$ mycli mv -f a.txt b.txt c.txt output/\n```\n\n---\n\n## Composing a Command Tree\n\nCommands compose into trees. A parent command has no handler — it contains sub-commands:\n\n```ts\n// src/commands/users/create.ts\nimport create from \"./create\";\nimport remove from \"./remove\";\n\nexport default zargv.command({\n  description: \"Manage users\",\n  commands: { create, remove }, // ← sub-commands\n});\n\n// src/cli.ts — entry point\nimport users from \"./commands/users\";\n\nzargv({\n  name: \"mycli\",\n  description: \"My application CLI\",\n  commands: { users },\n}).run(process.argv);\n```\n\nResult :\n\n```bash\n$ mycli --help\nMy application CLI\n\nCommands:\n  users   Manage users [command]\n\n$ mycli users create --name Bob\nCreating user Bob (admin=false)\n```\n\n---\n\n## External Handlers with `HandlerCtx`\n\nTo separate command definitions from their logic, use the helper type `HandlerCtx`:\n\n```ts\nimport { z } from \"zod\";\nimport { zargv, HandlerCtx } from \"zargv\";\n\n// 1. Define args and positionals separately\nconst mvArgs = zargv.from(\n  z.object({ force: z.boolean().default(false) }),\n  { aliases: { force: \"f\" } },\n);\n\nconst mvPositionals = zargv.positionals.splitLast([\n  [\"sources\",   z.array(z.string()).min(1)],\n  [\"directory\", z.string()],\n]);\n\n// 2. Build the command with an inline handler that delegates\nexport default zargv.command({\n  description: \"Move files\",\n  args: mvArgs,\n  positionals: mvPositionals,\n  async handler(ctx) { await handleMove(ctx); },\n});\n\n// 3. Infer the full context type\ntype MvCtx = HandlerCtx<typeof import(\"./mv\").default>;\n\n// 4. Write logic separately — automatically typed\nasync function handleMove({ args, positionals }: MvCtx) {\n  console.log(args.force, positionals.sources, positionals.directory);\n}\n```\n\n---\n\n## API Reference\n\n### `zargv.from(schema, options?)`\n\nConverts a Zod schema into an options definition for `zargv.command()`.\n\n| Parameter | Description |\n|-----------|-------------|\n| `schema` | A `ZodObject`, e.g. `z.object({ name: z.string() })` |\n| `options.aliases` | Optional map: canonical key → short flag character |\n\n### `zargv.command(options)`\n\nBuilds a command node (leaf or parent).\n\n| Parameter | Description |\n|-----------|-------------|\n| `description` | Short description, displayed in help |\n| `args` | Options definition from `zargv.from()` (optional) |\n| `positionals` | Positional arguments definition (optional) |\n| `commands` | Nested sub-commands (optional) |\n| `handler(ctx)` | Function receiving `{ args, positionals }` |\n\n### `zargv.positionals.single(tuple)`\n\nCommand with exactly **one** operand.\n\n```ts\nzargv.positionals.single([\"destination\", z.string()]);\n```\n\n### `zargv.positionals.splitLast(tuple)`\n\n`SOURCE... DEST` pattern — all operands except the last form a group, the last one is separate.\n\n```ts\nzargv.positionals.splitLast([\n  [\"sources\",   z.array(z.string()).min(1)],\n  [\"directory\", z.string()],\n]);\n```\n\n### `zargv(options).run(argv)`\n\nCreates and runs a CLI application.\n\n| Parameter | Description |\n|-----------|-------------|\n| `name` | Binary name (displayed in help) |\n| `description` | Root-level description |\n| `commands` | Command tree |\n","readmeFilename":"README.md"}