Skip to content

gh pr edit: new interactive prompt for assignee selection, performance and accessibility improvements#12526

Merged
BagToad merged 23 commits intotrunkfrom
github-cli-1070-multi-select-with-search-ccr
Jan 27, 2026
Merged

gh pr edit: new interactive prompt for assignee selection, performance and accessibility improvements#12526
BagToad merged 23 commits intotrunkfrom
github-cli-1070-multi-select-with-search-ccr

Conversation

@BagToad
Copy link
Member

@BagToad BagToad commented Jan 22, 2026

Description

Implements multiselect with search for gh pr edit assignees, addressing performance and accessibility issues in large organizations. Part of larger work to improve the reviewer and assignee experience in gh.

Key changes

  • New MultiSelectWithSearch prompter: Adds a search sentinel option to multiselect lists, allowing dynamic fetching of assignees via API search rather than loading all org members upfront
  • SuggestedAssignableActors API: New GraphQL query to fetch suggested actors for an assignable (Issue/PR) node with optional search filtering
  • gh pr edit assignee flow: Wires up the new prompter for interactive assignee selection when ActorIsAssignable feature is detected
  • Prompter interface expansion: Both surveyPrompter and accessiblePrompter implement the new method, with full test coverage
  • Preview command: Adds multi-select-with-search to gh preview prompter for testing

Notes for reviewers

  • This PR only covers assignees for gh pr edit; reviewers will follow in a subsequent PR

@BagToad BagToad force-pushed the github-cli-1070-multi-select-with-search-ccr branch from 25ce0f4 to 2a50965 Compare January 22, 2026 21:51
@BagToad BagToad changed the title WIP: Multiselect with search for gh pr edit WIP: Multiselect with search for gh pr edit with assignees Jan 22, 2026
BagToad and others added 15 commits January 26, 2026 13:29
Updated the Prompt interface in survey.go to include parameter names for all methods, improving code readability and clarity.
Initial implementation of MultiSelectWithSearch:

- Implement by survey and accessible prompters. They use the same internal func under the hood.
- Implement in `gh preview prompter` for initial testing and demonstration
- Implement interface changes across the codebase and mocks to satisfy compiler.
- Implement tests for new MultiSelectWithSearch prompter
Introduces SuggestedAssignableActors API query and wires up a dynamic assignee search function in the PR edit command. Updates Editable and EditPrompter interfaces to support search-based multi-select for assignees, improving the user experience when assigning users to pull requests.
The assigneeSearchFunc now receives the editable struct to update its Metadata.AssignableActors field with suggested assignable actors. This change ensures that the editable struct has the necessary actor metadata for later PR updates.
Added a comment explaining how to enable logging in expect-based tests by using expect.WithLogger. This helps developers debug by printing characters read to stdout.
Refactored the MultiSelectWithSearch function and related interfaces to use a MultiSelectSearchResult struct instead of multiple return values. This change improves clarity and extensibility of the search function signature, and updates all usages, mocks, and tests accordingly.
Updated test mocks and logic to consistently use lowercase 'monalisa' for login names and display names for user assignees. Improved handling of dynamic assignee fetching in interactive flows by relying on searchFunc and metadata population, and clarified logic in FetchOptions to fetch assignees only when necessary. These changes ensure more accurate simulation of interactive assignment and better test coverage for actor assignee features.
Updated the TODO comment to specify wiring up the reviewer search function if or when it exists, providing clearer intent for future development.
Co-authored-by: Babak K. Shandiz <babakks@github.com>
Co-authored-by: Babak K. Shandiz <babakks@github.com>
Simplifies SuggestedAssignableActors by no longer including the viewer in the returned actors list when the query is blank. Removes related logic and variables for viewer handling.
Refactored the construction of the variables map by directly assigning the 'query' key, removing the conditional logic for nil assignment.
Added detailed comments to the assigneeSearchFunc explaining its purpose and the importance of updating assignable actors metadata for later ID resolution when mutating assignees with the GraphQL API.
@BagToad BagToad force-pushed the github-cli-1070-multi-select-with-search-ccr branch from f3c2378 to e3a3a01 Compare January 26, 2026 20:29
@BagToad BagToad changed the title WIP: Multiselect with search for gh pr edit with assignees Multiselect with search for gh pr edit with assignees Jan 26, 2026
@BagToad BagToad changed the title Multiselect with search for gh pr edit with assignees gh pr edit: new interactive prompt for assignee selection, performance and accessibility improvements Jan 26, 2026
Deleted the Viewer struct from the responseData type in SuggestedAssignableActors as it was not being used.
Introduces a test case to verify that the interactive edit flow on GitHub Enterprise Server uses the legacy assignee selection without search, ensuring correct behavior when editing pull request assignees.
Introduces a test case to verify that errors returned from the MultiSelectWithSearch search function are properly propagated to the caller.
Updated SuggestedAssignableActors to return the total count of available assignees in the repository. Modified assigneeSearchFunc to use this count to calculate and display the number of additional assignees beyond the current results.
@BagToad BagToad marked this pull request as ready for review January 26, 2026 21:52
@BagToad BagToad requested a review from a team as a code owner January 26, 2026 21:52
@BagToad BagToad requested review from babakks and Copilot January 26, 2026 21:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an interactive multi-select prompt with on-demand search for assignee selection in gh pr edit, aiming to avoid loading large org member lists upfront and to improve accessibility.

Changes:

  • Introduces MultiSelectWithSearch in the prompter layer (survey + accessible) and extends mocks/tests to support it.
  • Wires assignee search into gh pr edit when ActorIsAssignable is available, plus a preview command to exercise the new prompt.
  • Adds a new GraphQL helper (SuggestedAssignableActors) intended to back dynamic assignee search.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/cmd/preview/prompter/prompter.go Adds a preview entry point for the new multi-select-with-search prompt.
pkg/cmd/pr/shared/survey.go Extends shared survey prompt interface to include MultiSelectWithSearch.
pkg/cmd/pr/shared/editable.go Adds assignee search hook to the editable model and uses MultiSelectWithSearch when available.
pkg/cmd/pr/edit/edit.go Wires assignee search function into gh pr edit for Actor assignees and updates fetch behavior.
pkg/cmd/pr/edit/edit_test.go Updates PR edit tests for the new Actor assignee flow and metadata handling.
pkg/cmd/issue/edit/edit_test.go Updates issue edit test fixtures for actor login casing changes.
internal/prompter/prompter.go Adds MultiSelectWithSearch implementation and supporting types.
internal/prompter/accessible_prompter_test.go Adds accessible prompter tests covering the new search flow.
internal/prompter/test.go Extends mock prompter helpers to stub MultiSelectWithSearch.
internal/prompter/prompter_mock.go Extends generated mock to support MultiSelectWithSearch calls.
api/queries_pr.go Adds SuggestedAssignableActors GraphQL query helper.
Comments suppressed due to low confidence (2)

internal/prompter/prompter.go:394

  • The search sentinel uses an empty-string key (optionKeys = append(optionKeys, "")). If defaultValues, persistentValues, or searchFunc results ever contain an empty key, it will collide with the sentinel and can drop selections or create duplicates. Filter out empty keys (and/or use a reserved non-empty sentinel key).
		// 1. Search sentinel.
		optionKeys = append(optionKeys, "")
		if moreResults > 0 {
			optionLabels = append(optionLabels, fmt.Sprintf("Search (%d more)", moreResults))
		} else {

pkg/cmd/pr/edit/edit.go:386

  • MoreResults is set to availableAssigneesCount (repo-wide assignable user total), but multiSelectWithSearch displays this as "Search (%d more)", which implies “more results for this search”. Either compute an actual remaining-results count (if available) or adjust the label/semantics so the number isn’t misleading.
		return prompter.MultiSelectSearchResult{
			Keys:        logins,
			Labels:      displayNames,
			MoreResults: availableAssigneesCount,
			Err:         nil,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

searchResultKeys := searchResult.Keys
searchResultLabels := searchResult.Labels
moreResults := searchResult.MoreResults

Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

multiSelectWithSearch indexes searchResultLabels[i] for each key without validating slice lengths. If a searchFunc returns mismatched Keys/Labels lengths, this will panic. Validate lengths and return a clear error (or use a slice of {Key, Label} pairs).

Suggested change
if len(searchResultLabels) != len(searchResultKeys) {
return nil, fmt.Errorf("failed to search: mismatched result lengths: %d keys, %d labels", len(searchResultKeys), len(searchResultLabels))
}

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

I think I'd rather see the panic error

BagToad and others added 3 commits January 26, 2026 15:05
Cleaned up obsolete TODO comments related to assignee and reviewer selection logic in the MetadataSurvey function.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Deleted a comment about the query variable being passed as null when empty, as it is no longer relevant or necessary.
Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

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

LGTM! Reviewed in sync! 🍻

@BagToad BagToad merged commit 6adf803 into trunk Jan 27, 2026
11 checks passed
@BagToad BagToad deleted the github-cli-1070-multi-select-with-search-ccr branch January 27, 2026 16:16
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Feb 25, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.86.0` → `v2.87.3` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.87.3`](https://github.com/cli/cli/releases/tag/v2.87.3): GitHub CLI 2.87.3

[Compare Source](cli/cli@v2.87.2...v2.87.3)

#### What's Changed

- Fix project mutation query variable usage by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12757](cli/cli#12757)

**Full Changelog**: <cli/cli@v2.87.2...v2.87.3>

### [`v2.87.2`](https://github.com/cli/cli/releases/tag/v2.87.2): GitHub CLI 2.87.2

[Compare Source](cli/cli@v2.87.1...v2.87.2)

#### ℹ️ Note

This release was cut primarily to resolve a publishing issue. We recommend reviewing [the v2.87.1 release notes](https://github.com/cli/cli/releases/tag/v2.87.1) for the complete set of latest features and fixes.

#### What's Changed

- chore(deps): bump golang.org/x/crypto from 0.47.0 to 0.48.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12659](cli/cli#12659)

**Full Changelog**: <cli/cli@v2.87.1...v2.87.2>

### [`v2.87.1`](https://github.com/cli/cli/releases/tag/v2.87.1): GitHub CLI 2.87.1

[Compare Source](cli/cli@v2.87.0...v2.87.1)

#### ⚠️ Incomplete Release

The v2.87.1 release experienced a failure in our workflow and is not fully published to the designated package managers/repositories. This is resolved in [v2.87.2](https://github.com/cli/cli/releases/tag/v2.87.2), so we recommend using that release instead.

#### What's Changed

- Remove license bundling debris by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12716](cli/cli#12716)
- fix(agent-task/capi): use a fixed CAPI API version by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12731](cli/cli#12731)

**Full Changelog**: <cli/cli@v2.87.0...v2.87.1>

### [`v2.87.0`](https://github.com/cli/cli/releases/tag/v2.87.0): GitHub CLI 2.87.0

[Compare Source](cli/cli@v2.86.0...v2.87.0)

#### `gh workflow run` immediately returns workflow run URL

One of our most requested features - with the latest changes in GitHub API, `gh workflow run` will immediately print the created workflow run URL.

#### Improved `gh auth login` experience in VM/WSL environments

We have observed rare cases of time drift between the wall and monotonic clocks, mostly in WSL or VM environments, causing failures during polling for the OAuth token. This new release implements measures to account for such situations.

If you continue to experience `gh auth login` issues in WSL, please comment in [#&#8203;9370](cli/cli#9370)

#### :copilot: Request Copilot Code Review from `gh` + performance improvements

`gh pr edit` now supports [Copilot Code Review](https://docs.github.com/en/copilot/using-github-copilot/code-review/using-copilot-code-review) as a reviewer. You can request a review from Copilot using the `--add-reviewer @&#8203;copilot` flag or interactively by selecting reviewers in the prompts.

This release also introduces a new search experience for selecting reviewers and assignees in `gh pr edit`. Instead of loading all collaborators and teams upfront, results are now fetched based on inputs to a new search option. Initial options are suggestions based on those involved with the pull request already.

```
? Reviewers  [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]
  [ ]  Search (7472 more)
  [x]  BagToad (Kynan Ware)
> [x]  Copilot (AI)
```

This experience will follow in `gh pr create` and `gh issue` for assignees in a later release.

#### What's Changed

##### ✨ Features

- Bundle licenses at release time by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12625](cli/cli#12625)
- Add `--query` flag to `project item-list` by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12696](cli/cli#12696)
- feat(workflow run): retrieve workflow dispatch run details by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12695](cli/cli#12695)
- Pin REST API version to 2022-11-28 by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12680](cli/cli#12680)
- Respect `--exit-status` with `--log` and `--log-failed` in `run view` by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12679](cli/cli#12679)
- Fork with default branch only during pr create by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12673](cli/cli#12673)
- `gh pr edit`: Add support for Copilot as reviewer with search capability, performance and accessibility improvements by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12567](cli/cli#12567)
- `gh pr edit`: new interactive prompt for assignee selection, performance and accessibility improvements by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12526](cli/cli#12526)

##### 📚 Docs & Chores

- Clean up project item-list query addition changes by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12714](cli/cli#12714)
- `gh release upload`: Clarify `--clobber` flag deletes assets before re-uploading by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12711](cli/cli#12711)
- Add usage examples to `gh gist edit` command by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12710](cli/cli#12710)
- Remove feedback issue template by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12708](cli/cli#12708)
- Migrate issue triage workflows to shared workflows by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12677](cli/cli#12677)
- Migrate MR triage workflows to shared workflows by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12707](cli/cli#12707)
- Add missing TODO comments for featuredetection if-statements by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12701](cli/cli#12701)
- Add manual dispatch to bump-go workflow by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12631](cli/cli#12631)
- typo: dont to don't by [@&#8203;cuiweixie](https://github.com/cuiweixie) in [#&#8203;12554](cli/cli#12554)
- Fix fmt.Errorf format argument in ParseFullReference by [@&#8203;mikelolasagasti](https://github.com/mikelolasagasti) in [#&#8203;12516](cli/cli#12516)
- Lint source.md by [@&#8203;Sethispr](https://github.com/Sethispr) in [#&#8203;12521](cli/cli#12521)

##### :dependabot: Dependencies

- chore(deps): bump golang.org/x/text from 0.32.0 to 0.33.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12468](cli/cli#12468)
- chore(deps): bump golang.org/x/term from 0.38.0 to 0.39.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12616](cli/cli#12616)
- Bump go to 1.25.7 by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12630](cli/cli#12630)
- chore(deps): bump golang.org/x/crypto from 0.46.0 to 0.47.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12629](cli/cli#12629)
- chore: bump `cli/oauth` to `v1.2.2` by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12573](cli/cli#12573)
- update Go to 1.25.6 by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12580](cli/cli#12580)
- chore(deps): bump actions/attest-build-provenance from 3.1.0 to 3.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12558](cli/cli#12558)
- chore(deps): bump github.com/sigstore/rekor from 1.4.3 to 1.5.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12524](cli/cli#12524)
- chore(deps): bump github.com/theupdateframework/go-tuf/v2 from 2.3.1 to 2.4.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12555](cli/cli#12555)
- chore(deps): bump github.com/gdamore/tcell/v2 from 2.13.4 to 2.13.7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12469](cli/cli#12469)
- chore(deps): bump github.com/sigstore/sigstore from 1.10.0 to 1.10.4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12525](cli/cli#12525)
- chore(deps): bump github.com/theupdateframework/go-tuf/v2 from 2.3.0 to 2.3.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12515](cli/cli#12515)
- chore(deps): bump actions/download-artifact from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12314](cli/cli#12314)
- chore(deps): bump actions/upload-artifact from 5 to 6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12315](cli/cli#12315)
- chore(deps): bump goreleaser/goreleaser-action from 6.0.0 to 6.4.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12354](cli/cli#12354)

#### New Contributors

- [@&#8203;Sethispr](https://github.com/Sethispr) made their first contribution in [#&#8203;12521](cli/cli#12521)
- [@&#8203;cuiweixie](https://github.com/cuiweixie) made their first contribution in [#&#8203;12554](cli/cli#12554)

**Full Changelog**: <cli/cli@v2.86.0...v2.87.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNC4yIiwidXBkYXRlZEluVmVyIjoiNDMuMzEuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
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