Skip to content

Require whirl run and unify CLI option resolution - #62

Merged
brynary merged 8 commits into
recover/05-language-and-grammarfrom
recover/06-cli-settings
Oct 5, 2026
Merged

brynary merged 8 commits into
recover/05-language-and-grammarfrom
recover/06-cli-settings

Conversation

@brynary

@brynary brynary commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Add explicit whirl run, -O overrides, renamed output/state flags, block-hosts, and effective settings in reports. Preserve the accepted recording settings and bundle contract without adding unimplemented recording commands.

Recovers the intended changes from #47, which were merged into the old development stack but did not reach main. Preserves the newer lithos-llm pin from #54.

Stage 6 of 10. Based on #61. Full recovery inventory and merge order: #57.

Merge the recovery PRs in order with merge commits. Once the preceding PR lands, retarget this PR to main.

Validation: CARGO_NET_OFFLINE=true mise run check passed on this branch. This runs formatting, Clippy, local Rust/browser tests, shim checks, eval tooling, and workflow checks. Paid model evals, the external BrowserSim round trip, and live Kernel checks were not rerun.

brynary and others added 8 commits September 30, 2026 06:47
Files now run only through `whirl run`. `whirl checkout.whirl` and
`whirl --headed checkout.whirl` fail with a hint to use `whirl run`, and
`whirl` alone prints help.

`--out DIR` names the output directory, with the same default
`whirl-artifacts/`. `--artifacts` stays as a deprecated alias that warns
and cannot be combined with `--out`. `--load-state` and `--save-state`
replace `--storage` and `--save-storage`, which are now usage errors that
name their replacements. The state file keeps its format.

`--storage` silently replaced a file's `storage` option. `--load-state`
is a command control instead, so it cannot be combined with a file's
`storage` or `setup` option.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`whirl run` and `whirl check` take repeatable `-O key=value` arguments
that set an `[Options]` key for every file, setup flows included.
Settings resolve from the built-in default, then the file, then the
command line. A value has the syntax of the file's `key: value` line, so
locators and quoted values keep their meaning, and an unknown key or
invalid value is a usage error before any browser starts.

For a scalar key the last value wins. For `allow-hosts` and
`snapshot-mask`, the values form a list that replaces the file's list,
and an empty value clears it. `-O setup=` is rejected, because setup
flows get the same options.

`--base`, `--browser`, `--step-timeout`, `--entry-timeout`, and
`--user-agent` now go through the same resolver, with their value taken
literally. Supplying one of them and `-O` for the same key is an error.

One module, lang::cli_options, owns this, so later commands can reuse
it. It puts the command line's lines in place of the file's, marked with
their source, so lint, the run, and reports read one list. `whirl check`
therefore lints with the overrides in place, and a lint about a `-O`
value has no line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`[Options] block-hosts` blocks the hosts its globs match, with the glob
rules of `allow-hosts`. A block wins over an allowance, including the
implicit allowance of the base host. The shim checks one host policy for
page requests, redirect hops, WebSockets, and `HTTP` entries, and it
routes requests when either list is set. `-O block-hosts=` forms and
clears a list like `allow-hosts`.

Each blocked host now carries the rule that blocked it: the matching
`block-hosts` glob, or `allow-hosts` when no allowed glob matched. The
console, JUnit, and HTML reports show it, and the JSON report adds
`blockedHostRules` beside the unchanged `blockedHosts`. This changes the
`endFlow` result, so the shim moves to protocol 9.

`browsersim-origin: build | recorded` is the first BrowserSim setting.
Ordinary runs validate it and do not apply it, and list it as inactive
when a file or `-O` sets it. Other `browsersim-` keys stay unknown.

Every file whose options resolve lists its settings in the JSON and HTML
reports: the value it ran with, masked like other output, where the value
came from, and whether this engine applies it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Later BrowserSim work will consume the settings rules of `whirl run`. This
draft ADR fixes what that work must follow: `whirl record` is the only
recording command, `--engine` and `--browser` stay separate, a
`*.sim.json` recording stores every effective setting and replay uses
only those, and each written flow records to a sibling bundle named after
its stem, with collisions and output-over-input paths rejected.

It is a draft: it becomes binding when it is accepted. Its two open
decisions, the privacy and matching option syntax and what happens when a
bundle exists, do not block the CLI work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A `-O` value is now literal text, as if quoted, the way the option flags
already took theirs: `-O 'user-agent=Whirl/1 (test)'` works without inner
quotes, and `#` and `{{` are part of the value. For a list option, each
`-O` gives one item, so a host list written as in a file is a usage error
that says to give each host its own `-O`. A `snapshot-mask` value stays a
locator written as in a file. An empty value for a single-value option is
a usage error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`-O` now sets every option, so these four flags were an arbitrary subset
of the 17 keys. Each is now a usage error that names its `-O` form, such
as `-O base=URL`. `--browser` stays: the accepted recording ADR keeps it
beside `--engine`, and `whirl doctor --browser` names browsers the same
way.

Tests, the example script, and the docs use `-O` instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e41e403)
@brynary
brynary added this pull request to stack #67 October 5, 2026 18:18
@brynary
brynary merged commit 4b1e20a into main Oct 5, 2026
3 checks passed
@brynary
brynary deleted the recover/06-cli-settings branch October 5, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant