Skip to content

Fix shell input, event streaming, and download completion - #395

Merged
saioai merged 9 commits into
mainfrom
codex/universal-io-runtime-20261008
Oct 9, 2026
Merged

saioai merged 9 commits into
mainfrom
codex/universal-io-runtime-20261008

Conversation

@saioai

@saioai saioai commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Explicit stdin could reach whole-request parsing before its selected field consumed it. Failed downloads could replace existing files. Short redirected event streams could also wait for a page of output. This makes stdin selection predictable and removes page buffering from redirected event streams. Downloads complete before the CLI updates existing ordinary files.

What changes

  • One explicit text or binary parameter can consume stdin. Conflicting consumers fail before reading or making a request.
  • Whole-request JSON/YAML, flag precedence, literal binary paths, and untrusted-stdin restrictions keep their behavior.
  • Final Boolean stream values select streaming dispatch. Explicit stream flags keep precedence; request bytes remain unchanged.
  • Redirected event streams emit each formatted event immediately. Terminal paging and finite lists retain their behavior.
  • Explicit downloads stage the response before updating ordinary files. Successful updates preserve existing inodes, links, and permissions.
  • Incomplete speech saves preserve existing ordinary files. Closed stdout and combined transfer/write failures return nonzero status.
  • Successful API save receipts move from stdout to stderr. Structured error formats and error extraction suppress optional receipts.
  • New explicit Windows destinations use protected permissions for the current user, SYSTEM, and Administrators. Existing DACLs remain unchanged.
  • The final local copy is not atomic. Local failures can leave partial contents, which the error reports.

Commands

No new commands or flags. These examples use existing options.

printf 'hello\n' | openai responses create --model MODEL --input @-  # one text field
cat notes.txt | openai files create --file - --purpose user_data   # binary stdin
openai files content file-example --output copy.bin > result.txt # receipt on stderr; result.txt stays empty
openai files content file-example --output - > copy.bin          # shell-owned redirection

Without an explicit stdin reference, piped JSON/YAML supplies the whole request. OPENAI_UNTRUSTED_STDIN=true keeps piped references literal.

Use --format-error text for text diagnostics alongside an explicit response format. Shell redirection and special destinations retain their existing partial-output behavior. Automatic terminal downloads retain their destination selection and partial-file behavior.

Windows PowerShell 5.1 can transform binary pipelines. File paths and explicit --output destinations avoid shell conversion. The input and save guide explains the supported forms.

Code

pkg/custom owns stdin selection, stream selection, staged downloads, and save diagnostics. Request middleware carries immutable receipt policy into the binary response helper. That helper reports after completion and consumes the returned message, preventing duplicate generated receipts. Direct library callers without that policy retain their returned-message contract.

internal/windowsfile owns private Windows file creation shared by downloads and shell-integration locks. Both callers retain their own diagnostics. Focused tests cover the callers and built CLI entrypoints. The existing Windows CI job now exercises cmd, Windows PowerShell, pwsh, save completion, permissions, and cancellation.

The shared iterator reuses its formatter and stdout error handling for immediate event delivery.

No new dependencies, entrypoint changes, or generated changes. API receipts use the supported handwritten orchestration path. Local manpage receipt and gzip-completion changes remain separate.

Tested

Candidate f67126c extracts the shared Windows file creator above validated 5a8855c. Independent review verified unchanged permissions, creation flags, handle ownership, and error behavior. Existing caller tests now require exact diagnostics and duplicate-file error identity. Both Windows caller test packages compile. Focused macOS checks passed 111 results, with one terminal-only skip.

CI passed at f67126c: the full Linux suite, native Windows caller tests, macOS cancellation, lint, and cross-platform help. CodeQL, artifact builds, nine release-target vulnerability scans, and both budget gates passed. Conditional jobs skipped. This head includes SDK 3.74.0 and Go 1.26.9 through main 1dc9d3d.

The streaming regression failed before its fix and passed afterward. All 33 additional input, completion, speech, and timing cases passed natively on Windows at 5a8855c. The refactor leaves those implementations unchanged. Platform-specific skips remain explicit in the retained evidence.

Human re-review remains pending for this extraction.

Demo

Real CLI binaries on macOS with a synthetic loopback API. Before is d32b3ae; the recording's after is ac277e0. It shows explicit stdin and preservation after a truncated transfer. Those visible behaviors remain unchanged. Receipt channels and Windows behavior have separate process checks.

The recording does not depict the new event timing case. Its process regression withholds later events until the first output arrives.

Explicit stdin and failed-save comparison

Before:

Before: stdin parsing and overwritten destination

After:

After: explicit stdin and preserved destination

Recording recipe · Scene and assertions

BEGIN_COMMIT_OVERRIDE
fix(io): preserve explicit stdin, stream events promptly, and protect incomplete downloads (#395)

fix(output): send successful API save receipts to stderr (#395)
END_COMMIT_OVERRIDE

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Castiron custom code

Evaluated main: 1dc9d3d2a18f2a9ad016f539d337f5544e665ac2.

✅ No new custom-code files detected.

2 mixed files remain; 0 existing customizations changed.

Compared 1dc9d3d2a18f → f67126c365c6. Generated baselines verified.

2 existing customizations unchanged
  • pkg/cmd/adminorganizationcertificate.go
  • pkg/cmd/audiovoice.go

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 37887478779 --repo openai/openai-cli \
  --name castiron-custom-code-37887478779-1 --dir /tmp/castiron-custom-code-37887478779-1
git apply --stat /tmp/castiron-custom-code-37887478779-1/custom-code.patch
cat /tmp/castiron-custom-code-37887478779-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin 1dc9d3d2a18f2a9ad016f539d337f5544e665ac2 f67126c365c6fa73844c8d7a3c9e0540cfac56c7
python3 scripts/castiron/custom_code_report.py report \
  --base 1dc9d3d2a18f2a9ad016f539d337f5544e665ac2 \
  --head f67126c365c6fa73844c8d7a3c9e0540cfac56c7 --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-f67126c365c6
cat /tmp/castiron-custom-code-f67126c365c6/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@saioai

saioai commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review commit ac277e0ac7f26d189d6637ac47456298c062ea36 against this PR's current base. Check public-command behavior, preserved input/output contracts, errors, and cancellation. Distinguish code defects from the documented validation limits.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T05:02:33.837375Z f67126c New commits
🔒 Security Review ✅ Completed 2026-10-09T05:06:05.114165Z f67126c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: ac277e0ac7

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: ac277e0ac7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@saioai

saioai commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review commit 0a3afb0de36ead75ea7f18bc44346506c73c8ad0 against base 86502b0d5b614155746daedb6a435e209fdb443e.
Check public input/output contracts, save completion, stderr receipts, streaming, errors, and cancellation.
Review the Windows console-test correction and preserved generated-caller contracts.
Distinguish demonstrated defects from documented limits and pending native CI evidence.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 0a3afb0de3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 0a3afb0de3

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@saioai saioai changed the title Support explicit stdin and preserve incomplete downloads Fix shell input, event streaming, and download completion Oct 9, 2026
@saioai

saioai commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review 5a8855cb92fcb88be91c5415d0832d0a16fc0257 against main base 1dc9d3d2a18f2a9ad016f539d337f5544e665ac2.
This follow-up fixes pre-existing buffering of redirected event streams and adds public input/completion regression cases.
Check incremental delivery, preserved formats, stdout versus upstream errors, cancellation, and unchanged terminal paging and finite lists.
Review the new tests' producer/consumer ordering, timeouts, cleanup, and native-platform assumptions.
Keep documented non-atomic local copying and separate integration work distinct from defects in this change.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 5a8855cb92

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 5a8855cb92

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@saioai
saioai marked this pull request as ready for review October 9, 2026 04:35
@saioai
saioai requested a review from a team as a code owner October 9, 2026 04:35

@markstuart-oai markstuart-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 5a8855cb92fcb88be91c5415d0832d0a16fc0257. One maintainability issue remains. The new Windows private-file creator duplicates the existing shell-integration implementation. The inline comment proposes sharing that operation.

I found no additional issues in stdin selection, Boolean stream dispatch, immediate redirected event output, staged downloads, cancellation, or save-receipt handling. The final copy into an existing file remains non-atomic, as documented.

Validation: hosted tests, Windows shell/permission checks, macOS upload cancellation, lint, artifact builds, help checks, CodeQL and Castiron checks passed for this head. This was a source-only review. I did not run repository workloads or live API calls.

Comment thread pkg/custom/download_file_windows.go Outdated
@saioai
saioai added this pull request to the merge queue Oct 9, 2026
Merged via the queue into main with commit 390a9c3 Oct 9, 2026
27 checks passed
@saioai
saioai deleted the codex/universal-io-runtime-20261008 branch October 9, 2026 06:16
Tmwakalasya pushed a commit to Tmwakalasya/openai-cli that referenced this pull request Oct 9, 2026
The existing upload alias requires `--file`; metadata and contents use
`retrieve` and `content`.
This adds a plain upload path, `get` for metadata, and `download` for
contents.
Help shows the workflow and gives runnable examples.

This inherits the merged output, stdin, and save policies from openai#392 and
openai#395.

### What changes

- Upload accepts one quoted local path and keeps purpose explicit.
- Files help lists upload, get, and download in workflow order.
- Shell completion supports the first upload path and preserves literal
leading `@` filenames.
- Bash completion also preserves colon-separated filename prefixes and
Readline's replacement suffix.
- Interactive uploads show returned values and a safely quoted,
read-only metadata command.
- Suggestions reuse the executable or development checkout, including
`go run` and `scripts/run`.
- Suggested commands preserve the selected project, organization, and
safe base URL. Sensitive overrides suppress the suggestion.
- Error-output options leave successful upload receipts unchanged.
Processing errors retain complete details through JSON inspection.
- Malformed known receipt fields use complete response output. Existing
null values and large integer timestamps remain supported.
- Interactive `get` shows complete metadata, full IDs, and UTC
timestamps.
- Existing names, flags, machine output, extraction, and download bytes
remain available.

### Commands

`get` and `download` are new routes. The existing `upload` route gains
positional paths.

```sh
openai files --help
openai files upload "upload space.txt" --purpose user_data
openai files get file-example
openai files download file-example --output "downloaded copy.txt"
openai files download file-example > copy.txt
openai files get file-example --format json  # complete metadata for scripts
cat upload.bin | openai files upload --file - --purpose user_data
```

Use one positional path or `--file PATH`. `create`, `retrieve`,
`content`, `-o`, and extraction options remain available.
Paths are literal. Quote a leading `@` in PowerShell, or use `./@name`.
Reload an existing completion adapter after updating the CLI.

Receipts and readable timestamps require terminal stdout and stderr,
text/auto output, and no extraction or raw output.
`--quiet` suppresses the upload receipt and retains selected metadata.
The suggested inspection command never selects a download destination or
overwrites the upload source.
Keep the same environment when copying it; credentials are never
included in suggestions.
Development hints retain their checkout with `go -C CHECKOUT run
./cmd/openai`.

After an uncertain upload, inspect its known ID or recent same-project
files before uploading again.
Upload acceptance does not imply processing completion. Streamed uploads
do not retry automatically.
The [Files recovery
guide](https://github.com/openai/openai-cli/blob/bcd5af538bf254c80dd5884a1c1cbbb37389bc96/docs/files.md#recover-from-a-failed-command)
gives concrete recovery steps.

### Code

`pkg/custom` adds routes, request-context capture, and terminal
presentation over existing decorated handlers.
`pkg/transformers` formats file timestamps without changing machine
data.
`internal/autocomplete` opts upload into first-path completion and
preserves literal filenames across four shell adapters.
`internal/clihelp` keeps fallback example notes out of command-owned
examples.
Files receipt hints can follow one recognized Go parent through platform
process metadata.
Unknown callers, lookup errors, cancellation, or unavailable checkout
paths omit the optional hint.
Image and setup callers keep their existing shell detection.
Existing terminal escaping, shell quoting, input handling, save policy,
and download code remain in use.
No new package, external dependency, generated-source change, or startup
change is required against main.

### Tested

Candidate: `bcd5af5` against main `866d8770`.
Its complete source tree matches tested `48aee722`; the final merge
changes ancestry only.
Local checks used Go 1.26.9 on macOS arm64 with synthetic loopback APIs.
The latest two findings reproduced in eight public processes before
correction.
Independent review checked `3ae27da` and executed 31 corrected public
processes.
That matrix covered 24 uploads and seven metadata requests.
`go run` and copied hints passed through Bash, zsh, fish, and PowerShell
on macOS.
`scripts/run` passed in Bash and zsh.
An absolute `scripts/run` invocation remained copyable from outside the
checkout. Unknown wrappers did not use a misleading SHELL value.
Malformed, nullable, omitted, signed, and large fields retained their
expected output, including a 17 MiB fallback.

At `3ae27da`, custom/transformer checks passed 165 results, public
Files/help passed 109, and manpage integration passed 18.
None of those runs skipped tests.
Windows and Linux custom-package test compilation passed at `3ae27da`.
Native ancestry checks remain unverified on those systems.
At runtime `10c10cb`, eight independent binary probes passed, including
partial-page and receipt-write failures.
That composition passed 128 public Files/local-utility results and 14
additional output/routing results.
The custom run passed 193 results; five unavailable-shell checks passed
after adding the existing cached shells to PATH.
That focused rerun passed 29 results without skips.
Go module verification passed. The trusted budget passed with 21/1000
custom lines against current main `866d8770`.
Earlier focused vet passed at `3ae27da`.
Earlier Bash completion coverage passed 74 results at `520dc58`; the
completion source remains unchanged.
The earlier three findings retain their separately recorded before/after
and context/byte-preservation evidence.
The previous published head `ae2ad9e` passed hosted tests, builds,
platform help, permissions, cancellation, and baseline checks.
See the [CI
run](https://github.com/openai/openai-cli/actions/runs/37907274504) and
[platform help
run](https://github.com/openai/openai-cli/actions/runs/37907274438).
Current-head CI will run after publication and retargeting to main.
At `48aee722`, the final table-policy update passed 55 focused results
and seven public Files results, with zero skips.
Independent review confirms all 44 Files feature files remain unchanged
through the parent update and final main alignment.
Live API acceptance and native Windows Files workflows remain
unverified.
PowerShell execution on macOS does not establish Windows filesystem
behavior.

The inherited save policy stages explicit ordinary downloads and reports
successful saves on stderr.
Quiet and structured error modes suppress optional save receipts;
receipt-write failures return nonzero after retaining completed files.
Final local copies remain non-atomic. Redirection and automatic or
special destinations can retain partial output.
Malformed HTTP 200 metadata can still return success. The guide explains
these limits without promising rollback.

### Demo

macOS arm64, Bash, Menlo 18px, terminal replay, and a synthetic loopback
API.
Before: Output production `7901147`. After: Files `2d482e3`.
The recorded ordinary workflow remains unchanged in this candidate.
Separate public-process checks cover the later development-launcher and
malformed-response corrections.
Workflow uses 110×46 cells; discovery uses 110×54 cells.

The workflow verifies twelve requests and eight exact text/binary
download comparisons.

![Files workflow before and
after](https://github.com/user-attachments/assets/8ce1c9da-72e4-415c-878e-31df09eb6d8b)

Before:

![Before: existing Files
commands](https://github.com/user-attachments/assets/759af276-1175-4c27-b2ad-342289a22f65)

After:

![After: upload, inspect, and
download](https://github.com/user-attachments/assets/ca42f90b-ac0e-4584-8432-afd91dd1fb80)

Command discovery verifies workflow ordering, runnable examples, and
zero API requests.

![Files command discovery before and
after](https://github.com/user-attachments/assets/9305ea4f-ae35-446a-b9d9-3d7c6314b8eb)

Before:

![Before: Files
help](https://github.com/user-attachments/assets/96377ca2-151a-4b18-bd0f-c41552bea4d4)

After:

![After: workflow ordering and
examples](https://github.com/user-attachments/assets/5e0637e1-fa0d-4b81-aae4-b2706bdab9ff)

[Recording
recipes](https://github.com/openai/openai-cli/blob/2d482e3f62adf109bca5dfbb8bee6565c277701e/scripts/demos/files-workflow/README.md).
@openai-sdks openai-sdks Bot mentioned this pull request Oct 16, 2026
Tmwakalasya pushed a commit to Tmwakalasya/openai-cli that referenced this pull request Oct 19, 2026
Resumed Responses streams could report success after a reasoning, audio,
or tool event ended early.
Empty API error objects could also discard the available HTTP status.
This reports those failures while preserving partial output and
meaningful API error fields.

### What changes

- Known Responses progress events require a response completion event,
including after `--starting-after`.
- Tool completion remains separate from response completion. Unknown
events and explicit event limits keep their behavior.
- Empty API error objects use the existing status/message fallback in
structured error formats.
- Two public regression tests join the existing macOS, Linux, and
Windows dispatch checks.

### Commands

No new commands or flags.

```sh
openai responses retrieve RESPONSE_ID --stream=true --starting-after 10
openai models retrieve MODEL_ID --format-error json
```

Formats, extraction, raw output, event limits, and selected stdout data
remain available.
Incomplete resumed streams now return nonzero. Empty error objects now
include HTTP status and a useful message.

### Code

`pkg/transformers` tracks known Responses progress events.
`pkg/custom` selects the empty-error fallback without changing
meaningful API fields.
Public tests reuse the existing process helpers. The demo reuses the
shared capture helper.
Generated commands, `main.go`, dependencies, and budget policy remain
unchanged.

### Tested

On macOS ARM64, 17 new regression cases failed before the fixes; all 61
pass afterward.
Another 280 public tests and subtests pass, including large events,
cancellation, partial failures, and output formats.
Focused helper checks pass, as do 20 independent executable probes.
These runs have no skips.
Earlier baseline checks also passed binary saves and Bash/zsh
redirection at `0ca3ac7`.
Independent adversarial review found no remaining blocker in these
fixes.
CI results are pending publication.

This is a focused compatibility catch-up, not complete platform
certification.
Native Windows/Linux terminals, WSL, SSH/tmux, Fish, x64, and terminal
appearance remain incomplete.
The separate Models SIGINT correction remains with its existing owner.
Files/Batches/Projects navigation helpers remain inactive through their
generated commands.
SDK CODEOWNER review is required before merging.

### Demo

macOS Bash terminal replay against a synthetic loopback API.
Before uses `0ca3ac7`; After uses `2bf0e38`; final `61503df` adds only
the reviewed recorder.
The CLI captures stdout and stderr separately; the replay displays those
actual bytes and exit statuses.
This is not native terminal appearance evidence.

[View image:
comparison.gif](https://flow.apps.openai.org/api/v1/gh/attachments/openai/openai-cli/439/68d7c16037ee457aa33204544dad85c1.gif)

Before:

[View image:
before.png](https://flow.apps.openai.org/api/v1/gh/attachments/openai/openai-cli/439/70990718677b41828cce63f9525b4442.png)

After:

[View image:
after.png](https://flow.apps.openai.org/api/v1/gh/attachments/openai/openai-cli/439/2bd629dfb7b54e428e70726abc141375.png)

[Recording
recipe](https://github.com/openai/openai-cli/blob/61503df9a70a8f1729978bd0f902085d99bfc6d8/scripts/demos/stream-errors/README.md).

<!-- compatibility-parent: openai#265 -->
<!-- compatibility-parent: openai#266 -->
<!-- compatibility-parent: openai#276 -->
<!-- compatibility-parent: openai#278 -->
<!-- compatibility-parent: openai#279 -->
<!-- compatibility-parent: openai#289 -->
<!-- compatibility-parent: openai#389 -->
<!-- compatibility-parent: openai#390 -->
<!-- compatibility-parent: openai#391 -->
<!-- compatibility-parent: openai#392 -->
<!-- compatibility-parent: openai#395 -->
<!-- compatibility-parent: openai#397 -->

<!-- codex-thread: 01a131fd-8d19-7013-b8d9-2de3e4ab3963 -->
Tmwakalasya pushed a commit to Tmwakalasya/openai-cli that referenced this pull request Oct 19, 2026
The WSL job can stop on a download startup timeout before any test runs.
It also covers only pager ownership.
This retries startup once and adds existing stdin, file, and output
checks to the same disposable Ubuntu WSL 1 session.

### What changes

- Run 17 existing public-entrypoint tests with 104 named subtests for
openai#392, openai#395, and openai#397.
- Check stdin precedence, incremental streams, download completion,
literal filenames, machine output, and quiet/verbose behavior.
- Retry one typed timeout before the image response opens. Certificate,
HTTP, integrity, body-transfer, and file failures never retry.
- Require exact test execution, successful exits, complete streams, and
verified payload hashes.
- Preserve the existing pager check, distro ownership, and work/cleanup
deadlines.

### Commands

Public CLI commands remain unchanged. Contributor controls run without
WSL or network access:

```sh
python -I -B scripts/test_wsl_pager.py
```

The existing CI job builds both Linux test binaries and imports one
pinned Ubuntu distro.
The runner accepts `--process-binary` for the fixed process suite.

### Code

The workflow adds one test-binary build. The existing Python runner
verifies and runs it inside the same owned distro.
Product code, Go tests, dependencies, and other CI jobs remain
unchanged.

### Tested

All 42 offline controls passed locally and on native Windows AMD64.
The [native WSL
job](https://github.com/openai/openai-cli/actions/runs/38513767693/job/115687910287)
passed all 17 process tests and 104 subtests.
The existing pager test and its two subtests also passed. Payload hashes
and named distro cleanup were verified.
The tested tree matches refreshed head 5a53de0. Head checks completed
without failures. Conditional jobs were skipped.
The download opened on its first attempt. Retry recovery still has
synthetic coverage only.
This does not establish WSL 2, ARM64 WSL, DrvFS, or Windows Terminal
coverage.

### Demo

There is no visible product change. CI retains separate process output,
exit statuses, binary hashes, and distro cleanup results.

<!-- compatibility-parent: openai#276 -->
<!-- compatibility-parent: openai#392 -->
<!-- compatibility-parent: openai#395 -->
<!-- compatibility-parent: openai#397 -->

<!-- codex-thread: 01a0e8d7-94ce-71c3-96a2-04ac2c7201e3 -->
Tmwakalasya pushed a commit to Tmwakalasya/openai-cli that referenced this pull request Oct 19, 2026
…penai#468)

Windows tests missed console cancellation for Responses, transcription,
and speech streams. They also lacked console upload receipts and full
ARM64 shell/download coverage. This adds checks through the built CLI
without changing runtime behavior.

### What changes

- Verify partial stream output, a nonzero child exit, and HTTP closure
after real Ctrl+C delivery.
- Upload through CMD, Windows PowerShell 5.1, and PowerShell 7 with real
console handles.
- Execute PowerShell 7’s printed Inspect command unchanged, preserving
request context and the modified local source.
- Preserve CMD and Windows PowerShell 5.1’s existing no-hint behavior.
- Run the full Windows shell root and four download roots on ARM64, with
exact event gates.

### Commands

No new CLI commands or flags. Existing commands keep their behavior.
These focused checks run on Windows:

```powershell
$env:OPENAI_CLI_REQUIRE_NATIVE_SHELLS = 'cmd,powershell,pwsh'
go test -p 2 ./cmd/openai -count=1 -timeout=3m -v -run '^TestMainShellWindowsNative$'
go test -p 2 ./pkg/custom -count=1 -timeout=2m -v -run '^TestWindowsDownload(AutomaticConsole|PrivateCreation|PrivatePublication|PreservesExistingDACL)$'
```

### Code

Tests reuse the production CLI build, synthetic upload fixture, console
captures, and existing Job Object owner. Console-owner receipts
distinguish child exits from watchdog or helper failures.

Production code and dependencies match main `82be28a`. This integration
preserves openai#465’s request cases and main’s Fish and Windows invocation
checks.

### Tested

At `dc7dfbb6`, native Windows x64 and ARM64 used Go 1.26.9 and all three
required shells. Each architecture passed 49 named tests and subtests
across five roots, without selected skips or failures. Eight unrelated
x64 download cases retained their existing Windows skips.

Fresh Help checks also passed:

- Nine Fish image-help names and four Fish invocation names on Linux x64
and ARM64.
- Thirteen image-order names on Windows x64, Windows ARM64, Linux ARM64,
and macOS Intel.
- Three Windows help-invocation names on each Windows architecture.

[CI](https://github.com/openai/openai-cli/actions/runs/38623632107) and
[Help
compatibility](https://github.com/openai/openai-cli/actions/runs/38623632205)
passed on their first attempts at this head. Each workflow completed
eight successful jobs. Independent review checked the exact test events
and prepared-source bindings.

The earlier `5e0ac7f3` CI run failed after a PowerShell completion
subprocess was killed. Its cause remains unknown. This fresh pass does
not explain that failure, and the earlier head was not retried.

Console cells combine stdout and stderr. These checks do not establish
graphical-terminal appearance or physical-keyboard behavior.

### Demo

This adds regression coverage without changing CLI presentation, so
there is no visual comparison.

<!-- compatibility-parent: openai#279 -->
<!-- compatibility-parent: openai#289 -->
<!-- compatibility-parent: openai#395 -->
<!-- compatibility-parent: openai#397 -->

<!-- codex-thread: 01a131fd-7e05-7622-8102-817940a4b4ee -->
fredatgithub pushed a commit to fredatgithub/openai-cli that referenced this pull request Oct 19, 2026
Automated Release PR
---


##
[1.39.0](openai/openai-cli@v1.38.0...v1.39.0)
(2026-10-19)


### Features

* **admin:** add guided admin-key setup and access verification
([openai#387](openai#387))
([4183995](openai@4183995))
* **api:** add Decisions creation and hosted environment reference
([openai#437](openai#437))
([0ca3ac7](openai@0ca3ac7))
* **api:** add Decisions prompt caching options
([openai#501](openai#501))
([5031be2](openai@5031be2))
* **api:** add organization Decisions usage reporting
([openai#435](openai#435))
([ba6cb09](openai@ba6cb09))
* **api:** add prompt-based voice creation
([openai#502](openai#502))
([72f552b](openai@72f552b))
* **api:** add safety identifiers to image requests and responses
([openai#503](openai#503))
([b624c9f](openai@b624c9f))
* **api:** configure Decisions when accepting Live SIP calls
([openai#505](openai#505))
([e17ac83](openai@e17ac83))
* **api:** support project API key scope updates
([openai#478](openai#478))
([7afecce](openai@7afecce))
* **api:** support updating project API key expiry
([openai#462](openai#462))
([97b43f2](openai@97b43f2))
* **audio:** add speech workflows, local history, playback, export, and
readable transcripts
([openai#403](openai#403))
([fe17bcb](openai@fe17bcb))
* **batches:** add waiting, result collection, and safe downloads
([openai#388](openai#388))
([ecaf876](openai@ecaf876))
* **cli:** add scoped error recovery and optional shell typo suggestions
([openai#409](openai#409))
([a81ec27](openai@a81ec27))
* **cli:** show a welcome card during bare interactive startup
([openai#401](openai#401))
([024dbaa](openai@024dbaa))
* **files:** add get and download routes with positional uploads
([openai#397](openai#397))
([e689398](openai@e689398))
* **help:** show complete help consistently and improve flag diagnostics
([openai#384](openai#384))
([6fcc478](openai@6fcc478))
* **images:** add interactive and opt-in Konsole previews
([openai#371](openai#371))
([d3bc819](openai@d3bc819))
* **images:** retain picker drafts and keep failed requests editable
([openai#394](openai#394))
([1dc9d3d](openai@1dc9d3d))
* **models:** add filtered ID and owner lists with interactive
navigation ([openai#391](openai#391))
([86502b0](openai@86502b0))
* **output:** add quiet and verbose controls
([openai#392](openai#392))
([866d877](openai@866d877))
* **tokenizer:** add offline token inspection and local Codex guidance
([openai#386](openai#386))
([217ff2e](openai@217ff2e))


### Bug Fixes

* **autocomplete:** preserve colon argument boundaries
([openai#413](openai#413))
([5739ce0](openai@5739ce0))
* **autocomplete:** preserve quoted and Unicode filenames during Bash
completion ([openai#446](openai#446))
([6ec7646](openai@6ec7646))
* **autocomplete:** preserve quoted Bash command prefixes
([openai#399](openai#399))
([c3c66c4](openai@c3c66c4))
* **autocomplete:** restore Fish 3 completion and literal filename
prefixes ([openai#447](openai#447))
([f93670c](openai@f93670c))
* **ci:** decode SDK cross-link events as UTF-8
([openai#457](openai#457))
([af0e8a0](openai@af0e8a0))
* **cli:** emit finite JSON arrays; use --format jsonl for independent
records ([openai#407](openai#407))
([b93e41e](openai@b93e41e))
* **cli:** wait briefly for Windows piped input
([openai#485](openai#485))
([8b40840](openai@8b40840))
* **errors:** preserve incomplete resumed-stream failures and empty API
error details ([openai#439](openai#439))
([e8ffaab](openai@e8ffaab))
* **help:** preserve literal flag values and quoted Bash file completion
([openai#440](openai#440))
([47d6a16](openai@47d6a16))
* **images:** preserve reserved probe directories during Windows image
saves ([openai#470](openai#470))
([e330cc2](openai@e330cc2))
* **images:** retain saved-file recovery guidance after cancellation
([openai#442](openai#442))
([337a7e4](openai@337a7e4))
* **io:** preserve explicit stdin, stream events promptly, and protect
incomplete downloads
([openai#395](openai#395))
([390a9c3](openai@390a9c3))
* **models:** finish SIGINT shutdown with status 130
([openai#441](openai#441))
([673c5eb](openai@673c5eb))
* **output:** keep redirected results undecorated and preserve stream
cleanup ([openai#392](openai#392))
([866d877](openai@866d877))
* **output:** send successful API save receipts to stderr
([openai#395](openai#395))
([390a9c3](openai@390a9c3))
* **tokenizer:** preserve Windows Unicode input and split terminal
replies ([openai#454](openai#454))
([911218a](openai@911218a))


### Chores

* **api:** clarify Decisions request and response fields
([openai#476](openai#476))
([8301197](openai@8301197))
* **api:** correct the shida Live voice name
([openai#430](openai#430))
([193ee5b](openai@193ee5b))
* **api:** document 128-character safety identifiers
([openai#428](openai#428))
([a6bf1af](openai@a6bf1af))
* **api:** document beta pagination validation and migration
([openai#431](openai#431))
([729045e](openai@729045e))
* **api:** document beta session spending controls
([openai#432](openai#432))
([47df976](openai@47df976))
* **api:** document billing_not_active session errors
([openai#429](openai#429))
([8f26fe4](openai@8f26fe4))
* **api:** document detailed safety alert explanations
([openai#434](openai#434))
([2b61ced](openai@2b61ced))
* **api:** document Files API rate-limit responses
([openai#427](openai#427))
([88cd309](openai@88cd309))
* **api:** document image tool error and moderation details
([openai#451](openai#451))
([53b3b6e](openai@53b3b6e))
* **api:** document Live audio fixture events in the API reference
([openai#481](openai#481))
([38c82ce](openai@38c82ce))
* **api:** document OCI external-storage providers
([openai#433](openai#433))
([4f1f7df](openai@4f1f7df))
* **api:** document Realtime response error messages
([openai#479](openai#479))
([ec8d114](openai@ec8d114))
* **api:** document regional processing residency values
([openai#477](openai#477))
([75865b6](openai@75865b6))
* **api:** document snapshot lifecycle status values and events
([openai#415](openai#415))
([53828f0](openai@53828f0))
* **api:** document vault updates and metadata filters
([openai#426](openai#426))
([b724518](openai@b724518))
* **api:** use neutral moderation examples
([openai#518](openai#518))
([180544a](openai@180544a))
* clarify Live limits and refresh generated-file verification
([openai#510](openai#510))
([9cddd6b](openai@9cddd6b))
* **deps:** bump charm.land/bubbletea/v2 from 2.0.10 to 2.1.0 in the
go-minor-and-patch group across 1 directory
([openai#539](openai#539))
([37d5e5c](openai@37d5e5c))
* **deps:** bump the codeql group across 1 directory with 2 updates
([openai#543](openai#543))
([9023b9e](openai@9023b9e))
* **deps:** bump the go-minor-and-patch group across 1 directory with 5
updates ([openai#444](openai#444))
([263dadd](openai@263dadd))
* **deps:** bump the golang-x group across 1 directory with 2 updates
([openai#540](openai#540))
([52f0ad0](openai@52f0ad0))
* **deps:** update openai-go to v3.74.0
([openai#393](openai#393))
([e32158e](openai@e32158e))
* **deps:** update openai-go to v3.75.0
([openai#412](openai#412))
([077ae69](openai@077ae69))
* **deps:** update openai-go to v3.77.0
([openai#414](openai#414))
([835de59](openai@835de59))
* **deps:** update openai-go to v3.78.0
([openai#450](openai#450))
([8f79e98](openai@8f79e98))
* **deps:** update openai-go to v3.79.0
([openai#507](openai#507))
([0828c79](openai@0828c79))
* **deps:** update openai-go to v3.81.0
([openai#516](openai#516))
([6c26343](openai@6c26343))
* **deps:** update openai-go to v3.82.0
([openai#532](openai#532))
([00add07](openai@00add07))
* restore generated reporting tools without behavior changes
([openai#475](openai#475))
([c12cd56](openai@c12cd56))


### Documentation

* define CLI layout migration and compatibility contract
([openai#486](openai#486))
([e9ad31e](openai@e9ad31e))
* **windows:** explain JSON stderr capture in Windows PowerShell 5.1
([openai#443](openai#443))
([960af77](openai@960af77))


### Refactors

* **batches:** separate local workflows from assembly policy
([openai#547](openai#547))
([0486923](openai@0486923))
* extract CLI invocation runner into internal app
([openai#488](openai#488))
([ee7a731](openai@ee7a731))
* **files:** separate handwritten workflows and shared shell helpers
([openai#546](openai#546))
([a6bfb0b](openai@a6bfb0b))
* **input:** move non-consuming piped input probes
([openai#529](openai#529))
([904c95d](openai@904c95d))
* isolate browser platform handling in internal/terminal
([openai#504](openai#504))
([9d304ca](openai@9d304ca))
* isolate command-tree organization
([openai#515](openai#515))
([b5cc7a8](openai@b5cc7a8))
* isolate generated tokenizer tables
([openai#496](openai#496))
([efda414](openai@efda414))
* isolate the Codex command feature
([openai#509](openai#509))
([a6530ae](openai@a6530ae))
* isolate the manpage command feature
([openai#514](openai#514))
([7617d3d](openai@7617d3d))
* isolate the shared terminal output runtime
([openai#512](openai#512))
([d93d0d0](openai@d93d0d0))
* isolate the tokenizer command feature
([openai#513](openai#513))
([fb023ee](openai@fb023ee))
* keep mTLS transport construction in internal/request
([openai#522](openai#522))
([393e1ae](openai@393e1ae))
* keep request-input help with its renderer
([openai#519](openai#519))
([5791763](openai@5791763))
* **lists:** add shared paged-list navigation runtime
([openai#389](openai#389))
([d866707](openai@d866707))
* **lists:** prepare compact table rendering for resource lists
([openai#390](openai#390))
([c65e03e](openai@c65e03e))
* move command recovery into help
([openai#517](openai#517))
([5662bc2](openai@5662bc2))
* move response transformations into internal output
([openai#487](openai#487))
([55ebd62](openai@55ebd62))
* **output:** move finite JSON list framing and paging
([openai#537](openai#537))
([ee77628](openai@ee77628))
* **output:** move lazy transformation iterator
([openai#535](openai#535))
([ad22022](openai@ad22022))
* **output:** move pager and stdout streaming runtime
([openai#536](openai#536))
([cb5a5a8](openai@cb5a5a8))
* **output:** move readable list and stream rendering
([openai#538](openai#538))
([8b304b0](openai@8b304b0))
* **output:** move result formatting and format selection
([openai#534](openai#534))
([50db1df](openai@50db1df))
* **request:** extract piped input reading and merge policy
([openai#528](openai#528))
([068bddc](openai@068bddc))
* **request:** move default client options and URL validation
([openai#530](openai#530))
([211f056](openai@211f056))
* **request:** move file expansion and single-use stdin
([openai#526](openai#526))
([8be3c0b](openai@8be3c0b))
* **request:** move multipart encoding and owned uploads
([openai#524](openai#524))
([73f9a1f](openai@73f9a1f))
* **request:** move shared flag and stdin preparation
([openai#533](openai#533))
([8e64575](openai@8e64575))
* **request:** move stdin provenance and input policies
([openai#525](openai#525))
([ac5aa07](openai@ac5aa07))
* **request:** move streaming mode resolution
([openai#527](openai#527))
([64ae997](openai@64ae997))
* **request:** separate final encoding from feature hooks
([openai#531](openai#531))
([711596c](openai@711596c))
* separate generated API commands from handwritten CLI code
([openai#500](openai#500))
([d44fb85](openai@d44fb85))
* separate generated commands from CLI compatibility behavior
([openai#474](openai#474))
([08df3f6](openai@08df3f6))
* share literal request headers through internal/request
([openai#521](openai#521))
([a9f35b9](openai@a9f35b9))
* share output writing and error classification
([openai#506](openai#506))
([bce2ab8](openai@bce2ab8))
* share root request flags and mTLS configuration
([openai#523](openai#523))
([a718ab6](openai@a718ab6))
* share terminal color and presentation policy
([openai#508](openai#508))
([575d494](openai@575d494))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.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.

3 participants