CLI binary

Updated Jun 28, 2026

The spycatcher-harness binary now supports three subcommands:

  • record
  • replay
  • verify

Each subcommand loads configuration using layered precedence:

CLI > env > config files > defaults

Per-subcommand defaults are loaded from the cmds namespace in config files:

  • cmds.record
  • cmds.replay
  • cmds.verify

CLI help documents this merged shape:

cargo run --bin spycatcher-harness -- --help

Common CLI flags

The current subcommands support the same top-level override flags:

  • --listen <SOCKET_ADDR>
  • --cassette-dir <PATH>
  • --cassette-name <NAME>
  • --locale <LANGID>
  • --fallback-locale <LANGID>

record additionally supports nested upstream config through file and env layering under cmds.record.upstream.

--locale selects the preferred BCP 47 language identifier for localized application messages. --fallback-locale selects the deterministic fallback locale and defaults to en-US. Invalid language identifiers fail startup before the harness begins serving.

Localized CLI help, version, and parse errors

The binary renders clap help, version, and parse-error text through OrthoConfig's Localizer abstraction. The bundled en-US Fluent catalogue in i18n/en-US/spycatcher-harness.ftl contains the cli-* help strings, cli-version, and the clap-error-* parse-error strings used by the command-line interface.

CLI parsing happens before subcommand configuration has been fully merged, so help, version, and parse errors use a best-effort early locale. The binary checks SPYCATCHER_HARNESS_LOCALE, then SPYCATCHER_HARNESS_FALLBACK_LOCALE, then falls back to en-US. After parsing, harness library errors still use the authoritative --locale and --fallback-locale values from the merged configuration.

Set SPYCATCHER_HARNESS_DISABLE_LOCALIZATION to a truthy value (1, true, yes, or on) to force stock clap help, version, and parse-error output. This is intended as a diagnostic escape hatch if localized CLI assets need to be ruled out while investigating startup behaviour. The binary uses the same NoOpLocalizer fallback automatically when localized CLI resources cannot be loaded.

Configuration file shape

Create .spycatcher_harness.toml in the working directory:

[cmds.record]
cassette_name = "record_smoke"

[cmds.record.upstream]
kind = "openrouter"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"

[cmds.replay]
cassette_name = "replay_smoke"

[cmds.replay.localization]
locale = "en-GB"
fallback_locale = "en-US"

[cmds.verify]
cassette_name = "verify_smoke"

Environment variable shape

Environment variables use the prefix SPYCATCHER_HARNESS_CMDS_<SUBCOMMAND>_....

Examples:

SPYCATCHER_HARNESS_CMDS_REPLAY_CASSETTE_NAME=env_replay
SPYCATCHER_HARNESS_CMDS_RECORD_UPSTREAM__BASE_URL=https://example.invalid/api
SPYCATCHER_HARNESS_CMDS_REPLAY_LOCALIZATION__LOCALE=en-GB
SPYCATCHER_HARNESS_CMDS_REPLAY_LOCALIZATION__FALLBACK_LOCALE=en-US

Nested environment keys use a double underscore between path segments. For example, LOCALIZATION__LOCALE maps to cmds.<subcommand>.localization.locale.

CLI usage examples

# Record using layered defaults and an explicit cassette name override.
cargo run --bin spycatcher-harness -- record --cassette-name cli_record

# Replay with layered configuration.
cargo run --bin spycatcher-harness -- replay

# Verify with layered configuration.
cargo run --bin spycatcher-harness -- verify

For replay and verify mode, ensure the cassette file already exists at the configured cassette_dir/cassette_name path and was created by a compatible format_version.