---
type: ultraresearch-brief
research_version: 1.0
question: How does small-auth currently parse arguments and where should --verbose hook in?
confidence: 0.85
dimensions: 4
created: 2026-05-01
---

# CLI parser conventions in small-auth

## Executive Summary

`small-auth` uses a hand-rolled argv parser at `src/cli.mjs:12-58` with a
two-pass approach: first pass extracts global flags (currently
`--help`, `--version`), second pass dispatches to command handlers in
`src/commands/*.mjs`. Adding `--verbose` requires touching only the
first-pass extractor and a new `verbose` parameter in the handler
contract — six command handlers each get a one-line update.

The parser does **not** use `commander`, `yargs`, or any external
library — this is intentional (zero deps) and consistent with the
plugin marketplace's broader convention. We keep that.

`stderr` is currently unused except for fatal errors. Adding verbose
output to stderr does not collide with anything.

Confidence: 0.85. The 0.15 uncertainty is around whether
`--verbose` should propagate into nested helper modules
(`src/lib/auth-token.mjs` calls `src/lib/db.mjs`); the plan should
either pass `verbose` via a context object or use a module-scoped
log function. Both work; the brief doesn't specify, so the planner
will choose.

## Dimensions

### 1. Argument-parsing layer

The parser at `src/cli.mjs:12-58` returns
`{globalFlags: {help, version}, command, positional, commandFlags}`.
We add `verbose: boolean` to `globalFlags`. The two-pass design means
`--verbose` works in any position automatically — no extra effort.

`-v` short form maps to `--verbose` via the existing alias table at
`src/cli.mjs:34`.

### 2. Command-handler contract

Each handler in `src/commands/*.mjs` exports
`async function run(positional, flags, ctx)`. Today `ctx` is
`{stdout, stderr, env}`. We extend `ctx` with `verbose: boolean` so
handlers can branch on it without re-reading globalFlags.

### 3. Internal log emission pattern

Existing fatal errors call `ctx.stderr.write(\`[error] ...\\n\`)`. The
verbose pattern matches: `if (ctx.verbose) ctx.stderr.write(\`[verbose] ...\\n\`)`.
No log helper needed for this iteration — six call sites total. Refactoring
into a `verbose()` helper is reasonable but not required for the goal.

### 4. Test infrastructure

Tests live in `tests/*.test.mjs` using `node:test`. Existing tests run
the CLI as a subprocess via `child_process.execFile` and assert on
exit code + stdout. Two new tests are needed:

- `tests/cli-verbose-flag.test.mjs` — assert `login --verbose alice`
  exits 0, stderr contains "[verbose]", stdout matches golden file.
- `tests/cli-no-verbose-stability.test.mjs` — assert
  `login alice` stdout is byte-identical to `tests/golden/login.stdout`.

## Citations

- `src/cli.mjs:12-58` — parser implementation
- `src/commands/login.mjs:8-42` — typical handler shape
- `tests/cli-help.test.mjs:14` — subprocess testing pattern
- `package.json:scripts.test` — `node --test tests/*.test.mjs`

## Brief anchoring

Brief task: "Add a --verbose flag to the small-auth CLI parser".
This research answers the planner's first question: where to hook
into. The parser is small and centralized, so the change is
minimal-scope.

The brief's success criteria around byte-identical default stdout
maps directly to the stability test in dimension 4.
