README.md

README.md is a file in Argv Contract. 92 lines of code and 0 definitions.

<!-- Auto-generated 2026-09-29T00:22Z v5 -->

# @govlab/argv

<!-- concern:overview -->

## Purpose

A dependency-free leaf that turns a script's command line into a contract. A script declares its command, its flags (name, whether a value follows, whether it may repeat) and its positionals. `resolveArgv` answers `--help` with that contract and exits before the script has any effect. It refuses an undeclared flag, a missing flag value, a repeated non-repeatable flag or a positional the contract does not declare, and only then hands the script a parsed view. It closes one failure: a script that filters unknown words out of `process.argv` and runs anyway, so that `--help` on a tree-rewriting script launches the rewrite.
<!-- /concern:overview -->

<!-- concern:use -->

## When to use

- Any script invoked from the shell or an npm script that reads `process.argv`, such as an entrypoint, a gate, a probe or a pipeline runner.
- A script that writes a tree, where an ignored word means a full run the developer did not ask for.

## When NOT to use

- Library code with no command line. Nothing here applies to a function taking arguments.
- A script needing subcommand grammars with their own flag sets. Declare one contract per entrypoint and dispatch on a positional instead.

<!-- /concern:use -->

<!-- concern:charts -->

## Architecture charts

The structure, logical-flow and dependency diagrams derived from the source AST live in [_code.info.generated/mermaid-charts.generated.md](./_code.info.generated/mermaid-charts.generated.md).
<!-- /concern:charts -->

<!-- concern:install -->

## Install

Nothing to install beyond the workspace root's single `npm install`. A consuming member declares `"@govlab/argv": "*"` as a sibling dependency.

## Quick start

```js EXAMPLE: Declare a contract and read the parsed flags
import { flagValue, hasFlag, resolveArgv } from "@govlab/argv";

const argv = resolveArgv({
    command: "npm run snapshot --",
    flags: [
        { describe: "the page to open", name: "--url", takesValue: true },
        { describe: "render on the gpu instead of in software", name: "--gpu", takesValue: false },
    ],
    summary: "Open a page in a headless browser and capture it.",
});
const url = flagValue(argv, "--url");
const gpu = hasFlag(argv, "--gpu");
```

<!-- /concern:install -->

<!-- concern:api -->

## API

- `function argvOf(spec: ArgvSpec, words: readonly string[]): ParsedArgv`
- `enum ArgvOutcome`
- `class ArgvRefusedError`
- `interface ArgvSpec`
- `interface FlagSpec`
- `function flagValue(argv: ParsedArgv, name: string): string | undefined` — the first value of a value-taking flag, or undefined when absent.
- `function flagValues(argv: ParsedArgv, name: string): readonly string[]` — every value of a repeatable flag, in order given.
- `function hasFlag(argv: ParsedArgv, name: string): boolean` — whether a flag was given at all.
- `function isMainModule(moduleUrl: string): boolean`
- `function numberFlag(argv: ParsedArgv, name: string, fallback: number): number` — a flag's value parsed as a base-ten integer, or the fallback when absent or not a number.
- `function parseArgv(spec: ArgvSpec, argv: readonly string[]): ArgvOutcome` — pure, and maps the contract plus a word list to a tagged `help`, `refused` or `parsed` outcome.
- `interface ParsedArgv`
- `interface PositionalSpec`
- `function resolveArgv(spec: ArgvSpec, argv?: readonly string[]): ParsedArgv` — the impure front: prints usage and exits clean on help, prints the reason and usage and exits non-zero on refusal, returns the parsed view otherwise.
- `function usageOf(spec: ArgvSpec): string` — renders the contract as the usage text `--help` prints.

<!-- /concern:api -->

<!-- concern:config -->

## Configuration

No configuration. The contract is the spec object the script passes. `resolveArgv` reads `process.argv` past the runtime and script path unless an explicit array is given, which is how a test drives it.
<!-- /concern:config -->

<!-- concern:deps -->

## Dependencies

The package is a leaf with no runtime dependencies.
<!-- /concern:deps -->

<!-- concern:ai-context -->

## AI context

- `parseArgv` is pure and returns a tagged outcome (`help`, `refused`, `parsed`). `resolveArgv` is the one impure surface, and it exits the process on `help` and `refused`, so a script never runs past a contract it did not satisfy.
- `--help` and `-h` are answered before any other word is read, so they win even beside a refused flag.
- A flag value is any following word that does not start with a dash. A flag given twice is refused unless declared repeatable, and a repeatable flag's values are read with `flagValues`.
- Positionals are counted against the contract: more than declared, or fewer than the required ones, is a refusal.
- A pure leaf: zero `@govlab/*` sibling dependencies.

<!-- /concern:ai-context -->

<!-- concern:domains -->

## Domains

This package serves these software domains, which `_manifest.json` declares in `domains` from the two-tier software-domain vocabulary (`meta → sub`):

- **developer-tooling** — build-tooling

<!-- /concern:domains -->

<!-- concern:quality-governance -->

## Quality governance

The canonical quality catalog resolves the quality concepts that govern this package. `_manifest.json` declares them in `governedBy`, and a lint package derives them from the concepts its own rules enforce. Each maps to the custom lint rules that enforce it:

- **immutability** — _best-practice_
- **separation-of-concerns** — _complexity_
- **type-safety** — _correctness_

<!-- /concern:quality-governance -->

<!-- concern:disposal -->

## Disposal

- Remove `govlab.root/govlab.utils/argv/`.
- Drop `"@govlab/argv": "*"` from every consuming package manifest.
- Every script that imported it goes back to reading `process.argv` directly.

<!-- /concern:disposal -->

<!-- concern:metrics -->

---

stable · 15 exports · 0 deps · 0 principles · 3 concepts
<!-- /concern:metrics -->