run_argv, run_argv_batch, fetch, fetch_local, and the vcs tools now return
their output whole, so the request-prep cap trims it on the wire and names
its document. A fetched page or a long log reads on from the tool message,
with no re-fetch and no re-run.
The run_argv_batch run budget stays as an execution guard: it stops a
runaway batch from spawning further huge-output steps.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The gate has four entry points and each now has a test: `view_image` and
`fetch_local` refuse with the message naming the config key, the registry drops
a plugin tool's picture and says why, and the workspace helpers keep `None` (no
host verdict) permissive. On the CLI side the verdict is asserted to follow the
selected model, and to reach the tools once an instance is bound.
`--yes` / `/yolo on|off|once` clears the prompt of a `YOLO`-tagged tool: interpreter runs (`run_argv`, `run_argv_batch`, `open_pty`), the file mutations (overwrite / copy / move / delete) and `fetch_local`'s cleartext and mutating requests. A tool without the tag still asks, and hard path/command denylists stay untouched.
`classify_danger` now answers with a `DangerReason` — the reason text plus `yolo_skip` — so one call can refuse that skip: a command that runs through `sudo` / `su` / `doas` / `pkexec` (as the program or a wrapper) keeps its confirm whatever YOLO mode says. It never adds a reason of its own, so the program the denylist gate already asks about is not asked twice.
`prepare_batch_confirm` leaves the covered calls out, so a skipped call neither prompts on its own nor takes a slot in the round's aggregated prompt, and one escalating step keeps the whole batch in front of the human.
New `view_image` reads a local picture (JPEG, PNG, GIF, WebP, sniffed from its
bytes) and hands it to the model as an image part, with an optional `detail`
level — `low` measured 3.4x cheaper on a 1200x900 picture. `read_file` now
points at it instead of returning decode noise.
`fetch_local` returns an image response as the picture itself, and MCP image
content blocks become image parts instead of `[image: ...]` placeholders, so a
screenshot server finally reaches the model.