Skip to content

feat(runner): write a screenshot to stdout with --out - - #1578

Draft
Goran Gajic (gorangajic) wants to merge 5 commits into
mainfrom
goran/wiz-11974-qawolf-runner-screenshot-can-write-to-stdout
Draft

feat(runner): write a screenshot to stdout with --out -#1578
Goran Gajic (gorangajic) wants to merge 5 commits into
mainfrom
goran/wiz-11974-qawolf-runner-screenshot-can-write-to-stdout

Conversation

@gorangajic

@gorangajic Goran Gajic (gorangajic) commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Relates to WIZ-11974

Overview of Changes

qawolf runner screenshot only wrote a file. The Tester session, which wants the bytes in a process, had to reserve a temp path, hand it to the sandboxed user, run the command, read the file back and delete it on every computer-use step.

--out - now writes the decoded JPEG to stdout, the same - that already means stdin for act and exec. Stdout carries the image alone: the confirmation, and the JSON line under --json, goes to stderr so nothing follows the bytes into a reader that treats stdout as the file. A terminal on stdout is refused, since nothing there can read the bytes. The help text, the runner guide and the skill say so.

Raw bytes rather than a base64 field in the JSON answer, because the repo's rule is to decode next to the write so nobody files base64 text as a JPEG, and because a byte stream is what a reader that pipes the command into a file or a viewer expects.

Testing

bun run typecheck
bun run lint
bun run format:check
bun run knip
bun run test
bun run build

Added tests: the writer sends decoded bytes to stdout and nothing to disk, refuses a non-JPEG answer for stdout too, and reports a closed pipe without letting the stream's error event crash the process (the doubles are real Writable streams for that reason); the handler keeps every confirmation off stdout in json and agent mode, refuses a terminal on stdout, and names stdout rather than a file when the pipe fails.

Checklist

  • Changes follow the code style of this project
  • Self-review completed
  • Tests added/updated (or not applicable)
  • No breaking changes (or described below)

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Comment @coderabbitai help to get the list of available commands.

`qawolf runner screenshot` only wrote a file, so a caller that wants the
bytes in a process reserved a path, ran the command, read the file back
and deleted it on every computer-use step. `--out -` writes the decoded
JPEG to stdout instead, the same `-` that reads stdin for act and exec.

Stdout then carries the image alone: the confirmation, and the JSON line
under --json, moves to stderr so nothing follows the bytes into a reader
that takes stdout as the file.
Under Node a write to a closed pipe reports EPIPE twice: to the write
callback, and as an error event a tick later. With no listener the event
is an uncaught exception, so the unwritable answer the writer had just
produced was followed by a crash and exit 1. The listener now goes on
before the write and comes off only after a success.

The test doubles are real Writable streams, since an object with only a
write method never emits the event and hid the crash.
Only a terminal on stdout selects human mode, and a terminal cannot read
JPEG bytes; the confirmation would also land among them, since clack
prints to stdout, rather than on stderr as the message promises.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant