Skip to content

feat(images): open the picker with Tab in supported shells - #359

Merged
saioai merged 9 commits into
mainfrom
codex/picker-3-tab
Oct 3, 2026
Merged

saioai merged 9 commits into
mainfrom
codex/picker-3-tab

Conversation

@saioai

@saioai saioai commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

The image picker currently opens when you press Enter after openai images generate. This adds an optional Tab shortcut for Bash, zsh and fish, while keeping ordinary command and file completion.

What changes

  • Open the picker with Tab on the complete bare image-generation command; Ctrl+C returns to the editable shell line.
  • Preserve existing completion, custom bindings and later binding replacements. openai_picker_disable turns the shortcut off in the current session.
  • Keep normal Tab completion in PowerShell and Bash before 4.3; Enter opens the picker.
  • Keep ordinary Bash completion compatible with Bash 3.2 and preserve the caller's file variable. Other commands retain normal Tab-key completion behavior.
  • Support Bash emacs and vi modes, including re-enabling after a temporary custom Tab binding.

Commands

The existing @completion command gains an explicit --picker option:

source <(openai @completion bash --picker) # Bash 4.3+
source <(openai @completion zsh --picker) # After compinit
openai @completion fish --picker | source

Scripts without --picker retain ordinary completion. The opt-in affects only the current shell and writes no startup files. Shortcut guide.

Code

Builds on #357, now merged into main. This remains independent of #358 (remembered settings). internal/autocomplete owns script rendering and shell hooks. The existing pkg/custom configurator adds the flag and fixed PowerShell guidance. Main, generated commands and dependencies are unchanged.

Tested

The Bash review fixes pass 171 autocomplete test/subtest results under the race detector and five public completion results, without skips on macOS arm64. New native Bash regressions cover key-sensitive completion for another command and disable/restore/re-enable in both emacs and vi modes. Both reported issues reproduce on the previous code. Build, focused vet and the trusted main custom-code budget check pass (435/1,000).

An independent reviewer passed 18 workflows using the emitted script and real Bash line editors, including repeated completion, replaced/private bindings, re-enabling and actual picker cancellation. The earlier merged-core checks passed 63 public CLI/native-shell, 75 picker race and 50 synthetic PTY/process results; their core code is unchanged by this two-file fix.

Hosted CI passed on the previous commit and will rerun for this update. Native Windows/Linux picker execution and the full platform campaign remain deferred.

Demo

macOS arm64 native zsh PTY replay, core 8fefbb8 to Tab candidate 238bc32. Before, Tab leaves the bare command in the shell; after enabling the shortcut, Tab opens the picker. No API request or real profile changes. The later module-classification fix and main update preserve this recorded Tab workflow; the new candidate was checked with fresh native-shell runs.

Before and after

Before:

Before

After:

After

Recording recipe and original captures. Native shortcut regression checks.

Base automatically changed from codex/picker-1-core to main October 3, 2026 03:55
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Castiron custom code

Evaluated main: 58edd84760a48b91d75e58afd0b6da056d95fbcd.

✅ No new custom-code files detected.

6 mixed files remain; 0 existing customizations changed.

Compared 100628d84900 → 8f1358463f00. Generated baselines verified.

6 existing customizations unchanged
  • pkg/cmd/adminorganizationcertificate.go
  • pkg/cmd/audiovoice.go
  • pkg/cmd/image.go
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py

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 37096471911 --repo openai/openai-cli \
  --name castiron-custom-code-37096471911-1 --dir /tmp/castiron-custom-code-37096471911-1
git apply --stat /tmp/castiron-custom-code-37096471911-1/custom-code.patch
cat /tmp/castiron-custom-code-37096471911-1/custom-code.patch

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

git fetch --no-tags origin 58edd84760a48b91d75e58afd0b6da056d95fbcd 8f1358463f00becdf37928ca4e723be864a289c6
python3 scripts/castiron/custom_code_report.py report \
  --base 58edd84760a48b91d75e58afd0b6da056d95fbcd \
  --head 8f1358463f00becdf37928ca4e723be864a289c6 --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-8f1358463f00
cat /tmp/castiron-custom-code-8f1358463f00/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 marked this pull request as ready for review October 3, 2026 04:08
@saioai
saioai requested a review from a team as a code owner October 3, 2026 04:08
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 3, 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-03T04:27:48.830154Z 8f13584 New commits
🔒 Security Review ✅ Completed 2026-10-03T04:28:57.892507Z 8f13584 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.

@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 6173092 against main 100628d. Two Bash issues remain. The Tab macro changes the key seen by other completion functions. A stale binding marker can also prevent re-enabling the picker. Details are inline.

Hosted CI is green on this commit. These findings come from source inspection; I did not run the shell tests locally.

Comment thread internal/autocomplete/shellscripts/bash_picker.bash Outdated
Comment thread internal/autocomplete/shellscripts/bash_picker.bash Outdated
@saioai
saioai added this pull request to the merge queue Oct 3, 2026
Merged via the queue into main with commit 8b6db1f Oct 3, 2026
23 checks passed
@saioai
saioai deleted the codex/picker-3-tab branch October 3, 2026 04:44
@openai-sdks openai-sdks Bot mentioned this pull request Oct 3, 2026
pedrobastosribeiro pushed a commit to pedrobastosribeiro/openai-cli that referenced this pull request Oct 3, 2026
The image picker resets its settings between invocations. This remembers
the last submitted image settings and save folder so the next image can
use the same setup. The prompt is not remembered: “Describe your image”
starts empty on every launch and after generation.

### What changes

- Remember the model, size, quality, background, file format, image
count and save folder. Prompt text is not saved in picker preferences.
- Reopen with those settings and an empty prompt after generation.
Canceling discards edits.
- Choose the default folder, current directory or another existing
folder. Tab completes folder names.
- Read older saved settings while ignoring their prompt field. Invalid
saved settings are kept; optional storage failures show a short warning.
- Preserve direct commands and the merged core's shell handling.
Generation still remembers settings when command printing is unavailable
for the shell.

### Commands

No new commands or flags.

```sh
openai images generate  # Restore image settings and start with an empty prompt.
openai images generate --prompt "A tiny orange robot"  # Use the direct command.
```

Choose Save to in the picker to change its output folder. The default is
`~/Downloads/gpt-images/`. Ctrl+C exits; Ctrl+P prints the selected
command without generating in Bash, zsh, fish and PowerShell 7. Only
image settings and the save folder are remembered in the local user
configuration folder.

### Code

`pkg/custom` handles folder selection, versioned local state and
submission ordering. The picker restores image settings separately from
its prompt; saved records omit prompt text. It reuses the core picker
and existing image saving. No generated command, dependency or startup
change relative to main.

Rebased onto main `100628d`, including merged openai#357's shell quoting and
output-error fixes. openai#359 remains a separate Tab-shortcut change.

### Tested

On the rebased candidate, macOS arm64: 80 focused picker tests passed
with the race detector, including 126 test/subtest pass results; two
shell subtests skipped because fish and PowerShell were unavailable. All
50 integrated CLI cases, 13 remembered-settings/folder cases and five
independent process probes passed with synthetic local fixtures.

Checks cover empty prompts on restart and automatic return, every
remembered setting, legacy records, cancellation, concurrent saves,
explicit JSON/flag paths and unsupported-shell generation. The
unsupported-shell persistence regression failed before its fix and
passed afterward. Independent adversarial review found no unresolved
demonstrated regression.

All packages compiled, module verification passed, and the trusted-main
custom-code budget and isolation checks passed at 435/1,000. Hosted CI
is running on this update. Native Windows/Linux picker execution and the
deferred graphical/platform campaign have not run.

### Demo

macOS arm64 synthetic PTY replay of the prompt correction. Before shows
the previous openai#358 behavior, using a retained binary with runtime sources
equivalent to `5f14e0c`; after is `5b6eb05` on merged main `100628d`.
Both use the same image settings and save folder. The description starts
empty afterward. No API calls.

![Before and
after](https://github.com/user-attachments/assets/7876ee4c-c586-42f2-b8be-a01cfd95baa5)

Before:

![Before: prompt and settings
restored](https://github.com/user-attachments/assets/a38034a3-133f-4d87-a455-fe6f3a83dc17)

After:

![After: image settings restored with an empty
prompt](https://github.com/user-attachments/assets/5fd1b6dc-bc4f-4ebc-8edd-130563b1a17e)

The GIF alternates the final Before and After frames. [Recording recipe,
provenance and original timed
captures](https://github.com/user-attachments/files/32988805/settings-only-demo-recipe.zip).
[Settings/folder regression
recipe](https://github.com/openai/openai-cli/blob/5b6eb05e4b3a21392f16289cdf14b8e8e3c2d97e/scripts/check-image-picker-reuse.py).
pedrobastosribeiro pushed a commit to pedrobastosribeiro/openai-cli that referenced this pull request Oct 3, 2026
Automated Release PR
---


##
[1.35.0](openai/openai-cli@v1.34.0...v1.35.0)
(2026-10-03)


### Features

* **images:** open the picker with Tab in supported shells
([openai#359](openai#359))
([8b6db1f](openai@8b6db1f))

---
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>
pedrobastosribeiro pushed a commit to pedrobastosribeiro/openai-cli that referenced this pull request Oct 4, 2026
The Tab shortcut previously needed activation in each shell session.
This saves it for future Bash, zsh and fish sessions, with explicit
removal and quiet first-use setup when the terminal and profile are
eligible.

### What changes

- Add installation/removal, explicit profile selection and a per-shell
opt-out. Consent and its decision lock stay under the native home's
`.openai/shell`, independently of XDG or AppData changes. Valid older
preferences in the current root migrate there.
- Preserve personal startup content, including line boundaries after
later edits. Keep unsafe permissions, hard links, ACLs and protected
metadata unchanged; Linux replacement accepts only matching SELinux
labels.
- Retain displaced profile files in private recovery directories,
including later edits through an open editor handle. Exclusive
publication preserves competing saves. Interrupted captures recover on
retry; completed removal stays absent. Recovery briefly leaves the
profile path absent, keeps at most 32 copies per profile, and requires
the recorded spelling for an ambiguous absent-path retry.
- Recognize equivalent profile paths and retain recorded script
locations after configuration changes, even if the newly selected
location is unusable. Retry verified obsolete-script cleanup after
interrupted refresh or removal, including a deleted startup directory,
while preserving modified or unproven files.
- Install fish's hook at the first prompt after user bindings. Managed
fish scripts honor the shared opt-out even when loaded from another XDG
root. Ordinary completion and current-session `--picker` remain
available.
- Find earlier Bash setup after login-file precedence changes, remove
empty profiles created by the CLI when ownership is recorded, and
continue independent cleanup after a profile fails.
- Require an exported absolute `ZDOTDIR` for default zsh targeting;
otherwise use an explicit profile. Automatic setup skips ambiguous zsh
locations. PowerShell retains ordinary Tab completion and Enter access
to the picker.
- Keep noninteractive and read-only commands free of automatic setup
writes. Bound the foreground wait for optional setup to 250
milliseconds; existing sessions keep their bindings.

### Commands

The existing `@completion` command gains setup options:

```sh
openai @completion zsh --install-picker --profile "${ZDOTDIR-$HOME}/.zshrc"
openai @completion zsh --uninstall-picker --profile "${ZDOTDIR-$HOME}/.zshrc"
openai @completion bash --install-picker --profile /path/to/startup
openai @completion --install-picker --automatic # Preserve automatic opt-out
```

Run the zsh examples in zsh so it expands its own startup location,
including unexported `ZDOTDIR`. Bash and fish accept
installation/removal without `--profile`. Omitted shell uses the
immediate parent for explicit setup. On Windows, default targeting
requires `HOME` to identify the native user home; otherwise use
`--profile`. Bash's Tab shortcut needs 4.3 or later; Enter remains
available in Bash 3.2. Open a new terminal after setup. [Setup
guide](https://github.com/openai/openai-cli/blob/6ee29f3d6047c1cc132098f31c9141d69816c88c/docs/image-picker-shell-setup.md).

### Code

Built on merged openai#358 and openai#359, rebased onto main `759464e`. `pkg/custom`
owns eligibility, profile selection, flags and consent.
`internal/autocomplete` owns scripts, locks, profile transactions and
metadata checks. Existing shell detection, rendering and private state
helpers are reused. Main adds first-use wiring and exempts actual local
setup actions from API configuration initialization. Generated commands,
dependencies and packaging are unchanged.

### Tested

At `6ee29f3`, 572 focused race test/subtest results, 58 public command
results and 22 independent CLI probes pass. Recovery regressions cover
late atomic and in-place editor saves, held file handles, process exit
after capture, competing publication, cancellation, failed completion
recording, 32-copy capacity, ambiguous profile aliases, and independent
pending captures. The installed-profile recipe passes in Bash 5.3, zsh,
fish 4.9.3 and Bash 3.2 fallback. One local case-sensitive-volume test
skips on this macOS filesystem.

All packages compile, native vet and Windows test compilation pass.
Module verification and the trusted-main custom-code budget pass. All 21
hosted checks pass at final head `3cca018`, with two expected skips.
Native Windows passes 474 results with 20 platform skips; native macOS
passes 524 results with 19 environment skips. All recovery and Windows
editor denial/retry cases pass. The full Linux suite, artifact build,
lint, CodeQL and native help checks pass. Automated code and security
reviews completed without new findings; all review threads are resolved.
The test-only follow-up has 40 fresh local recovery results and an
independent 62-result review; runtime source is unchanged from
`6ee29f3`. Synthetic SELinux label/error tests pass; the native Linux
SELinux lifecycle check skips because the runner assigns no labels, and
an enforcing SELinux host has not been tested. Special-mode checks run
outside the sandbox because it strips fixture bits. All profile writes
use synthetic temporary locations.

Older unguarded fish scripts need one refresh in their original root to
honor the new opt-out. An unknown historical preference root must be
selected once for migration. Actual stalled network filesystems and the
full platform/package-manager campaign remain untested. Already-issued
filesystem operations may finish after the foreground timeout;
unprovably owned files are retained. Windows junction/reparse ancestry
requires manual setup.

### Demo

macOS arm64, native zsh in a synthetic PTY, base `562318d` to candidate
`1000ca7`. Installation writes only a temporary test profile; a new zsh
reads it and Tab opens the picker. No real profile or API request. This
recording demonstrates the original setup flow; the follow-up lifecycle
fixes are covered by the checks above.

![Before and
after](https://github.com/user-attachments/assets/2b384ac6-c8b8-42ab-b4de-932841f7d52c)

Before:


![Before](https://github.com/user-attachments/assets/139e8120-8fdc-4966-8048-7217cc729e27)

After:


![After](https://github.com/user-attachments/assets/83b0c2ac-151d-4174-898b-fb4ac63be576)

[Recording recipe and original
captures](https://github.com/user-attachments/files/32985306/setup-demo-recipe.zip),
using the [shared capture/render
workflow](https://github.com/openai/openai-cli/blob/4a8082b7f4d67a9c065696fd80d6cbd61543990f/scripts/demos/capture_and_render.sh).
[Native shell regression
recipe](https://github.com/openai/openai-cli/blob/6ee29f3d6047c1cc132098f31c9141d69816c88c/scripts/check-image-picker-setup.py).
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