Skip to content

Add --headed, --no-solve-captchas and --no-file-storage - #61

Merged
giordano-lucas merged 2 commits into
mainfrom
feat/positive-opt-out-flags
Aug 6, 2026
Merged

Add --headed, --no-solve-captchas and --no-file-storage#61
giordano-lucas merged 2 commits into
mainfrom
feat/positive-opt-out-flags

Conversation

@giordano-lucas

Copy link
Copy Markdown
Member

Follow-up to #60. That PR made the true defaults visible; this makes them actionable.

Three session-start options default to true server-side, which left their flags shaped as opt-ins for something already on. Passing --headless or --solve-captchas changed nothing, and turning either off meant a double negative.

notte sessions start --headed              # was --headless=false
notte sessions start --no-solve-captchas   # was --solve-captchas=false
notte sessions start --no-file-storage     # was --use-file-storage=false

Naming

One rule: use the word the ecosystem already has, otherwise prefix with --no-.

--headed is Playwright's (playwright test --headed), and Notte's users mostly arrive from Playwright or Puppeteer, so it's the one they'll guess. The other two have no comparable term.

--no- rather than --disable- for a reason specific to this command: Chromium's own flags are --disable-*, and sessions start forwards them verbatim through --chrome-args. Distinct prefixes keep the layers legible —

notte sessions start --no-file-storage --chrome-args="--disable-gpu"

— one Notte flag, one browser flag, no ambiguity about which is which. --no- is also what git, docker, npm and curl use.

The originals are deliberately not deprecated

Pinning a value explicitly is legitimate defensive scripting. A caller who needs a headless session shouldn't have to trust that the server default stays true — that's precisely the failure mode #58 and #60 dealt with. Deprecating would also print a warning on the single most common invocation in our own docs (sessions start --headless appears eight times across the skills).

Passing both spellings at once is an error rather than letting precedence quietly pick a winner:

$ notte sessions start --headed --headless
Error: --headed and --headless set the same option; pass only one

Omitting them still sends nothing

The most important property, and the one with a dedicated test: when the new flags are absent, nothing is written to the request body, so the server default applies. Sending an explicit value would re-freeze today's default into the client — the bug #58 fixed.

Verification

Against the live API:

Command Result
--headed headless: false
--no-file-storage use_file_storage: false
--no-solve-captchas solve_captchas: false
(no flags) all three true — unchanged
--headed --headless rejected
  • New sessionstart_optout_test.go: absent flags leave the body untouched, each flag inverts its counterpart (including --headed=falseheadless=true), conflicting pairs are rejected, and the originals stay registered, visible and undeprecated
  • go build, go vet, gofmt -l clean; go test ./internal/... — all 10 packages pass
  • New flags live in sessionstart_optout.go, not the generated file, so make generate won't clobber them

Follow-up

notte-skills documents --headless=false and claims it's "not available on remote/CI environments" — but a cloud session accepts it and reports headless: false, so that claim looks wrong. I'll update the skills to use --headed and fix that claim once this lands.

🤖 Generated with Claude Code

Three session-start options default to true server-side, which left their flags
shaped as opt-ins for something already on. Passing --headless or
--solve-captchas changed nothing, and turning either off meant the double
negative `--headless=false`. #60 made the defaults visible in help; this gives
each a positive way to opt out.

  notte sessions start --headed              # was --headless=false
  notte sessions start --no-solve-captchas   # was --solve-captchas=false
  notte sessions start --no-file-storage     # was --use-file-storage=false

Naming follows one rule: use the word the ecosystem already has, otherwise
prefix with --no-. Playwright exposes a visible browser as --headed and users
arrive from Playwright and Puppeteer, so that is what they will guess. The other
two have no comparable term and take the --no- prefix used by git, docker, npm
and curl.

--no- rather than --disable- specifically because Chromium's own flags are
--disable-* and this command forwards them verbatim through --chrome-args.
Distinct prefixes mean `--no-file-storage --chrome-args="--disable-gpu"` reads
unambiguously as one Notte flag and one browser flag.

The originals are deliberately NOT deprecated. Pinning a value explicitly is
legitimate defensive scripting: a caller who needs a headless session should not
have to trust that the server default stays true, which is exactly the failure
mode #58 and #60 dealt with. Deprecating would also print a warning on the most
common invocation in our own docs. Passing both spellings at once is an error
rather than letting precedence silently pick a winner.

Omitting the new flags sends nothing, so the server default still applies -
covered by a test, since sending an explicit value would re-freeze the default
into the client.

Verified against the API: --headed -> headless=false, --no-file-storage ->
use_file_storage=false, --no-solve-captchas -> solve_captchas=false, no flags ->
all three true, and `--headed --headless` is rejected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds explicit opt-out spellings for three session-start options and moves conflicting-flag validation ahead of session replacement side effects.

  • Adds --headed, --no-solve-captchas, and --no-file-storage.
  • Rejects conflicting original and opt-out spellings in PreRunE.
  • Adds unit coverage for inversion, omission, conflict handling, and original-flag compatibility.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; conflicting flags are now rejected by the actual session-start command before replacement of the current session begins.

Important Files Changed

Filename Overview
internal/cmd/sessions.go Wires session-start validation into PreRunE, ensuring conflicting flags are rejected before the current session can be stopped.
internal/cmd/sessionstart_optout.go Registers the three opt-out flags, maps them to inverse request values, and validates conflicts with original flags.
internal/cmd/sessionstart_optout_test.go Adds focused unit tests covering unset request fields, inversion semantics, conflicts, early validation, and continued support for original flags.

Reviews (2): Last reviewed commit: "fix: validate session-start flag conflic..." | Re-trigger Greptile

Comment thread internal/cmd/sessions.go
…t session

Review catch, and a real one. runSessionsStart prompts, stops the current
session and clears the local pointers before it builds the request, so the
conflict check I put next to the request build ran too late:

  notte sessions start --headed --headless

with an active session stopped that session, wiped current_session,
current_viewer_url and current_agent, and only then refused to start a new one.
The user ends up with neither.

Validation now hangs off PreRunE, which cobra runs before RunE and therefore
before any of that. applySessionStartOptOuts revalidates so the invariant does
not depend on the command wiring.

The pre-existing proxy check had exactly the same shape - it also ran after the
stop - so it is extracted into validateSessionStartProxyFlags and runs from the
same place. `--proxy --proxy-country=us` no longer costs the caller their
session either.

Verified against the API with a session active: both conflicts now error while
the original session stays `active`. Previously it would have been stopped.

The regression test asserts the ordering rather than just the error - that
sessionsStartCmd has a PreRunE at all, and that RunE does not run for an invalid
combination. Testing only for a returned error would pass even with the bug.

Also fixes the gofumpt failure from CI: the table literal in
sessionstart_optout_test.go now uses named fields. `gofmt` accepted it, which is
why it slipped through locally; golangci-lint runs gofumpt, which is stricter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@giordano-lucas

Copy link
Copy Markdown
Member Author

@greptile new review

@giordano-lucas
giordano-lucas merged commit f45d482 into main Aug 6, 2026
4 of 5 checks passed
giordano-lucas added a commit that referenced this pull request Aug 6, 2026
…lp (#62)

The README still described the pre-v0.0.31 flag surface. It showed
--solve-captchas and --use-file-storage as things you switch on, when all three
of those options default to true server-side, and it did not mention --headed,
--no-solve-captchas or --no-file-storage at all.

  --headed                    # was: --headless (a no-op against the default)
  --no-solve-captchas         # was: --solve-captchas
  --no-file-storage           # was: --use-file-storage

Also:

- document the session lifetime that #60 surfaced: 3 minutes idle, 15 minutes
  total. Neither default appeared in the README, and both are short enough that
  the next command fails with a bare "Session closed" without saying why
- drop --headless and --solve-captchas from examples that only passed them to
  get the default behaviour
- correct `notte page upload`. The README showed a positional
  `notte page upload <id> <file>`; it is a required --file flag, and the name
  refers to a file in the uploads store rather than a path on the caller's
  machine, so a local path fails with "Unable to get file: <path> for upload".
  The `notte files upload` step it needs first is now spelled out, as is the
  matching `notte files download --from session` for retrieving what
  `page download` produced

Separately, fixes a cosmetic bug I shipped in #61. Cobra's UnquoteUsage takes
the first backquoted span in a usage string as the flag's value placeholder, and
the --no-file-storage description had `notte page download` in backticks, so
v0.0.31 renders it as:

  --no-file-storage notte page download   Do not attach FileStorage...

as though the flag took an argument. Single quotes instead.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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