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 -->