# @hulla/args reference

> Look up argument constructors, parsed result fields, parser settings, and error metadata.

Find argument constructors, parsed result fields, and parser defaults below. For a working command before the details, follow [Build a greeting command](https://hulla.dev/guides/args/quick-start.md).

## Choose an input constructor

| Constructor                | Config fields                                                                                                                    | Default and result                                                                                                                                                            |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `flag(config)`             | `name: string`, optional `description: string`, `schema?: ZodTypeAny`, `long?: string \| string[]`, `short?: string \| string[]` | Defaults to `z.boolean()` and derives long/short forms from `name`. Absent: `value: false`, `detected: false`.                                                                |
| `option(config)`           | Same named fields as `flag`                                                                                                      | Defaults to `z.string()`. Absent: `value: undefined`, `detected: false`.                                                                                                      |
| `positional(config)`       | `name: string`, optional `description: string`, `schema?: ZodTypeAny`                                                            | Defaults to `z.string()`; consumes one unclaimed token not beginning with `-`.                                                                                                |
| `sequence(config)`         | `name: string`, optional `description: string`, required `arguments: Positional[]`                                               | No caller schema; `.value` maps member names to their result records. The sequence is detected only when every member matches.                                                |
| `infiniteSequence(config)` | `name: string`, optional `description: string`, optional `schema: ZodArray<ZodString>`                                           | Defaults to `z.array(z.string())`; collects remaining unclaimed non-option tokens. With none, `.value` is `[]` and `detected` is false.                                       |
| `command(config)`          | `name: string`, optional `description: string`, `alias?: string \| string[]`, `arguments?: Argument[]`, `commands?: Command[]`   | Declares a branch under `result.commands[name]`. The typed result has `detected`, `arguments`, and nested `commands`; aliases still use the canonical name as the result key. |

All argument constructors accept a Zod `schema` except `sequence`, which uses its members' schemas. `infiniteSequence` accepts an array-of-strings schema. See [Validation](https://hulla.dev/docs/args/validation.md) for missing-input behavior.

The package also exports these types:

```ts
import type {
  ArgType,
  PossibleArguments,
  ArgumentConfig,
  CommandConfig,
  Flag,
  Option,
  Positional,
  Sequence,
  InfiniteSequence,
  Command,
  Parser,
  ArgOutput,
  ParserResult,
  ParserSettingsInit,
  ParserSettings,
  Code,
  ParserErrorConstructor,
} from '@hulla/args'
```

`ParserResult` contains `argv`, `arguments`, and `commands`. A nested command result contains `detected`, `arguments`, and its own `commands`.

### Named forms and matching

For flags and options, `name: 'output'` accepts `--output` and `-o`. Customize the spellings with:

| Config                  | Accepted names                      |
| ----------------------- | ----------------------------------- |
| `short: 'f'`            | `--output`, `-f`                    |
| `long: ['out', 'dest']` | `--output`, `--out`, `--dest`, `-o` |

Dashes are optional in these declarations. Duplicate names or aliases fail when you create the parser.

`mode: 'both'` accepts long and short spellings; `'long'` and `'short'` limit them. `sharedDash: true` permits flag groups such as `-qv`; every configured short name must then be one character. For options, a grouped option consumes a following value, for example `-vo file` when `v` is a flag and `o` an option.

## Read a parsed argument record

Each ordinary argument result has this shape:

```ts
{
  value: unknown,       // TypeScript infers the Zod output type
  raw: string | undefined,
  index: number,        // index in the read slice (plus nested offset); -1 when absent
  detected: boolean,
  parser: string        // parser path, e.g. "notes.add"
}
```

`raw` keeps exactly what was matched. For `--output report.txt`, it is `'--output report.txt'`; for `--output=report.txt`, it is `'--output=report.txt'`.

`index` points to the first matched token in the slice the parser reads. If you skip two entries with `startIndex: 2`, index `0` refers to the third entry of the original array. Nested commands add their offset within the same slice.

The top-level `argv` contains that parsed slice. It is lowercased when `caseSensitive` is `false`; use `raw` when you need the original text.

Omitted options and positionals have `value: undefined`, `raw: undefined`, `index: -1`, and `detected: false`. Their schemas don't run, so a Zod `.default()` won't supply a fallback.

A present option without a following value is different: it remains detected and can use the option token itself as its candidate value. Empty equals-form values skip schema validation. Use `requireEquals` to reject a present option without `=`, and check both `detected` and `value` when input is required.

Other constructors have their own empty-input behavior:

- Flags validate `false` when absent and `true` when present.
- `infiniteSequence` validates an empty array when no tokens were collected.
- `sequence` returns a record per member, plus its combined `raw`, first `index`, and `detected` fields.

## Configure argv reading and parsing

`parser({ name, arguments?, commands?, settings? })` returns the parser's `name`, normalized `settings`, and two methods: `read(argv)` and `parse(argv)`.

`read()` selects the input from `startIndex` (inclusive) to `stopIndex` (exclusive). The defaults read the whole array. Either pass `process.argv.slice(2)` with those defaults, or pass the full `process.argv` with `startIndex: 2`.

| Setting            | Default  | Effect                                                                                                                                                                                                       |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `caseSensitive`    | `false`  | Match command and argument names without case sensitivity. Equals-form values are taken from the normalized token, so they are lowercased too; space-separated and positional values retain original casing. |
| `mode`             | `'both'` | Accept long and short option/flag forms; can be `'long'` or `'short'`.                                                                                                                                       |
| `requireEquals`    | `false`  | Require an option value in `--name=value` form.                                                                                                                                                              |
| `keepOnlyDetected` | `false`  | Remove undetected entries from the returned results; parsing and validation rules stay the same.                                                                                                             |
| `mergeArgs`        | `false`  | Let root and selected command parsers inspect shared arguments across the command boundary. Without it, each parser sees its own command slice.                                                              |
| `sharedDash`       | `false`  | Expand grouped single-character short forms.                                                                                                                                                                 |
| `startIndex`       | `0`      | First argv entry to read.                                                                                                                                                                                    |
| `stopIndex`        | `null`   | Exclusive end of the argv slice.                                                                                                                                                                             |

See [Parser options](https://hulla.dev/docs/args/options.md) for argv ownership and examples; see [Commands](https://hulla.dev/docs/args/commands.md) for scope and merging.

## Handle parser errors

`ParserError` extends `Error` and exposes `message`, `parser`, `from`, `code`, `argvIndex`, `argumentName`, and `path`.

| Source (`from`) | Diagnostic behavior                                          |
| --------------- | ------------------------------------------------------------ |
| `zod`           | First issue, `argvIndex: -1`, empty `argumentName`.          |
| `parser`        | Can identify an argv token; declaration errors can use `-1`. |
| `runtime`       | Runtime failure details.                                     |

Treat `path` as diagnostic metadata. It isn't a guaranteed argument-name lookup, and every error doesn't have a user-supplied token index.

Parser construction can throw for duplicate/ambiguous declarations (including invalid `sharedDash` short-name lengths); parsing can throw on invalid schema input or unmatched/unhandled tokens. Required input is an application decision: check `detected` and report your own missing-value message. `@hulla/args` does not render help or set process exit codes. See [Validation](https://hulla.dev/docs/args/validation.md) for a CLI-boundary catch example.
