- --log-level (comma-separated string: info, error): pick which logs are emitted;
the level set is resolved once, up front
- Log responses at the info level: full self-contained JSON to a file or stderr,
a compact "status duration | body" summary in the TUI log box
- Route logs independently of the progress display: the TUI log box when it runs,
stderr when piped, or a file via --log-file/-w (parent dir validated up front)
- Replace --quiet with --progress (bar | none, default bar): progress and logs are
now independent — progress=none still shows the log box; quiet == progress=none
with an empty log level
- Rename the internal "message" concept to "log" (runtimeLog, runtimeLogger, ...)
First signal cancels the main context; second releases the terminal
and exits 130, unblocking shutdown when captcha polls or user scripts
ignore context. Also moves the bubbletea models and streamProgress
out of sarin.go into a new tui.go.
Replace ad-hoc fmt.Errorf/errors.New calls with typed error structs across config, sarin, and script packages to enable type-based error handling. Add script-specific error handlers in CLI entry point. Fix variable shadowing bug in Worker for scriptTransformer. Bump Go to 1.25.7 and golangci-lint to v2.8.0.